telepathy-qt: contacts-conn CM: Implement proper Conn.I.ClientTypes support

Dario Freddi drf at kemper.freedesktop.org
Thu Jul 5 06:06:01 PDT 2012


Module: telepathy-qt
Branch: master
Commit: 2613690ce569ed89a51a9791a4630ac4d74cdb30
URL:    http://cgit.freedesktop.org/telepathy/telepathy-qt/commit/?id=2613690ce569ed89a51a9791a4630ac4d74cdb30

Author: George Kiagiadakis <george.kiagiadakis at collabora.com>
Date:   Thu Jul  5 13:29:02 2012 +0300

contacts-conn CM: Implement proper Conn.I.ClientTypes support

---

 tests/lib/glib/contacts-conn.c |   88 +++++++++++++++++++++++++++++++++++-----
 tests/lib/glib/contacts-conn.h |    5 +-
 2 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/tests/lib/glib/contacts-conn.c b/tests/lib/glib/contacts-conn.c
index 47d0b03..e05b990 100644
--- a/tests/lib/glib/contacts-conn.c
+++ b/tests/lib/glib/contacts-conn.c
@@ -26,6 +26,7 @@ static void init_avatars (gpointer, gpointer);
 static void init_location (gpointer, gpointer);
 static void init_contact_caps (gpointer, gpointer);
 static void init_contact_info (gpointer, gpointer);
+static void init_client_types (gpointer, gpointer);
 static void conn_avatars_properties_getter (GObject *object, GQuark interface,
     GQuark name, GValue *value, gpointer getter_data);
 
@@ -47,14 +48,14 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection,
       init_contact_caps)
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO,
       init_contact_info)
+    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES,
+      init_client_types);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
       tp_contacts_mixin_iface_init);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST,
       tp_base_contact_list_mixin_list_iface_init);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS,
       tp_base_contact_list_mixin_groups_iface_init);
-    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES,
-      NULL);
     );
 
 /* type definition stuff */
@@ -95,6 +96,8 @@ struct _TpTestsContactsConnectionPrivate
   /* TpHandle => GPtrArray * */
   GHashTable *contact_info;
   GPtrArray *default_contact_info;
+  /* TpHandle => gchar ** */
+  GHashTable *client_types;
 
   TestContactListManager *list_manager;
 };
@@ -163,6 +166,8 @@ tp_tests_contacts_connection_init (TpTestsContactsConnection *self)
       g_direct_equal, NULL, (GDestroyNotify) g_ptr_array_unref);
   self->priv->default_contact_info = (GPtrArray *) dbus_g_type_specialized_construct (
       TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST);
+  self->priv->client_types = g_hash_table_new_full (g_direct_hash,
+      g_direct_equal, NULL, (GDestroyNotify) g_strfreev);
 }
 
 static void
@@ -178,6 +183,7 @@ finalize (GObject *object)
   g_hash_table_destroy (self->priv->locations);
   g_hash_table_destroy (self->priv->capabilities);
   g_hash_table_destroy (self->priv->contact_info);
+  g_hash_table_destroy (self->priv->client_types);
 
   if (self->priv->default_contact_info != NULL)
     g_ptr_array_unref (self->priv->default_contact_info);
@@ -350,15 +356,22 @@ client_types_fill_contact_attributes (
     const GArray *contacts,
     GHashTable *attributes)
 {
-  TpTestsContactsConnectionClass *klass =
-      TP_TESTS_CONTACTS_CONNECTION_GET_CLASS (object);
-
-  if (klass->fill_client_types != NULL)
-    klass->fill_client_types (object, contacts, attributes);
-  /* …else do nothing: a no-op implementation is valid, relatively speaking.
-   * The spec sez the /client-types attribute should be “omitted from the
-   * result if the contact's client types are not known.”
-   */
+  guint i;
+  TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
+
+  for (i = 0; i < contacts->len; i++)
+    {
+      TpHandle handle = g_array_index (contacts, TpHandle, i);
+      gchar **types = g_hash_table_lookup (self->priv->client_types,
+          GUINT_TO_POINTER (handle));
+
+      if (types != NULL)
+        {
+           tp_contacts_mixin_set_contact_attribute (attributes, handle,
+               TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES "/client-types",
+               tp_g_value_slice_new_boxed (G_TYPE_STRV, types));
+        }
+    }
 }
 
 static void
@@ -757,6 +770,19 @@ tp_tests_contacts_connection_set_default_contact_info (
   self->priv->default_contact_info = g_ptr_array_ref (info);
 }
 
+void
+tp_tests_contacts_connection_change_client_types(
+    TpTestsContactsConnection *self,
+    TpHandle handle,
+    gchar **client_types)
+{
+    g_hash_table_insert (self->priv->client_types, GUINT_TO_POINTER (handle),
+        client_types);
+
+    tp_svc_connection_interface_client_types_emit_client_types_updated (self,
+        handle, (const gchar **) client_types);
+}
+
 static void
 my_get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
                     DBusGMethodInvocation *context)
@@ -1269,6 +1295,46 @@ init_contact_info (gpointer g_iface,
 #undef IMPLEMENT
 }
 
+static void
+my_request_client_types (TpSvcConnectionInterfaceClientTypes *obj,
+    guint handle,
+    DBusGMethodInvocation *context)
+{
+  TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
+  TpBaseConnection *base = TP_BASE_CONNECTION (obj);
+  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
+      TP_HANDLE_TYPE_CONTACT);
+  GError *error = NULL;
+  gchar **types;
+
+  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
+
+  if (!tp_handle_is_valid (contact_repo, handle, &error))
+    {
+      dbus_g_method_return_error (context, error);
+      g_error_free (error);
+      return;
+    }
+
+  types = g_hash_table_lookup(self->priv->client_types, GUINT_TO_POINTER (handle));
+
+  tp_svc_connection_interface_client_types_return_from_request_client_types (
+      context, (const gchar **) types);
+}
+
+static void
+init_client_types (gpointer g_iface,
+    gpointer iface_data)
+{
+  TpSvcConnectionInterfaceClientTypesClass *klass = g_iface;
+
+#define IMPLEMENT(x) tp_svc_connection_interface_client_types_implement_##x (\
+    klass, my_##x)
+  /* IMPLEMENT (get_client_types); */
+  IMPLEMENT (request_client_types);
+#undef IMPLEMENT
+}
+
 /* =============== Legacy version (no Contacts interface) ================= */
 
 G_DEFINE_TYPE (TpTestsLegacyContactsConnection,
diff --git a/tests/lib/glib/contacts-conn.h b/tests/lib/glib/contacts-conn.h
index 58674d4..4c36b90 100644
--- a/tests/lib/glib/contacts-conn.h
+++ b/tests/lib/glib/contacts-conn.h
@@ -32,8 +32,6 @@ struct _TpTestsContactsConnectionClass {
     TpPresenceMixinClass presence_mixin;
     TpContactsMixinClass contacts_mixin;
     TpDBusPropertiesMixinClass properties_class;
-
-    TpContactsMixinFillContactAttributesFunc fill_client_types;
 };
 
 struct _TpTestsContactsConnection {
@@ -116,6 +114,9 @@ void tp_tests_contacts_connection_set_default_contact_info (
     TpTestsContactsConnection *self,
     GPtrArray *info);
 
+void tp_tests_contacts_connection_change_client_types (
+    TpTestsContactsConnection *self, TpHandle handle, gchar **client_types);
+
 /* Legacy version (no Contacts interface, and no immortal handles) */
 
 typedef struct _TpTestsLegacyContactsConnection TpTestsLegacyContactsConnection;



More information about the telepathy-commits mailing list