From 0f32662e7cd1775f6967de95209df30aa6b9c7ed Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 17:56:43 +0000 Subject: [PATCH 25/26] McdAccount: have a ref to the storage plugin from construct time onwards This will make the account more self-contained. --- src/mcd-account-manager.c | 74 +++++++++++++++++++++-------------- src/mcd-account.c | 99 ++++++++++++++--------------------------------- src/mcd-account.h | 5 ++- src/mcd-storage.c | 36 ++++++++--------- src/mcd-storage.h | 3 +- 5 files changed, 98 insertions(+), 119 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 9f05afd..1a9f687 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -108,6 +108,7 @@ typedef struct gchar *cm_name; gchar *protocol_name; gchar *display_name; + gchar *provider; GHashTable *parameters; GHashTable *properties; McdGetAccountCb callback; @@ -275,7 +276,7 @@ created_cb (GObject *storage_plugin_obj, /* actually fetch the data into our cache from the plugin: */ if (mcd_storage_add_account_from_plugin (storage, plugin, name, &error)) { - account = mcd_account_new (am, name, priv->minotaur); + account = mcd_account_new (am, name, priv->minotaur, plugin); lad->account = account; } else @@ -672,6 +673,7 @@ mcd_create_account_data_free (McdCreateAccountData *cad) if (cad->destroy != NULL) cad->destroy (cad->user_data); + g_free (cad->provider); g_free (cad->cm_name); g_free (cad->protocol_name); g_free (cad->display_name); @@ -817,10 +819,10 @@ identify_account_cb (GObject *source_object, { McdStorage *storage = MCD_STORAGE (source_object); McdCreateAccountData *cad = user_data; - const gchar *provider; gchar *id; gchar *unique_name; McdAccount *account; + McpAccountStorage *plugin; id = mcp_account_manager_identify_account_finish ( MCP_ACCOUNT_MANAGER (storage), result, &cad->error); @@ -832,12 +834,9 @@ identify_account_cb (GObject *source_object, return; } - provider = tp_asv_get_string (cad->properties, - TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER); - - unique_name = mcd_storage_create_account (storage, provider, + unique_name = mcd_storage_create_account (storage, cad->provider, cad->cm_name, cad->protocol_name, - id, &cad->error); + id, &plugin, &cad->error); if (unique_name == NULL) { @@ -860,8 +859,10 @@ identify_account_cb (GObject *source_object, cad->display_name); account = mcd_account_new (cad->account_manager, unique_name, - cad->account_manager->priv->minotaur); + cad->account_manager->priv->minotaur, + plugin); g_free (unique_name); + g_object_unref (plugin); if (G_LIKELY (account)) { @@ -904,18 +905,33 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, return; } - cad = g_slice_new (McdCreateAccountData); + cad = g_slice_new0 (McdCreateAccountData); cad->account_manager = account_manager; cad->cm_name = g_strdup (manager); cad->protocol_name = g_strdup (protocol); cad->display_name = g_strdup (display_name); cad->parameters = g_hash_table_ref (params); - cad->properties = (properties ? g_hash_table_ref (properties) : NULL); cad->callback = callback; cad->user_data = user_data; cad->destroy = destroy; cad->error = NULL; + if (properties != NULL) + { + cad->properties = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) tp_g_value_slice_free); + + tp_g_hash_table_update (cad->properties, properties, + (GBoxedCopyFunc) g_strdup, + (GBoxedCopyFunc) tp_g_value_slice_dup); + + /* special case: "construct-only" */ + cad->provider = g_strdup (tp_asv_get_string (cad->properties, + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER)); + g_hash_table_remove (cad->properties, + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER); + } + g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP); g_value_set_static_boxed (&value, params); variant_params = dbus_g_value_build_g_variant (&value); @@ -1365,9 +1381,9 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) McdAccountManagerPrivate *priv = account_manager->priv; McdStorage *storage = priv->storage; McdLoadAccountsData *lad; - gchar **accounts, **name; + GHashTable *accounts; GHashTableIter iter; - gpointer v; + gpointer k, v; tp_list_connection_names (priv->dbus_daemon, list_connection_names_cb, NULL, NULL, @@ -1377,29 +1393,35 @@ _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 = mcd_storage_dup_accounts (storage, NULL); + accounts = mcd_storage_get_accounts (storage); + g_hash_table_iter_init (&iter, accounts); - for (name = accounts; *name != NULL; name++) + while (g_hash_table_iter_next (&iter, &k, &v)) { gboolean plausible = FALSE; const gchar *manager = NULL; const gchar *protocol = NULL; + const gchar *account_name = k; + McpAccountStorage *plugin = v; McdAccount *account = mcd_account_manager_lookup_account ( - account_manager, *name); + account_manager, account_name); if (account != NULL) { - /* FIXME: this shouldn't really happen */ - DEBUG ("already have account %p called '%s'; skipping", account, *name); + /* FIXME: can't happen? We shouldn't create any accounts before + * we got here, and there can't be any duplicates in @accounts */ + DEBUG ("already have account %p called '%s'; skipping", + account, account_name); continue; } - account = mcd_account_new (account_manager, *name, priv->minotaur); + account = mcd_account_new (account_manager, account_name, + priv->minotaur, plugin); if (G_UNLIKELY (!account)) { g_warning ("%s: account %s failed to instantiate", G_STRFUNC, - *name); + account_name); continue; } @@ -1414,7 +1436,7 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) const gchar *dbg_protocol = (protocol == NULL) ? "(nil)" : protocol; g_warning ("%s: account %s has implausible manager/protocol: %s/%s", - G_STRFUNC, *name, dbg_manager, dbg_protocol); + G_STRFUNC, account_name, dbg_manager, dbg_protocol); g_object_unref (account); continue; } @@ -1424,7 +1446,8 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) _mcd_account_load (account, account_loaded, lad); g_object_unref (account); } - g_strfreev (accounts); + + g_hash_table_unref (accounts); uncork_storage_plugins (account_manager); @@ -1711,15 +1734,8 @@ mcd_account_manager_write_conf_async (McdAccountManager *account_manager, } else { - GStrv groups; - gsize n_accounts = 0; - - groups = mcd_storage_dup_accounts (storage, &n_accounts); - DEBUG ("updating all %" G_GSIZE_FORMAT " accounts", n_accounts); - + DEBUG ("updating all accounts"); mcd_storage_commit (storage, NULL); - - g_strfreev (groups); } if (callback != NULL) diff --git a/src/mcd-account.c b/src/mcd-account.c index 9d84732..edadbee 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -181,6 +181,7 @@ enum PROP_DBUS_DAEMON, PROP_CONNECTIVITY_MONITOR, PROP_STORAGE, + PROP_STORAGE_PLUGIN, PROP_NAME, }; @@ -2092,58 +2093,16 @@ get_supersedes (TpSvcDBusProperties *svc, g_value_set_boxed (value, self->priv->supersedes); } -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_storage_get_plugin (priv->storage, account_name); - - if (priv->storage_plugin != NULL) - g_object_ref (priv->storage_plugin); - - return priv->storage_plugin; -} - static void get_storage_provider (TpSvcDBusProperties *self, const gchar *name, GValue *value) { McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); g_value_init (value, G_TYPE_STRING); - if (storage_plugin != NULL) - g_value_set_string (value, mcp_account_storage_provider (storage_plugin)); - else - g_value_set_static_string (value, ""); -} - -static gboolean -set_storage_provider (TpSvcDBusProperties *self, - const gchar *name, - const GValue *value, - McdDBusPropSetFlags flags, - GError **error) -{ - McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); - const gchar *current_provider = mcp_account_storage_provider (storage_plugin); - - if (!G_VALUE_HOLDS_STRING (value) || - tp_strdiff (g_value_get_string (value), current_provider)) - { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Cannot change provider, it is defined at account creation only"); - return FALSE; - } - - return TRUE; + g_value_set_string (value, + mcp_account_storage_provider (account->priv->storage_plugin)); } static void @@ -2152,22 +2111,13 @@ get_storage_identifier (TpSvcDBusProperties *self, { McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); GValue identifier = G_VALUE_INIT; g_value_init (value, G_TYPE_VALUE); - if (storage_plugin != NULL) - { - mcp_account_storage_get_identifier ( - storage_plugin, account->priv->unique_name, &identifier); - } - else - { - g_value_init (&identifier, G_TYPE_UINT); - - g_value_set_uint (&identifier, 0); - } + mcp_account_storage_get_identifier ( + account->priv->storage_plugin, account->priv->unique_name, + &identifier); g_value_set_boxed (value, &identifier); @@ -2180,15 +2130,11 @@ get_storage_specific_info (TpSvcDBusProperties *self, { GHashTable *storage_specific_info; McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); g_value_init (value, TP_HASH_TYPE_STRING_VARIANT_MAP); - if (storage_plugin != NULL) - storage_specific_info = mcp_account_storage_get_additional_info ( - storage_plugin, account->priv->unique_name); - else - storage_specific_info = g_hash_table_new (g_str_hash, g_str_equal); + storage_specific_info = mcp_account_storage_get_additional_info ( + account->priv->storage_plugin, account->priv->unique_name); g_value_take_boxed (value, storage_specific_info); } @@ -2196,11 +2142,7 @@ get_storage_specific_info (TpSvcDBusProperties *self, static TpStorageRestrictionFlags mcd_account_get_storage_restrictions (McdAccount *self) { - McpAccountStorage *storage_plugin = get_storage_plugin (self); - - g_return_val_if_fail (storage_plugin != NULL, 0); - - return mcp_account_storage_get_restrictions (storage_plugin, + return mcp_account_storage_get_restrictions (self->priv->storage_plugin, self->priv->unique_name); } @@ -2244,7 +2186,7 @@ static const McdDBusProp account_avatar_properties[] = { }; static const McdDBusProp account_storage_properties[] = { - { "StorageProvider", set_storage_provider, get_storage_provider }, + { "StorageProvider", NULL, get_storage_provider }, { "StorageIdentifier", NULL, get_storage_identifier }, { "StorageSpecificInformation", NULL, get_storage_specific_info }, { "StorageRestrictions", NULL, get_storage_restrictions }, @@ -3457,6 +3399,11 @@ set_property (GObject *obj, guint prop_id, priv->storage = g_value_dup_object (val); break; + case PROP_STORAGE_PLUGIN: + g_assert (priv->storage_plugin == NULL); + priv->storage_plugin = g_value_dup_object (val); + break; + case PROP_DBUS_DAEMON: g_assert (priv->dbus_daemon == NULL); priv->dbus_daemon = g_value_dup_object (val); @@ -3721,6 +3668,12 @@ mcd_account_class_init (McdAccountClass * klass) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property + (object_class, PROP_STORAGE_PLUGIN, + g_param_spec_object ("storage-plugin", "storage-plugin", + "Storage plugin", MCP_TYPE_ACCOUNT_STORAGE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_NAME, g_param_spec_string ("name", "Unique name", "Unique name", NULL, @@ -3796,7 +3749,8 @@ mcd_account_init (McdAccount *account) McdAccount * mcd_account_new (McdAccountManager *account_manager, const gchar *name, - McdConnectivityMonitor *connectivity) + McdConnectivityMonitor *connectivity, + McpAccountStorage *storage_plugin) { gpointer *obj; McdStorage *storage = mcd_account_manager_get_storage (account_manager); @@ -3804,6 +3758,7 @@ mcd_account_new (McdAccountManager *account_manager, obj = g_object_new (MCD_TYPE_ACCOUNT, "storage", storage, + "storage-plugin", storage_plugin, "dbus-daemon", dbus, "connectivity-monitor", connectivity, "name", name, @@ -3817,6 +3772,12 @@ _mcd_account_get_storage (McdAccount *account) return account->priv->storage; } +McpAccountStorage * +mcd_account_get_storage_plugin (McdAccount *account) +{ + return account->priv->storage_plugin; +} + /* * mcd_account_is_valid: * @account: the #McdAccount. diff --git a/src/mcd-account.h b/src/mcd-account.h index 6dce649..a0b29af 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -80,7 +80,8 @@ GType mcd_account_get_type (void); McdAccount *mcd_account_new (McdAccountManager *account_manager, const gchar *name, - McdConnectivityMonitor *minotaur); + McdConnectivityMonitor *minotaur, + McpAccountStorage *storage_plugin); void mcd_account_delete_async (McdAccount *account, McdDBusPropSetFlags flags, @@ -159,6 +160,8 @@ void mcd_account_connection_proceed (McdAccount *account, gboolean success); void mcd_account_connection_proceed_with_reason (McdAccount *account, gboolean success, TpConnectionStatusReason reason); +McpAccountStorage *mcd_account_get_storage_plugin (McdAccount *account); + G_END_DECLS #endif diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 07d07f3..978c12d 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -535,30 +535,17 @@ mcd_storage_load (McdStorage *self) } /* - * mcd_storage_dup_accounts: + * mcd_storage_get_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(). + * Returns: (transfer container) (element-type utf8 Mcp.AccountStorage): a + * map from account object path tail to plugin */ -GStrv -mcd_storage_dup_accounts (McdStorage *self, - gsize *n) +GHashTable * +mcd_storage_get_accounts (McdStorage *self) { - GPtrArray *ret = g_ptr_array_new (); - GHashTableIter iter; - gpointer k; - - g_hash_table_iter_init (&iter, self->accounts); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - { - g_ptr_array_add (ret, g_strdup (k)); - } - - g_ptr_array_add (ret, NULL); - return (GStrv) g_ptr_array_free (ret, FALSE); + return g_hash_table_ref (self->accounts); } /* @@ -1684,6 +1671,7 @@ mcd_keyfile_set_variant (GKeyFile *keyfile, * @manager: the name of the manager * @protocol: the name of the protocol * @identification: the result of IdentifyAccount + * @plugin_out: (out) (transfer full): the plugin we used * @error: a #GError to fill when returning %NULL * * Create a new account in storage. This should not store any @@ -1699,12 +1687,16 @@ mcd_storage_create_account (McdStorage *self, const gchar *manager, const gchar *protocol, const gchar *identification, + McpAccountStorage **plugin_out, GError **error) { GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); gchar *ret; + if (plugin_out != NULL) + *plugin_out = NULL; + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (!tp_str_empty (manager), NULL); g_return_val_if_fail (!tp_str_empty (protocol), NULL); @@ -1723,6 +1715,9 @@ mcd_storage_create_account (McdStorage *self, if (mcd_storage_add_account_from_plugin (self, plugin, ret, error)) { + if (plugin_out != NULL) + *plugin_out = g_object_ref (plugin); + return ret; } else @@ -1754,6 +1749,9 @@ mcd_storage_create_account (McdStorage *self, if (mcd_storage_add_account_from_plugin (self, plugin, ret, error)) { + if (plugin_out != NULL) + *plugin_out = g_object_ref (plugin); + return ret; } else diff --git a/src/mcd-storage.h b/src/mcd-storage.h index d78b595..c2624a4 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -64,7 +64,7 @@ void mcd_storage_connect_signal (const gchar *signal, void mcd_storage_load (McdStorage *storage); -GStrv mcd_storage_dup_accounts (McdStorage *storage, gsize *n); +GHashTable *mcd_storage_get_accounts (McdStorage *storage); gboolean mcd_storage_set_string (McdStorage *storage, const gchar *account, @@ -91,6 +91,7 @@ gchar *mcd_storage_create_account (McdStorage *storage, const gchar *manager, const gchar *protocol, const gchar *identification, + McpAccountStorage **plugin_out, GError **error); void mcd_storage_delete_account (McdStorage *storage, const gchar *account); -- 1.8.4.3