[telepathy-mission-control/master] McdDispatcher: if a client exits, tell the CM it has no capabilities

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Sep 11 11:17:26 PDT 2009


---
 src/mcd-dispatcher.c                 |   65 +++++++++++++++++++++++----------
 test/twisted/capabilities/draft-2.py |   21 ++++++++++-
 2 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index ad6963e..f93a152 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -325,20 +325,8 @@ mcd_dispatcher_context_handler_done (McdDispatcherContext *context)
 }
 
 static void
-mcd_client_free (McdClient *client)
+mcd_client_become_incapable (McdClient *client)
 {
-    if (client->proxy)
-    {
-        GError error = { TP_DBUS_ERRORS,
-            TP_DBUS_ERROR_NAME_OWNER_LOST, "Client disappeared" };
-
-        _mcd_object_ready (client->proxy, client_ready_quark, &error);
-
-        g_object_unref (client->proxy);
-    }
-
-    g_free (client->name);
-
     g_list_foreach (client->approver_filters,
                     (GFunc)g_hash_table_destroy, NULL);
     g_list_free (client->approver_filters);
@@ -354,8 +342,29 @@ mcd_client_free (McdClient *client)
     g_list_free (client->observer_filters);
     client->observer_filters = NULL;
 
-    tp_handle_set_destroy (client->capability_tokens);
-    client->capability_tokens = NULL;
+    if (client->capability_tokens != NULL)
+    {
+        tp_handle_set_destroy (client->capability_tokens);
+        client->capability_tokens = NULL;
+    }
+}
+
+static void
+mcd_client_free (McdClient *client)
+{
+    if (client->proxy)
+    {
+        GError error = { TP_DBUS_ERRORS,
+            TP_DBUS_ERROR_NAME_OWNER_LOST, "Client disappeared" };
+
+        _mcd_object_ready (client->proxy, client_ready_quark, &error);
+
+        g_object_unref (client->proxy);
+    }
+
+    mcd_client_become_incapable (client);
+
+    g_free (client->name);
 
     g_slice_free (McdClient, client);
 }
@@ -1992,9 +2001,7 @@ mcd_dispatcher_append_client_caps (McdDispatcher *self,
 {
     GPtrArray *filters = g_ptr_array_sized_new (
         g_list_length (client->handler_filters));
-    GPtrArray *cap_tokens = g_ptr_array_sized_new (
-        tp_handle_set_size (client->capability_tokens) + 1);
-    TokenAppendContext context = { self->priv->string_pool, cap_tokens };
+    GPtrArray *cap_tokens;
     GValueArray *va;
     GList *list;
 
@@ -2009,8 +2016,21 @@ mcd_dispatcher_append_client_caps (McdDispatcher *self,
         g_ptr_array_add (filters, copy);
     }
 
-    tp_handle_set_foreach (client->capability_tokens, append_token_to_ptrs,
-                           &context);
+    if (client->capability_tokens == NULL)
+    {
+        cap_tokens = g_ptr_array_sized_new (1);
+    }
+    else
+    {
+        TokenAppendContext context = { self->priv->string_pool, NULL };
+
+        cap_tokens = g_ptr_array_sized_new (
+            tp_handle_set_size (client->capability_tokens) + 1);
+        context.array = cap_tokens;
+        tp_handle_set_foreach (client->capability_tokens, append_token_to_ptrs,
+                               &context);
+    }
+
     g_ptr_array_add (cap_tokens, NULL);
 
     if (DEBUGGING)
@@ -2803,6 +2823,11 @@ name_owner_changed_cb (TpDBusDaemon *proxy,
 
             if (!client->activatable)
             {
+                /* in ContactCapabilities.DRAFT2 we indicate the disappearance
+                 * of a client by giving it an empty set of capabilities and
+                 * filters */
+                mcd_client_become_incapable (client);
+                mcd_dispatcher_update_client_caps (self, client);
                 g_hash_table_remove (priv->clients, name);
             }
         }
diff --git a/test/twisted/capabilities/draft-2.py b/test/twisted/capabilities/draft-2.py
index 9b9238f..e451e7c 100644
--- a/test/twisted/capabilities/draft-2.py
+++ b/test/twisted/capabilities/draft-2.py
@@ -115,11 +115,14 @@ def test(q, bus, mc):
                     predicate=check_draft_2_caps),
                 ])
 
+    irssi_bus = dbus.bus.BusConnection()
+    irssi_bus.set_exit_on_disconnect(False)   # we'll disconnect later
+    q.attach_to_bus(irssi_bus)
     irssi_fixed_properties = dbus.Dictionary({
         cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
         cs.CHANNEL + '.TargetHandleType': cs.HT_ROOM,
         }, signature='sv')
-    irssi = SimulatedClient(q, bus, 'Irssi',
+    irssi = SimulatedClient(q, irssi_bus, 'Irssi',
             observe=[], approve=[], handle=[irssi_fixed_properties],
             cap_tokens=[],
             bypass_approval=False)
@@ -137,5 +140,21 @@ def test(q, bus, mc):
     assert struct[1] == [irssi_fixed_properties]
     assert struct[2] == []
 
+    # When Irssi exits, the CM is told it has gone
+    irssi.release_name()
+    del irssi
+    irssi_bus.flush()
+    irssi_bus.close()
+
+    e = q.expect('dbus-method-call', handled=False,
+        interface=cs.CONN_IFACE_CONTACT_CAPS_DRAFT2,
+        method='UpdateCapabilities')
+
+    assert len(e.args[0]) == 1
+    struct = e.args[0][0]
+    assert struct[0] == cs.CLIENT + '.Irssi'
+    assert struct[1] == []
+    assert struct[2] == []
+
 if __name__ == '__main__':
     exec_test(test, {})
-- 
1.5.6.5




More information about the telepathy-commits mailing list