aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--libempathy/empathy-avatar.c21
-rw-r--r--libempathy/empathy-contact-factory.c97
3 files changed, 64 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index efb055d46..a6365bc2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2007-09-27 Xavier Claessens <xclaesse@gmail.com>
+ * libempathy/empathy-avatar.c: Fix leak when loading avatar from cache.
+ * libempathy/empathy-contact-factory.c: Do not request avatar for
+ unknown tokens, wait for AvatarUpdate signal.
+
+2007-09-27 Xavier Claessens <xclaesse@gmail.com>
+
* libempathy-gtk/empathy-profile-chooser.c: Set the sort function before
begin to sort otherwise we get warnings.
diff --git a/libempathy/empathy-avatar.c b/libempathy/empathy-avatar.c
index e08dd28c4..fe4e613c6 100644
--- a/libempathy/empathy-avatar.c
+++ b/libempathy/empathy-avatar.c
@@ -67,18 +67,18 @@ avatar_get_filename (const gchar *token)
}
static EmpathyAvatar *
-avatar_new (const guchar *data,
- const gsize len,
- const gchar *format,
- const gchar *token)
+avatar_new (guchar *data,
+ gsize len,
+ gchar *format,
+ gchar *token)
{
EmpathyAvatar *avatar;
avatar = g_slice_new0 (EmpathyAvatar);
- avatar->data = g_memdup (data, len);
+ avatar->data = data;
avatar->len = len;
- avatar->format = g_strdup (format);
- avatar->token = g_strdup (token);
+ avatar->format = format;
+ avatar->token = token;
avatar->refcount = 1;
return avatar;
@@ -99,7 +99,10 @@ empathy_avatar_new (const guchar *data,
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (!G_STR_EMPTY (token), NULL);
- avatar = avatar_new (data, len, format, token);
+ avatar = avatar_new (g_memdup (data, len),
+ len,
+ g_strdup (format),
+ g_strdup (token));
/* Save to cache if not yet in it */
filename = avatar_get_filename (token);
@@ -142,7 +145,7 @@ empathy_avatar_new_from_cache (const gchar *token)
if (data) {
empathy_debug (DEBUG_DOMAIN, "Avatar loaded from %s", filename);
- avatar = avatar_new (data, len, NULL, token);
+ avatar = avatar_new (data, len, NULL, g_strdup (token));
}
g_free (filename);
diff --git a/libempathy/empathy-contact-factory.c b/libempathy/empathy-contact-factory.c
index b468ccec2..d6411ed54 100644
--- a/libempathy/empathy-contact-factory.c
+++ b/libempathy/empathy-contact-factory.c
@@ -335,6 +335,10 @@ contact_factory_avatar_retrieved_cb (DBusGProxy *proxy,
return;
}
+ empathy_debug (DEBUG_DOMAIN, "Avatar retrieved for contact %s (%d)",
+ empathy_contact_get_id (contact),
+ handle);
+
avatar = empathy_avatar_new (avatar_data->data,
avatar_data->len,
mime_type,
@@ -378,18 +382,18 @@ contact_factory_avatar_maybe_update (ContactFactoryAccountData *account_data,
return TRUE;
}
- /* Check if the avatar changed */
- avatar = empathy_contact_get_avatar (contact);
- if (avatar && !empathy_strdiff (avatar->token, token)) {
- return TRUE;
- }
-
/* Check if we have an avatar */
if (G_STR_EMPTY (token)) {
empathy_contact_set_avatar (contact, NULL);
return TRUE;
}
+ /* Check if the avatar changed */
+ avatar = empathy_contact_get_avatar (contact);
+ if (avatar && !empathy_strdiff (avatar->token, token)) {
+ return TRUE;
+ }
+
/* The avatar changed, search the new one in the cache */
avatar = empathy_avatar_new_from_cache (token);
if (avatar) {
@@ -399,17 +403,33 @@ contact_factory_avatar_maybe_update (ContactFactoryAccountData *account_data,
return TRUE;
}
+ /* Avatar is not up-to-date, we have to request it. */
return FALSE;
}
static void
+contact_factory_avatar_tokens_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TokensData *data = user_data;
+ const gchar *token = value;
+ guint handle = GPOINTER_TO_UINT (key);
+
+ if (!contact_factory_avatar_maybe_update (data->account_data,
+ handle, token)) {
+ g_array_append_val (data->handles, handle);
+ }
+}
+
+static void
contact_factory_get_known_avatar_tokens_cb (DBusGProxy *proxy,
GHashTable *tokens,
GError *error,
gpointer user_data)
{
- TokensData *data = user_data;
- gint i;
+ ContactFactoryAccountData *account_data = user_data;
+ TokensData data;
if (error) {
empathy_debug (DEBUG_DOMAIN,
@@ -418,48 +438,28 @@ contact_factory_get_known_avatar_tokens_cb (DBusGProxy *proxy,
goto OUT;
}
- /* Remove handles for which we have an avatar */
- for (i = 0; i < data->handles->len; i++) {
- const gchar *token;
- guint handle;
-
- handle = g_array_index (data->handles, guint, i);
- token = g_hash_table_lookup (tokens, GUINT_TO_POINTER (handle));
-
- /* If we have no token it means CM does not know what's the
- * avatar for that contact, we need to request it. */
- if (!token) {
- continue;
- }
-
- /* If avatar is not updated it means we don't have it in
- * the cache so we need to request it */
- if (!contact_factory_avatar_maybe_update (data->account_data,
- handle, token)) {
- continue;
- }
+ data.account_data = account_data;
+ data.handles = g_array_new (FALSE, FALSE, sizeof (guint));
+ g_hash_table_foreach (tokens,
+ contact_factory_avatar_tokens_foreach,
+ &data);
- /* We don't need to request the avatar for this handle,
- * remove it from the handles array. We need to check the handle
- * that takes the place of the current index we are removing,
- * so i-- is needed. */
- g_array_remove_index_fast (data->handles, i);
- i--;
- }
+ empathy_debug (DEBUG_DOMAIN, "Got %d tokens, need to request %d avatars",
+ g_hash_table_size (tokens),
+ data.handles->len);
/* Request needed avatars */
- if (data->handles->len > 0) {
- data->account_data->nb_pending_calls++;
- tp_conn_iface_avatars_request_avatars_async (data->account_data->avatars_iface,
- data->handles,
+ if (data.handles->len > 0) {
+ account_data->nb_pending_calls++;
+ tp_conn_iface_avatars_request_avatars_async (account_data->avatars_iface,
+ data.handles,
contact_factory_request_avatars_cb,
- data->account_data);
+ account_data);
}
+ g_array_free (data.handles, TRUE);
OUT:
- contact_factory_account_data_return_call (data->account_data);
- g_array_free (data->handles, TRUE);
- g_slice_free (TokensData, data);
+ contact_factory_account_data_return_call (account_data);
}
static void
@@ -476,6 +476,8 @@ contact_factory_avatar_updated_cb (DBusGProxy *proxy,
return;
}
+ empathy_debug (DEBUG_DOMAIN, "Need to request one avatar");
+
handles = g_array_new (FALSE, FALSE, sizeof (guint));
g_array_append_val (handles, handle);
@@ -620,18 +622,11 @@ contact_factory_request_everything (ContactFactoryAccountData *account_data,
}
if (account_data->avatars_iface) {
- TokensData *data;
-
account_data->nb_pending_calls++;
- data = g_slice_new (TokensData);
- data->account_data = account_data;
- data->handles = g_array_new (FALSE, FALSE, sizeof (guint));
- g_array_append_vals (data->handles, handles->data, handles->len);
-
tp_conn_iface_avatars_get_known_avatar_tokens_async (account_data->avatars_iface,
handles,
contact_factory_get_known_avatar_tokens_cb,
- data);
+ account_data);
}
if (account_data->capabilities_iface) {