From 27a5e6eca567075da154043d3499e9e77c43891a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 19 Sep 2012 15:17:51 +0100 Subject: [PATCH 02/15] tp_contact_dup_location, TpContact:location-vardict: add --- docs/reference/telepathy-glib-sections.txt | 1 + telepathy-glib/contact.c | 59 ++++++++++++++++++++++++++++ telepathy-glib/contact.h | 2 + tests/dbus/contacts.c | 55 +++++++++++++++++++++----- 4 files changed, 108 insertions(+), 9 deletions(-) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index b482fe3..773da93 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -5012,6 +5012,7 @@ tp_contact_get_presence_message tp_contact_get_presence_status tp_contact_get_presence_type tp_contact_get_location +tp_contact_dup_location tp_contact_get_capabilities tp_contact_get_contact_info tp_contact_dup_contact_info diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c index dea4409..cf5aed3 100644 --- a/telepathy-glib/contact.c +++ b/telepathy-glib/contact.c @@ -38,6 +38,7 @@ #include "telepathy-glib/contact-internal.h" #include "telepathy-glib/debug-internal.h" #include "telepathy-glib/util-internal.h" +#include "telepathy-glib/variant-util-internal.h" /** * SECTION:contact @@ -96,6 +97,7 @@ struct _TpContact { * @TP_CONTACT_FEATURE_PRESENCE: #TpContact:presence-type, * #TpContact:presence-status and #TpContact:presence-message * @TP_CONTACT_FEATURE_LOCATION: #TpContact:location (available since 0.11.1) + * and #TpContact:location-vardict (since 0.UNRELEASED) * @TP_CONTACT_FEATURE_CAPABILITIES: #TpContact:capabilities * (available since 0.11.3) * @TP_CONTACT_FEATURE_AVATAR_DATA: #TpContact:avatar-file and @@ -176,6 +178,7 @@ enum { PROP_PRESENCE_STATUS, PROP_PRESENCE_MESSAGE, PROP_LOCATION, + PROP_LOCATION_VARDICT, PROP_CAPABILITIES, PROP_CONTACT_INFO, PROP_CLIENT_TYPES, @@ -554,6 +557,32 @@ tp_contact_get_location (TpContact *self) } /** + * tp_contact_dup_location: + * @self: a contact + * + * Return the contact's user-defined location, or %NULL if the location is + * unspecified. + * + * This function returns the same information as tp_contact_get_location(), + * but in a different format. + * + * Returns: a variant of type %G_VARIANT_TYPE_VARDICT, the same as + * the #TpContact:location-vardict property + * + * Since: 0.UNRELEASED + */ +GVariant * +tp_contact_dup_location (TpContact *self) +{ + g_return_val_if_fail (self != NULL, NULL); + + if (self->priv->location == NULL) + return NULL; + + return _tp_asv_to_vardict (self->priv->location); +} + +/** * tp_contact_get_client_types: * @self: a contact * @@ -948,6 +977,10 @@ tp_contact_get_property (GObject *object, g_value_set_boxed (value, tp_contact_get_location (self)); break; + case PROP_LOCATION_VARDICT: + g_value_take_variant (value, tp_contact_dup_location (self)); + break; + case PROP_CAPABILITIES: g_value_set_object (value, tp_contact_get_capabilities (self)); break; @@ -1216,6 +1249,31 @@ tp_contact_class_init (TpContactClass *klass) param_spec); /** + * TpContact:location-vardict: + * + * If this contact has set a user-defined location, a string to + * variant map containing his location. If not, %NULL. + * tp_vardict_get_string() and similar functions can be used to access + * the contents. + * + * This may be %NULL even if the contact has set a location, + * if this #TpContact object has not been set up to track + * %TP_CONTACT_FEATURE_LOCATION. + * + * This property contains the same information as #TpContact:location, + * in a different format. + * + * Since: 0.UNRELEASED + */ + param_spec = g_param_spec_variant ("location-vardict", + "Location", + "User-defined location, or NULL", + G_VARIANT_TYPE_VARDICT, NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_LOCATION_VARDICT, + param_spec); + + /** * TpContact:capabilities: * * The capabilities supported by this contact. If the underlying Connection @@ -2386,6 +2444,7 @@ contact_maybe_set_location (TpContact *self, self->priv->has_features |= CONTACT_FEATURE_FLAG_LOCATION; self->priv->location = location; g_object_notify ((GObject *) self, "location"); + g_object_notify ((GObject *) self, "location-vardict"); } static void diff --git a/telepathy-glib/contact.h b/telepathy-glib/contact.h index 84b016b..1197b5e 100644 --- a/telepathy-glib/contact.h +++ b/telepathy-glib/contact.h @@ -97,6 +97,8 @@ const gchar *tp_contact_get_presence_message (TpContact *self); /* TP_CONTACT_FEATURE_LOCATION */ GHashTable *tp_contact_get_location (TpContact *self); +_TP_AVAILABLE_IN_UNRELEASED +GVariant *tp_contact_dup_location (TpContact *self); /* TP_CONTACT_FEATURE_CAPABILITIES */ TpCapabilities *tp_contact_get_capabilities (TpContact *self); diff --git a/tests/dbus/contacts.c b/tests/dbus/contacts.c index c06f5b9..2b85d8e 100644 --- a/tests/dbus/contacts.c +++ b/tests/dbus/contacts.c @@ -1202,12 +1202,18 @@ upgrade_cb (TpConnection *connection, /* Just put a country in locations for easier comparaisons. * FIXME: Ideally we should have a MYASSERT_SAME_ASV */ -#define ASSERT_SAME_LOCATION(left, right)\ +#define ASSERT_SAME_LOCATION(left, left_vardict, right)\ G_STMT_START {\ g_assert_cmpuint (g_hash_table_size (left), ==, \ g_hash_table_size (right));\ g_assert_cmpstr (tp_asv_get_string (left, "country"), ==,\ tp_asv_get_string (right, "country"));\ + \ + g_assert_cmpstr (g_variant_get_type_string (left_vardict), ==, "a{sv}"); \ + g_assert_cmpuint (g_variant_n_children (left_vardict), ==, \ + g_hash_table_size (right));\ + g_assert_cmpstr (tp_vardict_get_string (left_vardict, "country"), ==,\ + tp_asv_get_string (right, "country"));\ } G_STMT_END static void @@ -1393,6 +1399,8 @@ test_upgrade (Fixture *f, for (i = 0; i < 3; i++) { + GVariant *vardict; + g_assert_cmpuint (tp_contact_get_handle (contacts[i]), ==, handles[i]); g_assert_cmpstr (tp_contact_get_identifier (contacts[i]), ==, ids[i]); @@ -1414,8 +1422,18 @@ test_upgrade (Fixture *f, MYASSERT (tp_contact_has_feature (contacts[i], TP_CONTACT_FEATURE_LOCATION), ""); + + vardict = tp_contact_dup_location (contacts[i]); + ASSERT_SAME_LOCATION (tp_contact_get_location (contacts[i]), + vardict, locations[i]); + g_variant_unref (vardict); + + g_object_get (contacts[i], + "location-vardict", &vardict, + NULL); ASSERT_SAME_LOCATION (tp_contact_get_location (contacts[i]), - locations[i]); + vardict, locations[i]); + g_variant_unref (vardict); MYASSERT (tp_contact_has_feature (contacts[i], TP_CONTACT_FEATURE_CAPABILITIES), ""); @@ -1497,6 +1515,7 @@ typedef struct gboolean presence_status_changed; gboolean presence_msg_changed; gboolean location_changed; + gboolean location_vardict_changed; gboolean capabilities_changed; } notify_ctx; @@ -1509,6 +1528,7 @@ notify_ctx_init (notify_ctx *ctx) ctx->presence_status_changed = FALSE; ctx->presence_msg_changed = FALSE; ctx->location_changed = FALSE; + ctx->location_vardict_changed = FALSE; ctx->capabilities_changed = FALSE; } @@ -1518,7 +1538,7 @@ notify_ctx_is_fully_changed (notify_ctx *ctx) return ctx->alias_changed && ctx->avatar_token_changed && ctx->presence_type_changed && ctx->presence_status_changed && ctx->presence_msg_changed && ctx->location_changed && - ctx->capabilities_changed; + ctx->location_vardict_changed && ctx->capabilities_changed; } static gboolean @@ -1527,7 +1547,7 @@ notify_ctx_is_changed (notify_ctx *ctx) return ctx->alias_changed || ctx->avatar_token_changed || ctx->presence_type_changed || ctx->presence_status_changed || ctx->presence_msg_changed || ctx->location_changed || - ctx->capabilities_changed; + ctx->location_vardict_changed || ctx->capabilities_changed; } static void @@ -1547,6 +1567,8 @@ contact_notify_cb (TpContact *contact, ctx->presence_msg_changed = TRUE; else if (!tp_strdiff (param->name, "location")) ctx->location_changed = TRUE; + else if (!tp_strdiff (param->name, "location-vardict")) + ctx->location_vardict_changed = TRUE; else if (!tp_strdiff (param->name, "capabilities")) ctx->capabilities_changed = TRUE; } @@ -1633,9 +1655,11 @@ test_features (Fixture *f, gchar *presence_status; gchar *presence_message; GHashTable *location; + GVariant *location_vardict; TpCapabilities *capabilities; } from_gobject; notify_ctx notify_ctx_alice, notify_ctx_chris; + GVariant *vardict; g_message (G_STRFUNC); @@ -1704,8 +1728,10 @@ test_features (Fixture *f, MYASSERT (tp_contact_has_feature (contacts[i], TP_CONTACT_FEATURE_LOCATION), ""); + vardict = tp_contact_dup_location (contacts[i]); ASSERT_SAME_LOCATION (tp_contact_get_location (contacts[i]), - locations[i]); + vardict, locations[i]); + g_variant_unref (vardict); MYASSERT (tp_contact_has_feature (contacts[i], TP_CONTACT_FEATURE_CAPABILITIES), ""); @@ -1744,6 +1770,7 @@ test_features (Fixture *f, "presence-status", &from_gobject.presence_status, "presence-message", &from_gobject.presence_message, "location", &from_gobject.location, + "location-vardict", &from_gobject.location_vardict, "capabilities", &from_gobject.capabilities, NULL); MYASSERT (from_gobject.connection == client_conn, ""); @@ -1755,7 +1782,8 @@ test_features (Fixture *f, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE); g_assert_cmpstr (from_gobject.presence_status, ==, "available"); g_assert_cmpstr (from_gobject.presence_message, ==, ""); - ASSERT_SAME_LOCATION (from_gobject.location, locations[0]); + ASSERT_SAME_LOCATION (from_gobject.location, from_gobject.location_vardict, + locations[0]); MYASSERT (tp_capabilities_is_specific_to_contact (from_gobject.capabilities), ""); MYASSERT (tp_capabilities_supports_text_chats (from_gobject.capabilities) @@ -1769,6 +1797,7 @@ test_features (Fixture *f, g_free (from_gobject.presence_status); g_free (from_gobject.presence_message); g_hash_table_unref (from_gobject.location); + g_variant_unref (from_gobject.location_vardict); g_object_unref (from_gobject.capabilities); notify_ctx_init (¬ify_ctx_alice); @@ -1824,8 +1853,10 @@ test_features (Fixture *f, MYASSERT (tp_contact_has_feature (contacts[i], TP_CONTACT_FEATURE_LOCATION), ""); + vardict = tp_contact_dup_location (contacts[i]); ASSERT_SAME_LOCATION (tp_contact_get_location (contacts[i]), - new_locations[i]); + vardict, new_locations[i]); + g_variant_unref (vardict); caps = tp_contact_get_capabilities (contacts[i]); MYASSERT (caps != NULL, ""); @@ -2428,6 +2459,7 @@ test_no_location (Fixture *f, TpContactFeature feature = TP_CONTACT_FEATURE_LOCATION; GHashTable *norway = tp_asv_new ("country", G_TYPE_STRING, "Norway", NULL); notify_ctx notify_ctx_alice; + GVariant *vardict; g_test_bug ("39377"); @@ -2482,7 +2514,10 @@ test_no_location (Fixture *f, 1, &handle, &norway); tp_tests_proxy_run_until_dbus_queue_processed (f->client_conn); g_assert (notify_ctx_alice.location_changed); - ASSERT_SAME_LOCATION (tp_contact_get_location (contact), norway); + g_assert (notify_ctx_alice.location_vardict_changed); + vardict = tp_contact_dup_location (contact); + ASSERT_SAME_LOCATION (tp_contact_get_location (contact), vardict, norway); + g_variant_unref (vardict); weak_pointer = contact; g_object_add_weak_pointer ((GObject *) contact, &weak_pointer); @@ -2526,7 +2561,9 @@ test_no_location (Fixture *f, g_assert_cmpuint (f->result.contacts->len, ==, 1); g_assert (g_ptr_array_index (f->result.contacts, 0) == contact); - ASSERT_SAME_LOCATION (tp_contact_get_location (contact), norway); + vardict = tp_contact_dup_location (contact); + ASSERT_SAME_LOCATION (tp_contact_get_location (contact), vardict, norway); + g_variant_unref (vardict); reset_result (&f->result); weak_pointer = contact; -- 1.7.10.4