telepathy-glib: Actually implement room listing
Guillaume Desmottes
gdesmott at kemper.freedesktop.org
Mon Apr 30 02:47:38 PDT 2012
Module: telepathy-glib
Branch: master
Commit: 911847cd4fb1c1a27ebc0f537d8afe5032f4143c
URL: http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=911847cd4fb1c1a27ebc0f537d8afe5032f4143c
Author: Guillaume Desmottes <guillaume.desmottes at collabora.co.uk>
Date: Thu Apr 12 14:38:09 2012 +0200
Actually implement room listing
---
telepathy-glib/room-list-channel.c | 78 +++++++++++++++++++++++++++++++++++-
telepathy-glib/room-list-channel.h | 1 +
tests/dbus/room-list-channel.c | 44 ++++++++++++++++++++-
tests/lib/room-list-chan.c | 50 +++++++++++++++++++++++
4 files changed, 171 insertions(+), 2 deletions(-)
diff --git a/telepathy-glib/room-list-channel.c b/telepathy-glib/room-list-channel.c
index 7d57e0f..35bcb3d 100644
--- a/telepathy-glib/room-list-channel.c
+++ b/telepathy-glib/room-list-channel.c
@@ -54,6 +54,7 @@
#include <telepathy-glib/gnio-util.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/room-info-internal.h>
#include <telepathy-glib/util.h>
#include <telepathy-glib/util-internal.h>
@@ -96,6 +97,13 @@ enum
PROP_LISTING,
};
+enum {
+ SIG_GOT_ROOMS,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
static void
tp_room_list_channel_get_property (GObject *object,
guint property_id,
@@ -121,16 +129,44 @@ tp_room_list_channel_get_property (GObject *object,
}
static void
+got_rooms_cb (TpChannel *channel,
+ const GPtrArray *rooms,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ TpRoomListChannel *self = TP_ROOM_LIST_CHANNEL (channel);
+ guint i;
+
+ for (i = 0; i < rooms->len; i++)
+ {
+ TpRoomInfo *room;
+
+ room = _tp_room_info_new (g_ptr_array_index (rooms, i));
+ g_signal_emit (self, signals[SIG_GOT_ROOMS], 0, room);
+ g_object_unref (room);
+ }
+}
+
+static void
tp_room_list_channel_constructed (GObject *obj)
{
+ TpChannel *channel = TP_CHANNEL (obj);
GHashTable *props;
const char *type;
+ GError *error = NULL;
- props = tp_channel_borrow_immutable_properties (TP_CHANNEL (obj));
+ props = tp_channel_borrow_immutable_properties (channel);
g_assert (props != NULL);
type = tp_asv_get_string (props, TP_PROP_CHANNEL_CHANNEL_TYPE);
g_assert_cmpstr (type, ==, TP_IFACE_CHANNEL_TYPE_ROOM_LIST);
+
+ if (tp_cli_channel_type_room_list_connect_to_got_rooms (channel,
+ got_rooms_cb, NULL, NULL, NULL, &error) == NULL)
+ {
+ WARNING ("Failed to connect GotRooms signal: %s", error->message);
+ g_error_free (error);
+ }
}
enum {
@@ -263,6 +299,22 @@ tp_room_list_channel_class_init (TpRoomListChannelClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_LISTING, param_spec);
+
+ /**
+ * TpRoomListChannel::got-rooms:
+ * @self: a #TpRoomListChannel
+ *
+ * TODO
+ *
+ * Since: UNRELEASED
+ */
+ signals[SIG_GOT_ROOMS] = g_signal_new ("got-rooms",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1, TP_TYPE_ROOM_INFO);
+
g_type_class_add_private (gobject_class, sizeof (TpRoomListChannelPrivate));
}
@@ -354,6 +406,17 @@ list_rooms_cb (TpChannel *channel,
g_simple_async_result_complete (result);
}
+/**
+ * tp_room_list_channel_start_listing_async:
+ * @self: a #TpRoomListChannel
+ * @callback: a callback to call when room listing have been started
+ * @user_data: data to pass to @callback
+ *
+ * Start listing rooms using @self. Use the TpRoomListChannel::got-rooms
+ * signal to get the rooms found.
+ *
+ * Since: UNRELEASED
+ */
void
tp_room_list_channel_start_listing_async (TpRoomListChannel *self,
GAsyncReadyCallback callback,
@@ -368,6 +431,19 @@ tp_room_list_channel_start_listing_async (TpRoomListChannel *self,
list_rooms_cb, result, g_object_unref, G_OBJECT (self));
}
+/**
+ * tp_room_list_channel_start_listing_finish:
+ * @self: a #TpRoomListChannel
+ * @result: a #GAsyncResult
+ * @error: a #GError to fill
+ *
+ * <!-- -->
+ *
+ * Returns: %TRUE if the room listing process has been started,
+ * %FALSE otherwise.
+ *
+ * Since: UNRELEASED
+ */
gboolean
tp_room_list_channel_start_listing_finish (TpRoomListChannel *self,
GAsyncResult *result,
diff --git a/telepathy-glib/room-list-channel.h b/telepathy-glib/room-list-channel.h
index 6e79b79..253ebef 100644
--- a/telepathy-glib/room-list-channel.h
+++ b/telepathy-glib/room-list-channel.h
@@ -22,6 +22,7 @@
#define __TP_ROOM_LIST_CHANNEL_H__
#include <telepathy-glib/channel.h>
+#include <telepathy-glib/room-info.h>
G_BEGIN_DECLS
diff --git a/tests/dbus/room-list-channel.c b/tests/dbus/room-list-channel.c
index e8fd128..39ffd73 100644
--- a/tests/dbus/room-list-channel.c
+++ b/tests/dbus/room-list-channel.c
@@ -32,6 +32,7 @@ typedef struct {
TpConnection *connection;
TpRoomListChannel *channel;
+ GPtrArray *rooms; /* reffed TpRoomInfo */
GError *error /* initialized where needed */;
gint wait;
} Test;
@@ -77,6 +78,8 @@ setup (Test *test,
test->error = NULL;
+ test->rooms = g_ptr_array_new_with_free_func (g_object_unref);
+
/* Create (service and client sides) connection objects */
tp_tests_create_and_connect_conn (TP_TESTS_TYPE_CONTACTS_CONNECTION,
"me at test.com", &test->base_connection, &test->connection);
@@ -101,6 +104,7 @@ teardown (Test *test,
g_object_unref (test->base_connection);
tp_clear_object (&test->channel);
+ g_ptr_array_unref (test->rooms);
}
static void
@@ -175,10 +179,24 @@ notify_cb (GObject *object,
}
static void
+got_rooms_cb (TpRoomListChannel *channel,
+ TpRoomInfo *room,
+ Test *test)
+{
+ g_ptr_array_add (test->rooms, g_object_ref (room));
+
+ test->wait--;
+ if (test->wait <= 0)
+ g_main_loop_quit (test->mainloop);
+}
+
+static void
test_listing (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GQuark features[] = { TP_ROOM_LIST_CHANNEL_FEATURE_LISTING, 0 };
+ TpRoomInfo *room;
+ gboolean known;
g_assert (!tp_room_list_channel_get_listing (test->channel));
@@ -193,14 +211,38 @@ test_listing (Test *test,
g_signal_connect (test->channel, "notify::listing",
G_CALLBACK (notify_cb), test);
+ g_signal_connect (test->channel, "got-rooms",
+ G_CALLBACK (got_rooms_cb), test);
+
tp_room_list_channel_start_listing_async (test->channel, start_listing_cb,
test);
- test->wait = 2;
+ test->wait = 5;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (tp_room_list_channel_get_listing (test->channel));
+
+ g_assert_cmpuint (test->rooms->len, ==, 3);
+
+ room = g_ptr_array_index (test->rooms, 0);
+ g_assert (TP_IS_ROOM_INFO (room));
+
+ g_assert_cmpuint (tp_room_info_get_handle (room), ==, 0);
+ g_assert_cmpstr (tp_room_info_get_channel_type (room), ==,
+ TP_IFACE_CHANNEL_TYPE_TEXT);
+ g_assert_cmpstr (tp_room_info_get_handle_name (room), ==, "the handle name");
+ g_assert_cmpstr (tp_room_info_get_name (room), ==, "the name");
+ g_assert_cmpstr (tp_room_info_get_description (room), ==, "the description");
+ g_assert_cmpstr (tp_room_info_get_subject (room), ==, "the subject");
+ g_assert_cmpuint (tp_room_info_get_members (room, &known), ==, 10);
+ g_assert (known);
+ g_assert (tp_room_info_get_requires_password (room, &known));
+ g_assert (known);
+ g_assert (tp_room_info_get_invite_only (room, &known));
+ g_assert (known);
+ g_assert_cmpstr (tp_room_info_get_room_id (room), ==, "the room id");
+ g_assert_cmpstr (tp_room_info_get_server (room), ==, "the server");
}
int
diff --git a/tests/lib/room-list-chan.c b/tests/lib/room-list-chan.c
index 5336eb5..481beaa 100644
--- a/tests/lib/room-list-chan.c
+++ b/tests/lib/room-list-chan.c
@@ -154,6 +154,54 @@ tp_tests_room_list_chan_init (TpTestsRoomListChan *self)
}
static void
+add_room (GPtrArray *rooms)
+{
+ GHashTable *hash;
+
+ hash = tp_asv_new (
+ "handle-name", G_TYPE_STRING, "the handle name",
+ "name", G_TYPE_STRING, "the name",
+ "description", G_TYPE_STRING, "the description",
+ "subject", G_TYPE_STRING, "the subject",
+ "members", G_TYPE_UINT, 10,
+ "password", G_TYPE_BOOLEAN, TRUE,
+ "invite-only", G_TYPE_BOOLEAN, TRUE,
+ "room-id", G_TYPE_STRING, "the room id",
+ "server", G_TYPE_STRING, "the server",
+ NULL);
+
+ g_ptr_array_add (rooms, tp_value_array_build (3,
+ G_TYPE_UINT, 0,
+ G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+ TP_HASH_TYPE_STRING_VARIANT_MAP, hash,
+ G_TYPE_INVALID));
+
+ g_hash_table_unref (hash);
+}
+
+static gboolean
+find_rooms (gpointer data)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (data);
+ GPtrArray *rooms;
+
+ rooms = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free);
+
+ /* Find 2 rooms */
+ add_room (rooms);
+ add_room (rooms);
+ tp_svc_channel_type_room_list_emit_got_rooms (self, rooms);
+ g_ptr_array_set_size (rooms, 0);
+
+ /* Find 1 room */
+ add_room (rooms);
+ tp_svc_channel_type_room_list_emit_got_rooms (self, rooms);
+ g_ptr_array_unref (rooms);
+
+ return FALSE;
+}
+
+static void
room_list_list_rooms (TpSvcChannelTypeRoomList *chan,
DBusGMethodInvocation *context)
{
@@ -171,6 +219,8 @@ room_list_list_rooms (TpSvcChannelTypeRoomList *chan,
self->priv->listing = TRUE;
tp_svc_channel_type_room_list_emit_listing_rooms (self, TRUE);
+ g_idle_add (find_rooms, self);
+
tp_svc_channel_type_room_list_return_from_list_rooms (context);
}
More information about the telepathy-commits
mailing list