[Telepathy-commits] [telepathy-mission-control/master] Delay TpProxy creation on NewChannel

Alberto Mardegan alberto.mardegan at nokia.com
Mon Feb 2 00:00:20 PST 2009


Delay the creation of the proxy, because we won't be able to update its
properties.
---
 src/mcd-channel.c    |   53 +++++++++++++++++++------------
 src/mcd-channel.h    |    7 +++-
 src/mcd-connection.c |   84 ++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 109 insertions(+), 35 deletions(-)

diff --git a/src/mcd-channel.c b/src/mcd-channel.c
index 8a7ee62..b38300f 100644
--- a/src/mcd-channel.c
+++ b/src/mcd-channel.c
@@ -558,6 +558,38 @@ mcd_channel_new_from_path (TpConnection *connection, const gchar *object_path,
     return channel;
 }
 
+gboolean
+_mcd_channel_create_proxy_old (McdChannel *channel, TpConnection *connection,
+                               const gchar *object_path, const gchar *type,
+                               guint handle, TpHandleType handle_type)
+{
+    GHashTable *props;
+    GValue v_type = { 0 };
+    GValue v_handle = { 0 };
+    GValue v_handle_type = { 0 };
+    gboolean ret;
+
+    props = g_hash_table_new (g_str_hash, g_str_equal);
+
+    g_value_init (&v_type, G_TYPE_STRING);
+    g_value_set_static_string (&v_type, type);
+    g_hash_table_insert (props, TP_IFACE_CHANNEL ".ChannelType", &v_type);
+
+    g_value_init (&v_handle, G_TYPE_UINT);
+    g_value_set_uint (&v_handle, handle);
+    g_hash_table_insert (props, TP_IFACE_CHANNEL ".TargetHandle", &v_handle);
+
+    g_value_init (&v_handle_type, G_TYPE_UINT);
+    g_value_set_uint (&v_handle_type, handle_type);
+    g_hash_table_insert (props, TP_IFACE_CHANNEL ".TargetHandleType",
+                         &v_handle_type);
+
+    ret = _mcd_channel_create_proxy (channel, connection, object_path, props);
+
+    g_hash_table_unref (props);
+    return ret;
+}
+
 /**
  * mcd_channel_set_object_path:
  * @channel: the #McdChannel.
@@ -865,27 +897,6 @@ mcd_channel_leave (McdChannel *channel, const gchar *message,
 }
 
 /*
- * _mcd_channel_set_immutable_properties:
- * @channel: the #McdChannel.
- * @properties: a #GHashTable of immutable properties.
- *
- * Internal function: assign a hash table of properties to @channel.
- */
-void
-_mcd_channel_set_immutable_properties (McdChannel *channel,
-                                       GHashTable *properties)
-{
-    g_return_if_fail (MCD_IS_CHANNEL (channel));
-
-    if (G_LIKELY (channel->priv->tp_chan))
-        g_object_set (channel->priv->tp_chan,
-                      "channel-properties", properties,
-                      NULL);
-    else
-        g_warning ("%s: no TpChannel yet!", G_STRFUNC);
-}
-
-/*
  * _mcd_channel_get_immutable_properties:
  * @channel: the #McdChannel.
  *
diff --git a/src/mcd-channel.h b/src/mcd-channel.h
index 09ab540..08c49f8 100644
--- a/src/mcd-channel.h
+++ b/src/mcd-channel.h
@@ -142,8 +142,11 @@ TpChannel *mcd_channel_get_tp_channel (McdChannel *channel);
 
 /* not exported: */
 G_GNUC_INTERNAL
-void _mcd_channel_set_immutable_properties (McdChannel *channel,
-                                            GHashTable *properties);
+gboolean _mcd_channel_create_proxy_old (McdChannel *channel,
+                                        TpConnection *connection,
+                                        const gchar *object_path,
+                                        const gchar *type, guint handle,
+                                        TpHandleType handle_type);
 G_GNUC_INTERNAL
 GHashTable *_mcd_channel_get_immutable_properties (McdChannel *channel);
 
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index 6d1f03a..a66edfc 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -131,6 +131,16 @@ struct _McdConnectionPrivate
 
 typedef struct
 {
+    gchar *object_path;
+    gchar *channel_type;
+    TpHandle handle;
+    TpHandleType handle_type;
+} McdTmpChannelData;
+
+#define MCD_TMP_CHANNEL_DATA    "tmp_channel_data"
+
+typedef struct
+{
     TpConnectionPresenceType presence;
     guint may_set_on_self : 1;
     guint can_have_message : 1;
@@ -179,6 +189,16 @@ static void _mcd_connection_setup (McdConnection * connection);
 static void _mcd_connection_release_tp_connection (McdConnection *connection);
 
 static void
+mcd_tmp_channel_data_free (gpointer data)
+{
+    McdTmpChannelData *tcd = data;
+
+    g_free (tcd->object_path);
+    g_free (tcd->channel_type);
+    g_slice_free (McdTmpChannelData, tcd);
+}
+
+static void
 mcd_presence_info_free (McdPresenceInfo *pi)
 {
     g_slice_free (McdPresenceInfo, pi);
@@ -441,21 +461,37 @@ on_new_channel (TpConnection *proxy, const gchar *chan_obj_path,
     if (suppress_handler) return;
 
     /* It's an incoming channel, so we create a new McdChannel for it */
-    channel = mcd_channel_new_from_path (proxy,
-                                         chan_obj_path,
-                                         chan_type, handle, handle_type);
-    if (G_UNLIKELY (!channel)) return;
-
-    mcd_operation_take_mission (MCD_OPERATION (connection),
-				MCD_MISSION (channel));
-
     if (priv->can_dispatch)
     {
+        channel = mcd_channel_new_from_path (proxy,
+                                             chan_obj_path,
+                                             chan_type, handle, handle_type);
+        if (G_UNLIKELY (!channel)) return;
+        mcd_operation_take_mission (MCD_OPERATION (connection),
+                                    MCD_MISSION (channel));
         /* Dispatch the incoming channel */
         mcd_dispatcher_send (priv->dispatcher, channel);
     }
     else
+    {
+        /* create a void channel, but no TpProxy yet. Bundle the channel data,
+         * to be used later */
+        McdTmpChannelData *tcd;
+
+        channel = g_object_new (MCD_TYPE_CHANNEL,
+                                "outgoing", FALSE,
+                                NULL);
+        tcd = g_slice_new (McdTmpChannelData);
+        tcd->object_path = g_strdup (chan_obj_path);
+        tcd->channel_type = g_strdup (chan_type);
+        tcd->handle = handle;
+        tcd->handle_type = handle_type;
+        g_object_set_data_full (G_OBJECT (channel), MCD_TMP_CHANNEL_DATA,
+                                tcd, mcd_tmp_channel_data_free);
+        mcd_operation_take_mission (MCD_OPERATION (connection),
+                                    MCD_MISSION (channel));
         mcd_channel_set_status (channel, MCD_CHANNEL_STATUS_UNDISPATCHED);
+    }
 }
 
 static void
@@ -1175,6 +1211,21 @@ dispatch_undispatched_channels (McdConnection *connection)
 
         if (mcd_channel_get_status (channel) == MCD_CHANNEL_STATUS_UNDISPATCHED)
         {
+            /* undispatched channels have no TpProxy associated: create it now
+             */
+            McdTmpChannelData *tcd;
+
+            tcd = g_object_get_data (G_OBJECT (channel), MCD_TMP_CHANNEL_DATA);
+            if (G_UNLIKELY (!tcd))
+            {
+                g_warning ("Channel %p is undispatched without data", channel);
+                continue;
+            }
+
+            _mcd_channel_create_proxy_old (channel, priv->tp_conn,
+                                           tcd->object_path, tcd->channel_type,
+                                           tcd->handle, tcd->handle_type);
+            g_object_set_data (G_OBJECT (channel), MCD_TMP_CHANNEL_DATA, NULL);
             g_debug ("Dispatching channel %p", channel);
             /* dispatch the channel */
             mcd_dispatcher_send (priv->dispatcher, channel);
@@ -1306,15 +1357,24 @@ static void get_all_requests_cb (TpProxy *proxy, GHashTable *properties,
         for (; list != NULL; list = list->next)
         {
             McdChannel *channel = MCD_CHANNEL (list->data);
-            const gchar *channel_path;
+            McdTmpChannelData *tcd;
 
             if (mcd_channel_get_status (channel) !=
                 MCD_CHANNEL_STATUS_UNDISPATCHED)
                 continue;
-            channel_path = mcd_channel_get_object_path (channel);
-            if (channel_path && strcmp (channel_path, object_path) == 0)
+
+            tcd = g_object_get_data (G_OBJECT (channel), MCD_TMP_CHANNEL_DATA);
+            if (G_UNLIKELY (!tcd))
+            {
+                g_warning ("Channel %p is undispatched without data", channel);
+                continue;
+            }
+            if (strcmp (tcd->object_path, object_path) == 0)
             {
-                _mcd_channel_set_immutable_properties (channel, channel_props);
+                _mcd_channel_create_proxy (channel, priv->tp_conn,
+                                           object_path, channel_props);
+                g_object_set_data (G_OBJECT (channel), MCD_TMP_CHANNEL_DATA,
+                                   NULL);
                 /* channel is ready for dispatching */
                 mcd_dispatcher_send (priv->dispatcher, channel);
                 break;
-- 
1.5.6.5




More information about the Telepathy-commits mailing list