[telepathy-gabble/master] Add support for google video capabilities

Sjoerd Simons sjoerd.simons at collabora.co.uk
Thu Jun 25 09:59:34 PDT 2009


support google video capabilities (both recognising and setting them). Like
with voice-v1 the google web client doesn't actually asks us about our
capabilities but only assumes we can do video if video-v1 is in the ext
attribute of our capabilities
---
 src/capabilities.c     |    1 +
 src/capabilities.h     |    6 ++++--
 src/connection.c       |   21 +++++++++++++++++++--
 src/jingle-media-rtp.c |    5 +++++
 src/media-channel.c    |   34 ++++++++++++++++++++++++++++++----
 src/namespaces.h       |    3 +++
 src/types.h            |    1 +
 7 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/src/capabilities.c b/src/capabilities.c
index f814361..161fc9f 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -50,6 +50,7 @@ static const Feature self_advertised_features[] =
   { FEATURE_FIXED, 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 },
   { FEATURE_OPTIONAL, NS_JINGLE_DESCRIPTION_AUDIO,
     PRESENCE_CAP_JINGLE_DESCRIPTION_AUDIO},
   { FEATURE_OPTIONAL, NS_JINGLE_DESCRIPTION_VIDEO,
diff --git a/src/capabilities.h b/src/capabilities.h
index e5d1d6f..bed6eff 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -30,10 +30,12 @@
  * "The names of the feature bundles MUST NOT be used for semantic purposes:
  * they are merely opaque identifiers"
  *
- * However, some old Jabber clients (e.g. Gabble 0.2) requires the bundle name
- * "voice-v1". We keep this name for compatibility.
+ * However, some old Jabber clients (e.g. Gabble 0.2) and various Google
+ * clients require the bundle name "voice-v1" and "video-v1". We keep these 
+ * names for compatibility.
  */
 #define BUNDLE_VOICE_V1         "voice-v1"
+#define BUNDLE_VIDEO_V1         "video-v1"
 
 typedef struct _Feature Feature;
 
diff --git a/src/connection.c b/src/connection.c
index b129ef1..c27cfd3 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1480,8 +1480,25 @@ _gabble_connection_signal_own_presence (GabbleConnection *self, GError **error)
 
   /* XEP-0115 deprecates 'ext' feature bundles. But we still need
    * BUNDLE_VOICE_V1 it for backward-compatibility with Gabble 0.2 */
-  if (presence->caps & PRESENCE_CAP_GOOGLE_VOICE)
-    lm_message_node_set_attribute (node, "ext", BUNDLE_VOICE_V1);
+
+  if (presence->caps & (PRESENCE_CAP_GOOGLE_VOICE|PRESENCE_CAP_GOOGLE_VIDEO))
+    {
+      GString *ext = g_string_new ("");
+
+      if (presence->caps & PRESENCE_CAP_GOOGLE_VOICE)
+        g_string_append (ext, BUNDLE_VOICE_V1);
+
+      if (presence->caps & PRESENCE_CAP_GOOGLE_VIDEO)
+        {
+          if (ext->len > 0)
+            g_string_append_c (ext, ' ');
+          g_string_append (ext, BUNDLE_VIDEO_V1);
+        }
+
+      lm_message_node_set_attribute (node, "ext", ext->str);
+
+      g_string_free (ext, TRUE);
+    }
 
   ret = _gabble_connection_send (self, message, error);
 
diff --git a/src/jingle-media-rtp.c b/src/jingle-media-rtp.c
index e03f04e..6714cb8 100644
--- a/src/jingle-media-rtp.c
+++ b/src/jingle-media-rtp.c
@@ -801,6 +801,11 @@ jingle_media_rtp_register (GabbleJingleFactory *factory)
   gabble_jingle_factory_register_content_type (factory,
       NS_GOOGLE_SESSION_PHONE,
       GABBLE_TYPE_JINGLE_MEDIA_RTP);
+
+  /* GTalk video call namespace */
+  gabble_jingle_factory_register_content_type (factory,
+      NS_GOOGLE_SESSION_VIDEO,
+      GABBLE_TYPE_JINGLE_MEDIA_RTP);
 }
 
 /* We can't get remote codecs when they're signalled, because
diff --git a/src/media-channel.c b/src/media-channel.c
index 70c1c6c..6c29d2f 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -1329,6 +1329,13 @@ _pick_best_content_type (GabbleMediaChannel *chan, TpHandle peer,
     {
       return NS_GOOGLE_SESSION_PHONE;
     }
+  if ((type == JINGLE_MEDIA_TYPE_VIDEO) &&
+      gabble_presence_resource_has_caps (presence, resource,
+        PRESENCE_CAP_GOOGLE_VIDEO))
+    {
+      return NS_GOOGLE_SESSION_VIDEO;
+    }
+
 
   return NULL;
 }
@@ -1378,6 +1385,16 @@ _pick_best_resource (GabbleMediaChannel *chan,
       goto CHOOSE_TRANSPORT;
     }
 
+  /* There is still hope, try GTalk */
+  caps = PRESENCE_CAP_GOOGLE_VIDEO | PRESENCE_CAP_GOOGLE_VOICE;
+  resource = gabble_presence_pick_resource_by_caps (presence, caps);
+
+  if (resource != NULL)
+    {
+      *dialect = JINGLE_DIALECT_GTALK3;
+      goto CHOOSE_TRANSPORT;
+    }
+
   /* In this unlikely case, we can get by with just video */
   if (!want_audio)
     {
@@ -1393,7 +1410,10 @@ _pick_best_resource (GabbleMediaChannel *chan,
 
   /* Uh, huh, we can't provide what's requested. */
   if (want_video)
+    {
+      DEBUG ("No resource with video support available");
       return NULL;
+    }
 
   /* Ok, try just older Jingle draft, audio */
   caps = PRESENCE_CAP_JINGLE_DESCRIPTION_AUDIO;
@@ -1436,7 +1456,8 @@ CHOOSE_TRANSPORT:
     {
       *transport_ns = NS_JINGLE_TRANSPORT_RAWUDP;
     }
-  else if (*dialect == JINGLE_DIALECT_GTALK4)
+  else if (*dialect == JINGLE_DIALECT_GTALK4
+      || *dialect == JINGLE_DIALECT_GTALK3)
     {
       /* (Some) GTalk clients don't advertise gtalk-p2p, though
        * they support it. If we know it's GTalk and there's no
@@ -2027,8 +2048,10 @@ contact_is_media_capable (GabbleMediaChannel *chan,
   if (wait != NULL)
     *wait = wait_;
 
-  caps = PRESENCE_CAP_GOOGLE_VOICE | PRESENCE_CAP_JINGLE_RTP |
-    PRESENCE_CAP_JINGLE_DESCRIPTION_AUDIO | PRESENCE_CAP_JINGLE_DESCRIPTION_VIDEO;
+  caps = PRESENCE_CAP_GOOGLE_VOICE | PRESENCE_CAP_GOOGLE_VOICE |
+    PRESENCE_CAP_JINGLE_RTP |
+    PRESENCE_CAP_JINGLE_DESCRIPTION_AUDIO |
+    PRESENCE_CAP_JINGLE_DESCRIPTION_VIDEO;
 
   presence = gabble_presence_cache_get (priv->conn->presence_cache, peer);
 
@@ -2427,6 +2450,9 @@ stream_direction_changed_cb (GabbleMediaStream *stream,
 #define GTALK_CAPS \
   ( PRESENCE_CAP_GOOGLE_VOICE )
 
+#define GTALK_VIDEO_CAPS \
+   ( PRESENCE_CAP_GOOGLE_VIDEO )
+
 #define JINGLE_CAPS \
   ( PRESENCE_CAP_JINGLE015 | PRESENCE_CAP_JINGLE032 \
   | PRESENCE_CAP_GOOGLE_TRANSPORT_P2P )
@@ -2454,7 +2480,7 @@ _gabble_media_channel_typeflags_to_caps (TpChannelMediaCapabilities flags)
         caps |= GTALK_CAPS | JINGLE_AUDIO_CAPS;
 
       if (flags & TP_CHANNEL_MEDIA_CAPABILITY_VIDEO)
-        caps |= JINGLE_VIDEO_CAPS;
+        caps |= GTALK_VIDEO_CAPS | JINGLE_VIDEO_CAPS;
     }
 
   return caps;
diff --git a/src/namespaces.h b/src/namespaces.h
index cec629a..7e96420 100644
--- a/src/namespaces.h
+++ b/src/namespaces.h
@@ -34,6 +34,7 @@
 #define NS_GOOGLE_CAPS          "http://www.google.com/xmpp/client/caps"
 #define NS_GOOGLE_FEAT_SESSION  "http://www.google.com/xmpp/protocol/session"
 #define NS_GOOGLE_FEAT_VOICE    "http://www.google.com/xmpp/protocol/voice/v1"
+#define NS_GOOGLE_FEAT_VIDEO    "http://www.google.com/xmpp/protocol/video/v1"
 #define NS_GOOGLE_JINGLE_INFO   "google:jingleinfo"
 #define NS_GOOGLE_ROSTER        "google:roster"
 #define NS_IBB                  "http://jabber.org/protocol/ibb"
@@ -45,6 +46,8 @@
 #define NS_GOOGLE_SESSION       "http://www.google.com/session"
 /* Audio capability in Google Jingle dialect */
 #define NS_GOOGLE_SESSION_PHONE "http://www.google.com/session/phone"
+/* Video capability in Google's Jingle dialect */
+#define NS_GOOGLE_SESSION_VIDEO "http://www.google.com/session/video"
 /* XEP-0167 (Jingle RTP) */
 #define NS_JINGLE_RTP           "urn:xmpp:jingle:apps:rtp:0"
 #define NS_JINGLE_RTP_INFO      "urn:xmpp:jingle:apps:rtp:info:1"
diff --git a/src/types.h b/src/types.h
index bb95394..a3f6800 100644
--- a/src/types.h
+++ b/src/types.h
@@ -76,6 +76,7 @@ typedef enum {
     PRESENCE_CAP_JINGLE_TRANSPORT_RAWUDP = 1 << 15,
     PRESENCE_CAP_GEOLOCATION = 1 << 16,
     PRESENCE_CAP_SI_FILE_TRANSFER = 1 << 17,
+    PRESENCE_CAP_GOOGLE_VIDEO = 1 << 18
 } GabblePresenceCapabilities;
 
 G_END_DECLS
-- 
1.5.6.5




More information about the telepathy-commits mailing list