summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2010-09-14 16:00:12 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2010-09-14 16:00:12 +0100
commit85e35b0b8e4501ac4eb35fb2fc210eedf0282e3d (patch)
tree8f9b4c1bb6eec592c322098cf4f919bc67da0ac0
parent3116079d37cd389b10525a0f9d799e7fadb16e60 (diff)
parent9ac2c09945c69c32ca4a6e15a30048c58add2782 (diff)
downloadtelepathy-mission-control-85e35b0b8e4501ac4eb35fb2fc210eedf0282e3d.tar.gz
Merge branch 'master' into storage-tests
-rw-r--r--src/Makefile.am3
-rw-r--r--src/mcd-account-compat.c101
-rw-r--r--src/mcd-account-conditions.c57
-rw-r--r--src/mcd-account-manager-query.c82
-rw-r--r--src/mcd-account-manager-sso.c3
-rw-r--r--src/mcd-account-manager.c481
-rw-r--r--src/mcd-account-manager.h5
-rw-r--r--src/mcd-account-priv.h8
-rw-r--r--src/mcd-account-requests.c4
-rw-r--r--src/mcd-account.c688
-rw-r--r--src/mcd-account.h3
-rw-r--r--src/mcd-storage-priv.h35
-rw-r--r--src/mcd-storage.c388
-rw-r--r--src/mcd-storage.h151
-rw-r--r--src/plugin-account.c597
-rw-r--r--src/plugin-account.h11
16 files changed, 1634 insertions, 983 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 2ec922e5..0b75e728 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -186,6 +186,9 @@ libmcd_convenience_la_SOURCES = \
mcd-transport.c \
mcd-provisioning.c \
mcd-provisioning-factory.c \
+ mcd-storage.c \
+ mcd-storage.h \
+ mcd-storage-priv.h \
plugin-dispatch-operation.c \
plugin-dispatch-operation.h \
plugin-loader.c \
diff --git a/src/mcd-account-compat.c b/src/mcd-account-compat.c
index 77ab5245..3fe611c6 100644
--- a/src/mcd-account-compat.c
+++ b/src/mcd-account-compat.c
@@ -74,8 +74,10 @@ set_profile (TpSvcDBusProperties *self, const gchar *name,
const GValue *value, GError **error)
{
McdAccount *account = MCD_ACCOUNT (self);
- const gchar *string, *unique_name;
- GKeyFile *keyfile;
+ const gchar *string;
+ McdStorage *storage;
+ const GValue *set;
+ const gchar *account_name;
if (!G_VALUE_HOLDS_STRING (value))
{
@@ -88,18 +90,17 @@ set_profile (TpSvcDBusProperties *self, const gchar *name,
/* FIXME: should we reject profile changes after account creation? */
/* FIXME: some sort of validation beyond just the type? */
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
+ account_name = mcd_account_get_unique_name (account);
+ storage = _mcd_account_get_storage (account);
string = g_value_get_string (value);
+
if (string && string[0] != 0)
- g_key_file_set_string (keyfile, unique_name,
- name, string);
+ set = value;
else
- {
- g_key_file_remove_key (keyfile, unique_name,
- name, NULL);
- }
- _mcd_account_write_conf (account);
+ set = NULL;
+
+ mcd_storage_set_value (storage, account_name, name, set, FALSE);
+ mcd_storage_commit (storage, account_name);
g_signal_emit (account, _mcd_account_signal_profile_set, 0);
@@ -110,14 +111,10 @@ static void
get_profile (TpSvcDBusProperties *self, const gchar *name, GValue *value)
{
McdAccount *account = MCD_ACCOUNT (self);
- const gchar *unique_name;
- GKeyFile *keyfile;
- gchar *string;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ gchar *string = mcd_storage_dup_string (storage, account_name, name);
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
- string = g_key_file_get_string (keyfile, unique_name,
- name, NULL);
g_value_init (value, G_TYPE_STRING);
g_value_take_string (value, string);
}
@@ -138,8 +135,10 @@ set_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name,
const GValue *value, GError **error)
{
McdAccount *account = MCD_ACCOUNT (self);
- const gchar *unique_name, **fields, **field;
- GKeyFile *keyfile;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ GStrv fields;
+ const GValue *set = NULL;
/* FIXME: some sort of validation beyond just the type? */
@@ -151,25 +150,16 @@ set_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name,
return FALSE;
}
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
fields = g_value_get_boxed (value);
- if (fields)
- {
- gsize len;
- for (field = fields, len = 0; *field; field++, len++);
- g_key_file_set_string_list (keyfile, unique_name,
- name, fields, len);
- }
- else
- {
- g_key_file_remove_key (keyfile, unique_name,
- name, NULL);
- }
- _mcd_account_write_conf (account);
+ if (fields != NULL)
+ set = value;
+
+ mcd_storage_set_value (storage, account_name, name, set, FALSE);
+ mcd_storage_commit (storage, account_name);
emit_compat_property_changed (account, name, value);
+
return TRUE;
}
@@ -178,16 +168,26 @@ get_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name,
GValue *value)
{
McdAccount *account = MCD_ACCOUNT (self);
- GKeyFile *keyfile;
- const gchar *unique_name;
- gchar **fields;
-
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
- fields = g_key_file_get_string_list (keyfile, unique_name,
- name, NULL, NULL);
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ GValue *fetched;
+
g_value_init (value, G_TYPE_STRV);
- g_value_take_boxed (value, fields);
+ fetched =
+ mcd_storage_dup_value (storage, account_name, name, G_TYPE_STRV, NULL);
+
+ if (fetched != NULL)
+ {
+ GStrv fields = g_value_get_boxed (fetched);
+
+ g_value_take_boxed (value, fields);
+ g_slice_free (GValue, fetched);
+ fetched = NULL;
+ }
+ else
+ {
+ g_value_take_boxed (value, NULL);
+ }
}
@@ -225,20 +225,19 @@ account_compat_iface_init (McSvcAccountInterfaceCompatClass *iface,
McProfile *
mcd_account_compat_get_mc_profile (McdAccount *account)
{
- const gchar *unique_name;
- GKeyFile *keyfile;
gchar *profile_name;
McProfile *profile = NULL;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
- profile_name = g_key_file_get_string (keyfile, unique_name,
- "Profile", NULL);
- if (profile_name)
+ profile_name = mcd_storage_dup_string (storage, account_name, "Profile");
+
+ if (profile_name != NULL)
{
profile = mc_profile_lookup (profile_name);
g_free (profile_name);
}
+
return profile;
}
diff --git a/src/mcd-account-conditions.c b/src/mcd-account-conditions.c
index e8cd4e7e..eb647923 100644
--- a/src/mcd-account-conditions.c
+++ b/src/mcd-account-conditions.c
@@ -45,16 +45,15 @@
static void
store_condition (gpointer key, gpointer value, gpointer userdata)
{
- McdAccount *account = userdata;
+ McdAccount *account = MCD_ACCOUNT (userdata);
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
const gchar *name = key, *condition = value;
- const gchar *unique_name;
gchar condition_key[256];
- GKeyFile *keyfile;
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
g_snprintf (condition_key, sizeof (condition_key), "condition-%s", name);
- g_key_file_set_string (keyfile, unique_name, condition_key, condition);
+ mcd_storage_set_string (storage, account_name, condition_key, condition,
+ FALSE);
}
static gboolean
@@ -62,8 +61,8 @@ set_condition (TpSvcDBusProperties *self, const gchar *name,
const GValue *value, GError **error)
{
McdAccount *account = MCD_ACCOUNT (self);
- const gchar *unique_name;
- GKeyFile *keyfile;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
gchar **keys, **key;
GHashTable *conditions;
@@ -77,31 +76,33 @@ set_condition (TpSvcDBusProperties *self, const gchar *name,
return FALSE;
}
- unique_name = mcd_account_get_unique_name (account);
- conditions = g_value_get_boxed (value);
-
if (_mcd_account_get_always_on (account))
{
g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
"Account %s conditions cannot be changed",
- unique_name);
+ mcd_account_get_unique_name (account));
return FALSE;
}
- keyfile = _mcd_account_get_keyfile (account);
+ conditions = g_value_get_boxed (value);
+
/* first, delete existing conditions */
- keys = g_key_file_get_keys (keyfile, unique_name, NULL, NULL);
+ keys = mcd_storage_dup_settings (storage, account_name, NULL);
+
for (key = keys; *key != NULL; key++)
{
- if (strncmp (*key, "condition-", 10) != 0) continue;
- g_key_file_remove_key (keyfile, unique_name,
- *key, NULL);
+ if (strncmp (*key, "condition-", 10) != 0)
+ continue;
+
+ mcd_storage_set_value (storage, account_name, *key, NULL, FALSE);
}
+
g_strfreev (keys);
g_hash_table_foreach (conditions, store_condition, account);
- _mcd_account_write_conf (account);
+ mcd_storage_commit (storage, account_name);
+
return TRUE;
}
@@ -130,24 +131,28 @@ account_conditions_iface_init (McSvcAccountInterfaceConditionsClass *iface,
GHashTable *mcd_account_get_conditions (McdAccount *account)
{
- const gchar *unique_name;
- GKeyFile *keyfile;
gchar **keys, **key, *condition;
GHashTable *conditions;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
- keyfile = _mcd_account_get_keyfile (account);
- unique_name = mcd_account_get_unique_name (account);
conditions = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
- keys = g_key_file_get_keys (keyfile, unique_name, NULL, NULL);
+
+ keys = mcd_storage_dup_settings (storage, account_name, NULL);
+
for (key = keys; *key != NULL; key++)
{
- if (strncmp (*key, "condition-", 10) != 0) continue;
- condition = g_key_file_get_string (keyfile, unique_name, *key, NULL);
+ if (strncmp (*key, "condition-", 10) != 0)
+ continue;
+
+ condition = mcd_storage_dup_string (storage, account_name, *key);
DEBUG ("Condition: %s = %s", *key, condition);
- g_hash_table_insert (conditions, g_strdup (*key + 10), condition);
+ g_hash_table_insert (conditions, g_strdup (*key + 10), condition);
}
+
g_strfreev (keys);
+
return conditions;
}
diff --git a/src/mcd-account-manager-query.c b/src/mcd-account-manager-query.c
index 9e37d64f..4ec82171 100644
--- a/src/mcd-account-manager-query.c
+++ b/src/mcd-account-manager-query.c
@@ -94,46 +94,56 @@ static gboolean
match_account_parameter (McdAccount *account, const gchar *name,
const GValue *value)
{
- const gchar *unique_name;
- GKeyFile *keyfile;
gboolean match = FALSE;
+ McdStorage *storage = _mcd_account_get_storage (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ GType vtype = G_VALUE_TYPE (value);
- unique_name = mcd_account_get_unique_name (account);
- keyfile = _mcd_account_get_keyfile (account);
- if (g_key_file_has_key (keyfile, unique_name, name, NULL))
+ if (mcd_storage_has_value (storage, account_name, name))
{
- const gchar *value_str;
- gchar *conf_value_str;
- gint conf_value_int, value_int;
- gboolean conf_value_bool, value_bool;
- switch (G_VALUE_TYPE (value))
- {
- case G_TYPE_STRING:
- conf_value_str =
- g_key_file_get_string (keyfile, unique_name, name,
- NULL);
- value_str = g_value_get_string (value);
- if (strcmp (conf_value_str, value_str) == 0) match = TRUE;
- g_free (conf_value_str);
- break;
- case G_TYPE_UINT:
- conf_value_int =
- g_key_file_get_integer (keyfile, unique_name, name,
- NULL);
- value_int = (gint)g_value_get_uint (value);
- if (conf_value_int == value_int) match = TRUE;
- break;
- case G_TYPE_BOOLEAN:
- conf_value_bool =
- g_key_file_get_boolean (keyfile, unique_name, name,
- NULL);
- value_bool = g_value_get_boolean (value);
- if (conf_value_bool == value_bool) match = TRUE;
- break;
- default:
- g_warning ("Unexpected type %s", G_VALUE_TYPE_NAME (value));
- }
+ GValue *conf = NULL;
+
+ switch (vtype)
+ {
+ case G_TYPE_STRING:
+ case G_TYPE_UINT:
+ case G_TYPE_BOOLEAN:
+ conf = mcd_storage_dup_value (storage, account_name, name, vtype,
+ NULL);
+ break;
+ default:
+ g_warning ("Unexpected type %s", G_VALUE_TYPE_NAME (value));
+ }
+
+ if (conf != NULL)
+ {
+ if (G_VALUE_TYPE (conf) == vtype)
+ {
+ switch (vtype)
+ {
+ case G_TYPE_STRING:
+ match = g_strcmp0 (g_value_get_string (value),
+ g_value_get_string (conf)) == 0;
+ break;
+
+ case G_TYPE_UINT:
+ match = g_value_get_uint (value) == g_value_get_uint (conf);
+ break;
+
+ case G_TYPE_BOOLEAN:
+ match =
+ g_value_get_boolean (value) == g_value_get_boolean (conf);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ tp_g_value_slice_free (conf);
+ }
}
+
return match;
}
diff --git a/src/mcd-account-manager-sso.c b/src/mcd-account-manager-sso.c
index d0c42313..8e1796f3 100644
--- a/src/mcd-account-manager-sso.c
+++ b/src/mcd-account-manager-sso.c
@@ -1296,6 +1296,9 @@ _load_from_libaccounts (McdAccountManagerSso *sso,
mcp_account_manager_set_value (am, name, MC_PROTOCOL_KEY, mc_id[1]);
mcp_account_manager_set_value (am, name, MC_IDENTITY_KEY, name);
+ /* force the services value to be synthesised + cached */
+ _get (MCP_ACCOUNT_STORAGE (sso), am, name, SERVICES_KEY);
+
ag_account_select_service (account, service);
g_signal_connect (account, "enabled",
diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c
index c512b3f8..c48e24c0 100644
--- a/src/mcd-account-manager.c
+++ b/src/mcd-account-manager.c
@@ -44,13 +44,9 @@
#include <telepathy-glib/errors.h>
#include <telepathy-glib/interfaces.h>
#include <telepathy-glib/svc-account-manager.h>
-#include "mcd-account-manager-priv.h"
-/* these pseudo-plugins take care of the actual account storage/retrieval */
-#include "mcd-account-manager-default.h"
-#if ENABLE_LIBACCOUNTS_SSO
-#include "mcd-account-manager-sso.h"
-#endif
+#include "mcd-account-manager-priv.h"
+#include "mcd-storage.h"
#include "mcd-account.h"
#include "mcd-account-config.h"
@@ -82,9 +78,6 @@ static void _mcd_account_manager_constructed (GObject *obj);
static const McdDBusProp account_manager_properties[];
static const McdDBusProp sso_properties[];
-static gboolean plugins_cached = FALSE;
-static GList *stores = NULL;
-
static const McdInterfaceData account_manager_interfaces[] = {
MCD_IMPLEMENT_IFACE (tp_svc_account_manager_get_type,
account_manager,
@@ -162,19 +155,6 @@ static void account_loaded (McdAccount *account,
const GError *error,
gpointer user_data);
-/* sort in descending order of priority (ie higher prio => earlier in list) */
-static gint
-account_storage_cmp (gconstpointer a, gconstpointer b)
-{
- gint pa = mcp_account_storage_priority (a);
- gint pb = mcp_account_storage_priority (b);
-
- if (pa > pb) return -1;
- if (pa < pb) return 1;
-
- return 0;
-}
-
/* calback chain for asynchronously updates from backends: */
static void
async_altered_validity_cb (McdAccount *account, gboolean valid, gpointer data)
@@ -346,7 +326,7 @@ async_created_manager_cb (McdManager *cm, const GError *error, gpointer data)
}
/* account created by an McpAccountStorage plugin after the initial setup *
- * since the plugin does not have our GKeyFile, we need to poke the plugin *
+ * since the plugin does not have our cache, we need to poke the plugin *
* to fetch the named account explicitly at this point (ie it's a read, not *
* not a write, from the plugin's POV: */
static void
@@ -367,8 +347,7 @@ created_cb (GObject *storage, const gchar *name, gpointer data)
lad->storage = plugin;
lad->account_lock = 1; /* will be released at the end of this function */
- /* actually fetch the data into our GKeyFile from the plugin: */
- DEBUG ("-> mcp_account_storage_get");
+ /* actually fetch the data into our cache from the plugin: */
if (mcp_account_storage_get (plugin, MCP_ACCOUNT_MANAGER (pa), name, NULL))
{
account = mclass->account_new (am, name);
@@ -451,15 +430,14 @@ _mcd_account_delete_cb (McdAccount *account, const GError *error, gpointer data)
static void
deleted_cb (GObject *plugin, const gchar *name, gpointer data)
{
- GList *store = NULL;
McpAccountStorage *storage = MCP_ACCOUNT_STORAGE (plugin);
McdAccountManager *manager = MCD_ACCOUNT_MANAGER (data);
McdAccount *account = NULL;
- McdPluginAccountManager *pa = manager->priv->plugin_manager;
account = g_hash_table_lookup (manager->priv->accounts, name);
- DEBUG ("%s -> %p", name, account);
+ DEBUG ("%s reported deletion of %s (%p)",
+ mcp_account_storage_name (storage), name, account);
if (account != NULL)
{
@@ -467,83 +445,8 @@ deleted_cb (GObject *plugin, const gchar *name, gpointer data)
g_hash_table_remove (manager->priv->accounts, name);
mcd_account_delete (account, _mcd_account_delete_cb, NULL);
}
-
- /* NOTE: we have to do this here, the mcd_account deletion just *
- * steals a copy of your internal storage and erases the entry *
- * from underneath us, so we don't even know we had the account *
- * after mcd_account_delete: a rumsfeldian unknown unknown */
- /* PS: which will be fixed, but this will do for now */
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *p = store->data;
-
- DEBUG ("MCP:%s -> remove %s", mcp_account_storage_name (p), name);
-
- /* don't call the plugin who informed us of deletion, it should *
- * already have purged its own store and we don't want to risk *
- * some sort of crazy keep-on-deleting infinite loop shenanigans */
- if (p != storage)
- mcp_account_storage_delete (p, MCP_ACCOUNT_MANAGER (pa), name, NULL);
- }
}
-static void
-add_libaccount_plugin_if_enabled (void)
-{
-#if ENABLE_LIBACCOUNTS_SSO
- McdAccountManagerSso *sso_plugin = mcd_account_manager_sso_new ();
-
- stores = g_list_insert_sorted (stores, sso_plugin, account_storage_cmp);
-#endif
-}
-
-static void
-sort_and_cache_plugins (McdAccountManager *self)
-{
- const GList *p;
- McdAccountManagerDefault *default_plugin = NULL;
-
- if (plugins_cached)
- return;
-
- /* insert the default storage plugin into the sorted plugin list */
- default_plugin = mcd_account_manager_default_new ();
- stores = g_list_insert_sorted (stores, default_plugin, account_storage_cmp);
-
- /* now poke the pseudo-plugins into the sorted GList of storage plugins */
- add_libaccount_plugin_if_enabled ();
-
- for (p = mcp_list_objects(); p != NULL; p = g_list_next (p))
- {
- if (MCP_IS_ACCOUNT_STORAGE (p->data))
- {
- McpAccountStorage *plugin = g_object_ref (p->data);
-
- stores = g_list_insert_sorted (stores, plugin, account_storage_cmp);
- }
- }
-
- for (p = stores; p != NULL; p = g_list_next (p))
- {
- McpAccountStorage *plugin = p->data;
-
- DEBUG ("found plugin %s [%s; priority %d]\n%s",
- mcp_account_storage_name (plugin),
- g_type_name (G_TYPE_FROM_INSTANCE (plugin)),
- mcp_account_storage_priority (plugin),
- mcp_account_storage_description (plugin));
- g_signal_connect (plugin, "created", G_CALLBACK (created_cb), self);
- g_signal_connect (plugin, "altered", G_CALLBACK (altered_cb), self);
- g_signal_connect (plugin, "toggled", G_CALLBACK (toggled_cb), self);
- g_signal_connect (plugin, "deleted", G_CALLBACK (deleted_cb), self);
- g_signal_connect (plugin, "altered-one", G_CALLBACK (altered_one_cb),
- self);
- }
-
- plugins_cached = TRUE;
-}
-
-
GQuark
mcd_account_manager_error_quark (void)
{
@@ -716,9 +619,8 @@ static void
on_account_removed (McdAccount *account, McdAccountManager *account_manager)
{
McdAccountManagerPrivate *priv = account_manager->priv;
- McdPluginAccountManager *pa = priv->plugin_manager;
+ McdStorage *storage = MCD_STORAGE (priv->plugin_manager);
const gchar *name, *object_path;
- GList *store;
object_path = mcd_account_get_object_path (account);
tp_svc_account_manager_emit_account_removed (account_manager, object_path);
@@ -726,30 +628,29 @@ on_account_removed (McdAccount *account, McdAccountManager *account_manager)
name = mcd_account_get_unique_name (account);
g_hash_table_remove (priv->accounts, name);
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
-
- DEBUG ("MCP:%s -> remove %s", mcp_account_storage_name (plugin), name);
- mcp_account_storage_delete (plugin, MCP_ACCOUNT_MANAGER (pa), name, NULL);
- }
-
+ mcd_storage_delete_account (storage, name);
mcd_account_manager_write_conf_async (account_manager, account, NULL,
NULL);
}
+static inline void
+disconnect_signal (gpointer instance, gpointer func)
+{
+ g_signal_handlers_disconnect_matched (instance,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, func, NULL);
+}
+
static void
unref_account (gpointer data)
{
McdAccount *account = MCD_ACCOUNT (data);
- McdAccountManager *account_manager;
DEBUG ("called for %s", mcd_account_get_unique_name (account));
- account_manager = mcd_account_get_account_manager (account);
- g_signal_handlers_disconnect_by_func (account, on_account_validity_changed,
- account_manager);
- g_signal_handlers_disconnect_by_func (account, on_account_removed,
- account_manager);
+
+ disconnect_signal (account, on_account_validity_changed);
+ disconnect_signal (account, on_account_removed);
+
g_object_unref (account);
}
@@ -944,6 +845,7 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager,
{
McdAccountManagerPrivate *priv = account_manager->priv;
McpAccountManager *ma = MCP_ACCOUNT_MANAGER (priv->plugin_manager);
+ McdStorage *storage = MCD_STORAGE (priv->plugin_manager);
McdCreateAccountData *cad;
McdAccount *account;
gchar *unique_name;
@@ -965,13 +867,15 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager,
g_return_if_fail (unique_name != NULL);
/* create the basic account keys */
- g_key_file_set_string (priv->plugin_manager->keyfile, unique_name,
- MC_ACCOUNTS_KEY_MANAGER, manager);
- g_key_file_set_string (priv->plugin_manager->keyfile, unique_name,
- MC_ACCOUNTS_KEY_PROTOCOL, protocol);
- if (display_name)
- g_key_file_set_string (priv->plugin_manager->keyfile, unique_name,
- MC_ACCOUNTS_KEY_DISPLAY_NAME, display_name);
+ mcd_storage_set_string (storage, unique_name,
+ MC_ACCOUNTS_KEY_MANAGER, manager, FALSE);
+ mcd_storage_set_string (storage, unique_name,
+ MC_ACCOUNTS_KEY_PROTOCOL, protocol, FALSE);
+
+ if (display_name != NULL)
+ mcd_storage_set_string (storage, unique_name,
+ MC_ACCOUNTS_KEY_DISPLAY_NAME, display_name,
+ FALSE);
account = MCD_ACCOUNT_MANAGER_GET_CLASS (account_manager)->account_new
(account_manager, unique_name);
@@ -1049,43 +953,25 @@ sso_get_service_accounts (McSvcAccountManagerInterfaceSSO *iface,
gsize len;
McdAccountManager *manager = MCD_ACCOUNT_MANAGER (iface);
McdAccountManagerPrivate *priv = manager->priv;
- GKeyFile *cache = priv->plugin_manager->keyfile;
- GStrv accounts = g_key_file_get_groups (cache, &len);
+ McdStorage *storage = MCD_STORAGE (priv->plugin_manager);
+ GStrv accounts = mcd_storage_dup_accounts (storage, &len);
GList *srv_accounts = NULL;
GPtrArray *paths = g_ptr_array_new ();
- if (!plugins_cached)
- sort_and_cache_plugins (manager);
if (len > 0 && accounts != NULL)
{
guint i = 0;
gchar *name;
- McpAccountManager *ma = MCP_ACCOUNT_MANAGER (priv->plugin_manager);
for (name = accounts[i]; name != NULL; name = accounts[++i])
{
- gchar *id =
- g_key_file_get_string (cache, name, "libacct-uid", NULL);
+ gchar *id = mcd_storage_dup_string (storage, name, "libacct-uid");
if (id != NULL)
{
gchar *supported =
- g_key_file_get_string (cache, name, "sso-services", NULL);
-
- if (supported == NULL)
- {
-
- GList *store = g_list_last (stores);
- while (store != NULL)
- {
- McpAccountStorage *as = store->data;
- mcp_account_storage_get (as, ma, name, "sso-services");
- store = g_list_previous (store);
- }
- supported = g_key_file_get_string (cache, name,
- "sso-services", NULL);
- }
+ mcd_storage_dup_string (storage, name, "sso-services");
if (supported != NULL)
{
@@ -1138,14 +1024,13 @@ sso_get_account (McSvcAccountManagerInterfaceSSO *iface,
const guint id,
DBusGMethodInvocation *context)
{
- gsize len;
McdAccountManager *manager = MCD_ACCOUNT_MANAGER (iface);
McdAccountManagerPrivate *priv = manager->priv;
- GKeyFile *cache = priv->plugin_manager->keyfile;
- GStrv accounts = g_key_file_get_groups (cache, &len);
+ McdStorage *storage = MCD_STORAGE (priv->plugin_manager);
+ GStrv accounts = mcd_storage_dup_accounts (storage, NULL);
const gchar *path = NULL;
- if (len > 0 && accounts != NULL)
+ if (accounts != NULL)
{
guint i = 0;
gchar *name;
@@ -1154,7 +1039,7 @@ sso_get_account (McSvcAccountManagerInterfaceSSO *iface,
for (name = accounts[i]; name != NULL; name = accounts[++i])
{
gchar *str_id =
- g_key_file_get_string (cache, name, "libacct-uid", NULL);
+ mcd_storage_dup_string (storage, name, "libacct-uid");
guint64 sso_id = g_ascii_strtoull (str_id, NULL, 10);
if (sso_id != 0 && id != 0)
@@ -1301,76 +1186,13 @@ properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data)
static gboolean
write_conf (gpointer userdata)
{
- McdPluginAccountManager *pa = userdata;
- GKeyFile *keyfile = pa->keyfile;
- GStrv groups;
- gchar *group;
- gsize i = 0;
- GList *store;
+ McdStorage *storage = MCD_STORAGE (userdata);
DEBUG ("called");
g_source_remove (write_conf_id);
write_conf_id = 0;
- groups = g_key_file_get_groups (keyfile, NULL);
-
- if (groups == NULL)
- return TRUE;
-
- /* poke the account settings into the local cache of the relevant *
- * storage plugins, highest priority plugins get first dibs: *
- * Note that the MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_DEFAULT priority *
- * plugin is the default keyfile plugin and accepts all settings, *
- * so no plugin of a lower priority will be asked to save anything */
- for (group = groups[i]; group != NULL; group = groups[++i])
- {
- gsize n_keys;
- gsize j = 0;
- GStrv keys = g_key_file_get_keys (keyfile, group, &n_keys, NULL);
-
- if (keys == NULL)
- n_keys = 0;
-
- for (j = 0; j < n_keys; j++)
- {
- gboolean done = FALSE;
- gchar *set = keys[j];
- gchar *val = g_key_file_get_string (keyfile, group, set, NULL);
-
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
- McpAccountManager *ma = MCP_ACCOUNT_MANAGER (pa);
- const gchar *pn = mcp_account_storage_name (plugin);
-
- if (done)
- {
- DEBUG ("MCP:%s -> delete %s.%s", pn, group, set);
- mcp_account_storage_delete (plugin, ma, group, set);
- }
- else
- {
- done = mcp_account_storage_set (plugin, ma, group, set, val);
- DEBUG ("MCP:%s -> %s %s.%s",
- pn, done ? "store" : "ignore", group, set);
- }
- }
- }
-
- g_strfreev (keys);
- }
-
- g_strfreev (groups);
-
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountManager *ma = MCP_ACCOUNT_MANAGER (pa);
- McpAccountStorage *plugin = store->data;
- const gchar *pname = mcp_account_storage_name (plugin);
-
- DEBUG ("flushing plugin %s to long term storage", pname);
- mcp_account_storage_commit (plugin, ma);
- }
+ mcd_storage_commit (storage, NULL);
return TRUE;
}
@@ -1408,18 +1230,9 @@ static void
uncork_storage_plugins (McdAccountManager *account_manager)
{
McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (account_manager);
- McpAccountManager *mcp_am = MCP_ACCOUNT_MANAGER (priv->plugin_manager);
- GList *store;
- /* Allow plugins to register new accounts, highest prio first */
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
-
- DEBUG ("Unblocking async account ops by %s",
- mcp_account_storage_name (plugin));
- mcp_account_storage_ready (plugin, mcp_am);
- }
+ mcd_account_manager_write_conf_async (account_manager, NULL, NULL, NULL);
+ _mcd_plugin_account_manager_ready (priv->plugin_manager);
}
/**
@@ -1433,6 +1246,7 @@ void
_mcd_account_manager_setup (McdAccountManager *account_manager)
{
McdAccountManagerPrivate *priv = account_manager->priv;
+ McdStorage *storage = MCD_STORAGE (priv->plugin_manager);
McdLoadAccountsData *lad;
gchar **accounts, **name;
@@ -1444,7 +1258,8 @@ _mcd_account_manager_setup (McdAccountManager *account_manager)
lad->account_manager = account_manager;
lad->account_lock = 1; /* will be released at the end of this function */
- accounts = g_key_file_get_groups (priv->plugin_manager->keyfile, NULL);
+ accounts = mcd_storage_dup_accounts (storage, NULL);
+
for (name = accounts; *name != NULL; name++)
{
gboolean plausible = FALSE;
@@ -1462,6 +1277,7 @@ _mcd_account_manager_setup (McdAccountManager *account_manager)
account = MCD_ACCOUNT_MANAGER_GET_CLASS (account_manager)->account_new
(account_manager, *name);
+
if (G_UNLIKELY (!account))
{
g_warning ("%s: account %s failed to instantiate", G_STRFUNC,
@@ -1639,8 +1455,14 @@ static void
mcd_account_manager_init (McdAccountManager *account_manager)
{
McdAccountManagerPrivate *priv;
- GList *store = NULL;
- McpAccountManager *ma;
+ guint i = 0;
+ static struct { const gchar *name; GCallback handler; } sig[] =
+ { { "created", G_CALLBACK (created_cb) },
+ { "altered", G_CALLBACK (altered_cb) },
+ { "toggled", G_CALLBACK (toggled_cb) },
+ { "deleted", G_CALLBACK (deleted_cb) },
+ { "altered-one", G_CALLBACK (altered_one_cb) },
+ { NULL, NULL } };
DEBUG ("");
@@ -1650,7 +1472,6 @@ mcd_account_manager_init (McdAccountManager *account_manager)
account_manager->priv = priv;
priv->plugin_manager = mcd_plugin_account_manager_new ();
- ma = MCP_ACCOUNT_MANAGER (priv->plugin_manager);
priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, unref_account);
@@ -1660,40 +1481,13 @@ mcd_account_manager_init (McdAccountManager *account_manager)
NULL);
DEBUG ("loading plugins");
+ mcd_storage_load (MCD_STORAGE (priv->plugin_manager));
- /* not guaranteed to have been called, but idempotent: */
- _mcd_plugin_loader_init ();
-
- if (!plugins_cached)
- sort_and_cache_plugins (account_manager);
-
- store = g_list_last (stores);
-
- /* fetch accounts stored in plugins, in reverse priority so higher prio *
- * plugins can overwrite lower prio ones' account data */
- while (store != NULL)
- {
- GList *account;
- McpAccountStorage *plugin = store->data;
- GList *stored = mcp_account_storage_list (plugin, ma);
- const gchar *pname = mcp_account_storage_name (plugin);
- const gint prio = mcp_account_storage_priority (plugin);
-
- DEBUG ("listing from plugin %s [prio: %d]", pname, prio);
- for (account = stored; account != NULL; account = g_list_next (account))
- {
- gchar *name = account->data;
-
- DEBUG ("fetching %s from plugin %s [prio: %d]", name, pname, prio);
- mcp_account_storage_get (plugin, ma, name, NULL);
-
- g_free (name);
- }
-
- /* already freed the contents, just need to free the list itself */
- g_list_free (stored);
- store = g_list_previous (store);
- }
+ /* hook up all the storage plugin signals to their handlers: */
+ for (i = 0; sig[i].name != NULL; i++)
+ _mcd_plugin_account_manager_connect_signal (sig[i].name,
+ sig[i].handler,
+ account_manager);
/* initializes the interfaces */
mcd_dbus_init_interfaces_instances (account_manager);
@@ -1710,7 +1504,7 @@ _mcd_account_manager_constructed (GObject *obj)
* _init() to here and then mcd_plugin_account_manager_new() could take the
* TpDBusDaemon * as it should and everyone wins.
*/
- mcd_plugin_account_manager_set_dbus_daemon (pa, priv->dbus_daemon);
+ _mcd_plugin_account_manager_set_dbus_daemon (pa, priv->dbus_daemon);
}
McdAccountManager *
@@ -1749,68 +1543,6 @@ mcd_account_manager_get_dbus_daemon (McdAccountManager *account_manager)
* with the appropriate error.
*/
-/*
- * update_one_account:
- * @account_manager:
- * @ma:
- * @account: (allow-none): the #McdAccount if it exists, or %NULL
- * @account_name:
- * @keyfile:
- */
-static void
-update_one_account (McdAccountManager *account_manager,
- McpAccountManager *ma,
- McdAccount *account,
- const gchar *account_name,
- GKeyFile *keyfile)
-{
- gsize n_keys = 0;
- GStrv keys = g_key_file_get_keys (keyfile, account_name, &n_keys, NULL);
- gsize j = 0;
-
- if (keys == NULL)
- n_keys = 0;
-
- for (j = 0; j < n_keys; j++)
- {
- gboolean done = FALSE;
- gchar *set = keys[j];
- gchar *val = g_key_file_get_value (keyfile, account_name, set, NULL);
- GList *store;
-
- /* the param- prefix gets whacked on in the layer above us: *
- * mcd-account et al don't know it exists so don't pass it back */
- if (account != NULL && g_str_has_prefix (set, PARAM_PREFIX))
- {
- const gchar *p = set + strlen (PARAM_PREFIX);
-
- if (mcd_account_parameter_is_secret (account, p))
- mcp_account_manager_parameter_make_secret (ma, account_name,
- set);
- }
-
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
- const gchar *pname = mcp_account_storage_name (plugin);
-
- if (done)
- {
- DEBUG ("MCP:%s -> delete %s.%s", pname, account_name, set);
- mcp_account_storage_delete (plugin, ma, account_name, set);
- }
- else
- {
- done = mcp_account_storage_set (plugin, ma, account_name, set, val);
- DEBUG ("MCP:%s -> %s %s.%s",
- pname, done ? "store" : "ignore", account_name, set);
- }
- }
- }
-
- g_strfreev (keys);
-}
-
/**
* mcd_account_manager_write_conf_async:
* @account_manager: the #McdAccountManager
@@ -1826,68 +1558,33 @@ mcd_account_manager_write_conf_async (McdAccountManager *account_manager,
McdAccountManagerWriteConfCb callback,
gpointer user_data)
{
- GList *store;
- GKeyFile *keyfile;
- McpAccountManager *ma;
+ McdStorage *storage = NULL;
+ const gchar *account_name = NULL;
g_return_if_fail (MCD_IS_ACCOUNT_MANAGER (account_manager));
- keyfile = account_manager->priv->plugin_manager->keyfile;
- ma = MCP_ACCOUNT_MANAGER (account_manager->priv->plugin_manager);
+ storage = MCD_STORAGE (account_manager->priv->plugin_manager);
if (account != NULL)
{
- const gchar *account_name = mcd_account_get_unique_name (account);
+ account_name = mcd_account_get_unique_name (account);
DEBUG ("updating %s", account_name);
- update_one_account (account_manager, ma, account, account_name,
- keyfile);
+ mcd_storage_commit (storage, account_name);
}
else
{
GStrv groups;
gsize n_accounts = 0;
- gsize i = 0;
- gchar *group;
-
- groups = g_key_file_get_groups (keyfile, &n_accounts);
+ groups = mcd_storage_dup_accounts (storage, &n_accounts);
DEBUG ("updating all %" G_GSIZE_FORMAT " accounts)", n_accounts);
- for (group = groups[i]; group != NULL; group = groups[++i])
- {
- McdAccount *group_account =
- mcd_account_manager_lookup_account (account_manager,
- group);
-
- /* group_account might be %NULL, but update_one_account tolerates
- * that */
- update_one_account (account_manager, ma, group_account, group,
- keyfile);
- }
+ mcd_storage_commit (storage, NULL);
g_strfreev (groups);
}
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
- const gchar *pname = mcp_account_storage_name (plugin);
-
- DEBUG ("flushing plugin %s to long term storage", pname);
-
- if (account == NULL)
- {
- mcp_account_storage_commit (plugin, ma);
- }
- else
- {
- const gchar *account_name = mcd_account_get_unique_name (account);
-
- mcp_account_storage_commit_one (plugin, ma, account_name);
- }
- }
-
if (callback != NULL)
callback (account_manager, NULL, user_data);
}
@@ -1923,20 +1620,6 @@ mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager,
object_path + (sizeof (MC_ACCOUNT_DBUS_OBJECT_BASE) - 1));
}
-/**
- * mcd_account_manager_get_config:
- * @account_manager: the #McdAccountManager.
- *
- * Returns: the #GKeyFile holding the configuration.
- */
-GKeyFile *
-mcd_account_manager_get_config (McdAccountManager *account_manager)
-{
- g_return_val_if_fail (MCD_IS_ACCOUNT_MANAGER (account_manager), NULL);
-
- return account_manager->priv->plugin_manager->keyfile;
-}
-
/*
* _mcd_account_manager_store_account_connections:
* @account_manager: the #McdAccountManager.
@@ -1983,29 +1666,9 @@ _mcd_account_manager_store_account_connections (McdAccountManager *manager)
fclose (file);
}
-McpAccountStorage *
-mcd_account_manager_get_storage_plugin (McdAccountManager *account_manager,
- McdAccount *account)
+McdStorage *
+mcd_account_manager_get_storage (McdAccountManager *account_manager)
{
- GList *store;
- const gchar *account_name = mcd_account_get_unique_name (account);
- McpAccountManager *ma = MCP_ACCOUNT_MANAGER (
- account_manager->priv->plugin_manager);
-
- for (store = stores; store != NULL; store = g_list_next (store))
- {
- McpAccountStorage *plugin = store->data;
- GList *stored = mcp_account_storage_list (plugin, ma);
- GList *iter;
-
- for (iter = stored; iter != NULL; iter = g_list_next (iter))
- {
- gchar *name = iter->data;
-
- if (g_strcmp0 (name, account_name) == 0)
- return plugin;
- }
- }
-
- return NULL;
+ return MCD_STORAGE (account_manager->priv->plugin_manager);
}
+
diff --git a/src/mcd-account-manager.h b/src/mcd-account-manager.h
index 39db4622..6c60123a 100644
--- a/src/mcd-account-manager.h
+++ b/src/mcd-account-manager.h
@@ -26,6 +26,7 @@
#include <telepathy-glib/dbus.h>
#include "mission-control-plugins/mission-control-plugins.h"
+#include "mcd-storage.h"
G_BEGIN_DECLS
#define MCD_TYPE_ACCOUNT_MANAGER (mcd_account_manager_get_type ())
@@ -99,8 +100,6 @@ McdAccount *mcd_account_manager_lookup_account (McdAccountManager *account_manag
McdAccount *mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager,
const gchar *object_path);
-McpAccountStorage *mcd_account_manager_get_storage_plugin (
- McdAccountManager *account_manager,
- McdAccount *account);
+McdStorage *mcd_account_manager_get_storage (McdAccountManager *manager);
#endif
diff --git a/src/mcd-account-priv.h b/src/mcd-account-priv.h
index 9f0c9179..a8d76f2b 100644
--- a/src/mcd-account-priv.h
+++ b/src/mcd-account-priv.h
@@ -114,16 +114,16 @@ typedef struct {
G_GNUC_INTERNAL
GList *_mcd_account_get_online_requests (McdAccount *account);
+G_GNUC_INTERNAL McdStorage *_mcd_account_get_storage (McdAccount *account);
static inline void
_mcd_account_write_conf (McdAccount *account)
{
- McdAccountManager *account_manager;
+ McdStorage *storage = _mcd_account_get_storage (account);
- account_manager = mcd_account_get_account_manager (account);
- g_return_if_fail (MCD_IS_ACCOUNT_MANAGER (account_manager));
+ g_return_if_fail (MCD_IS_STORAGE (storage));
- mcd_account_manager_write_conf_async (account_manager, account, NULL, NULL);
+ mcd_storage_commit (storage, mcd_account_get_unique_name (account));
}
G_GNUC_INTERNAL void _mcd_account_compat_class_init (McdAccountClass *klass);
diff --git a/src/mcd-account-requests.c b/src/mcd-account-requests.c
index e9cfe316..1db1cc09 100644
--- a/src/mcd-account-requests.c
+++ b/src/mcd-account-requests.c
@@ -190,8 +190,8 @@ _mcd_account_create_request (McdAccount *account, GHashTable *properties,
{
McdChannel *channel;
GHashTable *props;
- TpDBusDaemon *dbus_daemon = mcd_account_manager_get_dbus_daemon (
- mcd_account_get_account_manager (account));
+ TpDBusDaemon *dbus_daemon = mcd_account_get_dbus_daemon (account);
+
DBusGConnection *dgc = tp_proxy_get_dbus_connection (dbus_daemon);
if (!mcd_account_check_request (account, properties, error))
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 2770a789..74af7280 100644
--- a/src/mcd-account.c
+++ b/src/mcd-account.c
@@ -26,6 +26,7 @@
#include "config.h"
#include "mcd-account.h"
+#include "mcd-storage-priv.h"
#include <stdio.h>
#include <string.h>
@@ -120,7 +121,10 @@ struct _McdAccountPrivate
TpConnection *tp_connection;
McdConnection *connection;
McdManager *manager;
- McdAccountManager *account_manager;
+
+ McdStorage *storage;
+ TpDBusDaemon *dbus_daemon;
+
McdTransport *transport;
McdAccountConnectionContext *connection_context;
GKeyFile *keyfile; /* configuration file */
@@ -181,7 +185,7 @@ enum
{
PROP_0,
PROP_DBUS_DAEMON,
- PROP_ACCOUNT_MANAGER,
+ PROP_STORAGE,
PROP_NAME,
PROP_ALWAYS_ON,
};
@@ -384,242 +388,34 @@ mcd_account_loaded (McdAccount *account)
g_object_unref (account);
}
-static gboolean
-keyfile_set_value (GKeyFile *keyfile,
- const gchar *group_name,
- const gchar *key_name,
- const GValue *value,
- GError **error)
-{
- gchar buf[21]; /* enough for '-' + the 19 digits of 2**63 + '\0' */
-
- if (!value)
- {
- g_key_file_remove_key (keyfile, group_name, key_name, NULL);
- DEBUG ("unset param %s", key_name);
- return TRUE;
- }
-
- switch (G_VALUE_TYPE (value))
- {
- case G_TYPE_STRING:
- g_key_file_set_string (keyfile, group_name, key_name,
- g_value_get_string (value));
- break;
-
- case G_TYPE_UINT:
- g_snprintf (buf, sizeof (buf), "%u", g_value_get_uint (value));
- g_key_file_set_string (keyfile, group_name, key_name,
- buf);
- break;
-
- case G_TYPE_INT:
- g_key_file_set_integer (keyfile, group_name, key_name,
- g_value_get_int (value));
- break;
-
- case G_TYPE_BOOLEAN:
- g_key_file_set_boolean (keyfile, group_name, key_name,
- g_value_get_boolean (value));
- break;
-
- case G_TYPE_UCHAR:
- g_key_file_set_integer (keyfile, group_name, key_name,
- g_value_get_uchar (value));
- break;
-
- case G_TYPE_UINT64:
- g_snprintf (buf, sizeof (buf), "%" G_GUINT64_FORMAT,
- g_value_get_uint64 (value));
- g_key_file_set_string (keyfile, group_name, key_name,
- buf);
- break;
-
- case G_TYPE_INT64:
- g_snprintf (buf, sizeof (buf), "%" G_GINT64_FORMAT,
- g_value_get_int64 (value));
- g_key_file_set_string (keyfile, group_name, key_name,
- buf);
- break;
-
- case G_TYPE_DOUBLE:
- g_key_file_set_double (keyfile, group_name, key_name,
- g_value_get_double (value));
- break;
-
- default:
- if (G_VALUE_HOLDS (value, G_TYPE_STRV))
- {
- gchar **strings = g_value_get_boxed (value);
-
- g_key_file_set_string_list (keyfile, group_name, key_name,
- (const gchar **)strings,
- g_strv_length (strings));
- }
- else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
- {
- const gchar *path = g_value_get_boxed (value);
-
- g_key_file_set_string (keyfile, group_name, key_name,
- path);
- }
- else
- {
- g_warning ("Unexpected param type %s", G_VALUE_TYPE_NAME (value));
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
static void
set_parameter (McdAccount *account, const gchar *name, const GValue *value,
McdAccountSetParameterCb callback, gpointer user_data)
{
McdAccountPrivate *priv = account->priv;
+ McdStorage *storage = priv->storage;
gchar key[MAX_KEY_LENGTH];
- GError *error = NULL;
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ gboolean secret = mcd_account_parameter_is_secret (account, name);
g_snprintf (key, sizeof (key), "param-%s", name);
- keyfile_set_value (priv->keyfile, priv->unique_name, key,
- value, &error);
+ mcd_storage_set_value (storage, account_name, key, value, secret);
if (callback != NULL)
- {
- callback (account, error, user_data);
- }
-
- if (error != NULL)
- g_error_free (error);
+ callback (account, NULL, user_data); /* set_parameter */
}
-static GValue *
-keyfile_get_value (GKeyFile *keyfile,
- const gchar *group_name,
- const gchar *key_name,
- GType type,
- GError **error)
-{
- GValue *value = NULL;
- gchar *v_string = NULL;
- gint64 v_int = 0;
- guint64 v_uint = 0;
- gboolean v_bool = FALSE;
- double v_double = 0.0;
- switch (type)
- {
- case G_TYPE_STRING:
- v_string = g_key_file_get_string (keyfile, group_name,
- key_name, error);
- value = tp_g_value_slice_new_take_string (v_string);
- break;
- case G_TYPE_INT:
- v_int = g_key_file_get_integer (keyfile, group_name,
- key_name, error);
- value = tp_g_value_slice_new_int (v_int);
- break;
- case G_TYPE_INT64:
- v_int = tp_g_key_file_get_int64 (keyfile, group_name,
- key_name, error);
- value = tp_g_value_slice_new_int64 (v_int);
- break;
- case G_TYPE_UINT:
- v_uint = tp_g_key_file_get_uint64 (keyfile,
- group_name, key_name, error);
- if (v_uint > 0xFFFFFFFFU)
- {
- g_set_error (error, MCD_ACCOUNT_ERROR,
- MCD_ACCOUNT_ERROR_GET_PARAMETER,
- "Integer is out of range");
- }
- else
- {
- value = tp_g_value_slice_new_uint (v_uint);
- }
- break;
- case G_TYPE_UCHAR:
- v_int = g_key_file_get_integer (keyfile, group_name,
- key_name, error);
- if (v_int < 0 || v_int > 0xFF)
- {
- g_set_error (error, MCD_ACCOUNT_ERROR,
- MCD_ACCOUNT_ERROR_GET_PARAMETER,
- "Integer is out of range");
- }
- else
- {
- value = tp_g_value_slice_new (G_TYPE_UCHAR);
- g_value_set_uchar (value, v_int);
- }
- break;
- case G_TYPE_UINT64:
- v_uint = tp_g_key_file_get_uint64 (keyfile,
- group_name, key_name, error);
- value = tp_g_value_slice_new_uint64 (v_uint);
- break;
-
- case G_TYPE_BOOLEAN:
- v_bool = g_key_file_get_boolean (keyfile, group_name,
- key_name, NULL);
-
- value = tp_g_value_slice_new_boolean (v_bool);
- break;
-
- case G_TYPE_DOUBLE:
- v_double = g_key_file_get_double (keyfile, group_name,
- key_name, NULL);
-
- value = tp_g_value_slice_new_double (v_double);
- break;
-
- default:
- if (type == G_TYPE_STRV)
- {
- gchar **v = g_key_file_get_string_list (keyfile,
- group_name, key_name,
- NULL, error);
-
- value = tp_g_value_slice_new_take_boxed (G_TYPE_STRV, v);
- }
- else if (type == DBUS_TYPE_G_OBJECT_PATH)
- {
- v_string = g_key_file_get_string (keyfile,
- group_name, key_name,
- error);
-
- if (!tp_dbus_check_valid_object_path (v_string, NULL))
- {
- g_set_error (error, MCD_ACCOUNT_ERROR,
- MCD_ACCOUNT_ERROR_GET_PARAMETER,
- "Invalid object path %s", v_string);
- g_free (v_string);
- }
- else
- {
- value = tp_g_value_slice_new_take_object_path (v_string);
- }
- }
- else
- {
- g_warning ("%s: cannot get property %s, unknown type %s",
- G_STRFUNC, key_name, g_type_name (type));
- }
- }
-
- return value;
-}
static GType mc_param_type (const TpConnectionManagerParam *param);
@@ -635,20 +431,23 @@ get_parameter_from_file (McdAccount *account, const gchar *name,
McdAccountGetParameterCb callback, gpointer user_data)
{
McdAccountPrivate *priv = account->priv;
+ McdStorage *storage = priv->storage;
gchar key[MAX_KEY_LENGTH];
const TpConnectionManagerParam *param;
GError *error = NULL;
GValue *value = NULL;
GType type;
+ const gchar *account_name = mcd_account_get_unique_name (account);
param = mcd_manager_get_protocol_param (priv->manager,
priv->protocol_name, name);
type = mc_param_type (param);
g_snprintf (key, sizeof (key), "param-%s", name);
- if (g_key_file_has_key (priv->keyfile, priv->unique_name, key, NULL))
+
+ if (mcd_storage_has_value (storage, account_name, key))
{
- value = keyfile_get_value (priv->keyfile, priv->unique_name, key, type, &error);
+ value = mcd_storage_dup_value (storage, account_name, key, type, &error);
}
else
{
@@ -740,26 +539,6 @@ get_account_data_path (McdAccountPrivate *priv)
return g_build_filename (base, priv->unique_name, NULL);
}
-typedef struct
-{
- McdAccount *account;
- McdAccountDeleteCb callback;
- gpointer user_data;
-} AccountDeleteData;
-
-static void
-_mcd_account_delete_write_conf_cb (McdAccountManager *account_manager,
- const GError *error,
- gpointer user_data)
-{
- AccountDeleteData *data = (AccountDeleteData *) user_data;
-
- if (data->callback != NULL)
- data->callback (data->account, error, data->user_data);
-
- g_slice_free (AccountDeleteData, data);
-}
-
static void
_mcd_account_delete (McdAccount *account,
McdAccountDeleteCb callback,
@@ -767,36 +546,20 @@ _mcd_account_delete (McdAccount *account,
{
McdAccountPrivate *priv = account->priv;
gchar *data_dir_str;
- GError *kf_error = NULL;
- AccountDeleteData *delete_data;
+ GError *error = NULL;
+ const gchar *name = mcd_account_get_unique_name (account);
/* got to turn the account off before removing it, otherwise we can *
* end up with an orphaned CM holding the account online */
- if (!_mcd_account_set_enabled (account, FALSE, FALSE, &kf_error))
+ if (!_mcd_account_set_enabled (account, FALSE, FALSE, &error))
{
- g_warning ("could not disable account (%s)", kf_error->message);
- callback (account, kf_error, user_data);
- g_error_free (kf_error);
+ g_warning ("could not disable account %s (%s)", name, error->message);
+ callback (account, error, user_data);
+ g_error_free (error);
return;
}
- if (!g_key_file_remove_group (priv->keyfile, priv->unique_name,
- &kf_error))
- {
- if (kf_error->domain == G_KEY_FILE_ERROR &&
- kf_error->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
- {
- DEBUG ("account not found in key file, doing nothing");
- g_clear_error (&kf_error);
- }
- else
- {
- g_warning ("Could not remove group (%s)", kf_error->message);
- callback (account, kf_error, user_data);
- g_error_free (kf_error);
- return;
- }
- }
+ mcd_storage_delete_account (priv->storage, name);
data_dir_str = get_account_data_path (priv);
@@ -823,15 +586,9 @@ _mcd_account_delete (McdAccount *account,
g_free (data_dir_str);
}
- delete_data = g_slice_new0 (AccountDeleteData);
- delete_data->account = account;
- delete_data->callback = callback;
- delete_data->user_data = user_data;
-
- mcd_account_manager_write_conf_async (priv->account_manager,
- account,
- _mcd_account_delete_write_conf_cb,
- delete_data);
+ mcd_storage_commit (priv->storage, name);
+ if (callback != NULL)
+ callback (account, NULL, user_data);
}
static void
@@ -1123,8 +880,12 @@ mcd_account_set_string_val (McdAccount *account, const gchar *key,
const GValue *value, GError **error)
{
McdAccountPrivate *priv = account->priv;
- const gchar *string;
+ McdStorage *storage = priv->storage;
+ const gchar *name = mcd_account_get_unique_name (account);
+
+ const gchar *new_string;
gchar *old_string;
+ const GValue *set = value;
if (!G_VALUE_HOLDS_STRING (value))
{
@@ -1134,28 +895,23 @@ mcd_account_set_string_val (McdAccount *account, const gchar *key,
return SET_RESULT_ERROR;
}
- string = g_value_get_string (value);
- old_string = g_key_file_get_string (priv->keyfile, priv->unique_name,
- key, NULL);
- if (!tp_strdiff (old_string, string))
+ old_string = mcd_storage_dup_string (storage, name, key);
+ new_string = g_value_get_string (value);
+
+ if (!tp_strdiff (old_string, new_string))
{
- g_free (old_string);
- return SET_RESULT_UNCHANGED;
+ g_free (old_string);
+ return SET_RESULT_UNCHANGED;
}
g_free (old_string);
- if (string && string[0] != 0)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- key, string);
- else
- {
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- key, NULL);
- string = NULL;
- }
- mcd_account_manager_write_conf_async (priv->account_manager, account, NULL,
- NULL);
+
+ if (new_string == NULL || *new_string == '\0')
+ set = NULL;
+
+ mcd_storage_set_value (storage, name, key, set, FALSE);
mcd_account_changed_property (account, key, value);
+
return SET_RESULT_CHANGED;
}
@@ -1164,12 +920,22 @@ mcd_account_get_string_val (McdAccount *account, const gchar *key,
GValue *value)
{
McdAccountPrivate *priv = account->priv;
- gchar *string;
+ const gchar *name = mcd_account_get_unique_name (account);
+ GValue *fetched = NULL;
- string = g_key_file_get_string (priv->keyfile, priv->unique_name,
- key, NULL);
+ fetched =
+ mcd_storage_dup_value (priv->storage, name, key, G_TYPE_STRING, NULL);
g_value_init (value, G_TYPE_STRING);
- g_value_take_string (value, string);
+
+ if (fetched != NULL)
+ {
+ g_value_copy (fetched, value);
+ tp_g_value_slice_free (fetched);
+ }
+ else
+ {
+ g_value_set_static_string (value, NULL);
+ }
}
static gboolean
@@ -1261,24 +1027,26 @@ _mcd_account_set_enabled (McdAccount *account,
if (priv->enabled != enabled)
{
GValue value = { 0, };
+ const gchar *name = mcd_account_get_unique_name (account);
if (!enabled)
mcd_account_request_presence (account,
TP_CONNECTION_PRESENCE_TYPE_OFFLINE,
"offline", NULL);
- g_key_file_set_boolean (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_ENABLED,
- enabled);
priv->enabled = enabled;
- if (write_out)
- mcd_account_manager_write_conf_async (priv->account_manager,
- account, NULL, NULL);
-
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, enabled);
+
+ mcd_storage_set_value (priv->storage, name,
+ MC_ACCOUNTS_KEY_ENABLED, &value, FALSE);
+
+ if (write_out)
+ mcd_storage_commit (priv->storage, name);
+
mcd_account_changed_property (account, "Enabled", &value);
+
g_value_unset (&value);
if (enabled)
@@ -1543,8 +1311,9 @@ set_automatic_presence (TpSvcDBusProperties *self,
TpConnectionPresenceType type;
gboolean changed = FALSE;
GValueArray *va;
+ const gchar *account_name = mcd_account_get_unique_name (account);
- DEBUG ("called for %s", priv->unique_name);
+ DEBUG ("called for %s", account_name);
if (!G_VALUE_HOLDS (value, TP_STRUCT_TYPE_SIMPLE_PRESENCE))
{
@@ -1571,45 +1340,55 @@ set_automatic_presence (TpSvcDBusProperties *self,
if (priv->auto_presence_type != type)
{
- g_key_file_set_integer (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE, type);
- priv->auto_presence_type = type;
- changed = TRUE;
+ GValue presence = { 0 };
+
+ g_value_init (&presence, G_TYPE_INT);
+ g_value_set_int (&presence, type);
+
+ mcd_storage_set_value (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE,
+ &presence, FALSE);
+ priv->auto_presence_type = type;
+ changed = TRUE;
}
+
if (tp_strdiff (priv->auto_presence_status, status))
{
- if (status && status[0] != 0)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
- status);
- else
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
- NULL);
- g_free (priv->auto_presence_status);
- priv->auto_presence_status = g_strdup (status);
- changed = TRUE;
+ const gchar *new_status = NULL;
+
+ if (status != NULL && status[0] != 0)
+ new_status = status;
+
+ mcd_storage_set_string (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
+ new_status, FALSE);
+
+ g_free (priv->auto_presence_status);
+ priv->auto_presence_status = g_strdup (status);
+ changed = TRUE;
}
+
if (tp_strdiff (priv->auto_presence_message, message))
{
- if (message && message[0] != 0)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
- message);
- else
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
- NULL);
- g_free (priv->auto_presence_message);
- priv->auto_presence_message = g_strdup (message);
- changed = TRUE;
+ const gchar *new_message = NULL;
+
+ if (!tp_str_empty (message))
+ new_message = message;
+
+ mcd_storage_set_string (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
+ new_message, FALSE);
+
+ g_free (priv->auto_presence_message);
+ priv->auto_presence_message = g_strdup (message);
+ changed = TRUE;
}
+
if (changed)
{
- mcd_account_manager_write_conf_async (priv->account_manager, account,
- NULL, NULL);
- mcd_account_changed_property (account, name, value);
+ mcd_storage_commit (priv->storage, account_name);
+ mcd_account_changed_property (account, name, value);
}
return TRUE;
@@ -1670,13 +1449,14 @@ set_connect_automatically (TpSvcDBusProperties *self,
if (priv->connect_automatically != connect_automatically)
{
- g_key_file_set_boolean (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY,
- connect_automatically);
- priv->connect_automatically = connect_automatically;
- mcd_account_manager_write_conf_async (priv->account_manager, account,
- NULL, NULL);
- mcd_account_changed_property (account, name, value);
+ const gchar *account_name = mcd_account_get_unique_name (account);
+ mcd_storage_set_value (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY,
+ value, FALSE);
+
+ priv->connect_automatically = connect_automatically;
+ mcd_storage_commit (priv->storage, account_name);
+ mcd_account_changed_property (account, name, value);
if (connect_automatically)
{
@@ -1878,15 +1658,15 @@ static McpAccountStorage *
get_storage_plugin (McdAccount *account)
{
McdAccountPrivate *priv = account->priv;
+ const gchar *account_name = mcd_account_get_unique_name (account);
if (priv->storage_plugin != NULL)
return priv->storage_plugin;
- priv->storage_plugin = mcd_account_manager_get_storage_plugin (
- priv->account_manager, account);
+ priv->storage_plugin = mcd_storage_get_plugin (priv->storage, account_name);
- if (priv->storage_plugin != NULL)
- g_object_ref (priv->storage_plugin);
+ if (priv->storage_plugin != NULL)
+ g_object_ref (priv->storage_plugin);
return priv->storage_plugin;
}
@@ -2565,7 +2345,6 @@ set_parameters_iter_param (McdAccount *account,
if (data->new != NULL)
{
- DEBUG ("Got param %s", data->param->name);
data->n_params++;
if (G_VALUE_TYPE (data->new) != type)
@@ -2703,14 +2482,14 @@ update_parameters_dup_params_cb (McdAccount *account, GHashTable *params,
McdAccountPrivate *priv = account->priv;
UpdateParametersData *data = (UpdateParametersData *) user_data;
GValue value = { 0 };
+ const gchar *account_name = mcd_account_get_unique_name (account);
g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP);
g_value_take_boxed (&value, params);
mcd_account_changed_property (account, "Parameters", &value);
g_value_unset (&value);
- mcd_account_manager_write_conf_async (priv->account_manager, account, NULL,
- NULL);
+ mcd_storage_commit (priv->storage, account_name);
g_ptr_array_add (data->not_yet, NULL);
@@ -2825,14 +2604,13 @@ register_dbus_service (McdAccount *self,
}
g_assert (MCD_IS_ACCOUNT (self));
- /* these are invariants - the account manager is set at construct-time
+ /* these are invariants - the storage is set at construct-time
* and the object path is set in mcd_account_setup, both of which are
* run before this callback can possibly be invoked */
- g_assert (self->priv->account_manager != NULL);
+ g_assert (self->priv->storage != NULL);
g_assert (self->priv->object_path != NULL);
- dbus_daemon = mcd_account_manager_get_dbus_daemon (
- self->priv->account_manager);
+ dbus_daemon = self->priv->dbus_daemon;
g_return_if_fail (dbus_daemon != NULL);
dbus_connection = TP_PROXY (dbus_daemon)->dbus_connection;
@@ -2847,55 +2625,46 @@ static gboolean
mcd_account_setup (McdAccount *account)
{
McdAccountPrivate *priv = account->priv;
-
- priv->keyfile = mcd_account_manager_get_config (priv->account_manager);
- if (!priv->keyfile)
- {
- g_error ("Could not find internal data");
- goto broken_account;
- }
+ McdStorage *storage = priv->storage;
+ const gchar *name = mcd_account_get_unique_name (account);
priv->manager_name =
- g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_MANAGER, NULL);
- if (!priv->manager_name)
+ mcd_storage_dup_string (storage, name, MC_ACCOUNTS_KEY_MANAGER);
+
+ if (priv->manager_name == NULL)
{
- g_warning ("Account '%s' has no manager", account->priv->unique_name);
+ g_warning ("Account '%s' has no manager", name);
goto broken_account;
}
priv->protocol_name =
- g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_PROTOCOL, NULL);
- if (!priv->protocol_name)
+ mcd_storage_dup_string (storage, name, MC_ACCOUNTS_KEY_PROTOCOL);
+
+ if (priv->protocol_name == NULL)
{
g_warning ("Account has no protocol");
goto broken_account;
}
- priv->object_path = g_strconcat (MC_ACCOUNT_DBUS_OBJECT_BASE,
- priv->unique_name, NULL);
+ priv->object_path = g_strconcat (MC_ACCOUNT_DBUS_OBJECT_BASE, name, NULL);
if (!priv->always_on)
{
priv->enabled =
- g_key_file_get_boolean (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_ENABLED, NULL);
+ mcd_storage_get_boolean (storage, name, MC_ACCOUNTS_KEY_ENABLED);
priv->connect_automatically =
- g_key_file_get_boolean (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY,
- NULL);
+ mcd_storage_get_boolean (storage, name,
+ MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY);
}
priv->has_been_online =
- g_key_file_get_boolean (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE, NULL);
+ mcd_storage_get_boolean (storage, name, MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE);
/* load the automatic presence */
priv->auto_presence_type =
- g_key_file_get_integer (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE, NULL);
+ mcd_storage_get_integer (storage, name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE);
/* If invalid or something, force it to AVAILABLE - we want the auto
* presence type to be an online status */
@@ -2909,16 +2678,14 @@ mcd_account_setup (McdAccount *account)
{
g_free (priv->auto_presence_status);
priv->auto_presence_status =
- g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
- NULL);
+ mcd_storage_dup_string (storage, name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS);
}
g_free (priv->auto_presence_message);
priv->auto_presence_message =
- g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
- NULL);
+ mcd_storage_dup_string (storage, name,
+ MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE);
/* check the manager */
if (!priv->manager && !load_manager (account))
@@ -2952,13 +2719,16 @@ set_property (GObject *obj, guint prop_id,
switch (prop_id)
{
- case PROP_ACCOUNT_MANAGER:
- g_assert (priv->account_manager == NULL);
- /* don't keep a reference to the account_manager: we can safely assume
- * its lifetime is longer than the McdAccount's */
- priv->account_manager = g_value_get_object (val);
+ case PROP_STORAGE:
+ g_assert (priv->storage == NULL);
+ priv->storage = g_value_dup_object (val);
break;
+ case PROP_DBUS_DAEMON:
+ g_assert (priv->dbus_daemon == NULL);
+ priv->dbus_daemon = g_value_dup_object (val);
+ break;
+
case PROP_NAME:
g_assert (priv->unique_name == NULL);
priv->unique_name = g_value_dup_string (val);
@@ -2993,8 +2763,7 @@ get_property (GObject *obj, guint prop_id,
switch (prop_id)
{
case PROP_DBUS_DAEMON:
- g_value_set_object
- (val, mcd_account_manager_get_dbus_daemon (priv->account_manager));
+ g_value_set_object (val, priv->dbus_daemon);
break;
case PROP_NAME:
g_value_set_string (val, priv->unique_name);
@@ -3076,8 +2845,9 @@ _mcd_account_dispose (GObject *object)
}
tp_clear_object (&priv->manager);
-
tp_clear_object (&priv->storage_plugin);
+ tp_clear_object (&priv->storage);
+ tp_clear_object (&priv->dbus_daemon);
_mcd_account_set_connection_context (self, NULL);
_mcd_account_set_connection (self, NULL);
@@ -3097,7 +2867,8 @@ _mcd_account_constructor (GType type, guint n_params,
priv = account->priv;
g_return_val_if_fail (account != NULL, NULL);
- if (G_UNLIKELY (!priv->account_manager || !priv->unique_name))
+
+ if (G_UNLIKELY (!priv->storage || !priv->unique_name))
{
g_object_unref (account);
return NULL;
@@ -3142,12 +2913,13 @@ mcd_account_class_init (McdAccountClass * klass)
g_object_class_install_property
(object_class, PROP_DBUS_DAEMON,
g_param_spec_object ("dbus-daemon", "DBus daemon", "DBus daemon",
- TP_TYPE_DBUS_DAEMON, G_PARAM_READABLE));
+ TP_TYPE_DBUS_DAEMON,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
- (object_class, PROP_ACCOUNT_MANAGER,
- g_param_spec_object ("account-manager", "account-manager",
- "account-manager", MCD_TYPE_ACCOUNT_MANAGER,
+ (object_class, PROP_STORAGE,
+ g_param_spec_object ("storage", "storage",
+ "storage", MCD_TYPE_STORAGE,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
@@ -3234,26 +3006,30 @@ McdAccount *
mcd_account_new (McdAccountManager *account_manager, const gchar *name)
{
gpointer *obj;
+ McdStorage *storage = mcd_account_manager_get_storage (account_manager);
+ TpDBusDaemon *dbus = mcd_account_manager_get_dbus_daemon (account_manager);
+
obj = g_object_new (MCD_TYPE_ACCOUNT,
- "account-manager", account_manager,
+ "storage", storage,
+ "dbus-daemon", dbus,
"name", name,
NULL);
return MCD_ACCOUNT (obj);
}
-/**
- * mcd_account_get_account_manager:
- * @account: the #McdAccount.
- *
- * Returns: the #McdAccountManager.
- */
-McdAccountManager *
-mcd_account_get_account_manager (McdAccount *account)
+McdStorage *
+_mcd_account_get_storage (McdAccount *account)
{
- g_return_val_if_fail (MCD_IS_ACCOUNT (account), NULL);
- return account->priv->account_manager;
+ return account->priv->storage;
+}
+
+TpDBusDaemon *
+mcd_account_get_dbus_daemon (McdAccount *account)
+{
+ return account->priv->dbus_daemon;
}
+
/*
* mcd_account_is_valid:
* @account: the #McdAccount.
@@ -3586,21 +3362,21 @@ _mcd_account_set_normalized_name (McdAccount *account, const gchar *name)
{
McdAccountPrivate *priv = account->priv;
GValue value = { 0, };
+ const gchar *account_name = mcd_account_get_unique_name (account);
DEBUG ("called (%s)", name);
- if (name)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_NORMALIZED_NAME, name);
- else
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_NORMALIZED_NAME, NULL);
-
- mcd_account_manager_write_conf_async (priv->account_manager, account, NULL,
- NULL);
g_value_init (&value, G_TYPE_STRING);
g_value_set_static_string (&value, name);
- mcd_account_changed_property (account, "NormalizedName", &value);
+
+ mcd_storage_set_value (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_NORMALIZED_NAME,
+ &value, FALSE);
+ mcd_storage_commit (priv->storage, account_name);
+ mcd_account_changed_property (account, MC_ACCOUNTS_KEY_NORMALIZED_NAME,
+ &value);
+
g_value_unset (&value);
}
@@ -3608,35 +3384,37 @@ gchar *
mcd_account_get_normalized_name (McdAccount *account)
{
McdAccountPrivate *priv = account->priv;
+ const gchar *account_name = mcd_account_get_unique_name (account);
- return g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_NORMALIZED_NAME, NULL);
+ return mcd_storage_dup_string (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_NORMALIZED_NAME);
}
void
_mcd_account_set_avatar_token (McdAccount *account, const gchar *token)
{
McdAccountPrivate *priv = account->priv;
+ const gchar *account_name = mcd_account_get_unique_name (account);
DEBUG ("called (%s)", token);
- if (token)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_TOKEN, token);
- else
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_TOKEN, NULL);
+ mcd_storage_set_string (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_AVATAR_TOKEN,
+ token, FALSE);
- mcd_account_manager_write_conf_async (priv->account_manager, account, NULL,
- NULL);
+ mcd_storage_commit (priv->storage, account_name);
}
gchar *
_mcd_account_get_avatar_token (McdAccount *account)
{
McdAccountPrivate *priv = account->priv;
+ const gchar *account_name = mcd_account_get_unique_name (account);
- return g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_TOKEN, NULL);
+ return mcd_storage_dup_string (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_AVATAR_TOKEN);
}
gboolean
@@ -3645,6 +3423,7 @@ _mcd_account_set_avatar (McdAccount *account, const GArray *avatar,
GError **error)
{
McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
gchar *data_dir, *filename;
DEBUG ("called");
@@ -3672,25 +3451,35 @@ _mcd_account_set_avatar (McdAccount *account, const GArray *avatar,
}
g_free (filename);
- if (mime_type)
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_MIME, mime_type);
+ if (mime_type != NULL)
+ mcd_storage_set_string (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_AVATAR_MIME,
+ mime_type, FALSE);
if (token)
{
gchar *prev_token;
prev_token = _mcd_account_get_avatar_token (account);
- g_key_file_set_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_TOKEN, token);
+
+ mcd_storage_set_string (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_AVATAR_TOKEN,
+ token, FALSE);
+
if (!prev_token || strcmp (prev_token, token) != 0)
tp_svc_account_interface_avatar_emit_avatar_changed (account);
+
g_free (prev_token);
}
else
{
- g_key_file_remove_key (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_TOKEN, NULL);
+ mcd_storage_set_value (priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_AVATAR_TOKEN,
+ NULL, FALSE);
+
/* this is a no-op if the connection doesn't support avatars */
if (priv->connection != NULL)
{
@@ -3698,8 +3487,8 @@ _mcd_account_set_avatar (McdAccount *account, const GArray *avatar,
}
}
- mcd_account_manager_write_conf_async (priv->account_manager, account, NULL,
- NULL);
+ mcd_storage_commit (priv->storage, account_name);
+
return TRUE;
}
@@ -3708,11 +3497,12 @@ _mcd_account_get_avatar (McdAccount *account, GArray **avatar,
gchar **mime_type)
{
McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
gchar *filename;
if (mime_type != NULL)
- *mime_type = g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_AVATAR_MIME, NULL);
+ *mime_type = mcd_storage_dup_string (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_AVATAR_MIME);
if (avatar == NULL)
return;
@@ -3761,9 +3551,10 @@ gchar *
mcd_account_get_alias (McdAccount *account)
{
McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account);
+ const gchar *account_name = mcd_account_get_unique_name (account);
- return g_key_file_get_string (priv->keyfile, priv->unique_name,
- MC_ACCOUNTS_KEY_ALIAS, NULL);
+ return mcd_storage_dup_string (priv->storage, account_name,
+ MC_ACCOUNTS_KEY_ALIAS);
}
void
@@ -3853,6 +3644,7 @@ clear_register_dup_params_cb (McdAccount *self,
if (tp_asv_get_boolean (params, "register", NULL))
{
GValue value = { 0 };
+ const gchar *account_name = mcd_account_get_unique_name (self);
_mcd_account_set_parameter (self, "register", NULL, NULL, NULL);
@@ -3863,8 +3655,7 @@ clear_register_dup_params_cb (McdAccount *self,
mcd_account_changed_property (self, "Parameters", &value);
g_value_unset (&value);
- mcd_account_manager_write_conf_async (self->priv->account_manager,
- self, NULL, NULL);
+ mcd_storage_commit (self->priv->storage, account_name);
}
else
{
@@ -4030,8 +3821,7 @@ _mcd_account_tp_connection_changed (McdAccount *account,
mcd_account_changed_property (account, "Connection", &value);
g_value_unset (&value);
- _mcd_account_manager_store_account_connections
- (account->priv->account_manager);
+ _mcd_storage_store_connections (account->priv->storage);
}
McdConnection *
@@ -4360,17 +4150,19 @@ _mcd_account_set_has_been_online (McdAccount *account)
if (!account->priv->has_been_online)
{
GValue value = { 0 };
-
- g_key_file_set_boolean (account->priv->keyfile,
- account->priv->unique_name,
- MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE, TRUE);
- account->priv->has_been_online = TRUE;
- mcd_account_manager_write_conf_async (account->priv->account_manager,
- account, NULL, NULL);
+ const gchar *account_name = mcd_account_get_unique_name (account);
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, TRUE);
- mcd_account_changed_property (account, "HasBeenOnline", &value);
+
+ mcd_storage_set_value (account->priv->storage,
+ account_name,
+ MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE,
+ &value, FALSE);
+ account->priv->has_been_online = TRUE;
+ mcd_storage_commit (account->priv->storage, account_name);
+ mcd_account_changed_property (account, MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE,
+ &value);
g_value_unset (&value);
}
}
diff --git a/src/mcd-account.h b/src/mcd-account.h
index 9e3789cc..0d7b6100 100644
--- a/src/mcd-account.h
+++ b/src/mcd-account.h
@@ -43,6 +43,7 @@ typedef struct _McdAccountPresencePrivate McdAccountPresencePrivate;
#include "mcd-connection.h"
#include "mcd-account-manager.h"
+#include "mcd-storage.h"
struct _McdAccount
{
@@ -102,7 +103,7 @@ GType mcd_account_get_type (void);
McdAccount *mcd_account_new (McdAccountManager *account_manager,
const gchar *name);
-McdAccountManager *mcd_account_get_account_manager (McdAccount *account);
+TpDBusDaemon *mcd_account_get_dbus_daemon (McdAccount *account);
void mcd_account_delete (McdAccount *account, McdAccountDeleteCb callback,
gpointer user_data);
diff --git a/src/mcd-storage-priv.h b/src/mcd-storage-priv.h
new file mode 100644
index 00000000..1b550d8f
--- /dev/null
+++ b/src/mcd-storage-priv.h
@@ -0,0 +1,35 @@
+/* Mission Control storage API - interface which provides access to account
+ * parameter/setting storage
+ *
+ * Copyright © 2010 Nokia Corporation
+ * Copyright © 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib-object.h>
+#include <mission-control-plugins/mission-control-plugins.h>
+#include "mcd-storage.h"
+
+#ifndef MCD_STORAGE_PRIV_H
+#define MCD_STORAGE_PRIV_H
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL void _mcd_storage_store_connections (McdStorage *storage);
+
+G_END_DECLS
+
+#endif /* MCD_STORAGE_H */
diff --git a/src/mcd-storage.c b/src/mcd-storage.c
new file mode 100644
index 00000000..7ca0feff
--- /dev/null
+++ b/src/mcd-storage.c
@@ -0,0 +1,388 @@
+/* Mission Control storage API - interface which provides access to account
+ * parameter/setting storage
+ *
+ * Copyright © 2010 Nokia Corporation
+ * Copyright © 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mcd-storage-priv.h"
+#include "mcd-master.h"
+#include "mcd-account-manager-priv.h"
+
+GType
+mcd_storage_get_type (void)
+{
+ static gsize once = 0;
+ static GType type = 0;
+
+ if (g_once_init_enter (&once))
+ {
+ static const GTypeInfo info = {
+ sizeof (McdStorageIface),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0, /* instance_size */
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE, "McdStorage", &info, 0);
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ g_once_init_leave (&once, 1);
+ }
+
+ return type;
+}
+
+/**
+ * mcd_storage_set_string:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: the unique name of an account
+ * @key: the key (name) of the parameter or setting
+ * @value: the value to be stored (or %NULL to erase it)
+ * @secret: whether the value is confidential (might get stored in the
+ * keyring, for example)
+ *
+ * Copies and stores the supplied @value (or removes it if %NULL) to the
+ * internal cache.
+ *
+ * Returns: a #gboolean indicating whether the cache actually required an
+ * update (so that the caller can decide whether to request a commit to
+ * long term storage or not). %TRUE indicates the cache was updated and
+ * may not be in sync with the store any longer, %FALSE indicates we already
+ * held the value supplied.
+ */
+gboolean
+mcd_storage_set_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const gchar *value,
+ gboolean secret)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_val_if_fail (account != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (iface->set_string != NULL, FALSE);
+
+ return iface->set_string (storage, account, key, value, secret);
+}
+
+/**
+ * mcd_storage_set_value:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: the unique name of an account
+ * @key: the key (name) of the parameter or setting
+ * @value: the value to be stored (or %NULL to erase it)
+ * @secret: whether the value is confidential (might get stored in the
+ * keyring, for example)
+ *
+ * Copies and stores the supplied @value (or removes it if %NULL) to the
+ * internal cache.
+ *
+ * Returns: a #gboolean indicating whether the cache actually required an
+ * update (so that the caller can decide whether to request a commit to
+ * long term storage or not). %TRUE indicates the cache was updated and
+ * may not be in sync with the store any longer, %FALSE indicates we already
+ * held the value supplied.
+ */
+gboolean
+mcd_storage_set_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const GValue *value,
+ gboolean secret)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_val_if_fail (account != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (iface->set_value != NULL, FALSE);
+
+ return iface->set_value (storage, account, key, value, secret);
+}
+
+/**
+ * mcd_storage_commit:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: the unique name of an account
+ *
+ * Sync the long term storage (whatever it might be) with the current
+ * state of our internal cache.
+ */
+void
+mcd_storage_commit (McdStorage *storage, const gchar *account)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_if_fail (iface->commit != NULL);
+
+ iface->commit (storage, account);
+}
+
+/**
+ * mcd_storage_load:
+ * @storage: An object implementing the #McdStorage interface
+ *
+ * Load the long term account settings storage into our internal cache.
+ * Should only really be called during startup, ie before our DBus names
+ * have been claimed and other people might be relying on responses from us.
+ */
+void
+mcd_storage_load (McdStorage *storage)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_if_fail (iface->load != NULL);
+
+ iface->load (storage);
+}
+
+/**
+ * mcd_storage_dup_accounts:
+ * @storage: An object implementing the #McdStorage interface
+ * @n: place for the number of accounts to be written to (or %NULL)
+ *
+ * Returns: a newly allocated GStrv containing the unique account names,
+ * which must be freed by the caller with g_strfreev().
+ **/
+GStrv
+mcd_storage_dup_accounts (McdStorage *storage, gsize *n)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_val_if_fail (iface->dup_accounts != NULL, NULL);
+
+ return iface->dup_accounts (storage, n);
+}
+
+/**
+ * mcd_storage_dup_settings:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @n: place for the number of settings to be written to (or %NULL)
+ *
+ * Returns: a newly allocated GStrv containing the names of all the
+ * settings or parameters currently stored for @account. Must be
+ * freed by the caller with g_strfreev().
+ **/
+GStrv
+mcd_storage_dup_settings (McdStorage *storage, const gchar *account, gsize *n)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_return_val_if_fail (account != NULL, NULL);
+ g_return_val_if_fail (iface->dup_settings != NULL, NULL);
+
+ return iface->dup_settings (storage, account, n);
+}
+
+/**
+ * mcd_storage_dup_string:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @key: name of the setting to be retrieved
+ *
+ * Returns: a newly allocated gchar * which must be freed with g_free().
+ **/
+gchar *
+mcd_storage_dup_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->dup_string != NULL);
+ g_return_val_if_fail (account != NULL, NULL);
+
+ return iface->dup_string (storage, account, key);
+}
+
+/**
+ * mcd_storage_dup_value:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @key: name of the setting to be retrieved
+ * @type: the type of #GValue to retrieve
+ * @error: a place to store any #GError<!-- -->s that occur
+ *
+ * Returns: a newly allocated #GValue of type @type, whihc should be freed
+ * with tp_g_value_slice_free() or g_slice_free() depending on whether the
+ * the value itself should be freed (the former frees everything, the latter
+ * only the #GValue container.
+ *
+ * If @error is set, but a non-%NULL value was returned, this indicates
+ * that no value for the @key was found for @account, and the default
+ * value for @type has been returned.
+ **/
+GValue *
+mcd_storage_dup_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ GType type,
+ GError **error)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->dup_value != NULL);
+ g_return_val_if_fail (account != NULL, NULL);
+
+ return iface->dup_value (storage, account, key, type, error);
+}
+
+/**
+ * mcd_storage_get_boolean:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @key: name of the setting to be retrieved
+ *
+ * Returns: a #gboolean. Unset/unparseable values are returned as %FALSE
+ **/
+gboolean
+mcd_storage_get_boolean (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->get_boolean != NULL);
+ g_return_val_if_fail (account != NULL, FALSE);
+
+ return iface->get_boolean (storage, account, key);
+}
+
+/**
+ * mcd_storage_get_integer:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @key: name of the setting to be retrieved
+ *
+ * Returns: a #gint. Unset or non-numeric values are returned as 0
+ **/
+gint
+mcd_storage_get_integer (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->get_integer != NULL);
+ g_return_val_if_fail (account != NULL, 0);
+
+ return iface->get_integer (storage, account, key);
+}
+
+
+/**
+ * mcd_storage_has_value:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ * @key: name of the setting to be retrieved
+ *
+ * Returns: a #gboolean: %TRUE if the setting is present in the store,
+ * %FALSE otherwise.
+ **/
+gboolean
+mcd_storage_has_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->has_value != NULL);
+ g_return_val_if_fail (account != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ return iface->has_value (storage, account, key);
+}
+
+/**
+ * mcd_storage_get_plugin:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ *
+ * Returns: the #McpAccountStorage object which is handling the account,
+ * if any (if a new account has not yet been flushed to storage this can
+ * be %NULL).
+ *
+ * Plugins are kept in permanent storage and can never be unloaded, so
+ * the returned pointer need not be reffed or unreffed. (Indeed, it's
+ * probably safer not to)
+ **/
+McpAccountStorage *
+mcd_storage_get_plugin (McdStorage *storage, const gchar *account)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->get_storage_plugin != NULL);
+ g_return_val_if_fail (account != NULL, NULL);
+
+ return iface->get_storage_plugin (storage, account);
+}
+
+/**
+ * mcd_storage_delete_account:
+ * @storage: An object implementing the #McdStorage interface
+ * @account: unique name of the account
+ *
+ * Removes an account's settings from long term storage.
+ * This does not handle any of the other logic to do with removing
+ * accounts, it merely ensures that no trace of the account remains
+ * in long term storage once mcd_storage_commit() has been called.
+ */
+void
+mcd_storage_delete_account (McdStorage *storage, const gchar *account)
+{
+ McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage);
+
+ g_assert (iface != NULL);
+ g_assert (iface->delete_account != NULL);
+ g_return_if_fail (account != NULL);
+
+ iface->delete_account (storage, account);
+}
+
+void
+_mcd_storage_store_connections (McdStorage *storage)
+{
+ McdMaster *master = mcd_master_get_default ();
+ McdAccountManager *account_manager = NULL;
+
+ g_object_get (master, "account-manager", &account_manager, NULL);
+
+ if (account_manager != NULL)
+ {
+ _mcd_account_manager_store_account_connections (account_manager);
+ g_object_unref (account_manager);
+ }
+}
diff --git a/src/mcd-storage.h b/src/mcd-storage.h
new file mode 100644
index 00000000..e16a7192
--- /dev/null
+++ b/src/mcd-storage.h
@@ -0,0 +1,151 @@
+/* Mission Control storage API - interface which provides access to account
+ * parameter/setting storage
+ *
+ * Copyright © 2010 Nokia Corporation
+ * Copyright © 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib-object.h>
+#include <mission-control-plugins/mission-control-plugins.h>
+
+#ifndef MCD_STORAGE_H
+#define MCD_STORAGE_H
+
+G_BEGIN_DECLS
+
+typedef struct _McdStorage McdStorage;
+typedef struct _McdStorageIface McdStorageIface;
+
+struct _McdStorageIface {
+ GTypeInterface parent;
+
+ void (*load) (McdStorage *storage);
+
+ GStrv (*dup_accounts) (McdStorage *storage, gsize *n);
+
+ GStrv (*dup_settings) (McdStorage *storage, const gchar *account, gsize *n);
+
+ gboolean (*set_string) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const gchar *value,
+ gboolean secret);
+
+ gboolean (*set_value) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const GValue *value,
+ gboolean secret);
+
+ void (*delete_account) (McdStorage *storage,
+ const gchar *account);
+
+ void (*commit) (McdStorage *storage, const gchar *account);
+
+ gchar * (*dup_string) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+ GValue * (*dup_value) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ GType type,
+ GError **error);
+
+ gboolean (*get_boolean) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+ gint (*get_integer) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+ gboolean (*has_value) (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+ McpAccountStorage *(*get_storage_plugin) (McdStorage *storage,
+ const gchar *account);
+};
+
+#define MCD_TYPE_STORAGE (mcd_storage_get_type ())
+
+#define MCD_STORAGE(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_STORAGE, McdStorage))
+
+#define MCD_IS_STORAGE(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_STORAGE))
+
+#define MCD_STORAGE_GET_IFACE(o) \
+ (G_TYPE_INSTANCE_GET_INTERFACE ((o), MCD_TYPE_STORAGE, McdStorageIface))
+
+GType mcd_storage_get_type (void);
+
+void mcd_storage_load (McdStorage *storage);
+
+GStrv mcd_storage_dup_accounts (McdStorage *storage, gsize *n);
+
+GStrv mcd_storage_dup_settings (McdStorage *storage,
+ const gchar *account,
+ gsize *n);
+
+gboolean mcd_storage_set_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const gchar *value,
+ gboolean secret);
+
+gboolean mcd_storage_set_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const GValue *value,
+ gboolean secret);
+
+void mcd_storage_delete_account (McdStorage *storage, const gchar *account);
+
+void mcd_storage_commit (McdStorage *storage, const gchar *account);
+
+gchar *mcd_storage_dup_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+gboolean mcd_storage_has_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+GValue *mcd_storage_dup_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ GType type,
+ GError **error);
+
+gboolean mcd_storage_get_boolean (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+gint mcd_storage_get_integer (McdStorage *storage,
+ const gchar *account,
+ const gchar *key);
+
+McpAccountStorage * mcd_storage_get_plugin (McdStorage *storage,
+ const gchar *account);
+
+G_GNUC_INTERNAL void _mcd_storage_store_connections (McdStorage *storage);
+
+G_END_DECLS
+
+#endif /* MCD_STORAGE_H */
diff --git a/src/plugin-account.c b/src/plugin-account.c
index 9960e266..cfdc7cb2 100644
--- a/src/plugin-account.c
+++ b/src/plugin-account.c
@@ -21,13 +21,22 @@
*
*/
+#include "plugin-loader.h"
#include "plugin-account.h"
#include "mission-control-plugins/implementation.h"
-#include <glib.h>
#include <telepathy-glib/util.h>
+/* these pseudo-plugins take care of the actual account storage/retrieval */
+#include "mcd-account-manager-default.h"
+#if ENABLE_LIBACCOUNTS_SSO
+#include "mcd-account-manager-sso.h"
+#endif
+
+static GList *stores = NULL;
+static void sort_and_cache_plugins (void);
+
enum {
PROP_DBUS_DAEMON = 1,
};
@@ -36,11 +45,15 @@ struct _McdPluginAccountManagerClass {
GObjectClass parent;
};
+static void storage_iface_init (McdStorageIface *iface,
+ gpointer unused G_GNUC_UNUSED);
+
static void plugin_iface_init (McpAccountManagerIface *iface,
gpointer unused G_GNUC_UNUSED);
G_DEFINE_TYPE_WITH_CODE (McdPluginAccountManager, mcd_plugin_account_manager, \
G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MCD_TYPE_STORAGE, storage_iface_init);
G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_MANAGER, plugin_iface_init))
static void
@@ -141,7 +154,7 @@ mcd_plugin_account_manager_new ()
}
void
-mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self,
+_mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self,
TpDBusDaemon *dbusd)
{
GValue value = { 0 };
@@ -247,6 +260,586 @@ unique_name (const McpAccountManager *ma,
return NULL;
}
+/* sort in descending order of priority (ie higher prio => earlier in list) */
+static gint
+account_storage_cmp (gconstpointer a, gconstpointer b)
+{
+ gint pa = mcp_account_storage_priority (a);
+ gint pb = mcp_account_storage_priority (b);
+
+ if (pa > pb) return -1;
+ if (pa < pb) return 1;
+
+ return 0;
+}
+
+static void
+add_libaccount_plugin_if_enabled (void)
+{
+#if ENABLE_LIBACCOUNTS_SSO
+ McdAccountManagerSso *sso_plugin = mcd_account_manager_sso_new ();
+
+ stores = g_list_insert_sorted (stores, sso_plugin, account_storage_cmp);
+#endif
+}
+
+static void
+sort_and_cache_plugins ()
+{
+ const GList *p;
+ McdAccountManagerDefault *default_plugin = NULL;
+ static gboolean plugins_cached = FALSE;
+
+ /* not guaranteed to have been called, but idempotent: */
+ _mcd_plugin_loader_init ();
+
+ /* insert the default storage plugin into the sorted plugin list */
+ default_plugin = mcd_account_manager_default_new ();
+ stores = g_list_insert_sorted (stores, default_plugin, account_storage_cmp);
+
+ /* now poke the pseudo-plugins into the sorted GList of storage plugins */
+ add_libaccount_plugin_if_enabled ();
+
+ for (p = mcp_list_objects(); p != NULL; p = g_list_next (p))
+ {
+ if (MCP_IS_ACCOUNT_STORAGE (p->data))
+ {
+ McpAccountStorage *plugin = g_object_ref (p->data);
+
+ stores = g_list_insert_sorted (stores, plugin, account_storage_cmp);
+ }
+ }
+
+ for (p = stores; p != NULL; p = g_list_next (p))
+ {
+ McpAccountStorage *plugin = p->data;
+
+ DEBUG ("found plugin %s [%s; priority %d]\n%s",
+ mcp_account_storage_name (plugin),
+ g_type_name (G_TYPE_FROM_INSTANCE (plugin)),
+ mcp_account_storage_priority (plugin),
+ mcp_account_storage_description (plugin));
+ }
+
+ plugins_cached = TRUE;
+}
+
+void
+_mcd_plugin_account_manager_connect_signal (const gchar *signame,
+ GCallback func,
+ gpointer user_data)
+{
+ GList *p;
+
+ for (p = stores; p != NULL; p = g_list_next (p))
+ {
+ McpAccountStorage *plugin = p->data;
+
+ DEBUG ("connecting handler to %s plugin signal %s ",
+ mcp_account_storage_name (plugin), signame);
+ g_signal_connect (plugin, signame, func, user_data);
+ }
+}
+
+/* implement the McdStorage interface */
+static void
+_storage_load (McdStorage *self)
+{
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+ GList *store = NULL;
+
+ sort_and_cache_plugins ();
+
+ store = g_list_last (stores);
+
+ /* fetch accounts stored in plugins, in reverse priority so higher prio *
+ * plugins can overwrite lower prio ones' account data */
+ while (store != NULL)
+ {
+ GList *account;
+ McpAccountStorage *plugin = store->data;
+ GList *stored = mcp_account_storage_list (plugin, ma);
+ const gchar *pname = mcp_account_storage_name (plugin);
+ const gint prio = mcp_account_storage_priority (plugin);
+
+ DEBUG ("listing from plugin %s [prio: %d]", pname, prio);
+ for (account = stored; account != NULL; account = g_list_next (account))
+ {
+ gchar *name = account->data;
+
+ DEBUG ("fetching %s from plugin %s [prio: %d]", name, pname, prio);
+ mcp_account_storage_get (plugin, ma, name, NULL);
+
+ g_free (name);
+ }
+
+ /* already freed the contents, just need to free the list itself */
+ g_list_free (stored);
+ store = g_list_previous (store);
+ }
+}
+
+static GStrv
+_storage_dup_accounts (McdStorage *storage, gsize *n)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ return g_key_file_get_groups (self->keyfile, n);
+}
+
+static GStrv
+_storage_dup_settings (McdStorage *storage, const gchar *account, gsize *n)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ return g_key_file_get_keys (self->keyfile, account, n, NULL);
+}
+
+static McpAccountStorage *
+_storage_get_plugin (McdStorage *storage, const gchar *account)
+{
+ GList *store = stores;
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+ McpAccountStorage *owner = NULL;
+
+ for (; store != NULL && owner == NULL; store = g_list_next (store))
+ {
+ McpAccountStorage *plugin = store->data;
+
+ if (mcp_account_storage_get (plugin, ma, account, "manager"))
+ owner = plugin;
+ }
+
+ return owner;
+}
+
+static gchar *
+_storage_dup_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ gchar *value = NULL;
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ value = g_key_file_get_string (self->keyfile, account, key, NULL);
+
+ return value;
+}
+
+static gboolean
+_storage_has_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ return g_key_file_has_key (self->keyfile, account, key, NULL);
+}
+
+static GValue *
+_storage_dup_value (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ GType type,
+ GError **error)
+{
+ GValue *value = NULL;
+ gchar *v_string = NULL;
+ gint64 v_int = 0;
+ guint64 v_uint = 0;
+ gboolean v_bool = FALSE;
+ double v_double = 0.0;
+ GKeyFile *keyfile = MCD_PLUGIN_ACCOUNT_MANAGER (storage)->keyfile;
+
+ switch (type)
+ {
+ case G_TYPE_STRING:
+ v_string = g_key_file_get_string (keyfile, account, key, error);
+ value = tp_g_value_slice_new_take_string (v_string);
+ break;
+
+ case G_TYPE_INT:
+ v_int = g_key_file_get_integer (keyfile, account, key, error);
+ value = tp_g_value_slice_new_int (v_int);
+ break;
+
+ case G_TYPE_INT64:
+ v_int = tp_g_key_file_get_int64 (keyfile, account, key, error);
+ value = tp_g_value_slice_new_int64 (v_int);
+ break;
+
+ case G_TYPE_UINT:
+ v_uint = tp_g_key_file_get_uint64 (keyfile, account, key, error);
+
+ if (v_uint > 0xFFFFFFFFU)
+ g_set_error (error, MCD_ACCOUNT_ERROR,
+ MCD_ACCOUNT_ERROR_GET_PARAMETER,
+ "Integer is out of range");
+ else
+ value = tp_g_value_slice_new_uint (v_uint);
+ break;
+
+ case G_TYPE_UCHAR:
+ v_int = g_key_file_get_integer (keyfile, account, key, error);
+
+ if (v_int < 0 || v_int > 0xFF)
+ {
+ g_set_error (error, MCD_ACCOUNT_ERROR,
+ MCD_ACCOUNT_ERROR_GET_PARAMETER,
+ "Integer is out of range");
+ }
+ else
+ {
+ value = tp_g_value_slice_new (G_TYPE_UCHAR);
+ g_value_set_uchar (value, v_int);
+ }
+ break;
+
+ case G_TYPE_UINT64:
+ v_uint = tp_g_key_file_get_uint64 (keyfile, account, key, error);
+ value = tp_g_value_slice_new_uint64 (v_uint);
+ break;
+
+ case G_TYPE_BOOLEAN:
+ v_bool = g_key_file_get_boolean (keyfile, account, key, error);
+ value = tp_g_value_slice_new_boolean (v_bool);
+ break;
+
+ case G_TYPE_DOUBLE:
+ v_double = g_key_file_get_double (keyfile, account, key, error);
+ value = tp_g_value_slice_new_double (v_double);
+ break;
+
+ default:
+ if (type == G_TYPE_STRV)
+ {
+ gchar **v =
+ g_key_file_get_string_list (keyfile, account, key, NULL, error);
+
+ value = tp_g_value_slice_new_take_boxed (G_TYPE_STRV, v);
+ }
+ else if (type == DBUS_TYPE_G_OBJECT_PATH)
+ {
+ v_string = g_key_file_get_string (keyfile, account, key, NULL);
+
+ if (v_string == NULL)
+ {
+ g_set_error (error, MCD_ACCOUNT_ERROR,
+ MCD_ACCOUNT_ERROR_GET_PARAMETER,
+ "Invalid object path NULL");
+ }
+ else if (!tp_dbus_check_valid_object_path (v_string, NULL))
+ {
+ g_set_error (error, MCD_ACCOUNT_ERROR,
+ MCD_ACCOUNT_ERROR_GET_PARAMETER,
+ "Invalid object path %s", v_string);
+ g_free (v_string);
+ }
+ else
+ {
+ value = tp_g_value_slice_new_take_object_path (v_string);
+ }
+ }
+ else
+ {
+ gchar *message =
+ g_strdup_printf ("cannot get property %s, unknown type %s",
+ key, g_type_name (type));
+
+ g_warning ("%s: %s", G_STRFUNC, message);
+ g_set_error (error, MCD_ACCOUNT_ERROR,
+ MCD_ACCOUNT_ERROR_GET_PARAMETER,
+ "%s", message);
+ g_free (message);
+ }
+ }
+
+ /* This can return a non-NULL GValue * _and_ a non-NULL GError *, *
+ * indicating a value was not found and the default for that type *
+ * (eg 0 for integers) has been returned - this matches the behaviour *
+ * of the old code that this function replaces. If changing this, make *
+ * sure all our callers are suitable updated */
+
+ return value;
+}
+
+static gboolean
+_storage_get_boolean (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ return g_key_file_get_boolean (self->keyfile, account, key, NULL);
+}
+
+static gint
+_storage_get_integer (McdStorage *storage,
+ const gchar *account,
+ const gchar *key)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+
+ return g_key_file_get_integer (self->keyfile, account, key, NULL);
+}
+
+static void
+update_storage (McdPluginAccountManager *self,
+ const gchar *account,
+ const gchar *key)
+{
+ GList *store;
+ gboolean done = FALSE;
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+ gchar *val = NULL;
+
+ /* don't unescape the value here, we're flushing it to storage *
+ * everywhere else should handle escaping on the way in and unescaping *
+ * on the way out of the keyfile, but not here: */
+ val = g_key_file_get_value (self->keyfile, account, key, NULL);
+
+ /* we're deleting, which is unconditional, no need to check if anyone *
+ * claims this setting for themselves */
+ if (val == NULL)
+ done = TRUE;
+
+ for (store = stores; store != NULL; store = g_list_next (store))
+ {
+ McpAccountStorage *plugin = store->data;
+ const gchar *pn = mcp_account_storage_name (plugin);
+
+ if (done)
+ {
+ DEBUG ("MCP:%s -> delete %s.%s", pn, account, key);
+ mcp_account_storage_delete (plugin, ma, account, key);
+ }
+ else
+ {
+ done = mcp_account_storage_set (plugin, ma, account, key, val);
+ DEBUG ("MCP:%s -> %s %s.%s",
+ pn, done ? "store" : "ignore", account, key);
+ }
+ }
+}
+
+static gboolean
+_storage_set_string (McdStorage *storage,
+ const gchar *account,
+ const gchar *key,
+ const gchar *val,
+ gboolean secret)
+{
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+ gboolean updated = FALSE;
+ gchar *old = g_key_file_get_string (self->keyfile, account, key, NULL);
+
+ if (val == NULL)
+ g_key_file_remove_key (self->keyfile, account, key, NULL);
+ else
+ g_key_file_set_string (self->keyfile, account, key, val);
+
+ if (tp_strdiff (old, val))
+ {
+ if (secret)
+ {
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+
+ mcp_account_manager_parameter_make_secret (ma, account, key);
+ }
+
+ update_storage (self, account, key);
+ updated = TRUE;
+ }
+
+ g_free (old);
+
+ return updated;
+}
+
+static gboolean
+_storage_set_value (McdStorage *storage,
+ const gchar *name,
+ const gchar *key,
+ const GValue *value,
+ gboolean secret)
+{
+ if (value == NULL)
+ {
+ return _storage_set_string (storage, name, key, NULL, secret);
+ }
+ else
+ {
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+ gboolean updated = FALSE;
+ gchar *old = g_key_file_get_value (self->keyfile, name, key, NULL);
+ gchar *new = NULL;
+ gchar *buf = NULL;
+
+ switch (G_VALUE_TYPE (value))
+ {
+ case G_TYPE_STRING:
+ g_key_file_set_string (self->keyfile, name, key,
+ g_value_get_string (value));
+ break;
+
+ case G_TYPE_UINT:
+ buf = g_strdup_printf ("%u", g_value_get_uint (value));
+ break;
+
+ case G_TYPE_INT:
+ g_key_file_set_integer (self->keyfile, name, key,
+ g_value_get_int (value));
+ break;
+
+ case G_TYPE_BOOLEAN:
+ g_key_file_set_boolean (self->keyfile, name, key,
+ g_value_get_boolean (value));
+ break;
+
+ case G_TYPE_UCHAR:
+ buf = g_strdup_printf ("%u", g_value_get_uchar (value));
+ break;
+
+ case G_TYPE_UINT64:
+ buf = g_strdup_printf ("%" G_GUINT64_FORMAT,
+ g_value_get_uint64 (value));
+ break;
+
+ case G_TYPE_INT64:
+ buf = g_strdup_printf ("%" G_GINT64_FORMAT,
+ g_value_get_int64 (value));
+ break;
+
+ case G_TYPE_DOUBLE:
+ g_key_file_set_double (self->keyfile, name, key,
+ g_value_get_double (value));
+ break;
+
+ default:
+ if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ gchar **strings = g_value_get_boxed (value);
+
+ g_key_file_set_string_list (self->keyfile, name, key,
+ (const gchar **)strings,
+ g_strv_length (strings));
+ }
+ else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
+ {
+ g_key_file_set_string (self->keyfile, name, key,
+ g_value_get_boxed (value));
+ }
+ else
+ {
+ g_warning ("Unexpected param type %s",
+ G_VALUE_TYPE_NAME (value));
+ return FALSE;
+ }
+ }
+
+ if (buf != NULL)
+ g_key_file_set_string (self->keyfile, name, key, buf);
+
+ new = g_key_file_get_value (self->keyfile, name, key, NULL);
+
+ if (tp_strdiff (old, new))
+ {
+ if (secret)
+ {
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+
+ mcp_account_manager_parameter_make_secret (ma, name, key);
+ }
+
+ update_storage (self, name, key);
+ updated = TRUE;
+ }
+
+ g_free (buf);
+ g_free (old);
+
+ return updated;
+ }
+}
+
+static void
+_storage_delete_account (McdStorage *storage, const gchar *account)
+{
+ GList *store;
+ McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage);
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+
+ g_key_file_remove_group (self->keyfile, account, NULL);
+
+ for (store = stores; store != NULL; store = g_list_next (store))
+ {
+ McpAccountStorage *plugin = store->data;
+
+ mcp_account_storage_delete (plugin, ma, account, NULL);
+ }
+}
+
+static void
+_storage_commit (McdStorage *self, const gchar *account)
+{
+ GList *store;
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+
+ for (store = stores; store != NULL; store = g_list_next (store))
+ {
+ McpAccountStorage *plugin = store->data;
+ const gchar *pname = mcp_account_storage_name (plugin);
+
+ if (account != NULL)
+ {
+ DEBUG ("flushing plugin %s %s to long term storage", pname, account);
+ mcp_account_storage_commit_one (plugin, ma, account);
+ }
+ else
+ {
+ DEBUG ("flushing plugin %s to long term storage", pname);
+ mcp_account_storage_commit (plugin, ma);
+ }
+ }
+}
+
+void
+_mcd_plugin_account_manager_ready (McdPluginAccountManager *self)
+{
+ GList *store;
+ McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self);
+
+ for (store = stores; store != NULL; store = g_list_next (store))
+ {
+ McpAccountStorage *plugin = store->data;
+ const gchar *plugin_name = mcp_account_storage_name (plugin);
+
+ DEBUG ("Unblocking async account ops by %s", plugin_name);
+ mcp_account_storage_ready (plugin, ma);
+ }
+}
+
+static void
+storage_iface_init (McdStorageIface *iface,
+ gpointer unused G_GNUC_UNUSED)
+{
+ iface->load = _storage_load;
+ iface->dup_accounts = _storage_dup_accounts;
+ iface->dup_settings = _storage_dup_settings;
+
+ iface->delete_account = _storage_delete_account;
+ iface->set_string = _storage_set_string;
+ iface->set_value = _storage_set_value;
+ iface->commit = _storage_commit;
+
+ iface->has_value = _storage_has_value;
+ iface->get_storage_plugin = _storage_get_plugin;
+ iface->dup_value = _storage_dup_value;
+ iface->dup_string = _storage_dup_string;
+ iface->get_integer = _storage_get_integer;
+ iface->get_boolean = _storage_get_boolean;
+}
static void
plugin_iface_init (McpAccountManagerIface *iface,
diff --git a/src/plugin-account.h b/src/plugin-account.h
index 5c2c3342..27fb731e 100644
--- a/src/plugin-account.h
+++ b/src/plugin-account.h
@@ -64,9 +64,18 @@ G_GNUC_INTERNAL GType mcd_plugin_account_manager_get_type (void);
McdPluginAccountManager *mcd_plugin_account_manager_new (void);
-void mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self,
+G_GNUC_INTERNAL
+void _mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self,
TpDBusDaemon *dbusd);
+G_GNUC_INTERNAL
+void _mcd_plugin_account_manager_ready (McdPluginAccountManager *self);
+
+G_GNUC_INTERNAL
+void _mcd_plugin_account_manager_connect_signal (const gchar *signal,
+ GCallback func,
+ gpointer user_data);
+
G_END_DECLS
#endif