[telepathy-gabble/telepathy-gabble-0.8] fd.o#25243: only advertise FT capability if we have a FT client

Simon McVittie simon.mcvittie at collabora.co.uk
Mon Nov 23 09:54:13 PST 2009


---
 src/capabilities.c                                 |    2 +-
 src/ft-manager.c                                   |   79 +++++++++++++++++++-
 tests/twisted/caps/advertise-draft1.py             |   11 ++-
 tests/twisted/caps/tube-caps.py                    |    2 +-
 tests/twisted/caps_helper.py                       |    3 +-
 .../file-transfer/test-caps-file-transfer.py       |   24 +------
 6 files changed, 90 insertions(+), 31 deletions(-)

diff --git a/src/capabilities.c b/src/capabilities.c
index 066e0f8..a509972 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -51,7 +51,7 @@ static const Feature self_advertised_features[] =
   { FEATURE_FIXED, NS_IBB, PRESENCE_CAP_IBB},
   { FEATURE_FIXED, NS_TUBES, PRESENCE_CAP_SI_TUBES},
   { FEATURE_FIXED, NS_BYTESTREAMS, PRESENCE_CAP_BYTESTREAMS},
-  { FEATURE_FIXED, NS_FILE_TRANSFER, PRESENCE_CAP_SI_FILE_TRANSFER},
+  { FEATURE_OPTIONAL, NS_FILE_TRANSFER, PRESENCE_CAP_SI_FILE_TRANSFER},
 
   { FEATURE_BUNDLE_COMPAT, NS_GOOGLE_FEAT_VOICE, PRESENCE_CAP_GOOGLE_VOICE},
   { FEATURE_OPTIONAL, NS_GOOGLE_FEAT_VIDEO, PRESENCE_CAP_GOOGLE_VIDEO },
diff --git a/src/ft-manager.c b/src/ft-manager.c
index c47f97c..e53f4f1 100644
--- a/src/ft-manager.c
+++ b/src/ft-manager.c
@@ -29,6 +29,7 @@
 #include <glib/gstdio.h>
 
 #include "caps-channel-manager.h"
+#include "capabilities.h"
 #include "connection.h"
 #include "ft-manager.h"
 #include "error.h"
@@ -653,12 +654,13 @@ gabble_ft_manager_get_contact_caps (GabbleCapsChannelManager *manager,
 
   if (handle == base->self_handle)
     {
-      /* We support file transfer */
-      add_file_transfer_channel_class (arr, handle);
-      return;
+      presence = conn->self_presence;
+    }
+  else
+    {
+      presence = gabble_presence_cache_get (conn->presence_cache, handle);
     }
 
- presence = gabble_presence_cache_get (conn->presence_cache, handle);
  if (presence == NULL)
    return;
 
@@ -673,6 +675,21 @@ gabble_ft_manager_get_contact_caps (GabbleCapsChannelManager *manager,
   add_file_transfer_channel_class (arr, handle);
 }
 
+static void
+gabble_ft_manager_get_feature_list (
+    GabbleCapsChannelManager *manager,
+    gpointer specific_caps,
+    GSList **features)
+{
+  static const Feature ft = { FEATURE_OPTIONAL, NS_FILE_TRANSFER,
+      PRESENCE_CAP_SI_FILE_TRANSFER };
+
+  if (GPOINTER_TO_INT (specific_caps))
+    {
+      *features = g_slist_prepend (*features, (gpointer) &ft);
+    }
+}
+
 static gpointer
 gabble_ft_manager_parse_caps (GabbleCapsChannelManager *manager,
                               LmMessageNode *query_result)
@@ -717,13 +734,67 @@ gabble_ft_manager_caps_diff (GabbleCapsChannelManager *manager,
 }
 
 static void
+gabble_ft_manager_update_caps (GabbleCapsChannelManager *manager,
+    gpointer specific_caps_out G_GNUC_UNUSED,
+    gpointer specific_caps_in G_GNUC_UNUSED)
+{
+  /* FIXME: can't be done! We'd need to turn our channel-specific caps into a
+   * real pointer. However, the only call to update_capabilities happens to
+   * work, because GPOINTER_TO_INT (FALSE) happens to be NULL. */
+}
+
+static void
+gabble_ft_manager_add_cap (GabbleCapsChannelManager *manager,
+    GabbleConnection *conn,
+    TpHandle handle,
+    GHashTable *channel_class)
+{
+  TpBaseConnection *base = TP_BASE_CONNECTION (conn);
+  GabblePresence *presence;
+
+  if (tp_strdiff (tp_asv_get_string (channel_class,
+          TP_IFACE_CHANNEL ".ChannelType"),
+        TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER))
+    return;
+
+  if (tp_asv_get_uint32 (channel_class, TP_IFACE_CHANNEL ".TargetHandleType",
+        NULL) != TP_HANDLE_TYPE_CONTACT)
+    {
+      return;
+    }
+
+  if (handle == base->self_handle)
+    {
+      presence = conn->self_presence;
+    }
+  else
+    {
+      /* FIXME: why would this ever be needed for others' presences? */
+      presence = gabble_presence_cache_get (conn->presence_cache, handle);
+    }
+
+  g_assert (presence != NULL);
+
+  if (presence->per_channel_manager_caps == NULL)
+    presence->per_channel_manager_caps = g_hash_table_new (NULL, NULL);
+
+  /* it doesn't matter whether we already had this capability - this either
+   * changes it from FALSE to TRUE, or from TRUE to TRUE */
+  g_hash_table_insert (presence->per_channel_manager_caps,
+      manager, GINT_TO_POINTER (TRUE));
+}
+
+static void
 caps_channel_manager_iface_init (gpointer g_iface,
                                  gpointer iface_data)
 {
   GabbleCapsChannelManagerIface *iface = g_iface;
 
   iface->get_contact_caps = gabble_ft_manager_get_contact_caps;
+  iface->get_feature_list = gabble_ft_manager_get_feature_list;
   iface->parse_caps = gabble_ft_manager_parse_caps;
   iface->copy_caps = gabble_ft_manager_copy_caps;
   iface->caps_diff = gabble_ft_manager_caps_diff;
+  iface->update_caps = gabble_ft_manager_update_caps;
+  iface->add_cap = gabble_ft_manager_add_cap;
 }
diff --git a/tests/twisted/caps/advertise-draft1.py b/tests/twisted/caps/advertise-draft1.py
index 817bc60..081f402 100644
--- a/tests/twisted/caps/advertise-draft1.py
+++ b/tests/twisted/caps/advertise-draft1.py
@@ -35,7 +35,8 @@ def run_test(q, bus, conn, stream):
     # test/twisted/capabilities/draft-1.py in MC 5.1 - MC doesn't know
     # how to map Client capabilities into the old Capabilities interface.
     add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA, 2L**32-1),
-            (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1)]
+            (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1),
+            (cs.CHANNEL_TYPE_FILE_TRANSFER, 2L**32-1)]
     remove = []
     caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
     (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
@@ -51,14 +52,20 @@ def run_test(q, bus, conn, stream):
             cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
             cs.STREAM_TUBE_SERVICE: 'x-abiword' },
         { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+        { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_FILE_TRANSFER,
+            cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT },
         ])
     (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
             False)
-    check_caps(namespaces, JINGLE_CAPS + [ns.TUBES + '/stream#x-abiword'])
+    check_caps(namespaces, JINGLE_CAPS + [
+        ns.FILE_TRANSFER,
+        ns.TUBES + '/stream#x-abiword',
+        ])
 
     # Remove all our caps again
     add = []
     remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
+            cs.CHANNEL_TYPE_FILE_TRANSFER,
             cs.CHANNEL_TYPE_STREAM_TUBE]
     caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
     (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
diff --git a/tests/twisted/caps/tube-caps.py b/tests/twisted/caps/tube-caps.py
index fcc0a89..5546165 100644
--- a/tests/twisted/caps/tube-caps.py
+++ b/tests/twisted/caps/tube-caps.py
@@ -235,7 +235,7 @@ def test_tube_caps_to_contact(q, bus, conn, stream):
         [(text_fixed_properties, text_allowed_properties),
          (stream_tube_fixed_properties, stream_tube_allowed_properties),
          (dbus_tube_fixed_properties, dbus_tube_allowed_properties),
-         (ft_fixed_properties, ft_allowed_properties)]})
+         ]})
     daap_caps = dbus.Dictionary({self_handle:
         [(text_fixed_properties, text_allowed_properties),
         (stream_tube_fixed_properties, stream_tube_allowed_properties),
diff --git a/tests/twisted/caps_helper.py b/tests/twisted/caps_helper.py
index c7a3ed8..e208410 100644
--- a/tests/twisted/caps_helper.py
+++ b/tests/twisted/caps_helper.py
@@ -44,9 +44,10 @@ JINGLE_CAPS = [
 VARIABLE_CAPS = (
     JINGLE_CAPS +
     [
+    ns.FILE_TRANSFER,
+
     # FIXME: currently we always advertise these, but in future we should
     # only advertise them if >= 1 client supports them:
-    # ns.FILE_TRANSFER,
     # ns.TUBES,
 
     # there is an unlimited set of these; only the ones actually relevant to
diff --git a/tests/twisted/file-transfer/test-caps-file-transfer.py b/tests/twisted/file-transfer/test-caps-file-transfer.py
index 1197ee8..288bb4d 100644
--- a/tests/twisted/file-transfer/test-caps-file-transfer.py
+++ b/tests/twisted/file-transfer/test-caps-file-transfer.py
@@ -98,27 +98,6 @@ def test_ft_caps_from_contact(q, bus, conn, stream, contact, contact_handle, cli
     assert caps_via_contacts_iface == caps[contact_handle], \
                                     caps_via_contacts_iface
 
-
-def test_ft_caps_to_contact(q, bus, conn, stream):
-    basic_caps = dbus.Dictionary({1:
-        [(text_fixed_properties, text_allowed_properties),
-         (stream_tube_fixed_properties, stream_tube_allowed_properties),
-         (dbus_tube_fixed_properties, dbus_tube_allowed_properties),
-         (ft_fixed_properties, ft_allowed_properties)]})
-
-    conn_caps_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACT_CAPS)
-    conn_contacts_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACTS)
-
-    # Check our own caps
-    caps = conn_caps_iface.GetContactCapabilities([1])
-    assertEquals(basic_caps, caps)
-
-    # check the Contacts interface give the same caps
-    caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
-            [1], [cs.CONN_IFACE_CONTACT_CAPS], False) \
-            [1][cs.CONN_IFACE_CONTACT_CAPS + '/caps']
-    assertEquals(caps[1], caps_via_contacts_iface)
-
 def test(q, bus, conn, stream):
     conn.Connect()
     q.expect('dbus-signal', signal='StatusChanged',
@@ -129,7 +108,8 @@ def test(q, bus, conn, stream):
     test_ft_caps_from_contact(q, bus, conn, stream, 'bilbo1 at foo.com/Foo',
         2L, client)
 
-    test_ft_caps_to_contact(q, bus, conn, stream)
+    # our own capabilities, formerly tested here, are now in
+    # tests/twisted/caps/advertise-draft1.py
 
 if __name__ == '__main__':
     exec_test(test)
-- 
1.5.6.5




More information about the telepathy-commits mailing list