diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c index c505bc8..66b4c45 100644 --- a/telepathy-glib/contact.c +++ b/telepathy-glib/contact.c @@ -2755,6 +2755,82 @@ out: static void contact_set_avatar_token (TpContact *self, const gchar *new_token, gboolean request); +typedef struct{ + TpContact *self; + gchar *str; + GArray *data; +} write_data; + + +static void mime_file_written (GObject *file, + GAsyncResult *res, + gpointer user_data){ + GError* error = NULL; + write_data* mime_data = (write_data *) user_data; + g_file_replace_contents_finish ((GFile *) file, res, NULL, &error); + if (error != NULL) + { + DEBUG ("Failed to store MIME type in cache (%s): %s", + g_file_get_path ((GFile *) file), + error ? error->message : "No error message"); + g_free (mime_data->str); + g_slice_free (write_data, mime_data); + g_clear_error (&error); + return; + } + + DEBUG ("Contact avatar MIME type stored in cache: %s", + g_file_get_path ((GFile *) file)); + if (mime_data->self == NULL) + { + g_free (mime_data->str); + g_slice_free (write_data, mime_data); + return; + } + g_free (mime_data->self->priv->avatar_mime_type); + mime_data->self->priv->avatar_mime_type = g_strdup (mime_data->str); + g_object_notify ((GObject *) mime_data->self, "avatar-mime-type"); + g_free (mime_data->str); + g_object_unref ((GFile *) file); + g_slice_free (write_data, mime_data); +} + +static void avatar_file_written (GObject *file, + GAsyncResult *res, + gpointer user_data){ + GError *error = NULL; + write_data *avatar_data = (write_data *) user_data; + g_array_unref (avatar_data->data); + g_file_replace_contents_finish ((GFile *) file, res, NULL, &error); + if (error != NULL) + { + DEBUG ("Failed to store avatar in cache (%s): %s", + g_file_get_path ((GFile *) file), + error ? error->message : "No error message"); + g_free (avatar_data->str); + g_slice_free (write_data, avatar_data); + g_clear_error (&error); + return; + } + + DEBUG ("Contact avatar stored in cache: %s", + g_file_get_path ((GFile *) file)); + if (avatar_data->self == NULL) + { + g_free (avatar_data->str); + g_slice_free (write_data, avatar_data); + return; + } + /* Update the avatar token if a newer one is given */ + contact_set_avatar_token (avatar_data->self, avatar_data->str, FALSE); + + tp_clear_object (&avatar_data->self->priv->avatar_file); + avatar_data->self->priv->avatar_file = (GFile *) file; + g_object_notify ((GObject *) avatar_data->self, "avatar-file"); + g_free (avatar_data->str); + g_slice_free (write_data, avatar_data); +} + static void contact_avatar_retrieved (TpConnection *connection, guint handle, @@ -2767,7 +2843,10 @@ contact_avatar_retrieved (TpConnection *connection, TpContact *self = _tp_connection_lookup_contact (connection, handle); gchar *filename; gchar *mime_filename; - GError *error = NULL; + GFile *avatar_file; + GFile *mime_file; + write_data *avatar_data = g_slice_new (write_data); + write_data *mime_data = g_slice_new (write_data); if (!build_avatar_filename (connection, token, TRUE, &filename, &mime_filename)) @@ -2775,40 +2854,24 @@ contact_avatar_retrieved (TpConnection *connection, /* Save avatar in cache, even if the contact is unknown, to avoid as much as * possible future avatar requests */ - if (!g_file_set_contents (filename, avatar->data, avatar->len, &error)) - { - DEBUG ("Failed to store avatar in cache (%s): %s", filename, - error ? error->message : "No error message"); - g_clear_error (&error); - goto out; - } - if (!g_file_set_contents (mime_filename, mime_type, -1, &error)) - { - DEBUG ("Failed to store MIME type in cache (%s): %s", mime_filename, - error ? error->message : "No error message"); - g_clear_error (&error); - goto out; - } - - DEBUG ("Contact#%u avatar stored in cache: %s, %s", handle, filename, - mime_type); + avatar_file = g_file_new_for_path (filename); + mime_file = g_file_new_for_path (mime_filename); - if (self == NULL) - goto out; - /* Update the avatar token if a newer one is given */ - contact_set_avatar_token (self, token, FALSE); + avatar_data->data = g_array_new (FALSE, FALSE, sizeof (gchar)); + g_array_append_vals (avatar_data->data, avatar->data, avatar->len); + avatar_data->self = self; + avatar_data->str = g_strdup (token); - tp_clear_object (&self->priv->avatar_file); - self->priv->avatar_file = g_file_new_for_path (filename); + mime_data->self = self; + mime_data->str = g_strdup (mime_type); - g_free (self->priv->avatar_mime_type); - self->priv->avatar_mime_type = g_strdup (mime_type); + g_file_replace_contents_async (avatar_file, avatar_data->data->data, avatar_data->data->len, + NULL, FALSE, G_FILE_CREATE_NONE, NULL, &avatar_file_written, avatar_data); - g_object_notify ((GObject *) self, "avatar-file"); - g_object_notify ((GObject *) self, "avatar-mime-type"); + g_file_replace_contents_async (mime_file, mime_data->str, strlen (mime_data->str), + NULL, FALSE, G_FILE_CREATE_NONE, NULL, &mime_file_written, mime_data); -out: g_free (filename); g_free (mime_filename); } diff --git a/tests/dbus/contacts.c b/tests/dbus/contacts.c index 9c070a7..7624492 100644 --- a/tests/dbus/contacts.c +++ b/tests/dbus/contacts.c @@ -585,6 +585,9 @@ create_contact_with_fake_avatar (TpTestsContactsConnection *service_conn, g_main_loop_run (result.loop); } + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpstr (tp_contact_get_avatar_mime_type (contact), ==, avatar_mime_type);