[telepathy-gabble/master] Implement C_Media_Capabilities_Immutable_Streams

Will Thompson will.thompson at collabora.co.uk
Mon Oct 19 06:44:07 PDT 2009


The tests needed changing because the definition of the
Immutable_Streams cap implies that contacts who can only make audio
calls should have that flag set. Most of the tests were changed to make
the contacts video capable too; the jingle-caps test checks that Google
Video contacts (who are capable of both audio and video) have this flag
set.

This is a version of 744b0d3, modified to work with the refactored
capabilities code in 0.9
---
 src/capabilities.c                   |   26 +++++++++++++++++++++
 src/capabilities.h                   |    2 +
 src/media-factory.c                  |   14 ++++++++++-
 tests/twisted/caps/caps-cache.py     |   12 +++++----
 tests/twisted/caps/from-bare-jid.py  |    9 ++++---
 tests/twisted/caps/hashed-caps.py    |   41 ++++++++++++++-------------------
 tests/twisted/caps/jingle-caps.py    |   16 ++++++++++---
 tests/twisted/caps/receive-jingle.py |   18 ++++++++++----
 tests/twisted/constants.py           |    1 +
 9 files changed, 96 insertions(+), 43 deletions(-)

diff --git a/src/capabilities.c b/src/capabilities.c
index c34fd32..c3718d6 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -96,6 +96,8 @@ static GabbleCapabilitySet *voice_v1_caps = NULL;
 static GabbleCapabilitySet *video_v1_caps = NULL;
 static GabbleCapabilitySet *any_audio_caps = NULL;
 static GabbleCapabilitySet *any_video_caps = NULL;
+static GabbleCapabilitySet *any_google_av_caps = NULL;
+static GabbleCapabilitySet *any_jingle_av_caps = NULL;
 static GabbleCapabilitySet *any_transport_caps = NULL;
 static GabbleCapabilitySet *fixed_caps = NULL;
 static GabbleCapabilitySet *geoloc_caps = NULL;
@@ -132,6 +134,18 @@ gabble_capabilities_get_any_video (void)
 }
 
 const GabbleCapabilitySet *
+gabble_capabilities_get_any_google_av (void)
+{
+  return any_google_av_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_jingle_av (void)
+{
+  return any_jingle_av_caps;
+}
+
+const GabbleCapabilitySet *
 gabble_capabilities_get_any_transport (void)
 {
   return any_transport_caps;
@@ -241,6 +255,14 @@ gabble_capabilities_init (GabbleConnection *conn)
       gabble_capability_set_add (any_video_caps, NS_JINGLE_DESCRIPTION_VIDEO);
       gabble_capability_set_add (any_video_caps, NS_GOOGLE_FEAT_VIDEO);
 
+      any_google_av_caps = gabble_capability_set_new ();
+      gabble_capability_set_add (any_google_av_caps, NS_GOOGLE_FEAT_VOICE);
+      gabble_capability_set_add (any_google_av_caps, NS_GOOGLE_FEAT_VIDEO);
+
+      any_jingle_av_caps = gabble_capability_set_copy (any_audio_caps);
+      gabble_capability_set_update (any_jingle_av_caps, any_video_caps);
+      gabble_capability_set_exclude (any_jingle_av_caps, any_google_av_caps);
+
       any_transport_caps = gabble_capability_set_new ();
       gabble_capability_set_add (any_transport_caps, NS_GOOGLE_TRANSPORT_P2P);
       gabble_capability_set_add (any_transport_caps, NS_JINGLE_TRANSPORT_ICEUDP);
@@ -283,6 +305,8 @@ gabble_capabilities_finalize (GabbleConnection *conn)
       gabble_capability_set_free (video_v1_caps);
       gabble_capability_set_free (any_audio_caps);
       gabble_capability_set_free (any_video_caps);
+      gabble_capability_set_free (any_google_av_caps);
+      gabble_capability_set_free (any_jingle_av_caps);
       gabble_capability_set_free (any_transport_caps);
       gabble_capability_set_free (fixed_caps);
       gabble_capability_set_free (geoloc_caps);
@@ -293,6 +317,8 @@ gabble_capabilities_finalize (GabbleConnection *conn)
       video_v1_caps = NULL;
       any_audio_caps = NULL;
       any_video_caps = NULL;
+      any_google_av_caps = NULL;
+      any_jingle_av_caps = NULL;
       any_transport_caps = NULL;
       fixed_caps = NULL;
       geoloc_caps = NULL;
diff --git a/src/capabilities.h b/src/capabilities.h
index d5712c9..b66c500 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -90,6 +90,8 @@ typedef gboolean (*GabbleCapabilitySetPredicate) (
 const GabbleCapabilitySet *gabble_capabilities_get_legacy (void);
 const GabbleCapabilitySet *gabble_capabilities_get_any_audio (void);
 const GabbleCapabilitySet *gabble_capabilities_get_any_video (void);
+const GabbleCapabilitySet *gabble_capabilities_get_any_google_av (void);
+const GabbleCapabilitySet *gabble_capabilities_get_any_jingle_av (void);
 const GabbleCapabilitySet *gabble_capabilities_get_any_transport (void);
 const GabbleCapabilitySet *gabble_capabilities_get_geoloc_notify (void);
 const GabbleCapabilitySet *gabble_capabilities_get_olpc_notify (void);
diff --git a/src/media-factory.c b/src/media-factory.c
index ecbfa89..36c4bd0 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -729,7 +729,7 @@ TpChannelMediaCapabilities
 _gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
 {
   TpChannelMediaCapabilities typeflags = 0;
-  gboolean has_a_transport;
+  gboolean has_a_transport, just_google, one_media_type;
 
   has_a_transport = gabble_capability_set_has_one (caps,
     gabble_capabilities_get_any_transport ());
@@ -755,6 +755,18 @@ _gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
   if (gabble_capability_set_has (caps, NS_GOOGLE_FEAT_VIDEO))
     typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_VIDEO;
 
+  just_google =
+      gabble_capability_set_has_one (caps,
+          gabble_capabilities_get_any_google_av ()) &&
+      !gabble_capability_set_has_one (caps,
+          gabble_capabilities_get_any_jingle_av ());
+
+  one_media_type = (typeflags == TP_CHANNEL_MEDIA_CAPABILITY_AUDIO)
+      || (typeflags == TP_CHANNEL_MEDIA_CAPABILITY_VIDEO);
+
+  if (just_google || one_media_type)
+    typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS;
+
   return typeflags;
 }
 
diff --git a/tests/twisted/caps/caps-cache.py b/tests/twisted/caps/caps-cache.py
index a654d74..e7e37ab 100644
--- a/tests/twisted/caps/caps-cache.py
+++ b/tests/twisted/caps/caps-cache.py
@@ -17,19 +17,21 @@ from caps_helper import (
 
 client = 'http://telepathy.freedesktop.org/fake-client'
 features = [
-    'http://jabber.org/protocol/jingle',
-    'http://jabber.org/protocol/jingle/description/audio',
-    'http://www.google.com/transport/p2p',
+    ns.JINGLE_015,
+    ns.JINGLE_015_AUDIO,
+    ns.JINGLE_015_VIDEO,
+    ns.GOOGLE_P2P,
     ]
 
 
 def expect_caps(q, conn, h):
-    # we can now do audio calls
+    # we can now do audio and video calls
     event = q.expect('dbus-signal', signal='CapabilitiesChanged')
     check_caps(conn, h)
 
 def check_caps(conn, h):
-    assertContains((h, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, cs.MEDIA_CAP_AUDIO),
+    assertContains((h, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3,
+            cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO),
         conn.Capabilities.GetCapabilities([h]))
 
 def update_contact_caps(q, conn, stream, contact, caps, disco = True,
diff --git a/tests/twisted/caps/from-bare-jid.py b/tests/twisted/caps/from-bare-jid.py
index 5664650..cdf51fe 100644
--- a/tests/twisted/caps/from-bare-jid.py
+++ b/tests/twisted/caps/from-bare-jid.py
@@ -24,9 +24,10 @@ def test(q, bus, conn, stream):
 
     # Gabble gets a presence stanza from a bare JID, which is a tad surprising.
     features = [
-        'http://jabber.org/protocol/jingle',
-        'http://jabber.org/protocol/jingle/description/audio',
-        'http://www.google.com/transport/p2p',
+        ns.JINGLE_015,
+        ns.JINGLE_015_AUDIO,
+        ns.JINGLE_015_VIDEO,
+        ns.GOOGLE_P2P,
         ]
     caps = {'node': client,
             'hash': 'sha-1',
@@ -48,7 +49,7 @@ def test(q, bus, conn, stream):
     # Gabble lets us know their caps have changed. (Gabble used to ignore the
     # reply.)
     streamed_media_caps = (contact_handle, cs.CHANNEL_TYPE_STREAMED_MEDIA,
-        0, 3, 0, 1)
+        0, 3, 0, cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)
     e = q.expect('dbus-signal', signal='CapabilitiesChanged')
     assertContains(streamed_media_caps, e.args[0])
 
diff --git a/tests/twisted/caps/hashed-caps.py b/tests/twisted/caps/hashed-caps.py
index 206acdd..375f92e 100644
--- a/tests/twisted/caps/hashed-caps.py
+++ b/tests/twisted/caps/hashed-caps.py
@@ -34,6 +34,13 @@ from caps_helper import (
 
 caps_changed_flag = False
 
+jingle_av_features = [
+    ns.JINGLE_015,
+    ns.JINGLE_015_AUDIO,
+    ns.JINGLE_015_VIDEO,
+    ns.GOOGLE_P2P,
+    ]
+
 def caps_changed_cb(dummy):
     # Workaround to bug 9980: do not raise an error but use a flag
     # https://bugs.freedesktop.org/show_bug.cgi?id=9980
@@ -74,10 +81,7 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
 
     # send good reply
     stream.send(make_caps_disco_reply(stream, event.stanza,
-        [ 'http://jabber.org/protocol/jingle',
-          'http://jabber.org/protocol/jingle/description/audio',
-          'http://www.google.com/transport/p2p',
-        ]))
+        jingle_av_features))
 
     # we can now do audio calls
     event = q.expect('dbus-signal', signal='CapabilitiesChanged')
@@ -139,13 +143,7 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
 
 
     # send correct presence
-    features = [
-        'http://jabber.org/protocol/jingle',
-        'http://jabber.org/protocol/jingle/description/audio',
-        'http://www.google.com/transport/p2p',
-        ]
-
-    ver = compute_caps_hash([], features, fake_client_dataforms)
+    ver = compute_caps_hash([], jingle_av_features, fake_client_dataforms)
     caps = {
         'node': client,
         'ver':  ver,
@@ -166,7 +164,7 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
     assert caps_changed_flag == False
 
     # send good reply
-    result = make_caps_disco_reply(stream, event.stanza, features,
+    result = make_caps_disco_reply(stream, event.stanza, jingle_av_features,
         fake_client_dataforms)
     stream.send(result)
 
@@ -209,12 +207,7 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
     assert conn.Capabilities.GetCapabilities([contact_handle2]) == basic_caps
 
     # send updated presence with Jingle caps info
-    features = [
-        'http://jabber.org/protocol/jingle',
-        'http://jabber.org/protocol/jingle/description/audio',
-        'http://www.google.com/transport/p2p',
-        ]
-    ver = compute_caps_hash([], features, {})
+    ver = compute_caps_hash([], jingle_av_features, {})
     caps = {
         'node': client,
         'ver': ver,
@@ -236,7 +229,7 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
     sync_dbus(bus, q, conn)
     assert caps_changed_flag == False
 
-    result = make_caps_disco_reply(stream, event.stanza, features)
+    result = make_caps_disco_reply(stream, event.stanza, jingle_av_features)
 
     if broken_hash:
         # make the hash break!
@@ -259,19 +252,19 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
         assert caps_changed_flag == False
 
         # send good reply
-        result = make_caps_disco_reply(stream, event.stanza, features)
+        result = make_caps_disco_reply(stream, event.stanza, jingle_av_features)
         stream.send(result)
 
     # we can now do audio calls with both contacts
     event = q.expect('dbus-signal', signal='CapabilitiesChanged',
-        #  what are the good values?!
-        args=[[(contact_handle2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0, 1)]])
+        args=[[(contact_handle2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0,
+            cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
     if not broken_hash:
         # if the first contact failed to provide a good hash, it does not
         # deserve its capabilities to be understood by Gabble!
         event = q.expect('dbus-signal', signal='CapabilitiesChanged',
-            #  what are the good values?!
-            args=[[(contact_handle1, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0, 1)]])
+            args=[[(contact_handle1, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0,
+                cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
 
     caps_changed_flag = False
 
diff --git a/tests/twisted/caps/jingle-caps.py b/tests/twisted/caps/jingle-caps.py
index 892e118..72c063b 100644
--- a/tests/twisted/caps/jingle-caps.py
+++ b/tests/twisted/caps/jingle-caps.py
@@ -17,7 +17,7 @@ all_transports = [
     ns.GOOGLE_P2P
 ]
 
-def test_caps(q, conn, stream, contact, features, audio, video):
+def test_caps(q, conn, stream, contact, features, audio, video, google=False):
     caps['ver'] = compute_caps_hash ([], features, {})
 
     h = presence_and_disco(q, conn, stream, contact, True,
@@ -30,6 +30,11 @@ def test_caps(q, conn, stream, contact, features, audio, video):
     if video:
       cflags |= cs.MEDIA_CAP_VIDEO
 
+    # If the contact can only do one of audio or video, or uses a Google
+    # client, they'll have the ImmutableStreams cap.
+    if cflags < (cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO) or google:
+        cflags |= cs.MEDIA_CAP_IMMUTABLE_STREAMS
+
     assertContains((h, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, cflags),
         conn.Capabilities.GetCapabilities([h]))
 
@@ -69,15 +74,18 @@ def test(q, bus, conn, stream):
 
     # Google media doesn't need a transport at all
     features = [ ns.GOOGLE_FEAT_VOICE, ns.GOOGLE_FEAT_VIDEO ]
-    test_caps(q, conn, stream, "full at google", features, True, True)
+    test_caps(q, conn, stream, "full at google", features, True, True,
+        google=True)
 
     # Google video only
     features = [ ns.GOOGLE_FEAT_VIDEO ]
-    test_caps(q, conn, stream, "video at google", features, False, True)
+    test_caps(q, conn, stream, "video at google", features, False, True,
+        google=True)
 
     # Google audio only
     features = [ ns.GOOGLE_FEAT_VOICE ]
-    test_caps(q, conn, stream, "audio at google", features, True, False)
+    test_caps(q, conn, stream, "audio at google", features, True, False,
+        google=True)
 
 
 if __name__ == '__main__':
diff --git a/tests/twisted/caps/receive-jingle.py b/tests/twisted/caps/receive-jingle.py
index 498ccd2..3d7a808 100644
--- a/tests/twisted/caps/receive-jingle.py
+++ b/tests/twisted/caps/receive-jingle.py
@@ -74,7 +74,8 @@ def test(q, bus, conn, stream):
 
     # we can now do audio and video calls
     event = q.expect('dbus-signal', signal='CapabilitiesChanged',
-        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0, 3)]])
+        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3,
+            0, cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
 
     caps = conn.Contacts.GetContactAttributes([2], [cs.CONN_IFACE_CAPS], False)
     assert caps.keys() == [2L]
@@ -91,16 +92,21 @@ def test(q, bus, conn, stream):
         })
     stream.send(presence)
 
-    # we can now do only audio calls
+    # we can now do only audio calls (and as a result have the ImmutableStreams
+    # cap)
     event = q.expect('dbus-signal', signal='CapabilitiesChanged',
-        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 3, 3, 1)]])
+        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 3,
+            cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO,
+            cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS)]])
 
     caps = conn.Contacts.GetContactAttributes([2], [cs.CONN_IFACE_CAPS], False)
     assert caps.keys() == [2L]
     assert icaps_attr in caps[2L]
     assert len(caps[2L][icaps_attr]) == 2
     assert basic_caps[0] in caps[2L][icaps_attr]
-    assert (2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 1) in caps[2L][icaps_attr]
+    assert (2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3,
+        cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS) \
+        in caps[2L][icaps_attr]
 
     # go offline
     presence = make_presence('bob at foo.com/Foo', type='unavailable')
@@ -108,7 +114,9 @@ def test(q, bus, conn, stream):
 
     # can't do audio calls any more
     event = q.expect('dbus-signal', signal='CapabilitiesChanged',
-        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 0, 1, 0)]])
+        args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 0,
+            cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS,
+            0)]])
 
     # Contact went offline and the handle is now invalid
     assert conn.Contacts.GetContactAttributes(
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index 6e38dcb..7f30964 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -244,6 +244,7 @@ MEDIA_CAP_VIDEO = 2
 MEDIA_CAP_STUN = 4
 MEDIA_CAP_GTALKP2P = 8
 MEDIA_CAP_ICEUDP = 16
+MEDIA_CAP_IMMUTABLE_STREAMS = 32
 
 CLIENT = 'org.freedesktop.Telepathy.Client'
 
-- 
1.5.6.5




More information about the telepathy-commits mailing list