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