From 030ca88a08afc0460230b815958fa9f24899891f Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Fri, 4 Oct 2013 16:10:55 +0200 Subject: [PATCH] client-types: implement RequestClientTypes() There is no reason to no implement it. Furthermore, that's the only remaining method on this interface in Telepathy 1.0. https://bugs.freedesktop.org/show_bug.cgi?id=70134 --- src/conn-client-types.c | 53 +++++++++++++++++++++++++++++++++++++++++++ src/connection.c | 3 +++ src/connection.h | 4 ++++ tests/twisted/client-types.py | 26 ++++++++++++++++++++- tests/twisted/servicetest.py | 1 + 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/conn-client-types.c b/src/conn-client-types.c index 1a5ff1e..2dd0aaf 100644 --- a/src/conn-client-types.c +++ b/src/conn-client-types.c @@ -132,6 +132,43 @@ client_types_get_client_types (TpSvcConnectionInterfaceClientTypes *iface, g_hash_table_unref (client_types); } +static void +client_types_request_client_types (TpSvcConnectionInterfaceClientTypes *iface, + TpHandle contact, + DBusGMethodInvocation *context) +{ + GabbleConnection *conn = GABBLE_CONNECTION (iface); + TpBaseConnection *base = (TpBaseConnection *) conn; + TpHandleRepoIface *contact_handles; + GError *error = NULL; + gchar **types; + + /* Validate contact */ + contact_handles = tp_base_connection_get_handles (base, + TP_HANDLE_TYPE_CONTACT); + + if (!tp_handle_is_valid (contact_handles, contact, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + DEBUG ("GetClientTypes called on the following handle: %u", contact); + + if (!get_client_types_from_handle (conn, contact, &types)) + { + DEBUG (" waiting for disco reply"); + + g_hash_table_insert (conn->client_types_pending, + GUINT_TO_POINTER (contact), context); + return; + } + + tp_svc_connection_interface_client_types_return_from_request_client_types ( + context, (const gchar **) types); +} + void conn_client_types_iface_init (gpointer g_iface, gpointer iface_data) @@ -141,6 +178,7 @@ conn_client_types_iface_init (gpointer g_iface, #define IMPLEMENT(x) tp_svc_connection_interface_client_types_implement_##x \ (klass, client_types_##x) IMPLEMENT (get_client_types); + IMPLEMENT (request_client_types); #undef IMPLEMENT } @@ -197,8 +235,23 @@ idle_timeout (gpointer user_data) if (get_client_types_from_handle (data->conn, data->handle, &types)) { + DBusGMethodInvocation *context; + tp_svc_connection_interface_client_types_emit_client_types_updated ( data->conn, data->handle, (const gchar **) types); + + context = g_hash_table_lookup (data->conn->client_types_pending, + GUINT_TO_POINTER (data->handle)); + + if (context != NULL) + { + tp_svc_connection_interface_client_types_return_from_request_client_types ( + context, (const gchar **) types); + + g_hash_table_remove (data->conn->client_types_pending, + GUINT_TO_POINTER (data->handle)); + } + g_strfreev (types); } diff --git a/src/connection.c b/src/connection.c index 2917bc2..dd5cc05 100644 --- a/src/connection.c +++ b/src/connection.c @@ -473,6 +473,8 @@ gabble_connection_constructor (GType type, priv->client_data_forms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); + self->client_types_pending = g_hash_table_new (NULL, NULL); + /* Historically, the optional Jingle transports were in our initial * presence, but could be removed by UpdateCapabilities(). Emulate * that here for now. */ @@ -1312,6 +1314,7 @@ gabble_connection_dispose (GObject *object) tp_clear_object (&self->pep_olpc_activities); tp_clear_object (&self->pep_olpc_current_act); tp_clear_object (&self->pep_olpc_act_props); + g_clear_pointer (&self->client_types_pending, g_hash_table_unref); conn_sidecars_dispose (self); diff --git a/src/connection.h b/src/connection.h index 653ec6a..0cb5b9c 100644 --- a/src/connection.h +++ b/src/connection.h @@ -254,6 +254,10 @@ struct _GabbleConnection { * no PEP alias" here. */ GHashTable *pep_alias_cache; + /* conn-client-types.c + * TpHandle -> DBusGMethodInvocation */ + GHashTable *client_types_pending; + GabbleConnectionPrivate *priv; }; diff --git a/tests/twisted/client-types.py b/tests/twisted/client-types.py index 9c7ba7a..8c2ada3 100644 --- a/tests/twisted/client-types.py +++ b/tests/twisted/client-types.py @@ -3,7 +3,8 @@ Test Conn.I.ClientTypes """ from functools import partial -from servicetest import EventPattern, assertEquals, assertLength, assertContains, assertSameSets +from servicetest import (EventPattern, assertEquals, assertLength, + assertContains, assertSameSets, call_async) from gabbletest import exec_test, make_presence, sync_stream import constants as cs import ns @@ -98,6 +99,12 @@ def test(q, bus, conn, stream): assertLength(1, types[meredith_handle]) assertEquals('pc', types[meredith_handle][0]) + types = conn.RequestClientTypes(meredith_handle, + dbus_interface=cs.CONN_IFACE_CLIENT_TYPES) + + assertLength(1, types) + assertEquals('pc', types[0]) + # Two now becomes more available stream.send(make_presence(meredith_two, show='chat')) @@ -277,8 +284,25 @@ def two_contacts_with_the_same_hash(q, bus, conn, stream, bare_jids): args=[h2, ['phone']]), ) +def request_waiting_disco_reply(q, bus, conn, stream): + contact = 'georges@foo.com/One' + handle = conn.get_contact_handle_sync(contact) + + (caps, client, types) = build_stuff(TRANSIENT_PHONE) + send_presence(q, conn, stream, contact, caps) + stanza = expect_disco(q, contact, client, caps) + stream.send(make_presence(contact, type='available')) + + call_async (q, conn.ClientTypes, 'RequestClientTypes', handle) + # RequestClientTypes() is waiting for the disco reply before returning + send_disco_reply(stream, stanza, TRANSIENT_PHONE, []) + + e = q.expect('dbus-return', method='RequestClientTypes') + assertEquals((['phone'],), e.value) + if __name__ == '__main__': exec_test(test) exec_test(test2) exec_test(partial(two_contacts_with_the_same_hash, bare_jids=False)) exec_test(partial(two_contacts_with_the_same_hash, bare_jids=True)) + exec_test(request_waiting_disco_reply) diff --git a/tests/twisted/servicetest.py b/tests/twisted/servicetest.py index dafdb64..c98bc70 100644 --- a/tests/twisted/servicetest.py +++ b/tests/twisted/servicetest.py @@ -632,6 +632,7 @@ def wrap_connection(conn): ('ContactGroups', cs.CONN_IFACE_CONTACT_GROUPS), ('PowerSaving', cs.CONN_IFACE_POWER_SAVING), ('Addressing', cs.CONN_IFACE_ADDRESSING), + ('ClientTypes', cs.CONN_IFACE_CLIENT_TYPES), ])) def wrap_channel(chan, type_, extra=None): -- 1.8.3.1