diff options
-rw-r--r-- | src/jingle-factory.c | 42 | ||||
-rw-r--r-- | src/jingle-mint.c | 37 |
2 files changed, 60 insertions, 19 deletions
diff --git a/src/jingle-factory.c b/src/jingle-factory.c index ff815fdca..0edd2b3d8 100644 --- a/src/jingle-factory.c +++ b/src/jingle-factory.c @@ -39,7 +39,6 @@ #include "jingle-transport-rawudp.h" #include "jingle-transport-iceudp.h" #include "namespaces.h" -#include "presence-cache.h" #include "util.h" #include "google-relay.h" @@ -50,6 +49,7 @@ G_DEFINE_TYPE(GabbleJingleFactory, gabble_jingle_factory, G_TYPE_OBJECT); enum { NEW_SESSION, + QUERY_CAP, LAST_SIGNAL }; @@ -235,6 +235,20 @@ gabble_jingle_factory_class_init (GabbleJingleFactoryClass *cls) G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST, 0, NULL, NULL, gabble_marshal_VOID__OBJECT_BOOL, G_TYPE_NONE, 2, GABBLE_TYPE_JINGLE_SESSION, G_TYPE_BOOLEAN); + + /* + * @contact: the peer in a call + * @cap: the XEP-0115 feature string the session is interested in. + * + * Emitted when a Jingle session wants to check whether the peer has a + * particular capability. The handler should return %TRUE if @contact has + * @cap. + */ + signals[QUERY_CAP] = g_signal_new ("query-cap", + G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST, + 0, g_signal_accumulator_first_wins, NULL, + gabble_marshal_BOOLEAN__OBJECT_STRING, + G_TYPE_BOOLEAN, 2, WOCKY_TYPE_CONTACT, G_TYPE_STRING); } GabbleJingleFactory * @@ -430,25 +444,15 @@ session_query_cap_cb ( gpointer user_data) { GabbleJingleFactory *self = GABBLE_JINGLE_FACTORY (user_data); - GabbleJingleFactoryPrivate *priv = self->priv; - GabblePresence *presence = gabble_presence_cache_get_for_contact ( - priv->conn->presence_cache, contact); - - if (presence == NULL) - return FALSE; + gboolean ret; - if (WOCKY_IS_RESOURCE_CONTACT (contact)) - { - const gchar *peer_resource = wocky_resource_contact_get_resource ( - WOCKY_RESOURCE_CONTACT (contact)); - - return gabble_presence_resource_has_caps (presence, peer_resource, - gabble_capability_set_predicate_has, cap_or_quirk); - } - else - { - return gabble_presence_has_cap (presence, cap_or_quirk); - } + /* Propagate the query out to the application. We can't depend on the + * application connecting to ::query-cap on the session because caps queries + * may happen while parsing the session-initiate stanza, which must happen + * before the session is announced to the application. + */ + g_signal_emit (self, signals[QUERY_CAP], 0, contact, cap_or_quirk, &ret); + return ret; } /* diff --git a/src/jingle-mint.c b/src/jingle-mint.c index b990f0eda..1bda393c9 100644 --- a/src/jingle-mint.c +++ b/src/jingle-mint.c @@ -33,6 +33,7 @@ #include "conn-presence.h" #include "jingle-factory.h" #include "jingle-session.h" +#include "presence-cache.h" struct _GabbleJingleMintPrivate { GabbleConnection *conn; @@ -62,6 +63,11 @@ static void factory_new_session_cb ( GabbleJingleSession *session, gboolean initiated_locally, gpointer user_data); +static gboolean factory_query_cap_cb ( + GabbleJingleFactory *factory, + WockyContact *contact, + const gchar *cap_or_quirk, + gpointer user_data); G_DEFINE_TYPE (GabbleJingleMint, gabble_jingle_mint, G_TYPE_OBJECT) @@ -130,6 +136,8 @@ gabble_jingle_mint_constructed (GObject *object) priv->factory = gabble_jingle_factory_new (priv->conn); tp_g_signal_connect_object (priv->factory, "new-session", (GCallback) factory_new_session_cb, self, 0); + tp_g_signal_connect_object (priv->factory, "query-cap", + (GCallback) factory_query_cap_cb, self, 0); } static void @@ -271,6 +279,35 @@ factory_new_session_cb ( g_signal_emit (self, signals[NEW_SESSION], 0, session); } +static gboolean +factory_query_cap_cb ( + GabbleJingleFactory *factory, + WockyContact *contact, + const gchar *cap_or_quirk, + gpointer user_data) +{ + GabbleJingleMint *self = GABBLE_JINGLE_MINT (user_data); + GabbleJingleMintPrivate *priv = self->priv; + GabblePresence *presence = gabble_presence_cache_get_for_contact ( + priv->conn->presence_cache, contact); + + if (presence == NULL) + return FALSE; + + if (WOCKY_IS_RESOURCE_CONTACT (contact)) + { + const gchar *peer_resource = wocky_resource_contact_get_resource ( + WOCKY_RESOURCE_CONTACT (contact)); + + return gabble_presence_resource_has_caps (presence, peer_resource, + gabble_capability_set_predicate_has, cap_or_quirk); + } + else + { + return gabble_presence_has_cap (presence, cap_or_quirk); + } +} + GabbleJingleFactory * gabble_jingle_mint_get_factory ( GabbleJingleMint *self) |