diff options
Diffstat (limited to 'telepathy-glib/contact.c')
-rw-r--r-- | telepathy-glib/contact.c | 194 |
1 files changed, 168 insertions, 26 deletions
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c index af81bf4fa..20f4bf681 100644 --- a/telepathy-glib/contact.c +++ b/telepathy-glib/contact.c @@ -1633,6 +1633,22 @@ typedef struct _ContactsContext ContactsContext; typedef void (*ContactsProc) (ContactsContext *self); typedef enum { CB_BY_HANDLE, CB_BY_ID, CB_UPGRADE } ContactsSignature; +static const gchar * +contacts_signature_to_string (ContactsSignature sig) +{ + switch (sig) + { + case CB_BY_HANDLE: + return "by handle"; + case CB_BY_ID: + return "by ID"; + case CB_UPGRADE: + return "upgrade"; + default: + return "???"; + } +} + struct _ContactsContext { gsize refcount; @@ -1653,9 +1669,13 @@ struct _ContactsContext { /* ID => GError, NULL unless we started from IDs */ GHashTable *request_errors; - /* features we need before this request can finish */ + /* features we need to get, if possible, before this request can finish */ ContactFeatureFlags wanted; + /* features we can expect to get from GetContactAttributes + * (subset of wanted) */ + ContactFeatureFlags getting; + /* callback for when we've finished, plus the usual misc */ ContactsSignature signature; union { @@ -1711,6 +1731,32 @@ contacts_context_new (TpConnection *connection, { ContactsContext *c = g_slice_new0 (ContactsContext); + DEBUG ("%p, for %u contacts, %s", c, n_contacts, + contacts_signature_to_string (signature)); + + DEBUG ("want alias: %s", + (want_features & CONTACT_FEATURE_FLAG_ALIAS) ? "yes" : "no"); + DEBUG ("want avatar token: %s", + (want_features & CONTACT_FEATURE_FLAG_AVATAR_TOKEN) ? "yes" : "no"); + DEBUG ("want presence: %s", + (want_features & CONTACT_FEATURE_FLAG_PRESENCE) ? "yes" : "no"); + DEBUG ("want location: %s", + (want_features & CONTACT_FEATURE_FLAG_LOCATION) ? "yes" : "no"); + DEBUG ("want caps: %s", + (want_features & CONTACT_FEATURE_FLAG_CAPABILITIES) ? "yes" : "no"); + DEBUG ("want avatar data: %s", + (want_features & CONTACT_FEATURE_FLAG_AVATAR_DATA) ? "yes" : "no"); + DEBUG ("want contact info: %s", + (want_features & CONTACT_FEATURE_FLAG_CONTACT_INFO) ? "yes" : "no"); + DEBUG ("want client types: %s", + (want_features & CONTACT_FEATURE_FLAG_CLIENT_TYPES) ? "yes" : "no"); + DEBUG ("want states: %s", + (want_features & CONTACT_FEATURE_FLAG_STATES) ? "yes" : "no"); + DEBUG ("want contact groups: %s", + (want_features & CONTACT_FEATURE_FLAG_CONTACT_GROUPS) ? "yes" : "no"); + DEBUG ("want contact blocking: %s", + (want_features & CONTACT_FEATURE_FLAG_CONTACT_BLOCKING) ? "yes" : "no"); + c->refcount = 1; c->connection = g_object_ref (connection); c->contacts = g_ptr_array_sized_new (n_contacts); @@ -1740,6 +1786,8 @@ contacts_context_unref (gpointer p) if ((--c->refcount) > 0) return; + DEBUG ("last-unref (%p)", c); + g_assert (c->connection != NULL); tp_clear_object (&c->connection); @@ -1938,7 +1986,10 @@ static void contacts_context_continue (ContactsContext *c) { if (c->no_purpose_in_life) - return; + { + DEBUG ("%p: no purpose in life", c); + return; + } if (g_queue_is_empty (&c->todo)) { @@ -1946,6 +1997,8 @@ contacts_context_continue (ContactsContext *c) * library user */ guint i; + DEBUG ("%p: nothing more to do", c); + g_assert (c->contacts != NULL); g_assert (c->invalid != NULL); @@ -1987,12 +2040,13 @@ contacts_context_continue (ContactsContext *c) if (G_UNLIKELY (tp_proxy_get_invalidated (c->connection) != NULL)) { - DEBUG ("failing due to connection having been invalidated: %s", - tp_proxy_get_invalidated (c->connection)->message); + DEBUG ("%p: failing due to connection having been invalidated: %s", + c, tp_proxy_get_invalidated (c->connection)->message); contacts_context_fail (c, tp_proxy_get_invalidated (c->connection)); } else { + DEBUG ("%p: on to the next thing", c); next (c); } } @@ -2160,12 +2214,16 @@ contacts_inspected (TpConnection *connection, { guint i; + DEBUG ("%p: inspected %u handles", c, c->contacts->len); + for (i = 0; i < c->contacts->len; i++) { TpContact *contact = g_ptr_array_index (c->contacts, i); g_assert (ids[i] != NULL); + DEBUG ("- #%u: \"%s\"", contact->priv->handle, ids[i]); + if (contact->priv->identifier == NULL) { contact->priv->identifier = g_strdup (ids[i]); @@ -2797,23 +2855,23 @@ mime_file_written (GObject *source_object, WriteAvatarData *avatar_data = user_data; GFile *file = G_FILE (source_object); TpContact *self; - gchar *path; + gchar *path = g_file_get_path (file); g_assert (file == avatar_data->mime_file); - path = g_file_get_path (file); if (!g_file_replace_contents_finish (file, res, NULL, &error)) { - DEBUG ("Failed to store MIME type in cache (%s): %s", - path, error->message); + DEBUG ("Failed to store MIME type in cache (%s): %s", path, + error->message); g_clear_error (&error); } else { - DEBUG ("Contact avatar MIME type stored in cache: %s", - path); + DEBUG ("Contact avatar MIME type stored in cache: %s", path); } + g_free (path); + self = g_weak_ref_get (&avatar_data->contact); if (self == NULL) @@ -2849,7 +2907,6 @@ mime_file_written (GObject *source_object, } write_avatar_data_free (avatar_data); - g_free (path); } static void @@ -2899,6 +2956,15 @@ contact_avatar_retrieved (TpConnection *connection, gchar *mime_filename; WriteAvatarData *avatar_data; + DEBUG ("token '%s', %u bytes, MIME type '%s'", + token, avatar->len, mime_type); + + if (self == NULL) + DEBUG ("handle #%u is not associated with any TpContact", handle); + else + DEBUG ("used by contact #%u '%s'", handle, + tp_contact_get_identifier (self)); + if (self != NULL) { /* Update the avatar token if a newer one is given @@ -2908,7 +2974,10 @@ contact_avatar_retrieved (TpConnection *connection, if (!build_avatar_filename (connection, token, TRUE, &filename, &mime_filename)) - return; + { + DEBUG ("failed to set up cache"); + return; + } /* Save avatar in cache, even if the contact is unknown, to avoid as much as * possible future avatar requests */ @@ -3822,6 +3891,7 @@ static gboolean tp_contact_set_attributes (TpContact *contact, GHashTable *asv, ContactFeatureFlags wanted, + ContactFeatureFlags getting, GError **error) { TpConnection *connection = tp_contact_get_connection (contact); @@ -3841,6 +3911,23 @@ tp_contact_set_attributes (TpContact *contact, return FALSE; } + DEBUG ("#%u: \"%s\"", contact->priv->handle, s); + + { + GHashTableIter iter; + gpointer k, v; + + g_hash_table_iter_init (&iter, asv); + + while (g_hash_table_iter_next (&iter, &k, &v)) + { + gchar *str = g_strdup_value_contents (v); + + DEBUG ("- %s => %s", (const gchar *) k, str); + g_free (str); + } + } + if (contact->priv->identifier == NULL) { contact->priv->identifier = g_strdup (s); @@ -3864,9 +3951,12 @@ tp_contact_set_attributes (TpContact *contact, if (s == NULL) { - WARNING ("%s supposedly implements Contacts and Aliasing, but " - "omitted " TP_TOKEN_CONNECTION_INTERFACE_ALIASING_ALIAS, - tp_proxy_get_object_path (connection)); + if (getting & CONTACT_FEATURE_FLAG_ALIAS) + { + WARNING ("%s supposedly implements Contacts and Aliasing, but " + "omitted " TP_TOKEN_CONNECTION_INTERFACE_ALIASING_ALIAS, + tp_proxy_get_object_path (connection)); + } } else { @@ -3900,13 +3990,20 @@ tp_contact_set_attributes (TpContact *contact, TP_STRUCT_TYPE_SIMPLE_PRESENCE); if (boxed == NULL) - WARNING ("%s supposedly implements Contacts and SimplePresence, " - "but omitted the mandatory " - TP_TOKEN_CONNECTION_INTERFACE_SIMPLE_PRESENCE_PRESENCE - " attribute", - tp_proxy_get_object_path (connection)); + { + if (getting & CONTACT_FEATURE_FLAG_PRESENCE) + { + WARNING ("%s supposedly implements Contacts and SimplePresence, " + "but omitted the mandatory " + TP_TOKEN_CONNECTION_INTERFACE_SIMPLE_PRESENCE_PRESENCE + " attribute", + tp_proxy_get_object_path (connection)); + } + } else - contact_maybe_set_simple_presence (contact, boxed); + { + contact_maybe_set_simple_presence (contact, boxed); + } } /* Location */ @@ -4009,7 +4106,8 @@ _tp_contact_set_attributes (TpContact *contact, if (!get_feature_flags (n_features, features, &feature_flags)) return FALSE; - return tp_contact_set_attributes (contact, asv, feature_flags, error); + return tp_contact_set_attributes (contact, asv, feature_flags, + 0 /* can't know what we expected to get */, error); } static void @@ -4022,6 +4120,9 @@ contacts_got_attributes (TpConnection *connection, ContactsContext *c = user_data; guint i; + DEBUG ("%p: reply from GetContactAttributes: %s", + c, (error == NULL ? "OK" : error->message)); + if (error != NULL) { contacts_context_fail (c, error); @@ -4072,7 +4173,7 @@ contacts_got_attributes (TpConnection *connection, else { /* set up the contact with its attributes */ - tp_contact_set_attributes (contact, asv, c->wanted, &e); + tp_contact_set_attributes (contact, asv, c->wanted, c->getting, &e); } if (e != NULL) @@ -4088,7 +4189,8 @@ contacts_got_attributes (TpConnection *connection, static const gchar ** contacts_bind_to_signals (TpConnection *connection, - ContactFeatureFlags wanted) + ContactFeatureFlags wanted, + ContactFeatureFlags *getting) { GArray *contact_attribute_interfaces = connection->priv->contact_attribute_interfaces; @@ -4096,6 +4198,9 @@ contacts_bind_to_signals (TpConnection *connection, guint i; guint len = 0; + if (getting != NULL) + *getting = 0; + if (contact_attribute_interfaces != NULL) len = contact_attribute_interfaces->len; @@ -4115,6 +4220,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_ALIASING); contacts_bind_to_aliases_changed (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_ALIAS; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS) @@ -4124,6 +4232,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_AVATARS); contacts_bind_to_avatar_updated (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_AVATAR_TOKEN; } if ((wanted & CONTACT_FEATURE_FLAG_AVATAR_DATA) != 0) @@ -4138,6 +4249,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE); contacts_bind_to_presences_changed (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_PRESENCE; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_LOCATION) @@ -4147,6 +4261,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_LOCATION); contacts_bind_to_location_updated (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_LOCATION; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_CAPABILITIES) @@ -4156,6 +4273,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES); contacts_bind_to_capabilities_updated (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_CAPABILITIES; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_INFO) @@ -4165,6 +4285,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO); contacts_bind_to_contact_info_changed (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_CONTACT_INFO; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CLIENT_TYPES) @@ -4174,6 +4297,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES); contacts_bind_to_client_types_updated (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_CLIENT_TYPES; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_LIST) @@ -4183,6 +4309,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST); contacts_bind_to_contacts_changed (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_STATES; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_GROUPS) @@ -4192,6 +4321,9 @@ contacts_bind_to_signals (TpConnection *connection, g_ptr_array_add (array, TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS); contacts_bind_to_contact_groups_changed (connection); + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_CONTACT_GROUPS; } } else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING) @@ -4212,6 +4344,9 @@ contacts_bind_to_signals (TpConnection *connection, { tp_proxy_prepare_async (connection, features, NULL, NULL); } + + if (getting != NULL) + *getting |= CONTACT_FEATURE_FLAG_CONTACT_BLOCKING; } } } @@ -4233,13 +4368,14 @@ _tp_contacts_bind_to_signals (TpConnection *connection, if (!get_feature_flags (n_features, features, &feature_flags)) return NULL; - return contacts_bind_to_signals (connection, feature_flags); + return contacts_bind_to_signals (connection, feature_flags, NULL); } static void contacts_get_attributes (ContactsContext *context) { const gchar **supported_interfaces; + guint i; /* tp_connection_get_contact_attributes insists that you have at least one * handle; skip it if we don't (can only happen if we started from IDs) */ @@ -4250,7 +4386,7 @@ contacts_get_attributes (ContactsContext *context) } supported_interfaces = contacts_bind_to_signals (context->connection, - context->wanted); + context->wanted, &context->getting); if (supported_interfaces[0] == NULL && !(context->signature == CB_BY_HANDLE && context->contacts->len == 0) && @@ -4267,6 +4403,11 @@ contacts_get_attributes (ContactsContext *context) /* The Hold parameter is only true if we started from handles, and we don't * already have all the contacts we need. */ context->refcount++; + DEBUG ("calling GetContactAttributes"); + + for (i = 0; supported_interfaces[i] != NULL; i++) + DEBUG ("- %s", supported_interfaces[i]); + tp_cli_connection_interface_contacts_call_get_contact_attributes ( context->connection, -1, context->handles, supported_interfaces, (context->signature == CB_BY_HANDLE && context->contacts->len == 0), @@ -4458,6 +4599,7 @@ tp_connection_get_contacts_by_handle (TpConnection *self, } /* if we haven't already returned, we're on the slow path */ + DEBUG ("slow path"); /* Before we return anything we'll want to inspect the handles */ g_queue_push_head (&context->todo, contacts_inspect); |