[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