[folks] Implement ContactInfo in the Telepathy test backend.
- From: Travis Reitter <treitter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Implement ContactInfo in the Telepathy test backend.
- Date: Tue, 11 Oct 2011 01:13:54 +0000 (UTC)
commit 9000d07cfcc00dbbbc6e118fca34a19675756877
Author: Travis Reitter <travis reitter collabora co uk>
Date: Thu Sep 29 14:44:35 2011 -0700
Implement ContactInfo in the Telepathy test backend.
Helps: bgo#657602 - Telepathy backend fails to set Personas' phone
numbers from ContactInfo
tests/lib/telepathy/contactlist/conn.c | 234 +++++++++++++++++++-
tests/lib/telepathy/contactlist/conn.h | 1 +
.../telepathy/contactlist/contact-list-manager.c | 80 +++++++
.../telepathy/contactlist/contact-list-manager.h | 2 +
tests/telepathy/individual-properties.vala | 4 +
5 files changed, 318 insertions(+), 3 deletions(-)
---
diff --git a/tests/lib/telepathy/contactlist/conn.c b/tests/lib/telepathy/contactlist/conn.c
index 748abef..cc35c4b 100644
--- a/tests/lib/telepathy/contactlist/conn.c
+++ b/tests/lib/telepathy/contactlist/conn.c
@@ -1,8 +1,8 @@
/*
* conn.c - an tp_test connection
*
- * Copyright  2007-2009 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright  2007-2009 Nokia Corporation
+ * Copyright  2007-2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright  2007-2010 Nokia Corporation
*
* Copying and distribution of this file, with or without modification,
* are permitted in any medium without royalty provided the copyright
@@ -22,6 +22,7 @@
#include "contact-list-manager.h"
static void init_aliasing (gpointer, gpointer);
+static void init_contact_info (gpointer, gpointer);
G_DEFINE_TYPE_WITH_CODE (TpTestContactListConnection,
tp_test_contact_list_connection,
@@ -33,7 +34,9 @@ G_DEFINE_TYPE_WITH_CODE (TpTestContactListConnection,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE,
tp_presence_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
- tp_presence_mixin_simple_presence_iface_init))
+ tp_presence_mixin_simple_presence_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO,
+ init_contact_info))
enum
{
@@ -245,6 +248,21 @@ alias_updated_cb (TpTestContactListManager *manager,
}
static void
+contact_info_updated_cb (TpTestContactListManager *manager,
+ TpHandle contact,
+ TpTestContactListConnection *self)
+{
+ GPtrArray *contact_info = tp_test_contact_list_manager_get_contact_info (
+ self->priv->list_manager, contact);
+
+ if (contact_info != NULL)
+ {
+ tp_svc_connection_interface_contact_info_emit_contact_info_changed (self,
+ contact, contact_info);
+ }
+}
+
+static void
presence_updated_cb (TpTestContactListManager *manager,
TpHandle contact,
TpTestContactListConnection *self)
@@ -280,6 +298,8 @@ create_channel_managers (TpBaseConnection *conn)
g_signal_connect (self->priv->list_manager, "alias-updated",
G_CALLBACK (alias_updated_cb), self);
+ g_signal_connect (self->priv->list_manager, "contact-info-updated",
+ G_CALLBACK (contact_info_updated_cb), self);
g_signal_connect (self->priv->list_manager, "presence-updated",
G_CALLBACK (presence_updated_cb), self);
@@ -343,6 +363,69 @@ aliasing_fill_contact_attributes (GObject *object,
}
static void
+contact_info_fill_contact_attributes (GObject *object,
+ const GArray *contacts,
+ GHashTable *attributes_hash)
+{
+ TpTestContactListConnection *self = TP_TEST_CONTACT_LIST_CONNECTION (object);
+ guint i;
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle contact = g_array_index (contacts, TpHandle, i);
+ GPtrArray *contact_info = tp_test_contact_list_manager_get_contact_info (
+ self->priv->list_manager, contact);
+ if (contact_info != NULL)
+ {
+ GValue *val = tp_g_value_slice_new_boxed (
+ TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, contact_info);
+
+ tp_contacts_mixin_set_contact_attribute (attributes_hash,
+ contact,
+ TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO "/info", val);
+ }
+ }
+}
+
+static TpDBusPropertiesMixinPropImpl conn_contact_info_properties[] = {
+ { "ContactInfoFlags", GUINT_TO_POINTER (TP_CONTACT_INFO_FLAG_PUSH |
+ TP_CONTACT_INFO_FLAG_CAN_SET), NULL },
+ { "SupportedFields", NULL, NULL },
+ { NULL }
+};
+
+static void
+conn_contact_info_properties_getter (GObject *object,
+ GQuark interface,
+ GQuark name,
+ GValue *value,
+ gpointer getter_data)
+{
+ GQuark q_supported_fields = g_quark_from_static_string ("SupportedFields");
+ static GPtrArray *supported_fields = NULL;
+
+ if (name == q_supported_fields)
+ {
+ if (supported_fields == NULL)
+ {
+ supported_fields = g_ptr_array_new ();
+
+ g_ptr_array_add (supported_fields, tp_value_array_build (4,
+ G_TYPE_STRING, "tel",
+ G_TYPE_STRV, NULL,
+ G_TYPE_UINT, 0,
+ G_TYPE_UINT, G_MAXUINT32,
+ G_TYPE_INVALID));
+ }
+ g_value_set_boxed (value, supported_fields);
+ }
+ else
+ {
+ g_value_set_uint (value, GPOINTER_TO_UINT (getter_data));
+ }
+}
+
+static void
constructed (GObject *object)
{
TpBaseConnection *base = TP_BASE_CONNECTION (object);
@@ -358,6 +441,9 @@ constructed (GObject *object)
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
aliasing_fill_contact_attributes);
+ tp_contacts_mixin_add_contact_attributes_iface (object,
+ TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
+ contact_info_fill_contact_attributes);
tp_presence_mixin_init (object,
G_STRUCT_OFFSET (TpTestContactListConnection, presence_mixin));
@@ -457,11 +543,21 @@ tp_test_contact_list_connection_class_init (
{
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
+ TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
NULL };
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
+ conn_contact_info_properties_getter,
+ NULL,
+ conn_contact_info_properties,
+ },
+ { NULL }
+ };
+
TpBaseConnectionClass *base_class = (TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
@@ -520,6 +616,10 @@ tp_test_contact_list_connection_class_init (
status_available, get_contact_statuses, set_own_status,
tp_test_contact_list_presence_statuses ());
tp_presence_mixin_simple_presence_init_dbus_properties (object_class);
+
+ klass->properties_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestContactListConnectionClass, properties_class));
}
static void
@@ -669,6 +769,134 @@ init_aliasing (gpointer iface,
#undef IMPLEMENT
}
+static void
+get_contact_info (
+ TpSvcConnectionInterfaceContactInfo *iface,
+ const GArray *contacts,
+ DBusGMethodInvocation *context)
+{
+ TpTestContactListConnection *self = TP_TEST_CONTACT_LIST_CONNECTION (iface);
+ TpBaseConnection *base = (TpBaseConnection *) self;
+ TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
+ TP_HANDLE_TYPE_CONTACT);
+ GError *error = NULL;
+ guint i;
+ GHashTable *ret;
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (TP_BASE_CONNECTION (iface),
+ context);
+
+ if (!tp_handles_are_valid (contact_handles, contacts, FALSE, &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ ret = dbus_g_type_specialized_construct (TP_HASH_TYPE_CONTACT_INFO_MAP);
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle contact = g_array_index (contacts, TpHandle, i);
+ GPtrArray *contact_info = tp_test_contact_list_manager_get_contact_info (
+ self->priv->list_manager, contact);
+ if (contact_info != NULL)
+ {
+ g_hash_table_insert (ret, GUINT_TO_POINTER (contact),
+ g_boxed_copy (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST,
+ contact_info));
+ }
+ }
+
+ tp_svc_connection_interface_contact_info_return_from_get_contact_info (
+ context, ret);
+
+ g_boxed_free (TP_HASH_TYPE_CONTACT_INFO_MAP, ret);
+}
+
+static void
+refresh_contact_info (TpSvcConnectionInterfaceContactInfo *iface,
+ const GArray *contacts,
+ DBusGMethodInvocation *context)
+{
+ TpTestContactListConnection *self = TP_TEST_CONTACT_LIST_CONNECTION (iface);
+ guint i;
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle contact = g_array_index (contacts, TpHandle, i);
+ GPtrArray *contact_info;
+
+ contact_info = tp_test_contact_list_manager_get_contact_info (
+ self->priv->list_manager, contact);
+
+ if (contact_info != NULL)
+ {
+ tp_svc_connection_interface_contact_info_emit_contact_info_changed (
+ iface, contact, contact_info);
+ }
+ }
+}
+
+static void
+_return_from_request_contact_info (TpTestContactListConnection *self,
+ guint contact,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+ GPtrArray *contact_info;
+
+ contact_info = tp_test_contact_list_manager_get_contact_info (
+ self->priv->list_manager, contact);
+
+ if (contact_info == NULL)
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ tp_svc_connection_interface_contact_info_return_from_request_contact_info (
+ context, contact_info);
+}
+
+static void
+request_contact_info (TpSvcConnectionInterfaceContactInfo *iface,
+ guint contact,
+ DBusGMethodInvocation *context)
+{
+ TpTestContactListConnection *self = TP_TEST_CONTACT_LIST_CONNECTION (iface);
+ TpBaseConnection *base = (TpBaseConnection *) self;
+ TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
+ TP_HANDLE_TYPE_CONTACT);
+ GError *err = NULL;
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
+
+ if (!tp_handle_is_valid (contact_handles, contact, &err))
+ {
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+ return;
+ }
+
+ _return_from_request_contact_info (self, contact, context);
+}
+
+static void
+init_contact_info (gpointer iface,
+ gpointer iface_data G_GNUC_UNUSED)
+{
+ TpSvcConnectionInterfaceContactInfoClass *klass = iface;
+
+#define IMPLEMENT(x) tp_svc_connection_interface_contact_info_implement_##x (\
+ klass, x)
+ IMPLEMENT(get_contact_info);
+ IMPLEMENT(refresh_contact_info);
+ IMPLEMENT(request_contact_info);
+#undef IMPLEMENT
+}
+
TpTestContactListConnection *
tp_test_contact_list_connection_new (const gchar *account,
const gchar *protocol,
diff --git a/tests/lib/telepathy/contactlist/conn.h b/tests/lib/telepathy/contactlist/conn.h
index c174d0a..e606603 100644
--- a/tests/lib/telepathy/contactlist/conn.h
+++ b/tests/lib/telepathy/contactlist/conn.h
@@ -29,6 +29,7 @@ typedef struct _TpTestContactListConnectionPrivate
struct _TpTestContactListConnectionClass {
TpBaseConnectionClass parent_class;
+ TpDBusPropertiesMixinClass properties_class;
TpPresenceMixinClass presence_mixin;
TpContactsMixinClass contacts_mixin;
};
diff --git a/tests/lib/telepathy/contactlist/contact-list-manager.c b/tests/lib/telepathy/contactlist/contact-list-manager.c
index 92f4367..e979f8e 100644
--- a/tests/lib/telepathy/contactlist/contact-list-manager.c
+++ b/tests/lib/telepathy/contactlist/contact-list-manager.c
@@ -62,6 +62,7 @@ typedef struct {
TpHandleSet *tags;
+ GPtrArray *contact_info;
} TpTestContactDetails;
static TpTestContactDetails *
@@ -78,6 +79,9 @@ tp_test_contact_details_destroy (gpointer p)
if (d->tags != NULL)
tp_handle_set_destroy (d->tags);
+ if (d->contact_info != NULL)
+ g_ptr_array_unref (d->contact_info);
+
g_free (d->id);
g_free (d->alias);
g_slice_free (TpTestContactDetails, d);
@@ -95,6 +99,7 @@ enum
{
ALIAS_UPDATED,
PRESENCE_UPDATED,
+ CONTACT_INFO_UPDATED,
N_SIGNALS
};
@@ -374,6 +379,38 @@ static TpTestContactGroup *ensure_group (TpTestContactListManager *self,
static TpTestContactList *ensure_list (TpTestContactListManager *self,
TpTestContactListHandle handle);
+/*
+ * _insert_contact_field:
+ * @contact_info: an array of Contact_Info_Field structures
+ * @field_name: a vCard field name in any case combination
+ * @field_params: a list of vCard type-parameters, typically of the form
+ * type=xxx; must be in lower-case if case-insensitive
+ * @field_values: for unstructured fields, an array containing one element;
+ * for structured fields, the elements of the field in order
+ */
+static void
+_insert_contact_field (GPtrArray *contact_info,
+ const gchar *field_name,
+ const gchar * const *field_params,
+ const gchar * const *field_values)
+{
+ const gchar * const *empty_strv = { NULL };
+ gchar *field_name_down = g_ascii_strdown (field_name, -1);
+
+ if (field_params == NULL)
+ field_params = empty_strv;
+ if (field_values == NULL)
+ field_values = empty_strv;
+
+ g_ptr_array_add (contact_info, tp_value_array_build (3,
+ G_TYPE_STRING, field_name_down,
+ G_TYPE_STRV, field_params,
+ G_TYPE_STRV, field_values,
+ G_TYPE_INVALID));
+
+ g_free (field_name_down);
+}
+
static gboolean
receive_contact_lists (gpointer p)
{
@@ -432,6 +469,13 @@ receive_contact_lists (gpointer p)
d->publish = TRUE;
d->tags = tp_handle_set_new (self->priv->group_repo);
tp_handle_set_add (d->tags, cambridge);
+ d->contact_info = dbus_g_type_specialized_construct (
+ TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST);
+ {
+ const gchar * values[] = { "+14401223357708", NULL };
+ _insert_contact_field (d->contact_info, "tel", NULL,
+ (const gchar * const *) values);
+ }
tp_handle_unref (self->priv->contact_repo, handle);
id = "guillaume example com";
@@ -466,6 +510,18 @@ receive_contact_lists (gpointer p)
d->tags = tp_handle_set_new (self->priv->group_repo);
tp_handle_set_add (d->tags, montreal);
tp_handle_set_add (d->tags, francophones);
+ d->contact_info = dbus_g_type_specialized_construct (
+ TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST);
+ {
+ const gchar * values[] = { "+15142345678", NULL };
+ _insert_contact_field (d->contact_info, "tel", NULL,
+ (const gchar * const *) values);
+ }
+ {
+ const gchar * values[] = { "Olivier Crete", NULL };
+ _insert_contact_field (d->contact_info, "fn", NULL,
+ (const gchar * const *) values);
+ }
tp_handle_unref (self->priv->contact_repo, handle);
id = "travis example com";
@@ -496,6 +552,7 @@ receive_contact_lists (gpointer p)
{
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
+ g_signal_emit (self, signals[CONTACT_INFO_UPDATED], 0, handle);
}
tp_intset_destroy (set);
@@ -548,6 +605,7 @@ receive_contact_lists (gpointer p)
{
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
+ g_signal_emit (self, signals[CONTACT_INFO_UPDATED], 0, handle);
}
tp_intset_destroy (set);
@@ -576,6 +634,7 @@ receive_contact_lists (gpointer p)
tp_intset_destroy (set);
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
+ g_signal_emit (self, signals[CONTACT_INFO_UPDATED], 0, handle);
id = "christian example com";
handle = tp_handle_ensure (self->priv->contact_repo, id, NULL, NULL);
@@ -598,6 +657,7 @@ receive_contact_lists (gpointer p)
tp_intset_destroy (set);
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
+ g_signal_emit (self, signals[CONTACT_INFO_UPDATED], 0, handle);
tp_group_mixin_change_members ((GObject *) cambridge_group, "",
cam_set, NULL, NULL, NULL,
@@ -724,6 +784,13 @@ tp_test_contact_list_manager_class_init (TpTestContactListManagerClass *klass)
0,
NULL, NULL,
g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ signals[CONTACT_INFO_UPDATED] = g_signal_new ("contact-info-updated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
}
static void
@@ -1076,6 +1143,7 @@ send_updated_roster (TpTestContactListManager *self,
* would make this mistake as well. */
g_signal_emit (self, signals[ALIAS_UPDATED], 0, handle);
g_signal_emit (self, signals[PRESENCE_UPDATED], 0, handle);
+ g_signal_emit (self, signals[CONTACT_INFO_UPDATED], 0, handle);
tp_handle_unref (self->priv->contact_repo, handle);
}
@@ -1683,3 +1751,15 @@ tp_test_contact_list_manager_set_alias (TpTestContactListManager *self,
TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
tp_intset_destroy (set);
}
+
+GPtrArray *
+tp_test_contact_list_manager_get_contact_info (TpTestContactListManager *self,
+ TpHandle contact)
+{
+ TpTestContactDetails *d = lookup_contact (self, contact);
+
+ if (d != NULL)
+ return d->contact_info;
+
+ return NULL;
+}
diff --git a/tests/lib/telepathy/contactlist/contact-list-manager.h b/tests/lib/telepathy/contactlist/contact-list-manager.h
index 586e3f6..797f3fb 100644
--- a/tests/lib/telepathy/contactlist/contact-list-manager.h
+++ b/tests/lib/telepathy/contactlist/contact-list-manager.h
@@ -102,6 +102,8 @@ const gchar *tp_test_contact_list_manager_get_alias (
TpTestContactListManager *self, TpHandle contact);
void tp_test_contact_list_manager_set_alias (
TpTestContactListManager *self, TpHandle contact, const gchar *alias);
+GPtrArray * tp_test_contact_list_manager_get_contact_info (
+ TpTestContactListManager *self, TpHandle contact);
G_END_DECLS
diff --git a/tests/telepathy/individual-properties.vala b/tests/telepathy/individual-properties.vala
index c5f222f..ae8e84c 100644
--- a/tests/telepathy/individual-properties.vala
+++ b/tests/telepathy/individual-properties.vala
@@ -93,6 +93,10 @@ public class IndividualPropertiesTests : Folks.TestCase
assert (i.groups.size == 2);
assert (i.groups.contains ("Montreal") == true);
assert (i.groups.contains ("Francophones") == true);
+
+ /* Check ContactInfo-provided properties */
+ assert (new PhoneFieldDetails ("+15142345678")
+ in i.phone_numbers);
}
assert (removed.size == 1);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]