[telepathy-gabble/master] Port SetSelfCapabilities to use capability sets
Will Thompson
will.thompson at collabora.co.uk
Tue Sep 8 04:10:02 PDT 2009
This ports gabble_caps_channel_manager_add_capability() to add nodes to
a GabbleCapabilitySet, rather than footling with
per_channel_manager_caps, and updates the SetSelfCapabilities
implementation accordingly.
This also alters the presence cache's capabilities-updated signal to
include GabbleCapabilitySets rather than per_channel_manager_caps hash
tables.
---
src/caps-channel-manager.c | 16 +++++--
src/caps-channel-manager.h | 11 +++--
src/connection.c | 102 ++++++++++++++++--------------------------
src/presence-cache.c | 47 ++++++++++++--------
src/private-tubes-factory.c | 67 +++++++++-------------------
5 files changed, 106 insertions(+), 137 deletions(-)
diff --git a/src/caps-channel-manager.c b/src/caps-channel-manager.c
index fac86aa..7ac167a 100644
--- a/src/caps-channel-manager.c
+++ b/src/caps-channel-manager.c
@@ -177,12 +177,20 @@ gboolean gabble_caps_channel_manager_capabilities_diff (
return FALSE;
}
+/**
+ * gabble_caps_channel_manager_add_capability:
+ * @cap: the Telepathy-level capability to add
+ * @cap_set: a set of XMPP namespaces, to which the namespaces corresponding to
+ * @cap should be added
+ *
+ * Used to advertise that we support the XMPP capabilities corresponding to the
+ * Telepathy capability supplied.
+ */
void
gabble_caps_channel_manager_add_capability (
GabbleCapsChannelManager *caps_manager,
- GabbleConnection *conn,
- TpHandle handle,
- GHashTable *cap)
+ GHashTable *cap,
+ GabbleCapabilitySet *cap_set)
{
GabbleCapsChannelManagerIface *iface =
GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager);
@@ -190,7 +198,7 @@ gabble_caps_channel_manager_add_capability (
if (method != NULL)
{
- method (caps_manager, conn, handle, cap);
+ method (caps_manager, cap, cap_set);
}
/* ... else, nothing to do */
}
diff --git a/src/caps-channel-manager.h b/src/caps-channel-manager.h
index 80298be..340cf7e 100644
--- a/src/caps-channel-manager.h
+++ b/src/caps-channel-manager.h
@@ -62,8 +62,9 @@ typedef void (*GabbleCapsChannelManagerGetContactCapsFunc) (
GPtrArray *arr);
typedef void (*GabbleCapsChannelManagerAddCapFunc) (
- GabbleCapsChannelManager *manager, GabbleConnection *conn, TpHandle handle,
- GHashTable *cap);
+ GabbleCapsChannelManager *manager,
+ GHashTable *cap,
+ GabbleCapabilitySet *cap_set);
/* Specific to Gabble */
typedef void (*GabbleCapsChannelManagerGetFeatureListFunc) (
@@ -118,9 +119,9 @@ gboolean gabble_caps_channel_manager_capabilities_diff (
gpointer specific_old_caps, gpointer specific_new_caps);
void gabble_caps_channel_manager_add_capability (
- GabbleCapsChannelManager *manager, GabbleConnection *conn, TpHandle handle,
- GHashTable *cap);
-
+ GabbleCapsChannelManager *caps_manager,
+ GHashTable *cap,
+ GabbleCapabilitySet *cap_set);
struct _GabbleCapsChannelManagerIface {
GTypeInterface parent;
diff --git a/src/connection.c b/src/connection.c
index 6b7a0f4..bf83118 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -204,10 +204,13 @@ struct _GabbleConnectionPrivate
gboolean dispose_has_run;
};
-static void connection_capabilities_update_cb (GabblePresenceCache *,
- TpHandle, GabblePresenceCapabilities, GabblePresenceCapabilities,
- GHashTable *, GHashTable *, gpointer);
-
+static void connection_capabilities_update_cb (GabblePresenceCache *cache,
+ TpHandle handle,
+ GabblePresenceCapabilities old_caps,
+ GabblePresenceCapabilities new_caps,
+ const GabbleCapabilitySet *old_cap_set,
+ const GabbleCapabilitySet *new_cap_set,
+ gpointer user_data);
static GPtrArray *
_gabble_connection_create_channel_managers (TpBaseConnection *conn)
@@ -2377,50 +2380,27 @@ gabble_free_enhanced_contact_capabilities (GPtrArray *caps)
static void
_emit_contact_capabilities_changed (GabbleConnection *conn,
- TpHandle handle,
- GHashTable *old_caps,
- GHashTable *new_caps)
+ TpHandle handle,
+ const GabbleCapabilitySet *old_caps,
+ const GabbleCapabilitySet *new_caps)
{
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (conn);
- TpChannelManagerIter iter;
- TpChannelManager *manager;
GPtrArray *ret;
GHashTable *hash;
- gboolean diff = FALSE;
- tp_base_connection_channel_manager_iter_init (&iter, base_conn);
- while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ /* Don't emit the D-Bus signal if there is no change */
+ if (gabble_capability_set_equals (old_caps, new_caps))
{
- gpointer per_channel_manager_caps_old = NULL;
- gpointer per_channel_manager_caps_new = NULL;
-
- /* all channel managers must implement the capability interface */
- g_assert (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager));
-
- if (old_caps != NULL)
- per_channel_manager_caps_old = g_hash_table_lookup (old_caps, manager);
- if (new_caps != NULL)
- per_channel_manager_caps_new = g_hash_table_lookup (new_caps, manager);
-
- if (gabble_caps_channel_manager_capabilities_diff (
- GABBLE_CAPS_CHANNEL_MANAGER (manager), handle,
- per_channel_manager_caps_old, per_channel_manager_caps_new))
- {
- diff = TRUE;
- break;
- }
+ DEBUG ("unchanged; not emitting ContactCapabilitiesChanged");
+ return;
}
- /* Don't emit the D-Bus signal if there is no change */
- if (! diff)
- return;
-
ret = g_ptr_array_new ();
gabble_connection_get_handle_contact_capabilities (conn, handle, ret);
hash = g_hash_table_new (NULL, NULL);
g_hash_table_insert (hash, GUINT_TO_POINTER (handle), ret);
+
gabble_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
conn, hash);
@@ -2430,21 +2410,19 @@ _emit_contact_capabilities_changed (GabbleConnection *conn,
static void
connection_capabilities_update_cb (GabblePresenceCache *cache,
- TpHandle handle,
- GabblePresenceCapabilities old_caps,
- GabblePresenceCapabilities new_caps,
- GHashTable *old_enhanced_caps,
- GHashTable *new_enhanced_caps,
- gpointer user_data)
+ TpHandle handle,
+ GabblePresenceCapabilities old_caps,
+ GabblePresenceCapabilities new_caps,
+ const GabbleCapabilitySet *old_cap_set,
+ const GabbleCapabilitySet *new_cap_set,
+ gpointer user_data)
{
GabbleConnection *conn = GABBLE_CONNECTION (user_data);
if (old_caps != new_caps)
_emit_capabilities_changed (conn, handle, old_caps, new_caps);
- if (old_enhanced_caps != NULL || new_enhanced_caps != NULL)
- _emit_contact_capabilities_changed (conn, handle,
- old_enhanced_caps, new_enhanced_caps);
+ _emit_contact_capabilities_changed (conn, handle, old_cap_set, new_cap_set);
}
/**
@@ -2589,17 +2567,15 @@ gabble_connection_set_self_capabilities (
GabbleConnection *self = GABBLE_CONNECTION (iface);
TpBaseConnection *base = (TpBaseConnection *) self;
GabbleConnectionPrivate *priv = self->priv;
+ GabbleCapabilitySet *old_caps, *new_caps;
guint i;
GabblePresence *pres = self->self_presence;
- GHashTable *save_caps;
GError *error = NULL;
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
- /* reset the caps, and fill with the given parameter but keep a backup for
- * diffing: we don't want to emit a signal if nothing has changed */
- save_caps = pres->per_channel_manager_caps;
- pres->per_channel_manager_caps = NULL;
+ old_caps = gabble_presence_get_caps (pres);
+ new_caps = gabble_capability_set_new ();
for (i = 0; i < caps->len; i++)
{
@@ -2614,28 +2590,28 @@ gabble_connection_set_self_capabilities (
g_assert (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager));
gabble_caps_channel_manager_add_capability (
- GABBLE_CAPS_CHANNEL_MANAGER (manager), self,
- base->self_handle, cap_to_add);
+ GABBLE_CAPS_CHANNEL_MANAGER (manager), cap_to_add, new_caps);
}
}
- priv->caps_serial++;
+ gabble_presence_set_capabilities (pres, priv->resource, new_caps,
+ pres->caps, NULL, priv->caps_serial++);
- if (!_gabble_connection_signal_own_presence (self, &error))
+ if (_gabble_connection_signal_own_presence (self, &error))
+ {
+ _emit_contact_capabilities_changed (self, base->self_handle, old_caps,
+ new_caps);
+
+ gabble_svc_connection_interface_contact_capabilities_return_from_set_self_capabilities (
+ context);
+ }
+ else
{
- gabble_presence_cache_free_cache_entry (save_caps);
dbus_g_method_return_error (context, error);
- return;
}
- _emit_contact_capabilities_changed (self, base->self_handle,
- save_caps,
- pres->per_channel_manager_caps);
- gabble_presence_cache_free_cache_entry (save_caps);
-
-
- gabble_svc_connection_interface_contact_capabilities_return_from_set_self_capabilities
- (context);
+ gabble_capability_set_free (old_caps);
+ gabble_capability_set_free (new_caps);
}
static const gchar *assumed_caps[] =
diff --git a/src/presence-cache.c b/src/presence-cache.c
index 4c2cbfc..4ab72ac 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -957,11 +957,11 @@ emit_capabilities_update (GabblePresenceCache *cache,
TpHandle handle,
GabblePresenceCapabilities old_caps,
GabblePresenceCapabilities new_caps,
- GHashTable *old_enhanced_caps,
- GHashTable *new_enhanced_caps)
+ const GabbleCapabilitySet *old_cap_set,
+ const GabbleCapabilitySet *new_cap_set)
{
g_signal_emit (cache, signals[CAPABILITIES_UPDATE], 0,
- handle, old_caps, new_caps, old_enhanced_caps, new_enhanced_caps);
+ handle, old_caps, new_caps, old_cap_set, new_cap_set);
}
/**
@@ -981,14 +981,14 @@ set_caps_for (DiscoWaiter *waiter,
{
GabblePresence *presence = gabble_presence_cache_get (cache, waiter->handle);
GabblePresenceCapabilities save_caps;
- GHashTable *save_enhanced_caps;
+ GabbleCapabilitySet *old_cap_set;
+ GabbleCapabilitySet *new_cap_set;
if (presence == NULL)
return;
save_caps = presence->caps;
- gabble_presence_cache_copy_cache_entry (&save_enhanced_caps,
- presence->per_channel_manager_caps);
+ old_cap_set = gabble_presence_get_caps (presence);
DEBUG ("setting caps for %d (thanks to %d %s) to %d (save_caps %d)",
waiter->handle, responder_handle, responder_jid, caps, save_caps);
@@ -998,9 +998,13 @@ set_caps_for (DiscoWaiter *waiter,
DEBUG ("caps for %d now %d", waiter->handle, presence->caps);
+ new_cap_set = gabble_presence_get_caps (presence);
+
emit_capabilities_update (cache, waiter->handle, save_caps, presence->caps,
- save_enhanced_caps, presence->per_channel_manager_caps);
- gabble_presence_cache_free_cache_entry (save_enhanced_caps);
+ old_cap_set, new_cap_set);
+
+ gabble_capability_set_free (old_cap_set);
+ gabble_capability_set_free (new_cap_set);
}
static void
@@ -1277,7 +1281,7 @@ _process_caps (GabblePresenceCache *cache,
GSList *uris, *i;
GabblePresenceCachePrivate *priv;
GabblePresenceCapabilities old_caps = 0;
- GHashTable *old_enhanced_caps;
+ GabbleCapabilitySet *old_cap_set;
guint serial;
const gchar *hash, *ver;
@@ -1293,8 +1297,7 @@ _process_caps (GabblePresenceCache *cache,
if (presence)
{
old_caps = presence->caps;
- gabble_presence_cache_copy_cache_entry (&old_enhanced_caps,
- presence->per_channel_manager_caps);
+ old_cap_set = gabble_presence_get_caps (presence);
}
for (i = uris; NULL != i; i = i->next)
@@ -1307,12 +1310,15 @@ _process_caps (GabblePresenceCache *cache,
if (presence)
{
+ GabbleCapabilitySet *new_cap_set = gabble_presence_get_caps (presence);
+
DEBUG ("Emitting caps update: handle %u, old %u, new %u",
handle, old_caps, presence->caps);
emit_capabilities_update (cache, handle, old_caps, presence->caps,
- old_enhanced_caps, presence->per_channel_manager_caps);
- gabble_presence_cache_free_cache_entry (old_enhanced_caps);
+ old_cap_set, new_cap_set);
+
+ gabble_capability_set_free (new_cap_set);
}
else
{
@@ -1320,6 +1326,7 @@ _process_caps (GabblePresenceCache *cache,
presence->caps, handle);
}
+ gabble_capability_set_free (old_cap_set);
g_slist_free (uris);
}
@@ -1584,7 +1591,7 @@ gabble_presence_cache_do_update (
const gchar *jid;
GabblePresence *presence;
GabblePresenceCapabilities caps_before;
- GHashTable *enhanced_caps_before;
+ GabbleCapabilitySet *old_cap_set, *new_cap_set;
gboolean ret = FALSE;
jid = tp_handle_inspect (contact_repo, handle);
@@ -1600,16 +1607,18 @@ gabble_presence_cache_do_update (
presence = _cache_insert (cache, handle);
caps_before = presence->caps;
- enhanced_caps_before = presence->per_channel_manager_caps;
- gabble_presence_cache_copy_cache_entry (&enhanced_caps_before,
- presence->per_channel_manager_caps);
+ old_cap_set = gabble_presence_get_caps (presence);
ret = gabble_presence_update (presence, resource, presence_id,
status_message, priority);
+ new_cap_set = gabble_presence_get_caps (presence);
+
emit_capabilities_update (cache, handle, caps_before, presence->caps,
- enhanced_caps_before, presence->per_channel_manager_caps);
- gabble_presence_cache_free_cache_entry (enhanced_caps_before);
+ old_cap_set, new_cap_set);
+
+ gabble_capability_set_free (old_cap_set);
+ gabble_capability_set_free (new_cap_set);
return ret;
}
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index c751100..c4e87bd 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -792,14 +792,11 @@ gabble_private_tubes_factory_caps_diff (
static void
gabble_private_tubes_factory_add_cap (GabbleCapsChannelManager *manager,
- GabbleConnection *conn,
- TpHandle handle,
- GHashTable *cap)
+ GHashTable *cap,
+ GabbleCapabilitySet *cap_set)
{
- TpBaseConnection *base = (TpBaseConnection *) conn;
- GabblePresence *presence;
- TubesCapabilities *caps;
- const gchar *channel_type;
+ const gchar *channel_type, *service;
+ gchar *ns = NULL;
channel_type = tp_asv_get_string (cap,
TP_IFACE_CHANNEL ".ChannelType");
@@ -814,50 +811,28 @@ gabble_private_tubes_factory_add_cap (GabbleCapsChannelManager *manager,
TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT)
return;
- if (handle == base->self_handle)
- presence = conn->self_presence;
- else
- presence = gabble_presence_cache_get (conn->presence_cache, handle);
-
- g_assert (presence != NULL);
-
- if (presence->per_channel_manager_caps == NULL)
- presence->per_channel_manager_caps = g_hash_table_new (NULL, NULL);
-
- caps = g_hash_table_lookup (presence->per_channel_manager_caps, manager);
- if (caps == NULL)
- {
- caps = g_new0 (TubesCapabilities, 1);
- caps->stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, gabble_private_tubes_factory_free_feat);
- caps->dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, gabble_private_tubes_factory_free_feat);
- g_hash_table_insert (presence->per_channel_manager_caps, manager, caps);
-
- if (handle == base->self_handle)
- /* We always support generic tubes caps */
- caps->tubes_supported = TRUE;
- }
-
if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
{
- Feature *feat = g_new0 (Feature, 1);
- gchar *service = g_strdup (tp_asv_get_string (cap,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service"));
- feat->feature_type = FEATURE_OPTIONAL;
- feat->ns = g_strdup_printf ("%s/stream#%s", NS_TUBES, service);
- feat->caps = 0;
- g_hash_table_insert (caps->stream_tube_caps, service, feat);
+ service = tp_asv_get_string (cap,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+
+ if (service != NULL)
+ ns = g_strconcat (STREAM_CAP_PREFIX, service, NULL);
}
else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
{
- Feature *feat = g_new0 (Feature, 1);
- gchar *service = g_strdup (tp_asv_get_string (cap,
- TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName"));
- feat->feature_type = FEATURE_OPTIONAL;
- feat->ns = g_strdup_printf ("%s/dbus#%s", NS_TUBES, service);
- feat->caps = 0;
- g_hash_table_insert (caps->dbus_tube_caps, service, feat);
+ service = tp_asv_get_string (cap,
+ TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+
+ if (service != NULL)
+ ns = g_strconcat (DBUS_CAP_PREFIX, service, NULL);
+ }
+
+ if (ns != NULL)
+ {
+ DEBUG ("adding capability %s", ns);
+ gabble_capability_set_add (cap_set, ns);
+ g_free (ns);
}
}
--
1.5.6.5
More information about the telepathy-commits
mailing list