[folks] telepathy: Make alias changes truly asynchronous and report errors properly



commit 197cda29d89b59cfdaafd8eda6754f82d93feb05
Author: Philip Withnall <philip tecnocode co uk>
Date:   Mon Mar 26 14:56:21 2012 +0100

    telepathy: Make alias changes truly asynchronous and report errors properly
    
    Take advantage of AliasDetails.change_alias() being async, and wait for the
    underlying Telepathy operation to complete before returning from it. This
    allows us to propagate errors properly, rather than just printing them as
    warnings on the terminal.
    
    This also includes changes to not notify of changes to Tpf.Persona.alias
    until Telepathy has notified us of the change. This should prevent aliases
    changing in the UI if the underlying operation has actually failed.
    
    Helps: https://bugzilla.gnome.org/show_bug.cgi?id=671662

 backends/telepathy/lib/tp-lowlevel.c          |   65 ++++++++++++++++++++++---
 backends/telepathy/lib/tp-lowlevel.h          |   11 ++++-
 backends/telepathy/lib/tpf-persona-store.vala |   19 +++++--
 backends/telepathy/lib/tpf-persona.vala       |    3 +-
 4 files changed, 81 insertions(+), 17 deletions(-)
---
diff --git a/backends/telepathy/lib/tp-lowlevel.c b/backends/telepathy/lib/tp-lowlevel.c
index c89c20e..aef97e1 100644
--- a/backends/telepathy/lib/tp-lowlevel.c
+++ b/backends/telepathy/lib/tp-lowlevel.c
@@ -212,26 +212,75 @@ set_contact_alias_cb (TpConnection *conn,
     gpointer user_data,
     GObject *weak_object)
 {
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
   if (error != NULL)
     {
-      /* Translators: the parameter is an error message. */
-      g_message (_("Failed to change contact's alias: %s"), error->message);
-      return;
+      g_simple_async_result_set_from_error (simple, error);
     }
+
+  g_simple_async_result_complete (simple);
 }
 
+/**
+ * folks_tp_lowlevel_connection_set_contact_alias_async:
+ * @conn: the connection to use
+ * @handle: handle of the contact whose alias is to be changed
+ * @alias: new human-readable alias for the contact
+ * @callback: function to call on completion
+ * @user_data: user data to pass to @callback
+ *
+ * Change the alias of the contact identified by @handle to @alias.
+ */
 void
-folks_tp_lowlevel_connection_set_contact_alias (
+folks_tp_lowlevel_connection_set_contact_alias_async (
     TpConnection *conn,
     guint handle,
-    const gchar *alias)
+    const gchar *alias,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
 {
-  GHashTable *ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
-      g_free);
+  GSimpleAsyncResult *result;
+  GHashTable *ht;
+
+  ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
   g_hash_table_insert (ht, GUINT_TO_POINTER (handle), g_strdup (alias));
 
+  result = g_simple_async_result_new (G_OBJECT (conn), callback, user_data,
+      folks_tp_lowlevel_connection_set_contact_alias_finish);
+
   tp_cli_connection_interface_aliasing_call_set_aliases (conn, -1,
-      ht, set_contact_alias_cb, NULL, NULL, NULL);
+      ht, set_contact_alias_cb, g_object_ref (result), g_object_unref,
+      G_OBJECT (conn));
 
+  g_object_unref (result);
   g_hash_table_destroy (ht);
 }
+
+/**
+ * folks_tp_lowlevel_connection_set_contact_alias_finish:
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finish an asynchronous call to
+ * folks_tp_lowlevel_connection-set_contact_alias_async().
+ */
+void
+folks_tp_lowlevel_connection_set_contact_alias_finish (
+    GAsyncResult *result,
+    GError **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+  TpConnection *conn;
+
+  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
+
+  conn = TP_CONNECTION (g_async_result_get_source_object (result));
+  g_return_if_fail (TP_IS_CONNECTION (conn));
+
+  g_return_if_fail (g_simple_async_result_is_valid (result,
+      G_OBJECT (conn),
+      folks_tp_lowlevel_connection_set_contact_alias_finish));
+
+  g_simple_async_result_propagate_error (simple, error);
+}
diff --git a/backends/telepathy/lib/tp-lowlevel.h b/backends/telepathy/lib/tp-lowlevel.h
index eff4875..e2b4e90 100644
--- a/backends/telepathy/lib/tp-lowlevel.h
+++ b/backends/telepathy/lib/tp-lowlevel.h
@@ -29,10 +29,17 @@
 G_BEGIN_DECLS
 
 void
-folks_tp_lowlevel_connection_set_contact_alias (
+folks_tp_lowlevel_connection_set_contact_alias_async (
     TpConnection *conn,
     guint handle,
-    const gchar *alias);
+    const gchar *alias,
+    GAsyncReadyCallback callback,
+    gpointer user_data);
+
+void
+folks_tp_lowlevel_connection_set_contact_alias_finish (
+    GAsyncResult *result,
+    GError **error);
 
 void
 folks_tp_lowlevel_connection_get_alias_flags_async (
diff --git a/backends/telepathy/lib/tpf-persona-store.vala b/backends/telepathy/lib/tpf-persona-store.vala
index 34fa873..1b96b0b 100644
--- a/backends/telepathy/lib/tpf-persona-store.vala
+++ b/backends/telepathy/lib/tpf-persona-store.vala
@@ -1225,6 +1225,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
     }
 
   internal async void change_alias (Tpf.Persona persona, string alias)
+      throws PropertyError
     {
       /* Deal with badly-behaved callers */
       if (alias == null)
@@ -1239,11 +1240,19 @@ public class Tpf.PersonaStore : Folks.PersonaStore
           return;
         }
 
-      debug ("Changing alias of persona %s to '%s'.",
-          persona.contact.get_identifier (), alias);
-
-      FolksTpLowlevel.connection_set_contact_alias (this._conn,
-          (Handle) persona.contact.handle, alias);
+      try
+        {
+          debug ("Changing alias of persona %s to '%s'.",
+              persona.contact.get_identifier (), alias);
+          yield FolksTpLowlevel.connection_set_contact_alias_async (this._conn,
+              (Handle) persona.contact.handle, alias);
+        }
+      catch (GLib.Error e1)
+        {
+          throw new PropertyError.UNKNOWN_ERROR (
+              /* Translators: the parameter is an error message. */
+              _("Failed to change contact's alias: %s"), e1.message);
+        }
     }
 
   internal async void change_user_birthday (Tpf.Persona persona,
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index a3675ee..8f2ac4c 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -303,8 +303,7 @@ public class Tpf.Persona : Folks.Persona,
           yield ((Tpf.PersonaStore) this.store).change_alias (this, alias);
         }
 
-      this._alias = alias;
-      this.notify_property ("alias");
+      /* The change will be notified when we receive changes from the store. */
     }
 
   private bool _is_favourite = false;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]