telepathy-glib: implement TP_ROOM_LIST_CHANNEL_FEATURE_LISTING

Guillaume Desmottes gdesmott at kemper.freedesktop.org
Mon Apr 30 02:47:37 PDT 2012


Module: telepathy-glib
Branch: master
Commit: 0173bb1410e7c60f71955304b847a898a1efd1c2
URL:    http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=0173bb1410e7c60f71955304b847a898a1efd1c2

Author: Guillaume Desmottes <guillaume.desmottes at collabora.co.uk>
Date:   Thu Apr 12 08:32:37 2012 +0200

implement TP_ROOM_LIST_CHANNEL_FEATURE_LISTING

Also start the implementation of tp_room_list_channel_start_listing_async().

---

 telepathy-glib/room-list-channel.c |  130 ++++++++++++++++++++++++++++++++++++
 telepathy-glib/room-list-channel.h |    8 ++
 tests/dbus/room-list-channel.c     |   70 +++++++++++++++++++
 tests/lib/room-list-chan.c         |   25 +++++++-
 4 files changed, 232 insertions(+), 1 deletions(-)

diff --git a/telepathy-glib/room-list-channel.c b/telepathy-glib/room-list-channel.c
index 2ca55f0..7d57e0f 100644
--- a/telepathy-glib/room-list-channel.c
+++ b/telepathy-glib/room-list-channel.c
@@ -55,6 +55,7 @@
 #include <telepathy-glib/gtypes.h>
 #include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/util.h>
+#include <telepathy-glib/util-internal.h>
 
 #define DEBUG_FLAG TP_DEBUG_CHANNEL
 #include "telepathy-glib/debug-internal.h"
@@ -132,15 +133,106 @@ tp_room_list_channel_constructed (GObject *obj)
   g_assert_cmpstr (type, ==, TP_IFACE_CHANNEL_TYPE_ROOM_LIST);
 }
 
+enum {
+    FEAT_LISTING,
+    N_FEAT
+};
+
+static void
+listing_rooms_cb (TpChannel *proxy,
+    gboolean listing,
+    gpointer user_data,
+    GObject *weak_object)
+{
+  TpRoomListChannel *self = TP_ROOM_LIST_CHANNEL (proxy);
+
+  if (self->priv->listing == listing)
+    return;
+
+  self->priv->listing = listing;
+  g_object_notify (G_OBJECT (self), "listing");
+}
+
+static void
+get_listing_rooms_cb (TpChannel *channel,
+    gboolean in_progress,
+    const GError *error,
+    gpointer user_data,
+    GObject *weak_object)
+{
+  TpRoomListChannel *self = TP_ROOM_LIST_CHANNEL (channel);
+  GSimpleAsyncResult *result = user_data;
+
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (result, error);
+    }
+  else if (in_progress)
+    {
+      self->priv->listing = in_progress;
+      g_object_notify (G_OBJECT (self), "listing");
+    }
+
+  g_simple_async_result_complete (result);
+}
+
+static void
+tp_room_list_channel_prepare_listing_async (TpProxy *proxy,
+    const TpProxyFeature *feature,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  TpRoomListChannel *self = TP_ROOM_LIST_CHANNEL (proxy);
+  TpChannel *channel = TP_CHANNEL (self);
+  GError *error = NULL;
+  GSimpleAsyncResult *result;
+
+  tp_cli_channel_type_room_list_connect_to_listing_rooms (channel,
+      listing_rooms_cb, proxy, NULL, G_OBJECT (proxy), &error);
+  if (error != NULL)
+    {
+      g_simple_async_report_take_gerror_in_idle ((GObject *) self,
+          callback, user_data, error);
+      return;
+    }
+
+  result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+      tp_room_list_channel_prepare_listing_async);
+
+  tp_cli_channel_type_room_list_call_get_listing_rooms (channel, -1,
+      get_listing_rooms_cb, result, g_object_unref, G_OBJECT (channel));
+}
+
+static const TpProxyFeature *
+tp_room_list_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED)
+{
+  static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
+
+  if (G_LIKELY (features[0].name != 0))
+    return features;
+
+  features[FEAT_LISTING].name = TP_ROOM_LIST_CHANNEL_FEATURE_LISTING;
+  features[FEAT_LISTING].prepare_async =
+    tp_room_list_channel_prepare_listing_async;
+
+  /* assert that the terminator at the end is there */
+  g_assert (features[N_FEAT].name == 0);
+
+  return features;
+}
+
 static void
 tp_room_list_channel_class_init (TpRoomListChannelClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  TpProxyClass *proxy_class = TP_PROXY_CLASS (klass);
   GParamSpec *param_spec;
 
   gobject_class->constructed = tp_room_list_channel_constructed;
   gobject_class->get_property = tp_room_list_channel_get_property;
 
+  proxy_class->list_features = tp_room_list_channel_list_features;
+
   /**
    * TpRoomListChannel:server:
    *
@@ -245,3 +337,41 @@ tp_room_list_channel_get_listing (TpRoomListChannel *self)
 {
   return self->priv->listing;
 }
+
+static void
+list_rooms_cb (TpChannel *channel,
+    const GError *error,
+    gpointer user_data,
+    GObject *weak_object)
+{
+  GSimpleAsyncResult *result = user_data;
+
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (result, error);
+    }
+
+  g_simple_async_result_complete (result);
+}
+
+void
+tp_room_list_channel_start_listing_async (TpRoomListChannel *self,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  GSimpleAsyncResult *result;
+
+  result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+      tp_room_list_channel_start_listing_async);
+
+  tp_cli_channel_type_room_list_call_list_rooms (TP_CHANNEL (self), -1,
+      list_rooms_cb, result, g_object_unref, G_OBJECT (self));
+}
+
+gboolean
+tp_room_list_channel_start_listing_finish (TpRoomListChannel *self,
+    GAsyncResult *result,
+    GError **error)
+{
+  _tp_implement_finish_void (self, tp_room_list_channel_start_listing_async)
+}
diff --git a/telepathy-glib/room-list-channel.h b/telepathy-glib/room-list-channel.h
index 4fddd72..6e79b79 100644
--- a/telepathy-glib/room-list-channel.h
+++ b/telepathy-glib/room-list-channel.h
@@ -61,6 +61,14 @@ gboolean tp_room_list_channel_get_listing (TpRoomListChannel *self);
 
 GQuark tp_room_list_channel_get_feature_quark_listing (void) G_GNUC_CONST;
 
+void tp_room_list_channel_start_listing_async (TpRoomListChannel *self,
+    GAsyncReadyCallback callback,
+    gpointer user_data);
+
+gboolean tp_room_list_channel_start_listing_finish (TpRoomListChannel *self,
+    GAsyncResult *result,
+    GError **error);
+
 G_END_DECLS
 
 #endif
diff --git a/tests/dbus/room-list-channel.c b/tests/dbus/room-list-channel.c
index b7d09ef..e8fd128 100644
--- a/tests/dbus/room-list-channel.c
+++ b/tests/dbus/room-list-channel.c
@@ -135,6 +135,74 @@ test_properties (Test *test,
   g_assert (!tp_room_list_channel_get_listing (test->channel));
 }
 
+static void
+proxy_prepare_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  Test *test = user_data;
+
+  tp_proxy_prepare_finish (source, result, &test->error);
+
+  test->wait--;
+  if (test->wait <= 0)
+    g_main_loop_quit (test->mainloop);
+}
+
+static void
+start_listing_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  Test *test = user_data;
+
+  tp_room_list_channel_start_listing_finish (TP_ROOM_LIST_CHANNEL (source),
+      result, &test->error);
+
+  test->wait--;
+  if (test->wait <= 0)
+    g_main_loop_quit (test->mainloop);
+}
+
+static void
+notify_cb (GObject *object,
+    GParamSpec *spec,
+    Test *test)
+{
+  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 };
+
+  g_assert (!tp_room_list_channel_get_listing (test->channel));
+
+  tp_proxy_prepare_async (test->channel, features, proxy_prepare_cb, test);
+
+  test->wait = 1;
+  g_main_loop_run (test->mainloop);
+  g_assert_no_error (test->error);
+
+  g_assert (!tp_room_list_channel_get_listing (test->channel));
+
+  g_signal_connect (test->channel, "notify::listing",
+      G_CALLBACK (notify_cb), test);
+
+  tp_room_list_channel_start_listing_async (test->channel, start_listing_cb,
+      test);
+
+  test->wait = 2;
+  g_main_loop_run (test->mainloop);
+  g_assert_no_error (test->error);
+
+  g_assert (tp_room_list_channel_get_listing (test->channel));
+}
+
 int
 main (int argc,
       char **argv)
@@ -146,6 +214,8 @@ main (int argc,
       test_creation, teardown);
   g_test_add ("/room-list-channel/properties", Test, NULL, setup,
       test_properties, teardown);
+  g_test_add ("/room-list-channel/listing", Test, NULL, setup,
+      test_listing, teardown);
 
   return g_test_run ();
 }
diff --git a/tests/lib/room-list-chan.c b/tests/lib/room-list-chan.c
index de4be4f..5336eb5 100644
--- a/tests/lib/room-list-chan.c
+++ b/tests/lib/room-list-chan.c
@@ -28,6 +28,7 @@ static guint signals[LAST_SIGNAL];
 
 struct _TpTestsRoomListChanPriv {
   gchar *server;
+  gboolean listing;
 };
 
 static void
@@ -153,12 +154,34 @@ tp_tests_room_list_chan_init (TpTestsRoomListChan *self)
 }
 
 static void
+room_list_list_rooms (TpSvcChannelTypeRoomList *chan,
+    DBusGMethodInvocation *context)
+{
+  TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (chan);
+
+  if (self->priv->listing)
+    {
+      GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+          "Already listing" };
+
+      dbus_g_method_return_error (context, &error);
+      return;
+    }
+
+  self->priv->listing = TRUE;
+  tp_svc_channel_type_room_list_emit_listing_rooms (self, TRUE);
+
+  tp_svc_channel_type_room_list_return_from_list_rooms (context);
+}
+
+static void
 room_list_iface_init (gpointer iface,
     gpointer data)
 {
-  //TpSvcChannelTypeRoomListClass *klass = iface;
+  TpSvcChannelTypeRoomListClass *klass = iface;
 
 #define IMPLEMENT(x) \
   tp_svc_channel_type_room_list_implement_##x (klass, room_list_##x)
+  IMPLEMENT(list_rooms);
 #undef IMPLEMENT
 }



More information about the telepathy-commits mailing list