[telepathy-gabble/master] Change gabble_presence_pick_resource_by_caps to check the cap.set, not the numeric caps
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue Sep 8 04:10:07 PDT 2009
---
src/ft-channel.c | 4 +++-
src/media-channel.c | 49 ++++++++++++++++++++++++++++++-------------------
src/presence.c | 7 +++++--
src/presence.h | 2 +-
src/tube-dbus.c | 2 +-
src/tube-stream.c | 4 ++--
tests/test-presence.c | 25 ++++++++++++++++++-------
7 files changed, 60 insertions(+), 33 deletions(-)
diff --git a/src/ft-channel.c b/src/ft-channel.c
index 2b4c4cd..b274cf6 100644
--- a/src/ft-channel.c
+++ b/src/ft-channel.c
@@ -1159,8 +1159,10 @@ gabble_file_transfer_channel_offer_file (GabbleFileTransferChannel *self,
/* Not a MUC jid, need to get a resource */
const gchar *resource;
+ /* FIXME: should we check for SI, bytestreams and/or IBB too? */
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_SI_FILE_TRANSFER);
+ gabble_capability_set_predicate_has, NS_FILE_TRANSFER);
+
if (resource == NULL)
{
DEBUG ("contact doesn't have file transfer capabilities");
diff --git a/src/media-channel.c b/src/media-channel.c
index 4aa15da..7d1db56 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -1386,7 +1386,6 @@ _pick_best_content_type (GabbleMediaChannel *chan, TpHandle peer,
return NULL;
}
-
static const gchar *
_pick_best_resource (GabbleMediaChannel *chan,
TpHandle peer, gboolean want_audio, gboolean want_video,
@@ -1394,7 +1393,7 @@ _pick_best_resource (GabbleMediaChannel *chan,
{
GabbleMediaChannelPrivate *priv = chan->priv;
GabblePresence *presence;
- GabblePresenceCapabilities caps;
+ GabbleCapabilitySet *caps;
const gchar *resource = NULL;
presence = gabble_presence_cache_get (priv->conn->presence_cache, peer);
@@ -1410,15 +1409,19 @@ _pick_best_resource (GabbleMediaChannel *chan,
g_return_val_if_fail (want_audio || want_video, NULL);
+ /* from here on, goto FINALLY to free this, instead of returning early */
+ caps = gabble_capability_set_new ();
+
/* Try newest Jingle standard */
- caps = PRESENCE_CAP_JINGLE_RTP;
+ gabble_capability_set_add (caps, NS_JINGLE_RTP);
if (want_audio)
- caps |= PRESENCE_CAP_JINGLE_RTP_AUDIO;
+ gabble_capability_set_add (caps, NS_JINGLE_RTP_AUDIO);
if (want_video)
- caps |= PRESENCE_CAP_JINGLE_RTP_VIDEO;
+ gabble_capability_set_add (caps, NS_JINGLE_RTP_VIDEO);
- resource = gabble_presence_pick_resource_by_caps (presence, caps);
+ resource = gabble_presence_pick_resource_by_caps (presence,
+ gabble_capability_set_predicate_at_least, caps);
if (resource != NULL)
{
@@ -1427,14 +1430,15 @@ _pick_best_resource (GabbleMediaChannel *chan,
}
/* Else try older Jingle draft */
- caps = 0;
+ gabble_capability_set_clear (caps);
if (want_audio)
- caps |= PRESENCE_CAP_JINGLE_DESCRIPTION_AUDIO;
+ gabble_capability_set_add (caps, NS_JINGLE_DESCRIPTION_AUDIO);
if (want_video)
- caps |= PRESENCE_CAP_JINGLE_DESCRIPTION_VIDEO;
+ gabble_capability_set_add (caps, NS_JINGLE_DESCRIPTION_VIDEO);
- resource = gabble_presence_pick_resource_by_caps (presence, caps);
+ resource = gabble_presence_pick_resource_by_caps (presence,
+ gabble_capability_set_predicate_at_least, caps);
if (resource != NULL)
{
@@ -1446,16 +1450,18 @@ _pick_best_resource (GabbleMediaChannel *chan,
if (!want_audio)
{
DEBUG ("No resource which supports video alone available");
- return NULL;
+ goto FINALLY;
}
/* Okay, let's try GTalk 0.3, possibly with video. */
- caps = PRESENCE_CAP_GOOGLE_VOICE;
+ gabble_capability_set_clear (caps);
+ gabble_capability_set_add (caps, NS_GOOGLE_FEAT_VOICE);
if (want_video)
- caps |= PRESENCE_CAP_GOOGLE_VIDEO;
+ gabble_capability_set_add (caps, NS_GOOGLE_FEAT_VIDEO);
- resource = gabble_presence_pick_resource_by_caps (presence, caps);
+ resource = gabble_presence_pick_resource_by_caps (presence,
+ gabble_capability_set_predicate_at_least, caps);
if (resource != NULL)
{
@@ -1466,12 +1472,15 @@ _pick_best_resource (GabbleMediaChannel *chan,
if (want_video)
{
DEBUG ("No resource which supports audio+video available");
- return NULL;
+ goto FINALLY;
}
/* Maybe GTalk 0.4 will save us all... ? */
- caps = PRESENCE_CAP_GOOGLE_VOICE | PRESENCE_CAP_GOOGLE_TRANSPORT_P2P;
- resource = gabble_presence_pick_resource_by_caps (presence, caps);
+ gabble_capability_set_clear (caps);
+ gabble_capability_set_add (caps, NS_GOOGLE_FEAT_VOICE);
+ gabble_capability_set_add (caps, NS_GOOGLE_TRANSPORT_P2P);
+ resource = gabble_presence_pick_resource_by_caps (presence,
+ gabble_capability_set_predicate_at_least, caps);
if (resource != NULL)
{
@@ -1480,7 +1489,7 @@ _pick_best_resource (GabbleMediaChannel *chan,
}
/* Nope, nothing we can do. */
- return NULL;
+ goto FINALLY;
CHOOSE_TRANSPORT:
/* We prefer gtalk-p2p to ice, because it can use tcp and https relays (if
@@ -1511,8 +1520,10 @@ CHOOSE_TRANSPORT:
}
if (*transport_ns == NULL)
- return NULL;
+ resource = NULL;
+FINALLY:
+ gabble_capability_set_free (caps);
return resource;
}
diff --git a/src/presence.c b/src/presence.c
index 4ce88c5..7b07c69 100644
--- a/src/presence.c
+++ b/src/presence.c
@@ -171,17 +171,20 @@ gabble_presence_get_caps (GabblePresence *presence)
const gchar *
gabble_presence_pick_resource_by_caps (
GabblePresence *presence,
- GabblePresenceCapabilities caps)
+ GabbleCapabilitySetPredicate predicate, gpointer user_data)
{
GabblePresencePrivate *priv = GABBLE_PRESENCE_PRIV (presence);
GSList *i;
Resource *chosen = NULL;
+ g_return_val_if_fail (presence != NULL, NULL);
+ g_return_val_if_fail (predicate != NULL, NULL);
+
for (i = priv->resources; NULL != i; i = i->next)
{
Resource *res = (Resource *) i->data;
- if (((res->caps & caps) == caps) &&
+ if (predicate (res->cap_set, user_data) &&
(resource_better_than (res, chosen)))
chosen = res;
}
diff --git a/src/presence.h b/src/presence.h
index e3d89ea..fa710e5 100644
--- a/src/presence.h
+++ b/src/presence.h
@@ -88,7 +88,7 @@ void gabble_presence_set_capabilities (GabblePresence *presence,
GabbleCapabilitySet *gabble_presence_get_caps (GabblePresence *presence);
const gchar *gabble_presence_pick_resource_by_caps (GabblePresence *presence,
- GabblePresenceCapabilities caps);
+ GabbleCapabilitySetPredicate predicate, gpointer user_data);
gboolean gabble_presence_resource_has_caps (GabblePresence *presence,
const gchar *resource,
diff --git a/src/tube-dbus.c b/src/tube-dbus.c
index c14fa49..f511ee9 100644
--- a/src/tube-dbus.c
+++ b/src/tube-dbus.c
@@ -1254,7 +1254,7 @@ gabble_tube_dbus_offer (GabbleTubeDBus *tube,
}
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_SI_TUBES);
+ gabble_capability_set_predicate_has, NS_TUBES);
if (resource == NULL)
{
diff --git a/src/tube-stream.c b/src/tube-stream.c
index b90b8f9..2d920d4 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -512,7 +512,7 @@ start_stream_initiation (GabbleTubeStream *self,
}
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_SI_TUBES);
+ gabble_capability_set_predicate_has, NS_TUBES);
if (resource == NULL)
{
DEBUG ("initiator doesn't have tubes capabilities");
@@ -2263,7 +2263,7 @@ send_tube_offer (GabbleTubeStream *self,
}
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_SI_TUBES);
+ gabble_capability_set_predicate_has, NS_TUBES);
if (resource == NULL)
{
DEBUG ("tube recipient doesn't have tubes capabilities");
diff --git a/tests/test-presence.c b/tests/test-presence.c
index 0c6d333..d591627 100644
--- a/tests/test-presence.c
+++ b/tests/test-presence.c
@@ -7,6 +7,14 @@
#include <glib.h>
#include "src/presence.h"
+#include "src/namespaces.h"
+
+static gboolean
+predicate_true (const GabbleCapabilitySet *set,
+ gpointer unused G_GNUC_UNUSED)
+{
+ return TRUE;
+}
int main (int argc, char **argv)
{
@@ -60,7 +68,8 @@ int main (int argc, char **argv)
/* but if we were to make a voip call, we would prefer the newer one */
g_assert (0 == strcmp ("bar",
- gabble_presence_pick_resource_by_caps (presence, 0)));
+ gabble_presence_pick_resource_by_caps (presence, predicate_true,
+ NULL)));
/* sleep a while so the next resource will have different timestamp */
sleep (1);
@@ -79,7 +88,8 @@ int main (int argc, char **argv)
g_assert (FALSE == gabble_presence_update (presence, "foo",
GABBLE_PRESENCE_AVAILABLE, "status message", 0));
g_assert (0 == strcmp ("foo",
- gabble_presence_pick_resource_by_caps (presence, 0)));
+ gabble_presence_pick_resource_by_caps (presence, predicate_true,
+ NULL)));
/* sleep a while so the next resource will have different timestamp */
sleep (1);
@@ -97,14 +107,15 @@ int main (int argc, char **argv)
/* we still prefer foo for the voip calls, because it's more present */
g_assert (0 == strcmp ("foo",
- gabble_presence_pick_resource_by_caps (presence, 0)));
+ gabble_presence_pick_resource_by_caps (presence, predicate_true,
+ NULL)));
g_assert (GABBLE_PRESENCE_CHAT == presence->status);
g_assert (0 == strcmp ("status message", presence->status_message));
/* no resource has the Google voice cap */
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_GOOGLE_VOICE);
+ gabble_capability_set_predicate_has, NS_GOOGLE_FEAT_VOICE);
g_assert (NULL == resource);
/* give voice cap to second resource, but make priority negative */
@@ -137,7 +148,7 @@ int main (int argc, char **argv)
/* no resource with non-negative priority has the Google voice cap */
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_GOOGLE_VOICE);
+ gabble_capability_set_predicate_has, NS_GOOGLE_FEAT_VOICE);
g_assert (NULL == resource);
/* give voice cap to first resource */
@@ -148,7 +159,7 @@ int main (int argc, char **argv)
/* resource has voice cap */
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_GOOGLE_VOICE);
+ gabble_capability_set_predicate_has, NS_GOOGLE_FEAT_VOICE);
g_assert (0 == strcmp ("foo", resource));
/* presence turns up from null resource; it trumps other presence regardless
@@ -160,7 +171,7 @@ int main (int argc, char **argv)
/* caps are gone too */
resource = gabble_presence_pick_resource_by_caps (presence,
- PRESENCE_CAP_GOOGLE_VOICE);
+ gabble_capability_set_predicate_has, NS_GOOGLE_FEAT_VOICE);
g_assert (NULL == resource);
dump = gabble_presence_dump (presence);
--
1.5.6.5
More information about the telepathy-commits
mailing list