diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-04-26 16:49:58 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-04-26 16:49:58 +0100 |
commit | 72a9105d6306784a4708c34efeb1bbd660098fe3 (patch) | |
tree | 4761ee37c33f2ef000f5f8181efaa1c84ab28b78 | |
parent | 95fbc5979525ba539977ad1cf63f4054f798fd90 (diff) |
caps-manager: keep a record of what clients expose which services
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r-- | salut/caps-manager.c | 53 | ||||
-rw-r--r-- | salut/caps-manager.h | 3 | ||||
-rwxr-xr-x | tests/twisted/salut/hct.py | 75 |
3 files changed, 126 insertions, 5 deletions
diff --git a/salut/caps-manager.c b/salut/caps-manager.c index 7a77e4c..8762b62 100644 --- a/salut/caps-manager.c +++ b/salut/caps-manager.c @@ -25,6 +25,7 @@ #include <string.h> #include <telepathy-glib/channel-manager.h> +#include <telepathy-glib/util.h> #include <wocky/wocky-data-form.h> #include <wocky/wocky-namespaces.h> @@ -51,14 +52,42 @@ G_DEFINE_TYPE_WITH_CODE (YtstCapsManager, ytst_caps_manager, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER, caps_channel_manager_iface_init); ) +/* private structure */ +struct _YtstCapsManagerPrivate +{ + GHashTable *services; +}; + +static void +ytst_caps_manager_init (YtstCapsManager *self) +{ + YtstCapsManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + YTST_TYPE_CAPS_MANAGER, YtstCapsManagerPrivate); + self->priv = priv; + + priv->services = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); +} + static void -ytst_caps_manager_init (YtstCapsManager *object) +ytst_caps_manager_dispose (GObject *object) { + YtstCapsManager *self = YTST_CAPS_MANAGER (object); + + tp_clear_pointer (&(self->priv->services), g_hash_table_unref); + + if (G_OBJECT_CLASS (ytst_caps_manager_parent_class)->dispose) + G_OBJECT_CLASS (ytst_caps_manager_parent_class)->dispose (object); } static void ytst_caps_manager_class_init (YtstCapsManagerClass *klass) { + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->dispose = ytst_caps_manager_dispose; + + g_type_class_add_private (klass, sizeof (YtstCapsManagerPrivate)); } static void @@ -126,6 +155,14 @@ make_new_data_form (const gchar *uid, } static void +add_to_array (gpointer key, + gpointer value, + gpointer user_data) +{ + g_ptr_array_add (user_data, g_object_ref (value)); +} + +static void ytst_caps_manager_represent_client (GabbleCapsChannelManager *manager, const gchar *client_name, const GPtrArray *filters, @@ -133,9 +170,10 @@ ytst_caps_manager_represent_client (GabbleCapsChannelManager *manager, GabbleCapabilitySet *cap_set, GPtrArray *data_forms) { + YtstCapsManager *self = YTST_CAPS_MANAGER (manager); + YtstCapsManagerPrivate *priv = self->priv; const gchar * const *t; - WockyDataForm *form; const gchar *uid = NULL; const gchar *yts_type = NULL; GPtrArray *names = g_ptr_array_new (); @@ -173,10 +211,17 @@ ytst_caps_manager_represent_client (GabbleCapsChannelManager *manager, if (uid != NULL) { - form = make_new_data_form (uid, yts_type, names, caps); - g_ptr_array_add (data_forms, form); + g_hash_table_insert (priv->services, + g_strdup (client_name), + make_new_data_form (uid, yts_type, names, caps)); + } + else + { + g_hash_table_remove (priv->services, client_name); } + g_hash_table_foreach (priv->services, add_to_array, data_forms); + g_ptr_array_unref (names); g_ptr_array_unref (caps); } diff --git a/salut/caps-manager.h b/salut/caps-manager.h index b471963..e25d89b 100644 --- a/salut/caps-manager.h +++ b/salut/caps-manager.h @@ -26,6 +26,7 @@ G_BEGIN_DECLS typedef struct _YtstCapsManagerClass YtstCapsManagerClass; +typedef struct _YtstCapsManagerPrivate YtstCapsManagerPrivate; typedef struct _YtstCapsManager YtstCapsManager; struct _YtstCapsManagerClass @@ -36,6 +37,8 @@ struct _YtstCapsManagerClass struct _YtstCapsManager { GObject parent; + + YtstCapsManagerPrivate *priv; }; GType ytst_caps_manager_get_type (void); diff --git a/tests/twisted/salut/hct.py b/tests/twisted/salut/hct.py index 805a187..1573b20 100755 --- a/tests/twisted/salut/hct.py +++ b/tests/twisted/salut/hct.py @@ -18,9 +18,10 @@ # 02110-1301 USA import avahi +import dbus from salutservicetest import call_async, EventPattern, assertEquals, \ - assertLength, assertContains + assertLength, assertContains, sync_dbus, ProxyWrapper from saluttest import exec_test, elem_iq, elem from avahitest import AvahiAnnouncer, AvahiListener, txt_get_key, get_host_name from xmppstream import connect_to_stream @@ -40,6 +41,13 @@ def test(q, bus, conn): path, props = e.value assertEquals({}, props) + status = ProxyWrapper(bus.get_object(conn.bus_name, path), + ycs.STATUS_IFACE, {}) + + discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', + dbus_interface=dbus.PROPERTIES_IFACE) + assertEquals({}, discovered) + self_handle = conn.GetSelfHandle() self_handle_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] @@ -121,5 +129,70 @@ def test(q, bus, conn): else: assert False + # now add another service + forbidden = [EventPattern('dbus-signal', signal='ServiceRemoved')] + q.forbid_events(forbidden) + + conn.ContactCapabilities.UpdateCapabilities([ + ('another.nice.gname', [], + ['com.meego.xpmn.ytstenut.Channel/uid/org.gnome.Eog', + 'com.meego.xpmn.ytstenut.Channel/type/application', + 'com.meego.xpmn.ytstenut.Channel/name/en_GB/Eye Of Gnome', + 'com.meego.xpmn.ytstenut.Channel/name/it/Occhio Di uno Gnomo', + 'com.meego.xpmn.ytstenut.Channel/caps/urn:ytstenut:capabilities:yts-picz'])]) + + e = q.expect('dbus-signal', signal='ServiceAdded') + + sync_dbus(bus, q, conn) + + discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', + dbus_interface=dbus.PROPERTIES_IFACE) + assertEquals({'testsuite@testsuite': + {'org.gnome.Banshee': ('application', + {'en_GB': 'Banshee Media Player', + 'fr': 'Banshee Lecteur de Musique'}, + ['urn:ytstenut:capabilities:yts-caps-audio', + 'urn:ytstenut:data:jingle:rtp']), + 'org.gnome.Eog': ('application', + {'en_GB': 'Eye Of Gnome', + 'it': 'Occhio Di uno Gnomo'}, + ['urn:ytstenut:capabilities:yts-picz'])}}, + discovered) + + q.unforbid_events(forbidden) + + forbidden = [EventPattern('dbus-signal', signal='ServiceRemoved', + args=[self_handle_name, 'org.gnome.Eog'])] + q.forbid_events(forbidden) + + conn.ContactCapabilities.UpdateCapabilities([ + ('well.gnome.name', [], [])]) + + e = q.expect('dbus-signal', signal='ServiceRemoved', + args=[self_handle_name, 'org.gnome.Banshee']) + + sync_dbus(bus, q, conn) + + discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', + dbus_interface=dbus.PROPERTIES_IFACE) + assertEquals({'testsuite@testsuite': + {'org.gnome.Eog': ('application', + {'en_GB': 'Eye Of Gnome', + 'it': 'Occhio Di uno Gnomo'}, + ['urn:ytstenut:capabilities:yts-picz'])}}, + discovered) + + q.unforbid_events(forbidden) + + conn.ContactCapabilities.UpdateCapabilities([ + ('another.nice.gname', [], [])]) + + e = q.expect('dbus-signal', signal='ServiceRemoved', + args=[self_handle_name, 'org.gnome.Eog']) + + discovered = status.Get(ycs.STATUS_IFACE, 'DiscoveredServices', + dbus_interface=dbus.PROPERTIES_IFACE) + assertEquals({}, discovered) + if __name__ == '__main__': exec_test(test) |