[telepathy-gabble/master] Upgrade ContactCapabilities spec to draft 2
Simon McVittie
simon.mcvittie at collabora.co.uk
Wed Aug 26 10:21:00 PDT 2009
---
.../Connection_Interface_Contact_Capabilities.xml | 150 +++++++++++++++-----
extensions/all.xml | 4 +
src/connection.c | 108 +++++++++++----
tests/twisted/Makefile.am | 2 +-
.../{advertise-draft1.py => advertise-draft2.py} | 145 +++++++++----------
tests/twisted/constants.py | 4 +-
6 files changed, 276 insertions(+), 137 deletions(-)
rename tests/twisted/caps/{advertise-draft1.py => advertise-draft2.py} (53%)
diff --git a/extensions/Connection_Interface_Contact_Capabilities.xml b/extensions/Connection_Interface_Contact_Capabilities.xml
index e06ab01..d5ccebf 100644
--- a/extensions/Connection_Interface_Contact_Capabilities.xml
+++ b/extensions/Connection_Interface_Contact_Capabilities.xml
@@ -18,9 +18,11 @@ Lesser General Public License for more details.</p>
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
</tp:license>
- <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.DRAFT">
+ <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.DRAFT2"
+ tp:causes-havoc="experimental">
<tp:requires interface="org.freedesktop.Telepathy.Connection"/>
<tp:added version="0.17.16">(as a draft)</tp:added>
+ <tp:changed version="0.17.27">(draft 2)</tp:changed>
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
<p>Contact capabilities describe the channel classes which may be
@@ -37,38 +39,77 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<p>This interface also enables user interfaces to notify the connection
manager what capabilities to advertise for the user to other contacts.
This is done by using the
- <tp:member-ref>SetSelfCapabilities</tp:member-ref> method, and deals
- with channel property values pertaining to them which are implemented
- by available client processes.</p>
+ <tp:member-ref>UpdateCapabilities</tp:member-ref> method.</p>
+ <tp:rationale>
+ <p>XMPP is a major user of this interface: XMPP contacts will not,
+ in general, be callable using VoIP unless they advertise suitable
+ Jingle capabilities.</p>
+
+ <p>Many other protocols also have some concept of capability flags,
+ which this interface exposes in a protocol-independent way.</p>
+ </tp:rationale>
</tp:docstring>
- <method name="SetSelfCapabilities"
- tp:name-for-bindings="Set_Self_Capabilities">
- <arg direction="in" name="caps" type="aa{sv}"
+ <tp:struct name="Handler_Capabilities"
+ array-name="Handler_Capabilities_List">
+ <tp:docstring>
+ A structure representing the capabilities of a single client.
+ </tp:docstring>
+
+ <tp:member name="Well_Known_Name" type="s" tp:type="DBus_Well_Known_Name">
+ <tp:docstring>
+ For implementations of the <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Client</tp:dbus-ref>
+ interface, the well-known bus name name of the client; for any other
+ process, any other reversed domain name that uniquely identifies it.
+ </tp:docstring>
+ </tp:member>
+
+ <tp:member name="Channel_Classes" type="aa{sv}"
tp:type="String_Variant_Map[]">
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- An array of channel classes to replace to the list of what the
- connection can handle. If you include optional properties, they
- may not get advertised. The given properties are matched to the
- mandatory properties.
+ An array of channel classes that can be handled by this client.
+ This will usually be a copy of the client's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">HandlerChannelFilter</tp:dbus-ref>
+ property.
</tp:docstring>
- </arg>
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>Used by user interfaces to indicate which channel classes they are
- able to handle on this connection. It replaces the previous advertised
- channel classes by the set given as parameter.</p>
+ </tp:member>
- <p>If a channel class is unknown by the connection manager, it is just
- ignored. No error are returned in this case, and other known channel
- class are added.</p>
+ <tp:member name="Capabilities"
+ type="as" tp:type="Handler_Capability_Token[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An array of client capabilities supported by this client, to be
+ used by the connection manager to determine what capabilities to
+ advertise. This will usually be a copy of the client's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Client.Handler">Capabilities</tp:dbus-ref>
+ property.
+ </tp:docstring>
+ </tp:member>
+ </tp:struct>
- <p>Upon a successful invocation of this method, the
- <tp:member-ref>ContactCapabilitiesChanged</tp:member-ref> signal
- will only be emitted for the user's own
- handle (as returned by GetSelfHandle) by the connection manager if, in
- the given protocol, the given capabilities are distinct from the
- previous state.</p>
+ <method name="UpdateCapabilities" tp:name-for-bindings="Update_Capabilities">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>Alter the connection's advertised capabilities to include
+ the intersection of the given clients' capabilities with what the
+ connection manager is able to implement.</p>
+
+ <p>On connections managed by the ChannelDispatcher, processes other
+ than the ChannelDispatcher SHOULD NOT call this method, and the
+ ChannelDispatcher SHOULD use this method to advertise the
+ capabilities of all the registered <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy">Client.Handler</tp:dbus-ref>
+ implementations.On connections not managed by the ChannelDispatcher,
+ clients MAY use this method directly, to indicate the channels they
+ will handle and the extra capabilities they have.</p>
+
+ <p>Upon a successful invocation of this method, the connection manager
+ will only emit the
+ <tp:member-ref>ContactCapabilitiesChanged</tp:member-ref> signal
+ for the user's <tp:dbus-ref
+ namespace="org.freedesktop.Telepathy.Connection">SelfHandle</tp:dbus-ref>
+ if, in the underlying protocol, the new capabilities are distinct
+ from the previous state.</p>
<tp:rationale>
<p>The connection manager will essentially intersect the provided
@@ -78,10 +119,45 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
channel) will almost certainly not be advertised.</p>
</tp:rationale>
+ <p>This method MAY be called on a newly-created connection while it
+ is still in the DISCONNECTED state, to request that when the
+ connection connects, it will do so with the appropriate
+ capabilities. Doing so MUST NOT fail.</p>
</tp:docstring>
+
+ <arg direction="in" name="Handler_Capabilities" type="a(saa{sv}as)"
+ tp:type="Handler_Capabilities[]">
+ <tp:docstring>
+ <p>The capabilities of one or more clients.</p>
+
+ <p>For each client in the given list, any capabilities previously
+ advertised for the same client name are discarded, then replaced by
+ the capabilities indicated.</p>
+
+ <p>As a result, if a client becomes unavailable, this method SHOULD
+ be called with a <tp:type>Handler_Capabilities</tp:type> structure
+ containing its name, an empty list of channel classes, and an
+ empty list of capabilities. When this is done, the connection
+ manager SHOULD free all memory associated with that client name.</p>
+
+ <tp:rationale>
+ <p>This method takes a list of clients so that
+ when the channel dispatcher first calls it (with a list of all
+ the Handlers that are initially available), the changes can be
+ made atomically, with only one transmission of updated
+ capabilities to the network. Afterwards, the channel dispatcher
+ will call this method with a single-element list every time
+ a Handler becomes available or unavailable.</p>
+ </tp:rationale>
+
+ <p>The connection manager MUST ignore any channel classes and client
+ capabilities for which there is no representation in the protocol
+ or no support in the connection manager.</p>
+ </tp:docstring>
+ </arg>
+
<tp:possible-errors>
<tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
- <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
</tp:possible-errors>
</method>
@@ -94,13 +170,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<p>The handle zero MUST NOT be included in the request.</p>
</tp:docstring>
</arg>
- <!-- There was a bug in dbus-glib that prevent to use the right type:
- Instead of a{ua(a{sv}as)}, we used a(ua{sv}as) as a workaround.
- See http://bugs.freedesktop.org/show_bug.cgi?id=17329
- Now there is a fix, so we don't use the workaround anymore.
- -->
- <arg direction="out" type="a{ua(a{sv}as)}" name="Contact_Capabilities"
- tp:type="Contact_Capabilities_Map">
+ <arg direction="out" type="a{ua(a{sv}as)}"
+ tp:type="Contact_Capabilities_Map" name="Contact_Capabilities">
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
An array of structures containing:
<ul>
@@ -139,7 +210,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<p>The underlying protocol can get several contacts' capabilities at
the same time.</p>
</tp:rationale>
-
+
</tp:docstring>
</signal>
@@ -160,6 +231,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
</tp:member>
</tp:mapping>
+ <tp:contact-attribute name="capabilities"
+ type="a(a{sv}as)" tp:type="Requestable_Channel_Class[]">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The same structs that would be returned by
+ <tp:member-ref>GetContactCapabilities</tp:member-ref>.
+ Omitted from the result if the contact's capabilities
+ are not known; present in the result as an empty array if the
+ contact is known to have no capabilities at all.</p>
+ </tp:docstring>
+ </tp:contact-attribute>
+
</interface>
</node>
<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/extensions/all.xml b/extensions/all.xml
index 203961c..10c0db7 100644
--- a/extensions/all.xml
+++ b/extensions/all.xml
@@ -57,6 +57,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA</p>
from="Telepathy specification"/>
<tp:external-type name="DBus_Error_Name" type="s"
from="Telepathy specification"/>
+ <tp:external-type name="DBus_Well_Known_Name" type="s"
+ from="Telepathy specification"/>
+ <tp:external-type name="Handler_Capability_Token" type="s"
+ from="Telepathy specification"/>
<!-- for localisation -->
<tp:external-type name="Rich_Presence_Access_Control_Type" type="u"
diff --git a/src/connection.c b/src/connection.c
index 6b627d0..e4c1e12 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -204,8 +204,8 @@ struct _GabbleConnectionPrivate
GabbleCapabilitySet *all_caps;
GabbleCapabilitySet *notify_caps;
GabbleCapabilitySet *legacy_caps;
- GabbleCapabilitySet *draft1_caps;
GabbleCapabilitySet *bonus_caps;
+ GHashTable *client_caps;
/* gobject housekeeping */
gboolean dispose_has_run;
@@ -327,7 +327,8 @@ gabble_connection_constructor (GType type,
priv->all_caps = gabble_capability_set_new ();
priv->notify_caps = gabble_capability_set_new ();
priv->legacy_caps = gabble_capability_set_new ();
- priv->draft1_caps = gabble_capability_set_new ();
+ priv->client_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) gabble_capability_set_free);
/* Historically, the optional Jingle transports were in our initial
* presence, but could be removed by AdvertiseCapabilities(). Emulate
@@ -932,10 +933,10 @@ gabble_connection_dispose (GObject *object)
*/
g_idle_add (_unref_lm_connection, self->lmconn);
+ g_hash_table_destroy (priv->client_caps);
gabble_capability_set_free (priv->all_caps);
gabble_capability_set_free (priv->notify_caps);
gabble_capability_set_free (priv->legacy_caps);
- gabble_capability_set_free (priv->draft1_caps);
gabble_capability_set_free (priv->bonus_caps);
if (G_OBJECT_CLASS (gabble_connection_parent_class)->dispose)
@@ -1595,6 +1596,8 @@ static gboolean
gabble_connection_refresh_capabilities (GabbleConnection *self)
{
GError *error = NULL;
+ GHashTableIter iter;
+ gpointer k, v;
gabble_capability_set_clear (self->priv->all_caps);
@@ -1602,9 +1605,23 @@ gabble_connection_refresh_capabilities (GabbleConnection *self)
gabble_capabilities_get_fixed_caps ());
gabble_capability_set_update (self->priv->all_caps, self->priv->notify_caps);
gabble_capability_set_update (self->priv->all_caps, self->priv->legacy_caps);
- gabble_capability_set_update (self->priv->all_caps, self->priv->draft1_caps);
gabble_capability_set_update (self->priv->all_caps, self->priv->bonus_caps);
+ g_hash_table_iter_init (&iter, self->priv->client_caps);
+
+ while (g_hash_table_iter_next (&iter, &k, &v))
+ {
+ if (DEBUGGING)
+ {
+ gchar *s = gabble_capability_set_dump (v, " ");
+
+ DEBUG ("incorporating caps for %s:\n%s", (const gchar *) k, s);
+ g_free (s);
+ }
+
+ gabble_capability_set_update (self->priv->all_caps, v);
+ }
+
if (gabble_presence_resource_has_caps (self->self_presence,
self->priv->resource, gabble_capability_set_predicate_equals,
self->priv->all_caps))
@@ -2392,7 +2409,7 @@ _emit_capabilities_changed (GabbleConnection *conn,
}
g_ptr_array_free (caps_arr, TRUE);
- /* ContactCapabilities (draft 1) */
+ /* ContactCapabilities (draft 2) */
caps_arr = g_ptr_array_new ();
@@ -2591,48 +2608,85 @@ gabble_connection_advertise_capabilities (TpSvcConnectionInterfaceCapabilities *
}
/**
- * gabble_connection_set_self_capabilities
+ * gabble_connection_update_capabilities
*
- * Implements D-Bus method SetSelfCapabilities
+ * Implements D-Bus method UpdateCapabilities
* on interface
* org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities
- *
- * @error: Used to return a pointer to a GError detailing any error
- * that occurred, D-Bus will throw the error only if this
- * function returns FALSE.
- *
- * Returns: TRUE if successful, FALSE if an error was thrown.
*/
static void
-gabble_connection_set_self_capabilities (
+gabble_connection_update_capabilities (
GabbleSvcConnectionInterfaceContactCapabilities *iface,
- const GPtrArray *caps,
+ const GPtrArray *clients,
DBusGMethodInvocation *context)
{
- static const gchar *null_string = NULL;
GabbleConnection *self = GABBLE_CONNECTION (iface);
TpBaseConnection *base = (TpBaseConnection *) self;
GabbleCapabilitySet *old_caps;
TpChannelManagerIter iter;
TpChannelManager *manager;
+ guint i;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
old_caps = gabble_capability_set_copy (self->priv->all_caps);
- gabble_capability_set_clear (self->priv->draft1_caps);
+ /* Now that someone has told us our *actual* capabilities, we can stop
+ * advertising spurious caps in initial presence */
+ gabble_capability_set_clear (self->priv->bonus_caps);
- tp_base_connection_channel_manager_iter_init (&iter, base);
+ DEBUG ("enter");
- while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ for (i = 0; i < clients->len; i++)
{
- /* all channel managers must implement the capability interface */
- g_assert (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager));
+ GValueArray *va = g_ptr_array_index (clients, i);
+ const gchar *client_name = g_value_get_string (va->values + 0);
+ const GPtrArray *filters = g_value_get_boxed (va->values + 1);
+ const gchar * const * cap_tokens = g_value_get_boxed (va->values + 2);
+ GabbleCapabilitySet *cap_set;
+
+ g_hash_table_remove (self->priv->client_caps, client_name);
+
+ if ((cap_tokens == NULL || cap_tokens[0] != NULL) &&
+ filters->len == 0)
+ {
+ /* no capabilities */
+ DEBUG ("client %s can't do anything", client_name);
+ continue;
+ }
+
+ cap_set = gabble_capability_set_new ();
+
+ tp_base_connection_channel_manager_iter_init (&iter, base);
+
+ while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ {
+ /* all channel managers must implement the capability interface */
+ g_assert (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager));
+
+ gabble_caps_channel_manager_represent_client (
+ GABBLE_CAPS_CHANNEL_MANAGER (manager), client_name, filters,
+ cap_tokens, cap_set);
+ }
+
+ if (gabble_capability_set_is_empty (cap_set))
+ {
+ DEBUG ("client %s has no interesting capabilities", client_name);
+ gabble_capability_set_free (cap_set);
+ }
+ else
+ {
+ if (DEBUGGING)
+ {
+ gchar *s = gabble_capability_set_dump (cap_set, " ");
- gabble_caps_channel_manager_represent_client (
- GABBLE_CAPS_CHANNEL_MANAGER (manager),
- "<ContactCapabilities.DRAFT1>", caps, &null_string,
- self->priv->draft1_caps);
+ DEBUG ("client %s contributes:\n%s", client_name, s);
+ g_free (s);
+ }
+
+ g_hash_table_insert (self->priv->client_caps, g_strdup (client_name),
+ cap_set);
+ }
}
if (gabble_connection_refresh_capabilities (self))
@@ -2641,7 +2695,7 @@ gabble_connection_set_self_capabilities (
self->priv->all_caps);
}
- gabble_svc_connection_interface_contact_capabilities_return_from_set_self_capabilities (
+ gabble_svc_connection_interface_contact_capabilities_return_from_update_capabilities (
context);
gabble_capability_set_free (old_caps);
@@ -3369,7 +3423,7 @@ gabble_conn_contact_caps_iface_init (gpointer g_iface, gpointer iface_data)
gabble_svc_connection_interface_contact_capabilities_implement_##x (\
klass, gabble_connection_##x)
IMPLEMENT(get_contact_capabilities);
- IMPLEMENT(set_self_capabilities);
+ IMPLEMENT(update_capabilities);
#undef IMPLEMENT
}
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 0ea0a8c..ed52f27 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -1,7 +1,7 @@
TWISTED_TESTS = \
avatar-requirements.py \
caps_helper.py \
- caps/advertise-draft1.py \
+ caps/advertise-draft2.py \
caps/advertise-legacy.py \
caps/caps-cache.py \
caps/compat-bundles.py \
diff --git a/tests/twisted/caps/advertise-draft1.py b/tests/twisted/caps/advertise-draft2.py
similarity index 53%
rename from tests/twisted/caps/advertise-draft1.py
rename to tests/twisted/caps/advertise-draft2.py
index c6befc8..971c8cc 100644
--- a/tests/twisted/caps/advertise-draft1.py
+++ b/tests/twisted/caps/advertise-draft2.py
@@ -1,5 +1,5 @@
"""
-Test SetSelfCapabilities.
+Test UpdateCapabilities.
"""
import dbus
@@ -22,6 +22,9 @@ def noop_presence_update(q, stream):
sync_stream(q, stream)
#q.unforbid_events(events)
+JINGLE_CAPS_EXCEPT_GVIDEO = [n for n in JINGLE_CAPS
+ if n != ns.GOOGLE_FEAT_VIDEO]
+
def run_test(q, bus, conn, stream):
conn.Connect()
@@ -31,124 +34,118 @@ def run_test(q, bus, conn, stream):
EventPattern('stream-presence'),
)
- # This method call looks wrong, but it's "the other side" of
- # 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)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, JINGLE_CAPS)
- # Immediately afterwards, we get SetSelfCapabilities, for which a
- # more comprehensive test exists in tube-caps.py.
- conn.ContactCapabilities.SetSelfCapabilities([
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.AbiWord', [
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.STREAM_TUBE_SERVICE: 'x-abiword' },
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
cs.STREAM_TUBE_SERVICE: 'x-abiword' },
+ ], []),
+ (cs.CLIENT + '.KCall', [
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_AUDIO: True},
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_VIDEO: True},
+ ], [
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/gtalk-p2p',
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/ice-udp',
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/video/h264',
+ ]),
])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
check_caps(namespaces, JINGLE_CAPS + [ns.TUBES + '/stream#x-abiword'])
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
+ # Removing our H264 codec removes our ability to do Google Video
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.KCall', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_AUDIO: True},
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_VIDEO: True},
+ ], [
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/gtalk-p2p',
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/ice-udp',
+ ]),
+ ])
+ (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
+ False)
+ check_caps(namespaces,
+ JINGLE_CAPS_EXCEPT_GVIDEO + [ns.TUBES + '/stream#x-abiword'])
+
+ # Remove AbiWord's caps
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.AbiWord', [], []),
+ ])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
- check_caps(namespaces, [ns.TUBES + '/stream#x-abiword'])
- conn.ContactCapabilities.SetSelfCapabilities([])
+ check_caps(namespaces, JINGLE_CAPS_EXCEPT_GVIDEO)
+
+ # Remove KCall's caps too
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.KCall', [], []),
+ ])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
check_caps(namespaces, [])
- # Add caps selectively (i.e. what a client that actually understood the
- # old Capabilities interface would do). With AUDIO and GTALK_P2P, we're
- # callable, but not via ICE-UDP, and not with video.
+ # Add caps selectively. Here we're callable, but not via ICE-UDP, and not
+ # with video.
#
# (Jingle and raw UDP need no special client support, so are automatically
# enabled whenever we can do audio or video.)
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_GTALKP2P)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.KCall', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_AUDIO: True},
+ ], [cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/gtalk-p2p']),
+ ])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
check_caps(namespaces,
[ns.GOOGLE_P2P, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
ns.JINGLE_015, ns.GOOGLE_FEAT_VOICE, ns.JINGLE_RTP_AUDIO,
ns.JINGLE_RTP, ns.JINGLE_015_AUDIO])
- # the call to SSC has no effect here
- conn.ContactCapabilities.SetSelfCapabilities([
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
- ])
- noop_presence_update(q, stream)
-
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, [])
- # the call to SSC has no effect here
- conn.ContactCapabilities.SetSelfCapabilities([])
- noop_presence_update(q, stream)
# With AUDIO but no transport, we are only callable via raw UDP, which
# Google clients cannot do.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.MEDIA_CAP_AUDIO)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.KCall', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_AUDIO: True},
+ ], [])
+ ])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
check_caps(namespaces,
[ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
ns.JINGLE_015, ns.JINGLE_RTP_AUDIO,
ns.JINGLE_RTP, ns.JINGLE_015_AUDIO])
- # the call to SSC has no effect here
- conn.ContactCapabilities.SetSelfCapabilities([
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
- ])
- noop_presence_update(q, stream)
-
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, [])
- # the call to SSC has no effect here
- conn.ContactCapabilities.SetSelfCapabilities([])
- noop_presence_update(q, stream)
# With VIDEO and ICE-UDP only, we are very futuristic indeed.
# Google clients cannot interop with us.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.MEDIA_CAP_VIDEO | cs.MEDIA_CAP_ICEUDP)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.KCall', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
+ cs.INITIAL_VIDEO: True},
+ ], [
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/ice-udp',
+ cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/video/theora',
+ ]),
+ ])
(disco_response, namespaces, _) = receive_presence_and_ask_caps(q, stream,
False)
check_caps(namespaces,
[ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
ns.JINGLE_015, ns.JINGLE_RTP_VIDEO,
ns.JINGLE_RTP, ns.JINGLE_015_VIDEO])
- # the call to SSC has no effect here
- conn.ContactCapabilities.SetSelfCapabilities([
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA },
- ])
- noop_presence_update(q, stream)
if __name__ == '__main__':
exec_test(run_test)
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index 957eed7..b45e283 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -51,7 +51,7 @@ CONN = "org.freedesktop.Telepathy.Connection"
CONN_IFACE_AVATARS = CONN + '.Interface.Avatars'
CONN_IFACE_CAPS = CONN + '.Interface.Capabilities'
CONN_IFACE_CONTACTS = CONN + '.Interface.Contacts'
-CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities.DRAFT'
+CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities.DRAFT2'
CONN_IFACE_SIMPLE_PRESENCE = CONN + '.Interface.SimplePresence'
CONN_IFACE_REQUESTS = CONN + '.Interface.Requests'
CONN_IFACE_LOCATION = CONN + '.Interface.Location'
@@ -231,3 +231,5 @@ MEDIA_CAP_VIDEO = 2
MEDIA_CAP_STUN = 4
MEDIA_CAP_GTALKP2P = 8
MEDIA_CAP_ICEUDP = 16
+
+CLIENT = 'org.freedesktop.Telepathy.Client'
--
1.5.6.5
More information about the telepathy-commits
mailing list