[Telepathy-commits] [telepathy-gabble/master] Fully implement signal ContactCapabilitiesChanged. Update unit test.

Alban Crequy alban.crequy at collabora.co.uk
Fri Dec 5 09:42:32 PST 2008


---
 src/channel-manager.c            |   22 ++++-
 src/channel-manager.h            |   15 +++-
 src/connection.c                 |   52 +++++++---
 src/presence-cache.c             |   29 +++---
 src/presence.c                   |   15 +++-
 src/private-tubes-factory.c      |  220 ++++++++++++++++++++++++--------------
 tests/twisted/test-caps-tubes.py |   66 +++++++++++-
 7 files changed, 302 insertions(+), 117 deletions(-)

diff --git a/src/channel-manager.c b/src/channel-manager.c
index f155485..c9984c0 100644
--- a/src/channel-manager.c
+++ b/src/channel-manager.c
@@ -380,7 +380,7 @@ gpointer gabble_channel_manager_parse_capabilities (
 }
 
 void gabble_channel_manager_free_capabilities (GabbleChannelManager *manager,
-                                               gpointer *specific_caps)
+                                               gpointer specific_caps)
 {
   GabbleChannelManagerIface *iface = GABBLE_CHANNEL_MANAGER_GET_INTERFACE (
       manager);
@@ -425,6 +425,26 @@ void gabble_channel_manager_update_capabilities (
   /* ... else, do what? */
 }
 
+void gabble_channel_manager_get_capability_changes (
+    GabbleChannelManager *manager,
+    TpHandle handle,
+    gpointer specific_old_caps,
+    gpointer specific_new_caps,
+    GPtrArray *added_array,
+    GPtrArray *removed_array)
+{
+  GabbleChannelManagerIface *iface = GABBLE_CHANNEL_MANAGER_GET_INTERFACE (
+      manager);
+  GabbleChannelManagerGetCapChangesFunc method = iface->get_cap_changes;
+
+  if (method != NULL)
+    {
+      method (manager, handle, specific_old_caps, specific_new_caps,
+          added_array, removed_array);
+    }
+  /* ... else, nothing to do */
+}
+
 void
 gabble_channel_manager_foreach_channel (GabbleChannelManager *manager,
                                         GabbleExportableChannelFunc func,
diff --git a/src/channel-manager.h b/src/channel-manager.h
index fbc7960..4154ea7 100644
--- a/src/channel-manager.h
+++ b/src/channel-manager.h
@@ -60,7 +60,7 @@ typedef gpointer (*GabbleChannelManagerParseCapsFunc) (
     GabbleChannelManager *manager, LmMessageNode *children);
 
 typedef void (*GabbleChannelManagerFreeCapsFunc) (
-    GabbleChannelManager *manager, gpointer *specific_caps);
+    GabbleChannelManager *manager, gpointer specific_caps);
 
 typedef void (*GabbleChannelManagerCopyCapsFunc) (
     GabbleChannelManager *manager, gpointer *specific_caps_out,
@@ -69,6 +69,11 @@ typedef void (*GabbleChannelManagerCopyCapsFunc) (
 typedef void (*GabbleChannelManagerUpdateCapsFunc) (
     GabbleChannelManager *manager, gpointer *specific_caps_out, gpointer specific_caps_in);
 
+typedef void (*GabbleChannelManagerGetCapChangesFunc) (
+    GabbleChannelManager *manager, TpHandle handle, gpointer specific_old_caps,
+    gpointer specific_new_caps, GPtrArray *added_array,
+    GPtrArray *removed_array);
+
 void gabble_channel_manager_get_contact_capabilities (
     GabbleChannelManager *manager, GabbleConnection *conn, TpHandle handle,
     GPtrArray *arr);
@@ -77,7 +82,7 @@ gpointer gabble_channel_manager_parse_capabilities (
     GabbleChannelManager *manager, LmMessageNode *children);
 
 void gabble_channel_manager_free_capabilities (GabbleChannelManager *manager,
-    gpointer *specific_caps);
+    gpointer specific_caps);
 
 void gabble_channel_manager_copy_capabilities (GabbleChannelManager *manager,
     gpointer *specific_caps_out, gpointer specific_caps_in);
@@ -86,6 +91,11 @@ void gabble_channel_manager_update_capabilities (
     GabbleChannelManager *manager, gpointer specific_caps_out,
     gpointer specific_caps_in);
 
+void gabble_channel_manager_get_capability_changes (
+    GabbleChannelManager *manager, TpHandle handle, gpointer specific_old_caps,
+    gpointer specific_new_caps, GPtrArray *added_array,
+    GPtrArray *removed_array);
+
 typedef void (*GabbleChannelManagerForeachChannelFunc) (
     GabbleChannelManager *manager, GabbleExportableChannelFunc func,
     gpointer user_data);
@@ -129,6 +139,7 @@ struct _GabbleChannelManagerIface {
     GabbleChannelManagerFreeCapsFunc free_caps;
     GabbleChannelManagerCopyCapsFunc copy_caps;
     GabbleChannelManagerUpdateCapsFunc update_caps;
+    GabbleChannelManagerGetCapChangesFunc get_cap_changes;
 
     GabbleChannelManagerForeachChannelFunc foreach_channel;
 
diff --git a/src/connection.c b/src/connection.c
index be60f82..972284d 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -2136,27 +2136,49 @@ _emit_contact_capabilities_changed (GabbleConnection *conn,
                                     GHashTable *new_caps)
 {
   GValueArray *arr = g_value_array_new (2);
-  GPtrArray *old_array;
-  GPtrArray *new_array;
-  GValue old = {0, };
-  GValue new = {0, };
+  GPtrArray *removed_array;
+  GPtrArray *added_array;
+  GValue removed = {0, };
+  GValue added = {0, };
+  guint i;
 
-  DEBUG ("Called.");
+  removed_array = g_ptr_array_new ();
+  added_array = g_ptr_array_new ();
 
-  old_array = g_ptr_array_new ();
-  new_array = g_ptr_array_new ();
+  for (i = 0; i < conn->channel_managers->len; i++)
+    {
+      GabbleChannelManager *manager = GABBLE_CHANNEL_MANAGER (
+          g_ptr_array_index (conn->channel_managers, i));
+      gpointer per_channel_factory_caps_old = NULL;
+      gpointer per_channel_factory_caps_new = NULL;
 
-  g_value_init (&old, GABBLE_ARRAY_TYPE_ENHANCED_CONTACT_CAPABILITY_LIST);
-  g_value_init (&new, GABBLE_ARRAY_TYPE_ENHANCED_CONTACT_CAPABILITY_LIST);
+      if (old_caps != NULL)
+        per_channel_factory_caps_old = g_hash_table_lookup (old_caps, manager);
+      if (new_caps != NULL)
+        per_channel_factory_caps_new = g_hash_table_lookup (new_caps, manager);
+
+      gabble_channel_manager_get_capability_changes (manager, handle,
+          per_channel_factory_caps_old, per_channel_factory_caps_new,
+          added_array, removed_array);
+    }
 
-  g_value_set_boxed (&old, old_array);
-  g_value_set_boxed (&new, new_array);
+  g_value_init (&removed, GABBLE_ARRAY_TYPE_ENHANCED_CONTACT_CAPABILITY_LIST);
+  g_value_init (&added, GABBLE_ARRAY_TYPE_ENHANCED_CONTACT_CAPABILITY_LIST);
 
-  g_value_array_append (arr, &old);
-  g_value_array_append (arr, &new);
+  g_value_set_boxed (&removed, removed_array);
+  g_value_set_boxed (&added, added_array);
+
+  g_value_array_append (arr, &removed);
+  g_value_array_append (arr, &added);
+
+  /* Don't emit the D-Bus signal if there is no change */
+  if (added_array->len + removed_array->len > 0)
+    {
+      gabble_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
+          conn, arr);
+    }
 
-  gabble_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
-      conn, arr);
+  g_value_array_free (arr);
 }
 
 static void
diff --git a/src/presence-cache.c b/src/presence-cache.c
index ab1b252..4618a6e 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -741,8 +741,9 @@ gabble_presence_cache_copy_specific_cache (
     GHashTable **out, GHashTable *in)
 {
   *out = g_hash_table_new (NULL, NULL);
-  g_hash_table_foreach (in, copy_specific_caps_helper,
-      *out);
+  if (in != NULL)
+    g_hash_table_foreach (in, copy_specific_caps_helper,
+        *out);
 }
 
 static void
@@ -998,9 +999,9 @@ _caps_disco_cb (GabbleDisco *disco,
               if (presence)
               {
                 GabblePresenceCapabilities save_caps = presence->caps;
-                GHashTable *save_enhenced_caps =
-                    presence->per_channel_factory_caps;
-                presence->per_channel_factory_caps = NULL;
+                GHashTable *save_enhenced_caps;
+                gabble_presence_cache_copy_specific_cache (&save_enhenced_caps,
+                    presence->per_channel_factory_caps);
 
                 DEBUG ("setting caps for %d (thanks to %d %s) to "
                     "%d (save_caps %d)",
@@ -1191,8 +1192,8 @@ _process_caps (GabblePresenceCache *cache,
   if (presence)
     {
       old_caps = presence->caps;
-      old_enhenced_caps = presence->per_channel_factory_caps;
-      presence->per_channel_factory_caps = NULL;
+      gabble_presence_cache_copy_specific_cache (&old_enhenced_caps,
+          presence->per_channel_factory_caps);
     }
 
   for (i = uris; NULL != i; i = i->next)
@@ -1497,18 +1498,16 @@ gabble_presence_cache_do_update (
 
   caps_before = presence->caps;
   enhenced_caps_before = presence->per_channel_factory_caps;
-  presence->per_channel_factory_caps = NULL;
+  gabble_presence_cache_copy_specific_cache (&enhenced_caps_before,
+      presence->per_channel_factory_caps);
 
   ret = gabble_presence_update (presence, resource, presence_id,
       status_message, priority);
 
-  if (caps_before != presence->caps)
-    {
-      g_signal_emit (cache, signals[CAPABILITIES_UPDATE], 0, handle,
-          caps_before, presence->caps, enhenced_caps_before,
-          presence->per_channel_factory_caps);
-      gabble_presence_cache_free_specific_cache (enhenced_caps_before);
-    }
+  g_signal_emit (cache, signals[CAPABILITIES_UPDATE], 0, handle,
+      caps_before, presence->caps, enhenced_caps_before,
+      presence->per_channel_factory_caps);
+  gabble_presence_cache_free_specific_cache (enhenced_caps_before);
 
   return ret;
 }
diff --git a/src/presence.c b/src/presence.c
index bd9630f..90f863c 100644
--- a/src/presence.c
+++ b/src/presence.c
@@ -331,8 +331,14 @@ gabble_presence_update (GabblePresence *presence,
           _resource_free (res);
           res = NULL;
 
-          /* recaulculate aggregate capability mask */
-
+          /* recalculate aggregate capability mask */
+          if (presence->per_channel_factory_caps != NULL)
+            {
+              gabble_presence_cache_free_specific_cache
+                (presence->per_channel_factory_caps);
+              presence->per_channel_factory_caps = NULL;
+            }
+          presence->per_channel_factory_caps = g_hash_table_new (NULL, NULL);
           presence->caps = 0;
 
           for (i = priv->resources; i; i = i->next)
@@ -340,6 +346,11 @@ gabble_presence_update (GabblePresence *presence,
               Resource *r = (Resource *) i->data;
 
               presence->caps |= r->caps;
+
+              if (r->per_channel_factory_caps != NULL)
+                gabble_presence_cache_update_specific_cache
+                    (presence->per_channel_factory_caps,
+                     r->per_channel_factory_caps);
             }
         }
     }
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index e60077e..1b9a4f5 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -373,14 +373,12 @@ gabble_private_tubes_factory_close_all (GabblePrivateTubesFactory *fac)
 }
 
 static void
-gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
-                                               GabbleConnection *conn,
-                                               TpHandle handle,
-                                               GPtrArray *arr)
+add_service_to_array (gchar *service,
+                      GPtrArray *arr,
+                      TpTubeType type,
+                      TpHandle handle)
 {
-  TubesCapabilities *caps;
-  GHashTable *stream_tube_caps;
-  GHashTable *dbus_tube_caps;
+  GValue monster = {0, };
   GHashTable *fixed_properties;
   GValue *channel_type_value;
   GValue *target_handle_type_value;
@@ -389,6 +387,63 @@ gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
         TP_IFACE_CHANNEL ".TargetHandle",
         NULL
       };
+
+  g_assert (type == TP_TUBE_TYPE_STREAM || type == TP_TUBE_TYPE_DBUS);
+
+  g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
+  g_value_take_boxed (&monster,
+      dbus_g_type_specialized_construct (
+        GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
+
+  fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+      (GDestroyNotify) tp_g_value_slice_free);
+
+  channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+  if (type == TP_TUBE_TYPE_STREAM)
+    g_value_set_static_string (channel_type_value,
+        GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+  else
+    g_value_set_static_string (channel_type_value,
+        GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE);
+  g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".ChannelType",
+      channel_type_value);
+
+  target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
+  g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
+  g_hash_table_insert (fixed_properties,
+      TP_IFACE_CHANNEL ".TargetHandleType", target_handle_type_value);
+
+  target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+  g_value_set_string (target_handle_type_value, service);
+  if (type == TP_TUBE_TYPE_STREAM)
+    g_hash_table_insert (fixed_properties,
+        GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
+        target_handle_type_value);
+  else
+    g_hash_table_insert (fixed_properties,
+        GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
+        target_handle_type_value);
+
+  dbus_g_type_struct_set (&monster,
+      0, handle,
+      1, fixed_properties,
+      2, tube_allowed_properties,
+      G_MAXUINT);
+
+  g_hash_table_destroy (fixed_properties);
+
+  g_ptr_array_add (arr, g_value_get_boxed (&monster));
+}
+
+static void
+gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
+                                               GabbleConnection *conn,
+                                               TpHandle handle,
+                                               GPtrArray *arr)
+{
+  TubesCapabilities *caps;
+  GHashTable *stream_tube_caps;
+  GHashTable *dbus_tube_caps;
   GabblePresence *presence;
   GHashTableIter tube_caps_iter;
   gchar *service;
@@ -416,41 +471,7 @@ gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
       g_hash_table_iter_init (&tube_caps_iter, stream_tube_caps);
       while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
         {
-          GValue monster = {0, };
-          g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
-          g_value_take_boxed (&monster,
-              dbus_g_type_specialized_construct (
-                GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
-
-          fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
-              (GDestroyNotify) tp_g_value_slice_free);
-
-          channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
-          g_value_set_static_string (channel_type_value,
-              GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE);
-          g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".ChannelType",
-              channel_type_value);
-
-          target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
-          g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
-          g_hash_table_insert (fixed_properties,
-              TP_IFACE_CHANNEL ".TargetHandleType", target_handle_type_value);
-
-          target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
-          g_value_set_string (target_handle_type_value, service);
-          g_hash_table_insert (fixed_properties,
-              GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
-              target_handle_type_value);
-
-          dbus_g_type_struct_set (&monster,
-              0, handle,
-              1, fixed_properties,
-              2, tube_allowed_properties,
-              G_MAXUINT);
-
-          g_hash_table_destroy (fixed_properties);
-
-          g_ptr_array_add (arr, g_value_get_boxed (&monster));
+          add_service_to_array (service, arr, TP_TUBE_TYPE_STREAM, handle);
         }
     }
 
@@ -459,41 +480,7 @@ gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
       g_hash_table_iter_init (&tube_caps_iter, dbus_tube_caps);
       while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
         {
-          GValue monster = {0, };
-          g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
-          g_value_take_boxed (&monster,
-              dbus_g_type_specialized_construct (
-                GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
-
-          fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
-              (GDestroyNotify) tp_g_value_slice_free);
-
-          channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
-          g_value_set_static_string (channel_type_value,
-              GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE);
-          g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".ChannelType",
-              channel_type_value);
-
-          target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
-          g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
-          g_hash_table_insert (fixed_properties,
-              TP_IFACE_CHANNEL ".TargetHandleType", target_handle_type_value);
-
-          target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
-          g_value_set_string (target_handle_type_value, service);
-          g_hash_table_insert (fixed_properties,
-              GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
-              target_handle_type_value);
-
-          dbus_g_type_struct_set (&monster,
-              0, handle,
-              1, fixed_properties,
-              2, tube_allowed_properties,
-              G_MAXUINT);
-
-          g_hash_table_destroy (fixed_properties);
-
-          g_ptr_array_add (arr, g_value_get_boxed (&monster));
+          add_service_to_array (service, arr, TP_TUBE_TYPE_DBUS, handle);
         }
     }
 }
@@ -548,7 +535,7 @@ gabble_private_tubes_factory_parse_caps (
   return caps;
 }
 
-static gpointer
+static void
 gabble_private_tubes_factory_free_caps (
     GabbleChannelManager *manager,
     gpointer data)
@@ -596,8 +583,8 @@ gabble_private_tubes_factory_update_caps (
     gpointer *specific_caps_out,
     gpointer specific_caps_in)
 {
-  TubesCapabilities *caps_out = specific_caps_out;
-  TubesCapabilities *caps_in = specific_caps_in;
+  TubesCapabilities *caps_out = (TubesCapabilities *) specific_caps_out;
+  TubesCapabilities *caps_in = (TubesCapabilities *) specific_caps_in;
 
   if (caps_in == NULL)
     return;
@@ -608,6 +595,78 @@ gabble_private_tubes_factory_update_caps (
       caps_out->dbus_tube_caps, g_strdup, NULL);
 }
 
+static void
+gabble_private_tubes_factory_get_cap_changes (
+    GabbleChannelManager *manager,
+    TpHandle handle,
+    gpointer specific_old_caps, 
+    gpointer specific_new_caps,
+    GPtrArray *added_array,
+    GPtrArray *removed_array)
+{
+  TubesCapabilities *old_caps = specific_old_caps;
+  TubesCapabilities *new_caps = specific_new_caps;
+  GHashTableIter tube_caps_iter;
+  gchar *service;
+  gpointer dummy;
+
+  if (old_caps != NULL)
+    {
+      g_hash_table_iter_init (&tube_caps_iter, old_caps->stream_tube_caps);
+      while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
+        {
+          gpointer key, value;
+          if (new_caps == NULL ||
+              !g_hash_table_lookup_extended (new_caps->stream_tube_caps,
+                  service, &key, &value))
+            {
+              add_service_to_array (service, removed_array,
+                  TP_TUBE_TYPE_STREAM, handle);
+            }
+        }
+      g_hash_table_iter_init (&tube_caps_iter, old_caps->dbus_tube_caps);
+      while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
+        {
+          gpointer key, value;
+          if (new_caps == NULL ||
+              !g_hash_table_lookup_extended (new_caps->dbus_tube_caps,
+                  service, &key, &value))
+            {
+              add_service_to_array (service, removed_array,
+                  TP_TUBE_TYPE_DBUS, handle);
+            }
+        }
+    }
+
+  if (new_caps != NULL)
+    {
+      g_hash_table_iter_init (&tube_caps_iter, new_caps->stream_tube_caps);
+      while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
+        {
+          gpointer key, value;
+          if (old_caps == NULL ||
+              !g_hash_table_lookup_extended (old_caps->stream_tube_caps,
+                  service, &key, &value))
+            {
+              add_service_to_array (service, added_array,
+                  TP_TUBE_TYPE_STREAM, handle);
+            }
+        }
+      g_hash_table_iter_init (&tube_caps_iter, new_caps->dbus_tube_caps);
+      while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy)) 
+        {
+          gpointer key, value;
+          if (old_caps == NULL ||
+              !g_hash_table_lookup_extended (old_caps->dbus_tube_caps,
+                  service, &key, &value))
+            {
+              add_service_to_array (service, added_array,
+                  TP_TUBE_TYPE_DBUS, handle);
+            }
+        }
+    }
+}
+
 struct _ForeachData
 {
   GabbleExportableChannelFunc foreach;
@@ -1033,6 +1092,7 @@ channel_manager_iface_init (gpointer g_iface,
   iface->free_caps = gabble_private_tubes_factory_free_caps;
   iface->copy_caps = gabble_private_tubes_factory_copy_caps;
   iface->update_caps = gabble_private_tubes_factory_update_caps;
+  iface->get_cap_changes = gabble_private_tubes_factory_get_cap_changes;
 
 
   iface->foreach_channel = gabble_private_tubes_factory_foreach_channel;
diff --git a/tests/twisted/test-caps-tubes.py b/tests/twisted/test-caps-tubes.py
index 899b2af..f5fba18 100644
--- a/tests/twisted/test-caps-tubes.py
+++ b/tests/twisted/test-caps-tubes.py
@@ -141,14 +141,17 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     feature['var'] = 'http://www.google.com/transport/p2p'
     stream.send(result)
 
-    event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
-    print str(event.args)
+    # no change in ContactCapabilities, so no signal ContactCapabilitiesChanged
+    sync_stream(q, stream)
 
     # no special capabilities
     basic_caps = [(contact_handle, text_fixed_properties,
             text_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == basic_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == basic_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
@@ -179,6 +182,13 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     stream.send(result)
 
     event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
+    removed = event.args[0][0]
+    added = event.args[0][1]
+    assert len(removed) == 0, removed
+    assert len(added) == 1, added
+    assert added[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service'] \
+        == 'daap'
 
     # daap capabilities
     daap_caps = [
@@ -186,6 +196,9 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
         (contact_handle, daap_fixed_properties, daap_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == daap_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == daap_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
@@ -216,6 +229,16 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     stream.send(result)
 
     event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
+    removed = event.args[0][0]
+    added = event.args[0][1]
+    assert len(removed) == 1, removed
+    assert len(added) == 1, added
+    assert removed[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service'] \
+        == 'daap'
+    assert added[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.DBusTube.DRAFT.ServiceName'] \
+        == 'com.example.Xiangqi'
 
     # xiangqi capabilities
     xiangqi_caps = [
@@ -223,6 +246,9 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
         (contact_handle, xiangqi_fixed_properties, xiangqi_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == xiangqi_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == xiangqi_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
@@ -255,6 +281,13 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     stream.send(result)
 
     event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
+    removed = event.args[0][0]
+    added = event.args[0][1]
+    assert len(removed) == 0, removed
+    assert len(added) == 1, added
+    assert added[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service'] \
+        == 'daap'
 
     # daap + xiangqi capabilities
     daap_xiangqi_caps = [
@@ -263,6 +296,9 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
         (contact_handle, xiangqi_fixed_properties, xiangqi_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == daap_xiangqi_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == daap_xiangqi_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
@@ -299,6 +335,16 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     stream.send(result)
 
     event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
+    removed = event.args[0][0]
+    added = event.args[0][1]
+    assert len(removed) == 0, removed
+    assert len(added) == 2, added
+    assert added[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service'] \
+        == 'http'
+    assert added[1][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.DBusTube.DRAFT.ServiceName'] \
+        == 'com.example.Go'
 
     # http + daap + xiangqi + go capabilities
     all_tubes_caps = [
@@ -310,6 +356,9 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
         (contact_handle, go_fixed_properties, go_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == all_tubes_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == all_tubes_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
@@ -327,6 +376,16 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
     # Gabble does not look up our capabilities because of the cache
 
     event = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
+    removed = event.args[0][0]
+    added = event.args[0][1]
+    assert len(removed) == 2, removed
+    assert len(added) == 0, added
+    assert removed[0][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service'] \
+        == 'http'
+    assert removed[1][1] \
+        ['org.freedesktop.Telepathy.Channel.Type.DBusTube.DRAFT.ServiceName'] \
+        == 'com.example.Go'
 
     # daap + xiangqi capabilities
     daap_xiangqi_caps = [
@@ -335,6 +394,9 @@ def _test_tube_caps(q, bus, conn, stream, contact, contact_handle, client):
         (contact_handle, xiangqi_fixed_properties, xiangqi_allowed_properties)]
     caps = conn_caps_iface.GetContactCapabilities([contact_handle])
     assert caps == daap_xiangqi_caps, caps
+    # test again, to check GetContactCapabilities does not have side effect
+    caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+    assert caps == daap_xiangqi_caps, caps
     # check the Contacts interface give the same caps
     caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
             [contact_handle], [caps_iface], False) \
-- 
1.5.6.5




More information about the Telepathy-commits mailing list