[telepathy-gabble/master] Let CallChannel implement GAsyncInitable

Sjoerd Simons sjoerd.simons at collabora.co.uk
Tue Dec 29 05:34:37 PST 2009


---
 src/call-channel.c  |   36 +++++++++++++++++++++++++++++++
 src/media-factory.c |   58 +++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 85 insertions(+), 9 deletions(-)

diff --git a/src/call-channel.c b/src/call-channel.c
index fd5fd00..83c2433 100644
--- a/src/call-channel.c
+++ b/src/call-channel.c
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <gio/gio.h>
+
 #include <telepathy-glib/dbus.h>
 #include <telepathy-glib/enums.h>
 #include <telepathy-glib/exportable-channel.h>
@@ -44,9 +46,11 @@
 
 static void channel_iface_init (gpointer, gpointer);
 static void call_iface_init (gpointer, gpointer);
+static void async_initable_iface_init (GAsyncInitableIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE(GabbleCallChannel, gabble_call_channel,
   G_TYPE_OBJECT,
+  G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init);
   G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
   G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CHANNEL_TYPE_CALL,
         call_iface_init);
@@ -542,3 +546,35 @@ static void
 call_iface_init (gpointer g_iface, gpointer iface_data)
 {
 }
+
+static void
+call_channel_init_async (GAsyncInitable *initable,
+  int priority,
+  GCancellable *cancellable,
+  GAsyncReadyCallback callback,
+  gpointer user_data)
+{
+  GabbleCallChannel *self = GABBLE_CALL_CHANNEL (initable);
+  GabbleCallChannelPrivate *priv = self->priv;
+  GSimpleAsyncResult *result;
+
+  result = g_simple_async_result_new (G_OBJECT (self),
+    callback, user_data, NULL);
+
+  if (priv->session != NULL)
+    {
+      /* Already done the setup */
+      g_simple_async_result_complete_in_idle (result);
+      g_object_unref (result);
+      return;
+    }
+
+  g_simple_async_result_complete_in_idle (result);
+  g_object_unref (result);
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = call_channel_init_async;
+}
diff --git a/src/media-factory.c b/src/media-factory.c
index 030a042..bfa6c39 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -72,6 +72,7 @@ struct _GabbleMediaFactoryPrivate
 
   GList *media_channels;
   GList *call_channels;
+  GList *pending_call_channels;
   guint channel_index;
 
   gboolean dispose_has_run;
@@ -717,6 +718,41 @@ call_channel_closed_cb (GabbleCallChannel *chan, gpointer user_data)
   g_object_unref (chan);
 }
 
+static void
+call_channel_initialized (GObject *source,
+  GAsyncResult *res,
+  gpointer user_data)
+{
+  MediaChannelRequest *mcr = user_data;
+  GabbleMediaFactoryPrivate *priv = mcr->self->priv;
+  GError *error = NULL;
+
+  priv->pending_call_channels =
+    g_list_remove (priv->pending_call_channels, mcr);
+
+  if (g_async_initable_init_finish (G_ASYNC_INITABLE (source),
+      res, &error))
+    {
+      priv->call_channels = g_list_prepend (priv->call_channels,
+        mcr->channel);
+
+      tp_channel_manager_emit_new_channel (mcr->self,
+        mcr->channel, mcr->request_tokens);
+
+      g_signal_connect (mcr->channel, "closed",
+        G_CALLBACK (call_channel_closed_cb), mcr->self);
+    }
+  else
+    {
+      GSList *l;
+      for (l = mcr->request_tokens; l != NULL; l = g_slist_next (l))
+        tp_channel_manager_emit_request_failed (mcr->self, l->data,
+          error->domain, error->code, error->message);
+    }
+
+  media_channel_request_free (mcr);
+}
+
 static gboolean
 gabble_media_factory_create_call (TpChannelManager *manager,
     gpointer request_token,
@@ -727,9 +763,9 @@ gabble_media_factory_create_call (TpChannelManager *manager,
   GabbleCallChannel *channel = NULL;
   TpBaseConnection *conn;
   GError *error = NULL;
-  GSList *tokens;
   gboolean initial_audio, initial_video;
   gchar *object_path;
+  MediaChannelRequest *mcr;
 
   conn = (TpBaseConnection *) self->priv->conn;
 
@@ -754,6 +790,7 @@ gabble_media_factory_create_call (TpChannelManager *manager,
 
   /* FIXME need to check if there is at least one of InitialAudio/InitialVideo
    * FIXME creating the channel should check and wait for the capabilities
+   * FIXME need to cope with disconnecting while channels are setting up
    */
 
   object_path = g_strdup_printf ("%s/CallChannel%u",
@@ -768,17 +805,20 @@ gabble_media_factory_create_call (TpChannelManager *manager,
       "initial-video", initial_video,
       NULL);
 
-  self->priv->call_channels
-    = g_list_prepend (self->priv->call_channels, channel);
-  g_signal_connect (channel, "closed",
-      G_CALLBACK (call_channel_closed_cb), self);
+  mcr = media_channel_request_new (self,
+    TP_EXPORTABLE_CHANNEL (channel), request_token);
 
-  tokens = g_slist_prepend (NULL, request_token);
-  tp_channel_manager_emit_new_channel (self,
-    TP_EXPORTABLE_CHANNEL (channel), tokens);
-  g_slist_free (tokens);
+  g_async_initable_init_async (G_ASYNC_INITABLE (channel),
+      G_PRIORITY_DEFAULT,
+      NULL, /* FIXME support cancelling the channel creation */
+      call_channel_initialized,
+      mcr);
+
+  self->priv->pending_call_channels
+    = g_list_prepend (self->priv->pending_call_channels, channel);
 
   return TRUE;
+
 error:
   tp_channel_manager_emit_request_failed (self, request_token,
       error->domain, error->code, error->message);
-- 
1.5.6.5




More information about the telepathy-commits mailing list