[Pkg-telepathy-commits] [telepathy-mission-control-6] 80/280: Call IdentifyAccount to get new accounts' names

Simon McVittie smcv at debian.org
Thu Mar 27 20:07:08 UTC 2014


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to branch debian
in repository telepathy-mission-control-6.

commit 76e09aa96406ed8219769c497ba50b9c8ca56e9b
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date:   Tue Oct 15 18:10:00 2013 +0100

    Call IdentifyAccount to get new accounts' names
    
    It's exposed through the plugin API so that exemplary plugins can
    use the same utility functions to decide how to name accounts for
    the ::created signal, if they want to.
    
    Reviewed-by: Guillaume Desmottes <guillaume.desmottes at collabora.co.uk>
    Bug: https://bugs.freedesktop.org/show_bug.cgi?id=34640
---
 configure.ac                                       |   4 +-
 mission-control-plugins/account.c                  |  42 +++++++
 mission-control-plugins/account.h                  |  11 ++
 mission-control-plugins/implementation.h           |  11 ++
 src/mcd-account-manager.c                          | 136 +++++++++++++--------
 src/mcd-storage.c                                  |  78 ++++++++++++
 .../account-manager/create-with-properties.py      |   5 +-
 7 files changed, 234 insertions(+), 53 deletions(-)

diff --git a/configure.ac b/configure.ac
index fc78f6a..99bcf13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -220,7 +220,7 @@ AC_DEFINE([TP_SEAL_ENABLE], [], [Define to hide deprecated struct fields])
 AC_DEFINE([TP_DISABLE_SINGLE_INCLUDE], [], [Avoid individual headers])
 
 PKG_CHECK_MODULES([GLIB],
-	[glib-2.0 >= 2.32, gobject-2.0, gmodule-no-export-2.0, gio-2.0])
+	[glib-2.0 >= 2.36, gobject-2.0, gmodule-no-export-2.0, gio-2.0])
 
 PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0],
   [
@@ -231,7 +231,7 @@ PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0],
   [])
 
 AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_30], [Ignore post 2.30 deprecations])
-AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_32], [Prevent post 2.32 APIs])
+AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_36], [Prevent post 2.36 APIs])
 
 dnl Check for MCE, a Maemo service used to determine when the device is idle.
 PKG_CHECK_MODULES([MCE], mce >= 1.5, [HAVE_MCE=yes], [HAVE_MCE=no])
diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c
index 62318d4..1744ef6 100644
--- a/mission-control-plugins/account.c
+++ b/mission-control-plugins/account.c
@@ -290,6 +290,7 @@ mcp_account_manager_parameter_make_secret (const McpAccountManager *mcpa,
  * Changed in 5.17: instead of a map from string to GValue, the last
  * argument is the result of calling IdentifyAccount on the parameters,
  * which normalizes the account's name in a protocol-dependent way.
+ * Use mcp_account_manager_identify_account_async() to do that.
  *
  * Returns: the newly allocated account name, which should be freed
  * once the caller is done with it.
@@ -308,6 +309,47 @@ mcp_account_manager_get_unique_name (McpAccountManager *mcpa,
   return iface->unique_name (mcpa, manager, protocol, identification);
 }
 
+void
+mcp_account_manager_identify_account_async (McpAccountManager *mcpa,
+    const gchar *manager,
+    const gchar *protocol,
+    GVariant *parameters,
+    GCancellable *cancellable,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
+
+  g_return_if_fail (iface != NULL);
+  g_return_if_fail (iface->identify_account_async != NULL);
+  g_return_if_fail (iface->identify_account_finish != NULL);
+
+  g_return_if_fail (manager != NULL);
+  g_return_if_fail (protocol != NULL);
+  g_return_if_fail (parameters != NULL);
+  g_return_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_VARDICT));
+
+  iface->identify_account_async (mcpa, manager, protocol, parameters,
+      cancellable, callback, user_data);
+}
+
+/**
+ * Returns: (transfer full): a newly allocated string, free with g_free()
+ */
+gchar *
+mcp_account_manager_identify_account_finish (McpAccountManager *mcpa,
+    GAsyncResult *res,
+    GError **error)
+{
+  McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
+
+  g_return_val_if_fail (iface != NULL, NULL);
+  g_return_val_if_fail (iface->identify_account_async != NULL, NULL);
+  g_return_val_if_fail (iface->identify_account_finish != NULL, NULL);
+
+  return iface->identify_account_finish (mcpa, res, error);
+}
+
 /**
  * mcp_account_manager_escape_value_from_keyfile:
  * @mcpa: a #McpAccountManager
diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h
index a476342..4015457 100644
--- a/mission-control-plugins/account.h
+++ b/mission-control-plugins/account.h
@@ -101,6 +101,17 @@ gboolean mcp_account_manager_init_value_for_attribute (
     GValue *value,
     const gchar *attribute);
 
+void mcp_account_manager_identify_account_async (McpAccountManager *mcpa,
+    const gchar *manager,
+    const gchar *protocol,
+    GVariant *parameters,
+    GCancellable *cancellable,
+    GAsyncReadyCallback callback,
+    gpointer user_data);
+gchar *mcp_account_manager_identify_account_finish (McpAccountManager *mcpa,
+    GAsyncResult *res,
+    GError **error);
+
 G_END_DECLS
 
 #endif
diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h
index 29d2937..2ad2893 100644
--- a/mission-control-plugins/implementation.h
+++ b/mission-control-plugins/implementation.h
@@ -128,6 +128,17 @@ struct _McpAccountManagerIface {
       const gchar *parameter,
       GVariant *value,
       McpParameterFlags flags);
+
+  void (* identify_account_async) (McpAccountManager *mcpa,
+      const gchar *manager,
+      const gchar *protocol,
+      GVariant *parameters,
+      GCancellable *cancellable,
+      GAsyncReadyCallback callback,
+      gpointer user_data);
+  gchar * (* identify_account_finish) (McpAccountManager *mcpa,
+      GAsyncResult *res,
+      GError **error);
 };
 
 G_END_DECLS
diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c
index 0a19de1..029c0c2 100644
--- a/src/mcd-account-manager.c
+++ b/src/mcd-account-manager.c
@@ -105,6 +105,9 @@ typedef struct
 typedef struct
 {
     McdAccountManager *account_manager;
+    gchar *cm_name;
+    gchar *protocol_name;
+    gchar *display_name;
     GHashTable *parameters;
     GHashTable *properties;
     McdGetAccountCb callback;
@@ -650,6 +653,10 @@ mcd_create_account_data_free (McdCreateAccountData *cad)
     if (G_UNLIKELY (cad->error))
         g_error_free (cad->error);
 
+    g_free (cad->cm_name);
+    g_free (cad->protocol_name);
+    g_free (cad->display_name);
+
     g_slice_free (McdCreateAccountData, cad);
 }
 
@@ -781,91 +788,120 @@ complete_account_creation (McdAccount *account,
                                  cad);
 }
 
-void
-_mcd_account_manager_create_account (McdAccountManager *account_manager,
-                                     const gchar *manager,
-                                     const gchar *protocol,
-                                     const gchar *display_name,
-                                     GHashTable *params,
-                                     GHashTable *properties,
-                                     McdGetAccountCb callback,
-                                     gpointer user_data,
-                                     GDestroyNotify destroy)
+static void
+identify_account_cb (GObject *source_object,
+                     GAsyncResult *result,
+                     gpointer user_data)
 {
-    McdAccountManagerPrivate *priv = account_manager->priv;
-    McdStorage *storage = priv->storage;
-    McdCreateAccountData *cad;
-    McdAccount *account;
-    gchar *unique_name = NULL;
+    McdStorage *storage = MCD_STORAGE (source_object);
+    McdCreateAccountData *cad = user_data;
     const gchar *provider;
-    GError *e = NULL;
-    const gchar *id;
+    gchar *id;
+    gchar *unique_name;
+    McdAccount *account;
 
-    DEBUG ("called");
-    if (G_UNLIKELY (manager == NULL || manager[0] == 0 ||
-                    protocol == NULL || protocol[0] == 0))
+    id = mcp_account_manager_identify_account_finish (
+        MCP_ACCOUNT_MANAGER (storage), result, &cad->error);
+
+    if (id == NULL)
     {
-        GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
-            "Invalid parameters"};
-        callback (account_manager, NULL, &error, user_data);
-        if (destroy)
-            destroy (user_data);
+        cad->callback (cad->account_manager, NULL, cad->error, cad->user_data);
+        mcd_create_account_data_free (cad);
         return;
     }
 
-    provider = tp_asv_get_string (properties,
+    provider = tp_asv_get_string (cad->properties,
                                   TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER);
 
-    id = tp_asv_get_string (params, "account");
-
-    if (id == NULL)
-        id = "account";
-
     unique_name = mcd_storage_create_account (storage, provider,
-                                              manager, protocol, id,
-                                              &e);
+                                              cad->cm_name, cad->protocol_name,
+                                              id, &cad->error);
 
     if (unique_name == NULL)
     {
-        callback (account_manager, NULL, e, user_data);
-        g_clear_error (&e);
-        if (destroy)
-            destroy (user_data);
+        g_free (id);
+        cad->callback (cad->account_manager, NULL, cad->error, cad->user_data);
+        mcd_create_account_data_free (cad);
         return;
     }
 
     /* create the basic account keys */
     mcd_storage_set_string (storage, unique_name,
-                            MC_ACCOUNTS_KEY_MANAGER, manager);
+                            MC_ACCOUNTS_KEY_MANAGER, cad->cm_name);
     mcd_storage_set_string (storage, unique_name,
-                            MC_ACCOUNTS_KEY_PROTOCOL, protocol);
+                            MC_ACCOUNTS_KEY_PROTOCOL, cad->protocol_name);
+    g_free (id);
 
-    if (display_name != NULL)
+    if (cad->display_name != NULL)
         mcd_storage_set_string (storage, unique_name,
-                                MC_ACCOUNTS_KEY_DISPLAY_NAME, display_name);
+                                MC_ACCOUNTS_KEY_DISPLAY_NAME,
+                                cad->display_name);
 
-    account = mcd_account_new (account_manager, unique_name, priv->minotaur);
+    account = mcd_account_new (cad->account_manager, unique_name,
+                               cad->account_manager->priv->minotaur);
     g_free (unique_name);
 
     if (G_LIKELY (account))
     {
-        cad = g_slice_new (McdCreateAccountData);
-        cad->account_manager = account_manager;
-        cad->parameters = g_hash_table_ref (params);
-        cad->properties = (properties ? g_hash_table_ref (properties) : NULL);
-        cad->callback = callback;
-        cad->user_data = user_data;
-        cad->destroy = destroy;
-        cad->error = NULL;
         _mcd_account_load (account, complete_account_creation, cad);
     }
     else
     {
         GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "" };
+        cad->callback (cad->account_manager, NULL, &error, cad->user_data);
+        mcd_create_account_data_free (cad);
+    }
+}
+
+void
+_mcd_account_manager_create_account (McdAccountManager *account_manager,
+                                     const gchar *manager,
+                                     const gchar *protocol,
+                                     const gchar *display_name,
+                                     GHashTable *params,
+                                     GHashTable *properties,
+                                     McdGetAccountCb callback,
+                                     gpointer user_data,
+                                     GDestroyNotify destroy)
+{
+    McdAccountManagerPrivate *priv = account_manager->priv;
+    McdStorage *storage = priv->storage;
+    McdCreateAccountData *cad;
+    GValue value = G_VALUE_INIT;
+    GVariant *variant_params;
+
+    DEBUG ("called");
+    if (G_UNLIKELY (manager == NULL || manager[0] == 0 ||
+                    protocol == NULL || protocol[0] == 0))
+    {
+        GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+            "Invalid parameters"};
         callback (account_manager, NULL, &error, user_data);
         if (destroy)
             destroy (user_data);
+        return;
     }
+
+    cad = g_slice_new (McdCreateAccountData);
+    cad->account_manager = account_manager;
+    cad->cm_name = g_strdup (manager);
+    cad->protocol_name = g_strdup (protocol);
+    cad->display_name = g_strdup (display_name);
+    cad->parameters = g_hash_table_ref (params);
+    cad->properties = (properties ? g_hash_table_ref (properties) : NULL);
+    cad->callback = callback;
+    cad->user_data = user_data;
+    cad->destroy = destroy;
+    cad->error = NULL;
+
+    g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP);
+    g_value_set_static_boxed (&value, params);
+    variant_params = dbus_g_value_build_g_variant (&value);
+    g_value_unset (&value);
+
+    mcp_account_manager_identify_account_async (MCP_ACCOUNT_MANAGER (storage),
+        manager, protocol, variant_params, NULL, identify_account_cb, cad);
+    g_variant_unref (variant_params);
 }
 
 static void
diff --git a/src/mcd-storage.c b/src/mcd-storage.c
index dfe972d..d52e345 100644
--- a/src/mcd-storage.c
+++ b/src/mcd-storage.c
@@ -611,6 +611,82 @@ unique_name (const McpAccountManager *ma,
   return NULL;
 }
 
+static void
+identify_account_cb (TpProxy *proxy,
+    const gchar *identification,
+    const GError *error,
+    gpointer task,
+    GObject *weak_object G_GNUC_UNUSED)
+{
+  if (error == NULL)
+    {
+      g_task_return_pointer (task, g_strdup (identification), g_free);
+    }
+  else if (g_error_matches (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED) ||
+      g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN))
+    {
+      g_task_return_pointer (task, g_strdup (g_task_get_task_data (task)),
+          g_free);
+    }
+  else
+    {
+      g_task_return_error (task, g_error_copy (error));
+    }
+}
+
+static gchar *
+identify_account_finish (McpAccountManager *mcpa,
+    GAsyncResult *result,
+    GError **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, mcpa), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
+identify_account_async (McpAccountManager *mcpa,
+    const gchar *manager,
+    const gchar *protocol_name,
+    GVariant *parameters,
+    GCancellable *cancellable,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  McdStorage *self = MCD_STORAGE (mcpa);
+  GError *error = NULL;
+  TpProtocol *protocol;
+  GTask *task;
+  GValue value = G_VALUE_INIT;
+  const gchar *base;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  /* in case IdentifyAccount fails and we need to make something up */
+  if (!g_variant_lookup (parameters, "account", "&s", &base))
+    base = "account";
+
+  g_task_set_task_data (task, g_strdup (base), g_free);
+
+  protocol = tp_protocol_new (self->dbusd, manager, protocol_name,
+      NULL, &error);
+
+  if (protocol == NULL)
+    {
+      g_task_return_error (task, error);
+      g_object_unref (task);
+      return;
+    }
+
+  dbus_g_value_parse_g_variant (parameters, &value);
+
+  tp_cli_protocol_call_identify_account (protocol, -1,
+      g_value_get_boxed (&value), identify_account_cb, task, g_object_unref,
+      NULL);
+  g_object_unref (protocol);
+  g_value_unset (&value);
+}
+
 /* sort in descending order of priority (ie higher prio => earlier in list) */
 static gint
 account_storage_cmp (gconstpointer a, gconstpointer b)
@@ -2062,6 +2138,8 @@ plugin_iface_init (McpAccountManagerIface *iface,
   iface->is_secret = is_secret;
   iface->make_secret = make_secret;
   iface->unique_name = unique_name;
+  iface->identify_account_async = identify_account_async;
+  iface->identify_account_finish = identify_account_finish;
   iface->list_keys = list_keys;
   iface->escape_value_for_keyfile = mcpa_escape_value_for_keyfile;
   iface->escape_variant_for_keyfile = mcpa_escape_variant_for_keyfile;
diff --git a/tests/twisted/account-manager/create-with-properties.py b/tests/twisted/account-manager/create-with-properties.py
index 8d02e2d..fb276c4 100644
--- a/tests/twisted/account-manager/create-with-properties.py
+++ b/tests/twisted/account-manager/create-with-properties.py
@@ -50,7 +50,7 @@ def test(q, bus, mc):
     assert (cs.ACCOUNT + '.Supersedes') in supported
     assertContains(cs.ACCOUNT + '.Service', supported)
 
-    params = dbus.Dictionary({"account": "anarki at example.com",
+    params = dbus.Dictionary({"account": "aNaRkI at eXaMpLe.CoM",
         "password": "secrecy"}, signature='sv')
 
     simulated_cm = SimulatedConnectionManager(q, bus)
@@ -94,6 +94,9 @@ def test(q, bus, mc):
             )
     account_path = ret.value[0]
     assert am_signal.args == [account_path, True], am_signal.args
+    # We called IdentifyAccount, which normalized the silly account name.
+    # The _xx hex-escaping and the trailing digit are implementation details.
+    assert account_path.endswith('/anarki_40example_2ecom0'), account_path
 
     assert account_path is not None
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/telepathy-mission-control-6.git



More information about the Pkg-telepathy-commits mailing list