[telepathy-mission-control/master] McdClientProxy: indicate initially-handled channels, and possible changes to handler capabilities, via signals

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Sep 23 10:29:38 PDT 2009


---
 src/mcd-client-priv.h |    5 +-
 src/mcd-client.c      |   57 ++++++++++++++++++++++++----
 src/mcd-dispatcher.c  |  101 +++++++++++++++++++++++++++---------------------
 3 files changed, 108 insertions(+), 55 deletions(-)

diff --git a/src/mcd-client-priv.h b/src/mcd-client-priv.h
index c920e5d..7cd8e07 100644
--- a/src/mcd-client-priv.h
+++ b/src/mcd-client-priv.h
@@ -118,9 +118,8 @@ typedef enum
 G_GNUC_INTERNAL void _mcd_client_proxy_set_channel_filters (McdClientProxy *self,
     const GValue *value, const GError *error, McdClientInterface iface);
 
-G_GNUC_INTERNAL gboolean _mcd_client_proxy_set_handler_properties (
-    McdClientProxy *client, GHashTable *properties, const GError *error,
-    const GPtrArray **handled_channels);
+G_GNUC_INTERNAL void _mcd_client_proxy_set_handler_properties (
+    McdClientProxy *client, GHashTable *properties, const GError *error);
 
 G_GNUC_INTERNAL void _mcd_client_proxy_inc_ready_lock (McdClientProxy *self);
 G_GNUC_INTERNAL void _mcd_client_proxy_dec_ready_lock (McdClientProxy *self);
diff --git a/src/mcd-client.c b/src/mcd-client.c
index 89e3950..aa27d9b 100644
--- a/src/mcd-client.c
+++ b/src/mcd-client.c
@@ -52,6 +52,8 @@ enum
 {
     S_READY,
     S_UNIQUE_NAME_KNOWN,
+    S_IS_HANDLING_CHANNEL,
+    S_HANDLER_CAPABILITIES_CHANGED,
     N_SIGNALS
 };
 
@@ -564,14 +566,14 @@ _mcd_client_proxy_get_unique_name (McdClientProxy *self)
     return self->priv->unique_name;
 }
 
-gboolean
+void
 _mcd_client_proxy_set_handler_properties (McdClientProxy *self,
                                           GHashTable *properties,
-                                          const GError *error,
-                                          const GPtrArray **handled_channels)
+                                          const GError *error)
 {
     const gchar *bus_name = tp_proxy_get_bus_name (self);
     GPtrArray *filters;
+    GPtrArray *handled_channels;
     gboolean bypass;
 
     if (error != NULL)
@@ -579,7 +581,7 @@ _mcd_client_proxy_set_handler_properties (McdClientProxy *self,
         DEBUG ("GetAll(Handler) for client %s failed: %s #%d: %s",
                bus_name, g_quark_to_string (error->domain), error->code,
                error->message);
-        return FALSE;
+        return;
     }
 
     filters = tp_asv_get_boxed (properties, "HandlerChannelFilter",
@@ -604,12 +606,34 @@ _mcd_client_proxy_set_handler_properties (McdClientProxy *self,
 
     _mcd_client_proxy_add_cap_tokens (self,
         tp_asv_get_boxed (properties, "Capabilities", G_TYPE_STRV));
+    g_signal_emit (self, signals[S_HANDLER_CAPABILITIES_CHANGED], 0);
 
-    if (handled_channels != NULL)
-        *handled_channels = tp_asv_get_boxed (properties, "HandledChannels",
-                                              TP_ARRAY_TYPE_OBJECT_PATH_LIST);
+    /* by now, we at least know whether the client is running or not */
+    g_assert (self->priv->unique_name != NULL);
 
-    return TRUE;
+    /* If our unique name is "", then we're not *really* handling these
+     * channels - they're the last known information from before the
+     * client exited - so don't claim them.
+     *
+     * At the moment, McdDispatcher deals with the transition from active
+     * to inactive in a centralized way, so we don't need to signal that. */
+    if (self->priv->unique_name[0] != '\0')
+    {
+        guint i;
+
+        handled_channels = tp_asv_get_boxed (properties, "HandledChannels",
+                                             TP_ARRAY_TYPE_OBJECT_PATH_LIST);
+
+        if (handled_channels != NULL)
+        {
+            for (i = 0; i < handled_channels->len; i++)
+            {
+                const gchar *path = g_ptr_array_index (handled_channels, i);
+
+                g_signal_emit (self, signals[S_IS_HANDLING_CHANNEL], 0, path);
+            }
+        }
+    }
 }
 
 void
@@ -843,6 +867,23 @@ _mcd_client_proxy_class_init (McdClientProxyClass *klass)
         g_cclosure_marshal_VOID__VOID,
         G_TYPE_NONE, 0);
 
+    /* Never emitted until after the unique name is known */
+    signals[S_IS_HANDLING_CHANNEL] = g_signal_new ("is-handling-channel",
+        G_OBJECT_CLASS_TYPE (klass),
+        G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+        0, NULL, NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1, G_TYPE_STRING);
+
+    /* Never emitted until after the unique name is known */
+    signals[S_HANDLER_CAPABILITIES_CHANGED] = g_signal_new (
+        "handler-capabilities-changed",
+        G_OBJECT_CLASS_TYPE (klass),
+        G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+        0, NULL, NULL,
+        g_cclosure_marshal_VOID__VOID,
+        G_TYPE_NONE, 0);
+
     g_object_class_install_property (object_class, PROP_ACTIVATABLE,
         g_param_spec_boolean ("activatable", "Activatable?",
             "TRUE if this client can be service-activated", FALSE,
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 47a59e0..a0297ff 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -1695,6 +1695,48 @@ _mcd_dispatcher_finalize (GObject * object)
     G_OBJECT_CLASS (mcd_dispatcher_parent_class)->finalize (object);
 }
 
+static void
+mcd_dispatcher_client_handling_channel_cb (McdClientProxy *client,
+                                           const gchar *object_path,
+                                           McdDispatcher *self)
+{
+    const gchar *bus_name = tp_proxy_get_bus_name (client);
+    const gchar *unique_name = _mcd_client_proxy_get_unique_name (client);
+
+    if (unique_name == NULL || unique_name[0] == '\0')
+    {
+        /* if it said it was handling channels but it doesn't seem to exist
+         * (or worse, doesn't know whether it exists) then we don't believe
+         * it */
+        DEBUG ("%s doesn't seem to exist, assuming it's not handling %s",
+               bus_name, object_path);
+        return;
+    }
+
+    DEBUG ("%s (%s) is handling %s", bus_name, unique_name,
+           object_path);
+
+    _mcd_handler_map_set_path_handled (self->priv->handler_map,
+                                       object_path, unique_name);
+}
+
+static void mcd_dispatcher_update_client_caps (McdDispatcher *self,
+                                               McdClientProxy *client);
+
+static void
+mcd_dispatcher_client_capabilities_changed_cb (McdClientProxy *client,
+                                               McdDispatcher *self)
+{
+    /* Ignore the last known capabilities of clients that have already exited,
+     * unless we can reactivate them. */
+
+    if (_mcd_client_proxy_is_activatable (client) ||
+        _mcd_client_proxy_is_active (client))
+    {
+        mcd_dispatcher_update_client_caps (self, client);
+    }
+}
+
 static void mcd_client_start_introspection (McdClientProxy *client,
                                             McdDispatcher *dispatcher);
 
@@ -1710,6 +1752,12 @@ mcd_dispatcher_discard_client (McdDispatcher *self,
                                           self);
 
     g_signal_handlers_disconnect_by_func (client,
+        mcd_dispatcher_client_capabilities_changed_cb, self);
+
+    g_signal_handlers_disconnect_by_func (client,
+        mcd_dispatcher_client_handling_channel_cb, self);
+
+    g_signal_handlers_disconnect_by_func (client,
                                           mcd_dispatcher_client_ready_cb,
                                           self);
 
@@ -1871,51 +1919,8 @@ handler_get_all_cb (TpProxy *proxy,
                     GObject *weak_object)
 {
     McdClientProxy *client = MCD_CLIENT_PROXY (proxy);
-    McdDispatcher *self = MCD_DISPATCHER (weak_object);
-    const gchar *bus_name = tp_proxy_get_bus_name (proxy);
-    const GPtrArray *channels = NULL;
-    const gchar *unique_name;
-
-    if (!_mcd_client_proxy_set_handler_properties (client,
-                                                   properties,
-                                                   error,
-                                                   &channels))
-    {
-        goto finally;
-    }
-
-    unique_name = _mcd_client_proxy_get_unique_name (client);
-
-    /* This function is only called in (indirect) response to the
-     * McdClientProxy signalling unique-name-known */
-    g_assert (unique_name != NULL);
-
-    if (unique_name[0] == '\0')
-    {
-        /* if it said it was handling channels but it doesn't seem to exist,
-         * then we don't believe it */
-        DEBUG ("%s doesn't seem to exist, assuming no channels handled",
-               bus_name);
-    }
-    else if (channels != NULL)
-    {
-        guint i;
 
-        for (i = 0; i < channels->len; i++)
-        {
-            const gchar *path = g_ptr_array_index (channels, i);
-
-            DEBUG ("%s (%s) is handling %s", bus_name, unique_name,
-                   path);
-
-            _mcd_handler_map_set_path_handled (self->priv->handler_map,
-                                               path, unique_name);
-        }
-    }
-
-    mcd_dispatcher_update_client_caps (self, client);
-
-finally:
+    _mcd_client_proxy_set_handler_properties (client, properties, error);
     _mcd_client_proxy_dec_ready_lock (client);
 }
 
@@ -2122,6 +2127,14 @@ mcd_dispatcher_add_client (McdDispatcher *self,
                       G_CALLBACK (mcd_dispatcher_client_ready_cb),
                       self);
 
+    g_signal_connect (client, "is-handling-channel",
+                      G_CALLBACK (mcd_dispatcher_client_handling_channel_cb),
+                      self);
+
+    g_signal_connect (client, "handler-capabilities-changed",
+                      G_CALLBACK (mcd_dispatcher_client_capabilities_changed_cb),
+                      self);
+
     g_signal_connect (client, "unique-name-known",
                       G_CALLBACK (mcd_client_start_introspection),
                       self);
-- 
1.5.6.5




More information about the telepathy-commits mailing list