]> git.0d.be Git - empathy.git/blobdiff - ubuntu-online-accounts/mc-plugin/mcp-account-manager-uoa.c
Center the 'smiley images' inside the menu items
[empathy.git] / ubuntu-online-accounts / mc-plugin / mcp-account-manager-uoa.c
index 87d966f7d8069f381dcdf3413530d7fdfd301f12..0607b9e2929516804ae767a57a7c8e0d47d872c2 100644 (file)
 #include "mcp-account-manager-uoa.h"
 
 #include <telepathy-glib/telepathy-glib.h>
-
 #include <libaccounts-glib/ag-account.h>
 #include <libaccounts-glib/ag-account-service.h>
 #include <libaccounts-glib/ag-manager.h>
 #include <libaccounts-glib/ag-service.h>
-
 #include <string.h>
 #include <ctype.h>
 
+#include "empathy-webcredentials-monitor.h"
+
 #define PLUGIN_NAME "uoa"
 #define PLUGIN_PRIORITY (MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING + 10)
 #define PLUGIN_DESCRIPTION "Provide Telepathy Accounts from UOA via libaccounts-glib"
@@ -39,6 +39,7 @@
 #define SERVICE_TYPE "IM"
 #define KEY_PREFIX "telepathy/"
 #define KEY_ACCOUNT_NAME "mc-account-name"
+#define KEY_READONLY_PARAMS "mc-readonly-params"
 
 static void account_storage_iface_init (McpAccountStorageIface *iface);
 
@@ -52,6 +53,7 @@ struct _McpAccountManagerUoaPrivate
   McpAccountManager *am;
 
   AgManager *manager;
+  EmpathyWebcredentialsMonitor *monitor;
 
   /* alloc'ed string -> ref'ed AgAccountService
    * The key is the account_name, an MC unique identifier.
@@ -82,15 +84,14 @@ _service_dup_tp_value (AgAccountService *service,
     const gchar *key)
 {
   gchar *real_key = g_strdup_printf (KEY_PREFIX "%s", key);
-  GValue value = { 0, };
-  gchar *ret;
+  GVariant *value;
 
-  g_value_init (&value, G_TYPE_STRING);
-  ag_account_service_get_value (service, real_key, &value);
-  ret = g_value_dup_string (&value);
-  g_value_unset (&value);
+  value = ag_account_service_get_variant (service, real_key, NULL);
+  g_free (real_key);
+  if (value == NULL)
+    return NULL;
 
-  return ret;
+  return g_variant_dup_string (value, NULL);
 }
 
 static void
@@ -102,18 +103,14 @@ _service_set_tp_value (AgAccountService *service,
 
   if (value != NULL)
     {
-      GValue gvalue = { 0, };
-
-      g_value_init (&gvalue, G_TYPE_STRING);
-      g_value_set_string (&gvalue, value);
-      ag_account_service_set_value (service, real_key, &gvalue);
-      g_value_unset (&gvalue);
-      g_free (real_key);
+      GVariant *gvariant = g_variant_new_string (value);
+      ag_account_service_set_variant (service, real_key, gvariant);
     }
   else
     {
-      ag_account_service_set_value (service, real_key, NULL);
+      ag_account_service_set_variant (service, real_key, NULL);
     }
+  g_free (real_key);
 }
 
 /* Returns NULL if the account never has been imported into MC before */
@@ -167,15 +164,20 @@ _service_changed_cb (AgAccountService *service,
 }
 
 static void
-_account_stored_cb (AgAccount *account,
-    const GError *error,
+_account_stored_cb (GObject *source_object,
+    GAsyncResult *res,
     gpointer user_data)
 {
-  if (error != NULL)
+  AgAccount *account = AG_ACCOUNT(source_object);
+  GError *error = NULL;
+
+  if (!ag_account_store_finish (account, res, &error))
     {
+      g_assert (error != NULL);
       DEBUG ("Error storing UOA account '%s': %s",
           ag_account_get_display_name (account),
           error->message);
+      g_error_free (error);
     }
 }
 
@@ -257,7 +259,7 @@ _account_created_cb (AgManager *manager,
                   cm_name, protocol_name, params);
               _service_set_tp_account_name (service, account_name);
 
-              ag_account_store (account, _account_stored_cb, self);
+              ag_account_store_async (account, NULL, _account_stored_cb, self);
 
               g_hash_table_unref (params);
             }
@@ -332,6 +334,7 @@ mcp_account_manager_uoa_dispose (GObject *object)
   tp_clear_object (&self->priv->am);
   tp_clear_object (&self->priv->manager);
   tp_clear_pointer (&self->priv->accounts, g_hash_table_unref);
+  tp_clear_object (&self->priv->monitor);
 
   G_OBJECT_CLASS (mcp_account_manager_uoa_parent_class)->dispose (object);
 }
@@ -349,11 +352,15 @@ mcp_account_manager_uoa_init (McpAccountManagerUoa *self)
   self->priv->pending_signals = g_queue_new ();
 
   self->priv->manager = ag_manager_new_for_service_type (SERVICE_TYPE);
+  g_return_if_fail (self->priv->manager != NULL);
 
   g_signal_connect (self->priv->manager, "account-created",
       G_CALLBACK (_account_created_cb), self);
   g_signal_connect (self->priv->manager, "account-deleted",
       G_CALLBACK (_account_deleted_cb), self);
+
+  self->priv->monitor = empathy_webcredentials_monitor_new (
+      self->priv->manager);
 }
 
 static void
@@ -420,6 +427,8 @@ account_manager_uoa_list (const McpAccountStorage *storage,
 
   DEBUG (G_STRFUNC);
 
+  g_return_val_if_fail (self->priv->manager != NULL, NULL);
+
   _ensure_loaded (self);
 
   g_hash_table_iter_init (&iter, self->priv->accounts);
@@ -429,6 +438,17 @@ account_manager_uoa_list (const McpAccountStorage *storage,
   return accounts;
 }
 
+static const gchar *
+provider_to_tp_service_name (const gchar *provider_name)
+{
+  /* Well known services are defined in Telepathy spec:
+   * http://telepathy.freedesktop.org/spec/Account.html#Property:Service */
+  if (!tp_strdiff (provider_name, "google"))
+    return "google-talk";
+
+  return provider_name;
+}
+
 static gboolean
 account_manager_uoa_get (const McpAccountStorage *storage,
     const McpAccountManager *am,
@@ -441,6 +461,8 @@ account_manager_uoa_get (const McpAccountStorage *storage,
   AgService *s;
   gboolean handled = FALSE;
 
+  g_return_val_if_fail (self->priv->manager != NULL, FALSE);
+
   service = g_hash_table_lookup (self->priv->accounts, account_name);
   if (service == NULL)
     return FALSE;
@@ -455,16 +477,16 @@ account_manager_uoa_get (const McpAccountStorage *storage,
     {
       AgAccountSettingIter iter;
       const gchar *k;
-      const GValue *v;
+      GVariant *v;
 
       ag_account_service_settings_iter_init (service, &iter, KEY_PREFIX);
-      while (ag_account_service_settings_iter_next (&iter, &k, &v))
+      while (ag_account_settings_iter_get_next (&iter, &k, &v))
         {
-          if (!G_VALUE_HOLDS_STRING (v))
+          if (!g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
             continue;
 
           mcp_account_manager_set_value (am, account_name,
-              k, g_value_get_string (v));
+              k, g_variant_get_string (v, NULL));
         }
     }
 
@@ -486,7 +508,7 @@ account_manager_uoa_get (const McpAccountStorage *storage,
   if (key == NULL || !tp_strdiff (key, "Service"))
     {
       mcp_account_manager_set_value (am, account_name, "Service",
-          ag_account_get_provider_name (account));
+          provider_to_tp_service_name (ag_account_get_provider_name (account)));
       handled = TRUE;
     }
 
@@ -520,6 +542,8 @@ account_manager_uoa_set (const McpAccountStorage *storage,
   AgAccountService *service;
   AgAccount *account;
 
+  g_return_val_if_fail (self->priv->manager != NULL, FALSE);
+
   service = g_hash_table_lookup (self->priv->accounts, account_name);
   if (service == NULL)
     return FALSE;
@@ -530,6 +554,9 @@ account_manager_uoa_set (const McpAccountStorage *storage,
 
   if (!tp_strdiff (key, "Enabled"))
     {
+      /* Enabled is a global setting on the account, not per-services,
+       * unfortunately */
+      ag_account_select_service (account, NULL);
       ag_account_set_enabled (account, !tp_strdiff (val, "true"));
     }
   else if (!tp_strdiff (key, "DisplayName"))
@@ -558,6 +585,8 @@ account_manager_uoa_create (const McpAccountStorage *storage,
   AgAccountService *service;
   GList *l;
 
+  g_return_val_if_fail (self->priv->manager != NULL, NULL);
+
   if (!self->priv->ready)
     {
       g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
@@ -604,6 +633,8 @@ account_manager_uoa_delete (const McpAccountStorage *storage,
   AgAccountService *service;
   AgAccount *account;
 
+  g_return_val_if_fail (self->priv->manager != NULL, FALSE);
+
   service = g_hash_table_lookup (self->priv->accounts, account_name);
   if (service == NULL)
     return FALSE;
@@ -635,18 +666,50 @@ account_manager_uoa_commit (const McpAccountStorage *storage,
 
   DEBUG (G_STRFUNC);
 
+  g_return_val_if_fail (self->priv->manager != NULL, FALSE);
+
   g_hash_table_iter_init (&iter, self->priv->accounts);
   while (g_hash_table_iter_next (&iter, NULL, &value))
     {
       AgAccountService *service = value;
       AgAccount *account = ag_account_service_get_account (service);
 
-      ag_account_store (account, _account_stored_cb, self);
+      ag_account_store_async (account, NULL, _account_stored_cb, self);
     }
 
   return TRUE;
 }
 
+static void
+failure_removed_cb (EmpathyWebcredentialsMonitor *monitor,
+    AgAccount *account,
+    McpAccountManagerUoa *self)
+{
+  GList *l;
+
+  DEBUG ("Account '%u' is not failing any more", account->id);
+
+  l = ag_account_list_services_by_type (account, SERVICE_TYPE);
+  while (l != NULL)
+    {
+      AgAccountService *service = ag_account_service_new (account, l->data);
+      gchar *account_name = _service_dup_tp_account_name (service);
+
+      if (account_name != NULL)
+        {
+          DEBUG ("Reconnect account %s", account_name);
+
+          mcp_account_storage_emit_reconnect (MCP_ACCOUNT_STORAGE (self),
+              account_name);
+        }
+
+      g_free (account_name);
+      g_object_unref (service);
+      ag_service_unref (l->data);
+      l = g_list_delete_link (l, l);
+    }
+}
+
 static void
 account_manager_uoa_ready (const McpAccountStorage *storage,
     const McpAccountManager *am)
@@ -654,6 +717,8 @@ account_manager_uoa_ready (const McpAccountStorage *storage,
   McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage;
   DelayedSignalData *data;
 
+  g_return_if_fail (self->priv->manager != NULL);
+
   if (self->priv->ready)
     return;
 
@@ -681,6 +746,9 @@ account_manager_uoa_ready (const McpAccountStorage *storage,
 
   g_queue_free (self->priv->pending_signals);
   self->priv->pending_signals = NULL;
+
+  g_signal_connect (self->priv->monitor, "failure-removed",
+      G_CALLBACK (failure_removed_cb), self);
 }
 
 static void
@@ -692,6 +760,8 @@ account_manager_uoa_get_identifier (const McpAccountStorage *storage,
   AgAccountService *service;
   AgAccount *account;
 
+  g_return_if_fail (self->priv->manager != NULL);
+
   service = g_hash_table_lookup (self->priv->accounts, account_name);
   if (service == NULL)
     return;
@@ -703,11 +773,29 @@ account_manager_uoa_get_identifier (const McpAccountStorage *storage,
 }
 
 static guint
-account_manager_uoa_get_restrictions (const McpAccountStorage *self,
+account_manager_uoa_get_restrictions (const McpAccountStorage *storage,
     const gchar *account_name)
 {
+  McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage;
+  AgAccountService *service;
+  guint restrictions = TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE;
+  GVariant *value;
+
+  g_return_val_if_fail (self->priv->manager != NULL, 0);
+
+  /* If we don't know this account, we cannot do anything */
+  service = g_hash_table_lookup (self->priv->accounts, account_name);
+  if (service == NULL)
+    return G_MAXUINT;
+
+  value = ag_account_service_get_variant (service,
+      KEY_PREFIX KEY_READONLY_PARAMS, NULL);
+
+  if (value != NULL && g_variant_get_boolean (value))
+    restrictions |= TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS;
+
   /* FIXME: We can't set Icon either, but there is no flag for that */
-  return TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE;
+  return restrictions;
 }
 
 static void