]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-contact-factory.c
Move avatar cache to ~/.cache and don't mix avatar from different contacts, tokens...
[empathy.git] / libempathy / empathy-tp-contact-factory.c
index 678e53b365dbb3dbb455664dcdac2f4072d209e7..fe68ed0a7d50d188f4ad4eb8442a097f5ee40649 100644 (file)
 
 #include "empathy-tp-contact-factory.h"
 #include "empathy-utils.h"
-#include "empathy-debug.h"
-
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-                      EMPATHY_TYPE_TP_CONTACT_FACTORY, EmpathyTpContactFactoryPriv))
 
-#define DEBUG_DOMAIN "TpContactFactory"
+#define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CONTACT
+#include "empathy-debug.h"
 
-struct _EmpathyTpContactFactoryPriv {
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpContactFactory)
+typedef struct {
        MissionControl *mc;
        McAccount      *account;
        TpConnection   *connection;
@@ -44,10 +42,8 @@ struct _EmpathyTpContactFactoryPriv {
 
        GList          *contacts;
        EmpathyContact *user;
-};
-
-static void empathy_tp_contact_factory_class_init (EmpathyTpContactFactoryClass *klass);
-static void empathy_tp_contact_factory_init       (EmpathyTpContactFactory      *factory);
+       gpointer        token;
+} EmpathyTpContactFactoryPriv;
 
 G_DEFINE_TYPE (EmpathyTpContactFactory, empathy_tp_contact_factory, G_TYPE_OBJECT);
 
@@ -95,8 +91,7 @@ tp_contact_factory_weak_notify (gpointer data,
 {
        EmpathyTpContactFactoryPriv *priv = GET_PRIV (data);
 
-       empathy_debug (DEBUG_DOMAIN, "Remove finalized contact %p",
-                      where_the_object_was);
+       DEBUG ("Remove finalized contact %p", where_the_object_was);
 
        priv->contacts = g_list_remove (priv->contacts, where_the_object_was);
 }
@@ -107,14 +102,18 @@ tp_contact_factory_presences_table_foreach (const gchar    *state_str,
                                            EmpathyContact *contact)
 {
        const GValue *message;
+       const gchar  *message_str = NULL;
 
        empathy_contact_set_presence (contact,
                                      empathy_presence_from_str (state_str));
        
        message = g_hash_table_lookup (presences_table, "message");
-       if (message != NULL) {
-               empathy_contact_set_presence_message (contact,
-                                                     g_value_get_string (message));
+       if (message) {
+               message_str = g_value_get_string (message);
+       }
+
+       if (!G_STR_EMPTY (message_str)) {
+               empathy_contact_set_presence_message (contact, message_str);
        } else {
                empathy_contact_set_presence_message (contact, NULL);
        }
@@ -139,11 +138,11 @@ tp_contact_factory_parse_presence_foreach (guint                    handle,
                              (GHFunc) tp_contact_factory_presences_table_foreach,
                              contact);
 
-       empathy_debug (DEBUG_DOMAIN, "Changing presence for contact %s (%d) to %s (%d)",
-                     empathy_contact_get_id (contact),
-                     handle,
-                     empathy_contact_get_presence_message (contact),
-                     empathy_contact_get_presence (contact));
+       DEBUG ("Changing presence for contact %s (%d) to '%s' (%d)",
+               empathy_contact_get_id (contact),
+               handle,
+               empathy_contact_get_presence_message (contact),
+               empathy_contact_get_presence (contact));
 }
 
 static void
@@ -154,8 +153,7 @@ tp_contact_factory_get_presence_cb (TpConnection *connection,
                                    GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error getting presence: %s",
-                             error->message);
+               DEBUG ("Error getting presence: %s", error->message);
                if (error->domain == TP_DBUS_ERRORS &&
                    error->code == TP_DBUS_ERROR_NO_INTERFACE) {
                        guint *handles = user_data;
@@ -203,8 +201,7 @@ tp_contact_factory_set_aliases_cb (TpConnection *connection,
                                   GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error setting alias: %s",
-                              error->message);
+               DEBUG ("Error setting alias: %s", error->message);
        }
 }
 
@@ -220,8 +217,23 @@ tp_contact_factory_request_aliases_cb (TpConnection *connection,
        const gchar **name;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
-                             error->message);
+               DEBUG ("Error requesting aliases: %s", error->message);
+
+               /* If we failed to get alias set it to NULL, like that if
+                * someone is waiting for the name to be ready it won't wait
+                * infinitely */
+               while (*handles != 0) {
+                       EmpathyContact *contact;
+
+                       contact = tp_contact_factory_find_by_handle (
+                               (EmpathyTpContactFactory*) tp_factory,
+                               *handles);
+                       if (contact) {
+                               empathy_contact_set_name (contact, NULL);
+                       }
+
+                       handles++;
+               }
                return;
        }
 
@@ -234,10 +246,10 @@ tp_contact_factory_request_aliases_cb (TpConnection *connection,
                        continue;
                }
 
-               empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (request cb)",
-                              empathy_contact_get_id (contact),
-                              empathy_contact_get_handle (contact),
-                              *name);
+               DEBUG ("Renaming contact %s (%d) to %s (request cb)",
+                       empathy_contact_get_id (contact),
+                       empathy_contact_get_handle (contact),
+                       *name);
 
                empathy_contact_set_name (contact, *name);
 
@@ -270,9 +282,9 @@ tp_contact_factory_aliases_changed_cb (TpConnection    *connection,
                        continue;
                }
 
-               empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (changed cb)",
-                              empathy_contact_get_id (contact),
-                              handle, alias);
+               DEBUG ("Renaming contact %s (%d) to %s (changed cb)",
+                       empathy_contact_get_id (contact),
+                       handle, alias);
 
                empathy_contact_set_name (contact, alias);
        }
@@ -286,8 +298,7 @@ tp_contact_factory_set_avatar_cb (TpConnection *connection,
                                  GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error setting avatar: %s",
-                              error->message);
+               DEBUG ("Error setting avatar: %s", error->message);
        }
 }
 
@@ -298,8 +309,7 @@ tp_contact_factory_clear_avatar_cb (TpConnection *connection,
                                    GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error clearing avatar: %s",
-                              error->message);
+               DEBUG ("Error clearing avatar: %s", error->message);
        }
 }
 
@@ -313,7 +323,6 @@ tp_contact_factory_avatar_retrieved_cb (TpConnection *connection,
                                        GObject      *tp_factory)
 {
        EmpathyContact *contact;
-       EmpathyAvatar  *avatar;
 
        contact = tp_contact_factory_find_by_handle (EMPATHY_TP_CONTACT_FACTORY (tp_factory),
                                                     handle);
@@ -321,17 +330,15 @@ tp_contact_factory_avatar_retrieved_cb (TpConnection *connection,
                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,
-                                    token);
+       DEBUG ("Avatar retrieved for contact %s (%d)",
+               empathy_contact_get_id (contact),
+               handle);
 
-       empathy_contact_set_avatar (contact, avatar);
-       empathy_avatar_unref (avatar);
+       empathy_contact_load_avatar_data (contact,
+                                         avatar_data->data,
+                                         avatar_data->len,
+                                         mime_type,
+                                         token);
 }
 
 static void
@@ -341,8 +348,7 @@ tp_contact_factory_request_avatars_cb (TpConnection *connection,
                                       GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error requesting avatars: %s",
-                              error->message);
+               DEBUG ("Error requesting avatars: %s", error->message);
        }
 }
 
@@ -372,11 +378,8 @@ tp_contact_factory_avatar_maybe_update (EmpathyTpContactFactory *tp_factory,
        }
 
        /* The avatar changed, search the new one in the cache */
-       avatar = empathy_avatar_new_from_cache (token);
-       if (avatar) {
+       if (empathy_contact_load_avatar_cache (contact, token)) {
                /* Got from cache, use it */
-               empathy_contact_set_avatar (contact, avatar);
-               empathy_avatar_unref (avatar);
                return TRUE;
        }
 
@@ -414,9 +417,7 @@ tp_contact_factory_get_known_avatar_tokens_cb (TpConnection *connection,
        TokensData data;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN,
-                              "Error getting known avatars tokens: %s",
-                              error->message);
+               DEBUG ("Error getting known avatars tokens: %s", error->message);
                return;
        }
 
@@ -426,9 +427,8 @@ tp_contact_factory_get_known_avatar_tokens_cb (TpConnection *connection,
                              tp_contact_factory_avatar_tokens_foreach,
                              &data);
 
-       empathy_debug (DEBUG_DOMAIN, "Got %d tokens, need to request %d avatars",
-                      g_hash_table_size (tokens),
-                      data.handles->len);
+       DEBUG ("Got %d tokens, need to request %d avatars",
+               g_hash_table_size (tokens), data.handles->len);
 
        /* Request needed avatars */
        if (data.handles->len > 0) {
@@ -458,8 +458,7 @@ tp_contact_factory_avatar_updated_cb (TpConnection *connection,
                return;
        }
 
-       empathy_debug (DEBUG_DOMAIN, "Need to request avatar for token %s",
-                      new_token);
+       DEBUG ("Need to request avatar for token %s", new_token);
 
        handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (handles, handle);
@@ -502,10 +501,10 @@ tp_contact_factory_update_capabilities (EmpathyTpContactFactory *tp_factory,
                }
        }
 
-       empathy_debug (DEBUG_DOMAIN, "Changing capabilities for contact %s (%d) to %d",
-                      empathy_contact_get_id (contact),
-                      empathy_contact_get_handle (contact),
-                      capabilities);
+       DEBUG ("Changing capabilities for contact %s (%d) to %d",
+               empathy_contact_get_id (contact),
+               empathy_contact_get_handle (contact),
+               capabilities);
 
        empathy_contact_set_capabilities (contact, capabilities);
 }
@@ -521,8 +520,7 @@ tp_contact_factory_get_capabilities_cb (TpConnection    *connection,
        guint                    i;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error getting capabilities: %s",
-                              error->message);
+               DEBUG ("Error getting capabilities: %s", error->message);
                /* FIXME Should set the capabilities of the contacts for which this request
                 * originated to NONE */
                return;
@@ -600,7 +598,8 @@ tp_contact_factory_request_everything (EmpathyTpContactFactory *tp_factory,
        /* FIXME: Sometimes the dbus call timesout because CM takes
         * too much time to request all aliases from the server,
         * that's why we increase the timeout here. See fd.o bug #14795 */
-       dup_handles = g_memdup (handles->data, handles->len * sizeof (guint));
+       dup_handles = g_malloc0 ((handles->len + 1) * sizeof (guint));
+       g_memmove (dup_handles, handles->data, handles->len * sizeof (guint));
        tp_cli_connection_interface_aliasing_call_request_aliases (priv->connection,
                                                                   5*60*1000,
                                                                   handles,
@@ -644,8 +643,7 @@ tp_contact_factory_request_handles_cb (TpConnection *connection,
        guint  i = 0;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Failed to request handles: %s",
-                              error->message);
+               DEBUG ("Failed to request handles: %s", error->message);
                return;
        }
 
@@ -674,8 +672,7 @@ tp_contact_factory_inspect_handles_cb (TpConnection  *connection,
        GList        *l;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Failed to inspect handles: %s",
-                              error->message);
+               DEBUG ("Failed to inspect handles: %s", error->message);
                return;
        }
 
@@ -701,7 +698,7 @@ tp_contact_factory_connection_invalidated_cb (EmpathyTpContactFactory *tp_factor
 {
        EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
 
-       empathy_debug (DEBUG_DOMAIN, "Connection invalidated");
+       DEBUG ("Connection invalidated");
 
        g_object_unref (priv->connection);
        priv->connection = NULL;
@@ -730,12 +727,11 @@ tp_contact_factory_got_self_handle_cb (TpConnection *proxy,
        GList                       *id_needed_contacts = NULL;
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Failed to get self handles: %s",
-                              error->message);
+               DEBUG ("Failed to get self handles: %s", error->message);
                return;
        }
 
-       empathy_debug (DEBUG_DOMAIN, "Connection ready");
+       DEBUG ("Connection ready");
 
        empathy_contact_set_handle (priv->user, handle);
        priv->ready = TRUE;
@@ -802,8 +798,6 @@ tp_contact_factory_got_self_handle_cb (TpConnection *proxy,
                                                handle_needed_contacts, tp_contact_factory_list_free,
                                                G_OBJECT (tp_factory));
 
-       tp_contact_factory_request_everything ((EmpathyTpContactFactory*) tp_factory,
-                                              id_needed);
        tp_cli_connection_call_inspect_handles (priv->connection,
                                                -1,
                                                TP_HANDLE_TYPE_CONTACT,
@@ -812,6 +806,9 @@ tp_contact_factory_got_self_handle_cb (TpConnection *proxy,
                                                id_needed_contacts, tp_contact_factory_list_free,
                                                G_OBJECT (tp_factory));
 
+       tp_contact_factory_request_everything ((EmpathyTpContactFactory*) tp_factory,
+                                              id_needed);
+
        g_array_free (handle_needed, TRUE);
        g_array_free (id_needed, TRUE);
 }
@@ -889,9 +886,9 @@ tp_contact_factory_add_contact (EmpathyTpContactFactory *tp_factory,
                           tp_factory);
        priv->contacts = g_list_prepend (priv->contacts, contact);
 
-       empathy_debug (DEBUG_DOMAIN, "Contact added: %s (%d)",
-                      empathy_contact_get_id (contact),
-                      empathy_contact_get_handle (contact));
+       DEBUG ("Contact added: %s (%d)",
+               empathy_contact_get_id (contact),
+               empathy_contact_get_handle (contact));
 }
 
 static void
@@ -901,8 +898,7 @@ tp_contact_factory_hold_handles_cb (TpConnection *connection,
                                    GObject      *tp_factory)
 {
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Failed to hold handles: %s",
-                              error->message);
+               DEBUG ("Failed to hold handles: %s", error->message);
        }
 }
 
@@ -1075,9 +1071,9 @@ empathy_tp_contact_factory_set_alias (EmpathyTpContactFactory *tp_factory,
 
        handle = empathy_contact_get_handle (contact);
 
-       empathy_debug (DEBUG_DOMAIN, "Setting alias for contact %s (%d) to %s",
-                      empathy_contact_get_id (contact),
-                      handle, alias);
+       DEBUG ("Setting alias for contact %s (%d) to %s",
+               empathy_contact_get_id (contact),
+               handle, alias);
 
        new_alias = g_hash_table_new_full (g_direct_hash,
                                           g_direct_equal,
@@ -1115,8 +1111,8 @@ empathy_tp_contact_factory_set_avatar (EmpathyTpContactFactory *tp_factory,
                avatar.data = (gchar*) data;
                avatar.len = size;
 
-               empathy_debug (DEBUG_DOMAIN, "Setting avatar on account %s",
-                              mc_account_get_unique_name (priv->account));
+               DEBUG ("Setting avatar on account %s",
+                       mc_account_get_unique_name (priv->account));
 
                tp_cli_connection_interface_avatars_call_set_avatar (priv->connection,
                                                                     -1,
@@ -1126,8 +1122,8 @@ empathy_tp_contact_factory_set_avatar (EmpathyTpContactFactory *tp_factory,
                                                                     NULL, NULL,
                                                                     G_OBJECT (tp_factory));
        } else {
-               empathy_debug (DEBUG_DOMAIN, "Clearing avatar on account %s",
-                              mc_account_get_unique_name (priv->account));
+               DEBUG ("Clearing avatar on account %s",
+                       mc_account_get_unique_name (priv->account));
 
                tp_cli_connection_interface_avatars_call_clear_avatar (priv->connection,
                                                                       -1,
@@ -1192,14 +1188,10 @@ tp_contact_factory_finalize (GObject *object)
        EmpathyTpContactFactoryPriv *priv = GET_PRIV (object);
        GList                       *l;
 
-       empathy_debug (DEBUG_DOMAIN, "Finalized: %p (%s)",
-                      object,
-                      mc_account_get_normalized_name (priv->account));
+       DEBUG ("Finalized: %p (%s)", object,
+               mc_account_get_normalized_name (priv->account));
 
-       dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
-                                       "AccountStatusChanged",
-                                       G_CALLBACK (tp_contact_factory_status_changed_cb),
-                                       object);
+       empathy_disconnect_account_status_changed (priv->token);
 
        for (l = priv->contacts; l; l = l->next) {
                g_object_weak_unref (G_OBJECT (l->data),
@@ -1274,10 +1266,12 @@ empathy_tp_contact_factory_class_init (EmpathyTpContactFactoryClass *klass)
 static void
 empathy_tp_contact_factory_init (EmpathyTpContactFactory *tp_factory)
 {
-       EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
+       EmpathyTpContactFactoryPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (tp_factory,
+               EMPATHY_TYPE_TP_CONTACT_FACTORY, EmpathyTpContactFactoryPriv);
 
+       tp_factory->priv = priv;
        priv->mc = empathy_mission_control_new ();
-       empathy_connect_to_account_status_changed (priv->mc,
+       priv->token = empathy_connect_to_account_status_changed (priv->mc,
                                                   G_CALLBACK (tp_contact_factory_status_changed_cb),
                                                   tp_factory, NULL);
 }