summaryrefslogtreecommitdiff
path: root/src/mcd-account.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mcd-account.c')
-rw-r--r--src/mcd-account.c283
1 files changed, 154 insertions, 129 deletions
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 7b51afb8..28e3602c 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,
};
@@ -314,6 +315,20 @@ mcd_account_loaded (McdAccount *account)
g_return_if_fail (!account->priv->loaded);
account->priv->loaded = TRUE;
+ if (account->priv->invalid_reason == NULL)
+ {
+ DEBUG ("account %s is now loaded and valid",
+ account->priv->unique_name);
+ }
+ else
+ {
+ DEBUG ("account %s is now loaded, but not valid: %s #%d: %s",
+ account->priv->unique_name,
+ g_quark_to_string (account->priv->invalid_reason->domain),
+ account->priv->invalid_reason->code,
+ account->priv->invalid_reason->message);
+ }
+
/* invoke all the callbacks */
g_object_ref (account);
@@ -378,12 +393,12 @@ _mcd_account_set_parameter (McdAccount *account, const gchar *name,
McdAccountPrivate *priv = account->priv;
McdStorage *storage = priv->storage;
const gchar *account_name = mcd_account_get_unique_name (account);
- gboolean secret = mcd_account_parameter_is_secret (account, name);
- mcd_storage_set_parameter (storage, account_name, name, value, secret);
+ mcd_storage_set_parameter (storage, account_name, name, value);
}
-static GType mc_param_type (const TpConnectionManagerParam *param);
+static GType mc_param_type (const TpConnectionManagerParam *param,
+ const GVariantType **variant_type_out);
/**
* mcd_account_get_parameter:
@@ -406,18 +421,22 @@ mcd_account_get_parameter (McdAccount *account, const gchar *name,
McdAccountPrivate *priv = account->priv;
const TpConnectionManagerParam *param;
GType type;
+ const GVariantType *variant_type;
+ gboolean ret;
param = mcd_manager_get_protocol_param (priv->manager,
priv->protocol_name, name);
- type = mc_param_type (param);
+ type = mc_param_type (param, &variant_type);
- return mcd_account_get_parameter_of_known_type (account, name,
- type, parameter, error);
+ ret = mcd_account_get_parameter_of_known_type (account, name,
+ variant_type, type, parameter, error);
+ return ret;
}
gboolean
mcd_account_get_parameter_of_known_type (McdAccount *account,
const gchar *name,
+ const GVariantType *variant_type,
GType type,
GValue *parameter,
GError **error)
@@ -428,7 +447,8 @@ mcd_account_get_parameter_of_known_type (McdAccount *account,
g_value_init (&tmp, type);
- if (mcd_storage_get_parameter (storage, account_name, name, &tmp, error))
+ if (mcd_storage_get_parameter (storage, account_name, name, variant_type,
+ &tmp, error))
{
if (parameter != NULL)
{
@@ -675,16 +695,19 @@ static TpStorageRestrictionFlags mcd_account_get_storage_restrictions (
McdAccount *account);
void
-mcd_account_delete (McdAccount *account,
- McdDBusPropSetFlags flags,
- McdAccountDeleteCb callback,
- gpointer user_data)
+mcd_account_delete_async (McdAccount *account,
+ McdDBusPropSetFlags flags,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
McdAccountPrivate *priv = account->priv;
gchar *data_dir_str;
GError *error = NULL;
const gchar *name = mcd_account_get_unique_name (account);
TpConnectionManager *cm = mcd_account_get_cm (account);
+ GTask *task;
+
+ task = g_task_new (account, NULL, callback, user_data);
/* We don't really have a flag for "cannot delete accounts" yet, but
* it seems reasonable that if you can't disable it or put it
@@ -695,16 +718,18 @@ mcd_account_delete (McdAccount *account,
(TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED |
TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE)) != 0)
{
- g_set_error (&error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
+ g_task_return_new_error (task, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
"Storage plugin for %s does not allow deleting it",
name);
- callback (account, error, user_data);
- g_error_free (error);
+ g_object_unref (task);
return;
}
- /* if the CM implements CM.I.AccountStorage, we need to tell the CM
- * to forget any account credentials it knows */
+ /* If the CM implements CM.I.AccountStorage, we need to tell the CM
+ * to forget any account credentials it knows.
+ *
+ * FIXME: put this in the main flow rather than doing it async and
+ * throwing away its result? */
if (tp_proxy_has_interface_by_id (cm,
MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE))
{
@@ -729,12 +754,13 @@ mcd_account_delete (McdAccount *account,
flags, &error))
{
g_warning ("could not disable account %s (%s)", name, error->message);
- callback (account, error, user_data);
- g_error_free (error);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- mcd_storage_delete_account (priv->storage, name);
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0)
+ mcd_storage_delete_account (priv->storage, name);
data_dir_str = get_old_account_data_path (priv);
@@ -761,20 +787,25 @@ mcd_account_delete (McdAccount *account,
g_free (data_dir_str);
}
- mcd_storage_commit (priv->storage, name);
-
- if (callback != NULL)
- callback (account, NULL, user_data);
-
- /* If the account was not removed via the DBus Account interface code *
- * path and something is holding a ref to it so it does not get disposed, *
- * then this signal may not get fired, so we make sure it _does_ here */
if (!priv->removed)
{
- DEBUG ("Forcing Account.Removed for %s", name);
+ DEBUG ("emitting Account.Removed for %s", name);
priv->removed = TRUE;
tp_svc_account_emit_removed (account);
}
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+gboolean
+mcd_account_delete_finish (McdAccount *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
}
void
@@ -782,10 +813,29 @@ _mcd_account_load (McdAccount *account, McdAccountLoadCb callback,
gpointer user_data)
{
if (account->priv->loaded)
+ {
+ if (account->priv->invalid_reason == NULL)
+ {
+ DEBUG ("account %s already loaded and valid",
+ account->priv->unique_name);
+ }
+ else
+ {
+ DEBUG ("account %s already loaded, but not valid: %s #%d: %s",
+ account->priv->unique_name,
+ g_quark_to_string (account->priv->invalid_reason->domain),
+ account->priv->invalid_reason->code,
+ account->priv->invalid_reason->message);
+ }
+
callback (account, NULL, user_data);
+ }
else
+ {
+ DEBUG ("account %s not yet loaded", account->priv->unique_name);
_mcd_object_call_when_ready (account, account_ready_quark,
(McdReadyCb)callback, user_data);
+ }
}
static void
@@ -1081,7 +1131,8 @@ mcd_account_get_string_val (McdAccount *account, const gchar *key,
g_value_init (value, G_TYPE_STRING);
- if (!mcd_storage_get_attribute (priv->storage, name, key, value, NULL))
+ if (!mcd_storage_get_attribute (priv->storage, name, key,
+ G_VARIANT_TYPE_STRING, value, NULL))
{
g_value_set_static_string (value, NULL);
}
@@ -2076,58 +2127,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
@@ -2136,22 +2145,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);
@@ -2164,15 +2164,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);
}
@@ -2180,11 +2176,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);
}
@@ -2228,7 +2220,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 },
@@ -2366,10 +2358,13 @@ properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data)
}
static GType
-mc_param_type (const TpConnectionManagerParam *param)
+mc_param_type (const TpConnectionManagerParam *param,
+ const GVariantType **variant_type_out)
{
const gchar *dbus_signature;
+ *variant_type_out = NULL;
+
if (G_UNLIKELY (param == NULL))
return G_TYPE_INVALID;
@@ -2381,37 +2376,49 @@ mc_param_type (const TpConnectionManagerParam *param)
switch (dbus_signature[0])
{
case DBUS_TYPE_STRING:
+ *variant_type_out = G_VARIANT_TYPE_STRING;
return G_TYPE_STRING;
case DBUS_TYPE_BYTE:
+ *variant_type_out = G_VARIANT_TYPE_BYTE;
return G_TYPE_UCHAR;
case DBUS_TYPE_INT16:
case DBUS_TYPE_INT32:
+ *variant_type_out = G_VARIANT_TYPE_INT32;
return G_TYPE_INT;
case DBUS_TYPE_UINT16:
case DBUS_TYPE_UINT32:
+ *variant_type_out = G_VARIANT_TYPE_UINT32;
return G_TYPE_UINT;
case DBUS_TYPE_BOOLEAN:
+ *variant_type_out = G_VARIANT_TYPE_BOOLEAN;
return G_TYPE_BOOLEAN;
case DBUS_TYPE_DOUBLE:
+ *variant_type_out = G_VARIANT_TYPE_DOUBLE;
return G_TYPE_DOUBLE;
case DBUS_TYPE_OBJECT_PATH:
+ *variant_type_out = G_VARIANT_TYPE_OBJECT_PATH;
return DBUS_TYPE_G_OBJECT_PATH;
case DBUS_TYPE_INT64:
+ *variant_type_out = G_VARIANT_TYPE_INT64;
return G_TYPE_INT64;
case DBUS_TYPE_UINT64:
+ *variant_type_out = G_VARIANT_TYPE_UINT64;
return G_TYPE_UINT64;
case DBUS_TYPE_ARRAY:
if (dbus_signature[1] == DBUS_TYPE_STRING)
+ {
+ *variant_type_out = G_VARIANT_TYPE_STRING_ARRAY;
return G_TYPE_STRV;
+ }
/* other array types are not supported:
* fall through the default case */
default:
@@ -2428,25 +2435,24 @@ typedef struct
} RemoveMethodData;
static void
-account_remove_delete_cb (McdAccount *account, const GError *error,
+account_remove_delete_cb (GObject *source,
+ GAsyncResult *res,
gpointer user_data)
{
RemoveMethodData *data = (RemoveMethodData *) user_data;
+ GError *error = NULL;
- if (error != NULL)
+ if (!mcd_account_delete_finish (MCD_ACCOUNT (source), res, &error))
{
dbus_g_method_return_error (data->context, (GError *) error);
+ g_error_free (error);
return;
}
- if (!data->self->priv->removed)
- {
- data->self->priv->removed = TRUE;
- tp_svc_account_emit_removed (data->self);
- }
+ /* mcd_account_delete() is meant to have deleted it */
+ g_warn_if_fail (data->self->priv->removed);
tp_svc_account_return_from_remove (data->context);
-
g_slice_free (RemoveMethodData, data);
}
@@ -2461,8 +2467,8 @@ account_remove (TpSvcAccount *svc, DBusGMethodInvocation *context)
data->context = context;
DEBUG ("called");
- mcd_account_delete (self, MCD_DBUS_PROP_SET_FLAG_NONE,
- account_remove_delete_cb, data);
+ mcd_account_delete_async (self, MCD_DBUS_PROP_SET_FLAG_NONE,
+ account_remove_delete_cb, data);
}
/*
@@ -2489,11 +2495,13 @@ mcd_account_altered_by_plugin (McdAccount *account,
const McdDBusProp *prop = NULL;
GValue value = G_VALUE_INIT;
GError *error = NULL;
+ const GVariantType *variant_type = NULL;
DEBUG ("%s", name);
if (tp_strdiff (name, "Parameters") &&
- !mcd_storage_init_value_for_attribute (&value, name))
+ !mcd_storage_init_value_for_attribute (&value, name,
+ &variant_type))
{
WARNING ("plugin wants to alter %s but I don't know what "
"type that ought to be", name);
@@ -2506,7 +2514,8 @@ mcd_account_altered_by_plugin (McdAccount *account,
}
else if (!mcd_storage_get_attribute (account->priv->storage,
account->priv->unique_name,
- name, &value, &error))
+ name, variant_type, &value,
+ &error))
{
WARNING ("cannot get new value of %s: %s", name, error->message);
g_error_free (error);
@@ -2695,6 +2704,7 @@ check_one_parameter_update (McdAccount *account,
const TpConnectionManagerParam *param =
tp_protocol_get_param (protocol, name);
GType type;
+ const GVariantType *variant_type;
if (param == NULL)
{
@@ -2704,15 +2714,18 @@ check_one_parameter_update (McdAccount *account,
return FALSE;
}
- type = mc_param_type (param);
+ type = mc_param_type (param, &variant_type);
if (G_VALUE_TYPE (new_value) != type)
{
/* FIXME: use D-Bus type names, not GType names. */
g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "parameter '%s' must be of type %s, not %s",
+ "parameter '%s' must be of type %s ('%.*s'), not %s",
tp_connection_manager_param_get_name (param),
- g_type_name (type), G_VALUE_TYPE_NAME (new_value));
+ g_type_name (type),
+ (int) g_variant_type_get_string_length (variant_type),
+ g_variant_type_peek_string (variant_type),
+ G_VALUE_TYPE_NAME (new_value));
return FALSE;
}
@@ -3297,7 +3310,8 @@ mcd_account_setup (McdAccount *account)
g_free (priv->auto_presence_message);
if (mcd_storage_get_attribute (storage, name,
- MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, &value,
+ MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE,
+ G_VARIANT_TYPE ("(uss)"), &value,
NULL))
{
GValueArray *va = g_value_get_boxed (&value);
@@ -3369,7 +3383,9 @@ mcd_account_setup (McdAccount *account)
g_ptr_array_unref (priv->supersedes);
if (mcd_storage_get_attribute (storage, name,
- MC_ACCOUNTS_KEY_SUPERSEDES, &value, NULL))
+ MC_ACCOUNTS_KEY_SUPERSEDES,
+ G_VARIANT_TYPE_OBJECT_PATH_ARRAY,
+ &value, NULL))
{
priv->supersedes = g_value_dup_boxed (&value);
}
@@ -3417,6 +3433,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);
@@ -3503,6 +3524,9 @@ _mcd_account_dispose (GObject *object)
if (!self->priv->removed)
{
+ /* this can happen in certain account-creation error paths,
+ * as far as I can see */
+ DEBUG ("Account never emitted Removed, emitting it now");
self->priv->removed = TRUE;
tp_svc_account_emit_removed (self);
}
@@ -3678,6 +3702,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,
@@ -3753,7 +3783,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);
@@ -3761,6 +3792,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,
@@ -3774,6 +3806,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.
@@ -5156,19 +5194,6 @@ _mcd_account_needs_dispatch (McdAccount *self)
return self->priv->always_dispatch;
}
-gboolean
-mcd_account_parameter_is_secret (McdAccount *self, const gchar *name)
-{
- McdAccountPrivate *priv = self->priv;
- const TpConnectionManagerParam *param;
-
- param = mcd_manager_get_protocol_param (priv->manager,
- priv->protocol_name, name);
-
- return (param != NULL &&
- tp_connection_manager_param_is_secret (param));
-}
-
void
_mcd_account_set_changing_presence (McdAccount *self, gboolean value)
{