diff options
Diffstat (limited to 'libempathy/empathy-account.c')
-rw-r--r-- | libempathy/empathy-account.c | 920 |
1 files changed, 757 insertions, 163 deletions
diff --git a/libempathy/empathy-account.c b/libempathy/empathy-account.c index e0a8e756b..091950880 100644 --- a/libempathy/empathy-account.c +++ b/libempathy/empathy-account.c @@ -18,17 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <telepathy-glib/enums.h> +#include <telepathy-glib/dbus.h> +#include <telepathy-glib/account.h> +#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/util.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/defs.h> #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT #include <libempathy/empathy-debug.h> +#include <glib/gi18n-lib.h> + #include "empathy-account.h" -#include "empathy-account-priv.h" #include "empathy-utils.h" #include "empathy-marshal.h" @@ -36,6 +43,7 @@ enum { STATUS_CHANGED, PRESENCE_CHANGED, + REMOVED, LAST_SIGNAL }; @@ -45,10 +53,14 @@ static guint signals[LAST_SIGNAL]; enum { PROP_ENABLED = 1, PROP_PRESENCE, + PROP_STATUS, + PROP_STATUS_MESSAGE, + PROP_READY, PROP_CONNECTION_STATUS, PROP_CONNECTION_STATUS_REASON, PROP_CONNECTION, PROP_UNIQUE_NAME, + PROP_DBUS_DAEMON, PROP_DISPLAY_NAME }; @@ -64,19 +76,37 @@ struct _EmpathyAccountPriv TpConnection *connection; guint connection_invalidated_id; - TpConnectionStatus status; + TpConnectionStatus connection_status; TpConnectionStatusReason reason; + TpConnectionPresenceType presence; + gchar *status; + gchar *message; gboolean enabled; + gboolean valid; + gboolean ready; + gboolean removed; /* Timestamp when the connection got connected in seconds since the epoch */ glong connect_time; - McAccount *mc_account; + gchar *cm_name; + gchar *proto_name; + gchar *icon_name; + + gchar *unique_name; + gchar *display_name; + TpDBusDaemon *dbus; + + TpAccount *account; + GHashTable *parameters; }; #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccount) +static void _empathy_account_set_connection (EmpathyAccount *account, + const gchar *path); + static void empathy_account_init (EmpathyAccount *obj) { @@ -87,7 +117,34 @@ empathy_account_init (EmpathyAccount *obj) obj->priv = priv; - priv->status = TP_CONNECTION_STATUS_DISCONNECTED; + priv->connection_status = TP_CONNECTION_STATUS_DISCONNECTED; +} + +static void +empathy_account_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (object); + EmpathyAccountPriv *priv = GET_PRIV (account); + + switch (prop_id) + { + case PROP_ENABLED: + empathy_account_set_enabled_async (account, + g_value_get_boolean (value), NULL, NULL); + break; + case PROP_UNIQUE_NAME: + priv->unique_name = g_value_dup_string (value); + break; + case PROP_DBUS_DAEMON: + priv->dbus = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -104,11 +161,20 @@ empathy_account_get_property (GObject *object, case PROP_ENABLED: g_value_set_boolean (value, priv->enabled); break; + case PROP_READY: + g_value_set_boolean (value, priv->ready); + break; case PROP_PRESENCE: g_value_set_uint (value, priv->presence); break; + case PROP_STATUS: + g_value_set_string (value, priv->status); + break; + case PROP_STATUS_MESSAGE: + g_value_set_string (value, priv->message); + break; case PROP_CONNECTION_STATUS: - g_value_set_uint (value, priv->status); + g_value_set_uint (value, priv->connection_status); break; case PROP_CONNECTION_STATUS_REASON: g_value_set_uint (value, priv->reason); @@ -125,12 +191,297 @@ empathy_account_get_property (GObject *object, g_value_set_string (value, empathy_account_get_display_name (account)); break; + case PROP_DBUS_DAEMON: + g_value_set_object (value, priv->dbus); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } +static void +empathy_account_update (EmpathyAccount *account, + GHashTable *properties) +{ + EmpathyAccountPriv *priv = GET_PRIV (account); + GValueArray *arr; + TpConnectionStatus old_s = priv->connection_status; + gboolean presence_changed = FALSE; + + if (g_hash_table_lookup (properties, "ConnectionStatus") != NULL) + priv->connection_status = + tp_asv_get_int32 (properties, "ConnectionStatus", NULL); + + if (g_hash_table_lookup (properties, "ConnectionStatusReason") != NULL) + priv->reason = tp_asv_get_int32 (properties, + "ConnectionStatusReason", NULL); + + if (g_hash_table_lookup (properties, "CurrentPresence") != NULL) + { + presence_changed = TRUE; + arr = tp_asv_get_boxed (properties, "CurrentPresence", + TP_STRUCT_TYPE_SIMPLE_PRESENCE); + priv->presence = g_value_get_uint (g_value_array_get_nth (arr, 0)); + + g_free (priv->status); + priv->status = g_value_dup_string (g_value_array_get_nth (arr, 1)); + + g_free (priv->message); + priv->message = g_value_dup_string (g_value_array_get_nth (arr, 2)); + } + + if (g_hash_table_lookup (properties, "DisplayName") != NULL) + { + g_free (priv->display_name); + priv->display_name = + g_strdup (tp_asv_get_string (properties, "DisplayName")); + g_object_notify (G_OBJECT (account), "display-name"); + } + + if (g_hash_table_lookup (properties, "Enabled") != NULL) + { + gboolean enabled = tp_asv_get_boolean (properties, "Enabled", NULL); + if (priv->enabled != enabled) + { + priv->enabled = enabled; + g_object_notify (G_OBJECT (account), "enabled"); + } + } + + if (g_hash_table_lookup (properties, "Valid") != NULL) + priv->valid = tp_asv_get_boolean (properties, "Valid", NULL); + + if (g_hash_table_lookup (properties, "Parameters") != NULL) + { + GHashTable *parameters; + + parameters = tp_asv_get_boxed (properties, "Parameters", + TP_HASH_TYPE_STRING_VARIANT_MAP); + + if (priv->parameters != NULL) + g_hash_table_unref (priv->parameters); + + priv->parameters = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, + parameters); + } + + if (!priv->ready) + { + priv->ready = TRUE; + g_object_notify (G_OBJECT (account), "ready"); + } + + if (priv->connection_status != old_s) + { + if (priv->connection_status == TP_CONNECTION_STATUS_CONNECTED) + { + GTimeVal val; + g_get_current_time (&val); + + priv->connect_time = val.tv_sec; + } + + g_signal_emit (account, signals[STATUS_CHANGED], 0, + old_s, priv->connection_status, priv->reason); + + g_object_notify (G_OBJECT (account), "connection-status"); + g_object_notify (G_OBJECT (account), "connection-status-reason"); + } + + if (presence_changed) + { + g_signal_emit (account, signals[PRESENCE_CHANGED], 0, + priv->presence, priv->status, priv->message); + g_object_notify (G_OBJECT (account), "presence"); + g_object_notify (G_OBJECT (account), "status"); + g_object_notify (G_OBJECT (account), "status-message"); + } + + if (g_hash_table_lookup (properties, "Connection") != NULL) + { + const gchar *conn_path = + tp_asv_get_object_path (properties, "Connection"); + + _empathy_account_set_connection (account, conn_path); + } +} + +static void +empathy_account_properties_changed (TpAccount *proxy, + GHashTable *properties, + gpointer user_data, + GObject *weak_object) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (weak_object); + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (!priv->ready) + return; + + empathy_account_update (account, properties); +} + +static void +empathy_account_removed_cb (TpAccount *proxy, + gpointer user_data, + GObject *weak_object) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (weak_object); + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (priv->removed) + return; + + priv->removed = TRUE; + + g_signal_emit (account, signals[REMOVED], 0); +} + +static void +empathy_account_got_all_cb (TpProxy *proxy, + GHashTable *properties, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (weak_object); + + DEBUG ("Got initial set of properties for %s", + empathy_account_get_unique_name (account)); + + if (error != NULL) + { + DEBUG ("Failed to get the initial set of account properties: %s", + error->message); + return; + } + + empathy_account_update (account, properties); +} + +static gchar * +empathy_account_unescape_protocol (const gchar *protocol, gssize len) +{ + gchar *result, *escape; + /* Bad implementation might accidentally use tp_escape_as_identifier, + * which escapes - in the wrong way... */ + if ((escape = g_strstr_len (protocol, len, "_2d")) != NULL) + { + GString *str; + const gchar *input; + + str = g_string_new (""); + input = protocol; + do { + g_string_append_len (str, input, escape - input); + g_string_append_c (str, '-'); + + len -= escape - input + 3; + input = escape + 3; + } while ((escape = g_strstr_len (input, len, "_2d")) != NULL); + + g_string_append_len (str, input, len); + + result = g_string_free (str, FALSE); + } + else + { + result = g_strndup (protocol, len); + } + + g_strdelimit (result, "_", '-'); + + return result; +} + +static gboolean +empathy_account_parse_unique_name (const gchar *bus_name, + gchar **protocol, gchar **manager) +{ + const gchar *proto, *proto_end; + const gchar *cm, *cm_end; + + g_return_val_if_fail ( + g_str_has_prefix (bus_name, TP_ACCOUNT_OBJECT_PATH_BASE), FALSE); + + cm = bus_name + strlen (TP_ACCOUNT_OBJECT_PATH_BASE); + + for (cm_end = cm; *cm_end != '/' && *cm_end != '\0'; cm_end++) + /* pass */; + + if (*cm_end == '\0') + return FALSE; + + if (cm_end == '\0') + return FALSE; + + proto = cm_end + 1; + + for (proto_end = proto; *proto_end != '/' && *proto_end != '\0'; proto_end++) + /* pass */; + + if (*proto_end == '\0') + return FALSE; + + if (protocol != NULL) + { + *protocol = empathy_account_unescape_protocol (proto, proto_end - proto); + } + + if (manager != NULL) + *manager = g_strndup (cm, cm_end - cm); + + return TRUE; +} + +static void +account_invalidated_cb (TpProxy *proxy, guint domain, gint code, + gchar *message, gpointer user_data) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (user_data); + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (priv->removed) + return; + + priv->removed = TRUE; + + g_signal_emit (account, signals[REMOVED], 0); +} + +static void +empathy_account_constructed (GObject *object) +{ + EmpathyAccount *account = EMPATHY_ACCOUNT (object); + EmpathyAccountPriv *priv = GET_PRIV (account); + + priv->account = tp_account_new (priv->dbus, priv->unique_name, NULL); + + g_signal_connect (priv->account, "invalidated", + G_CALLBACK (account_invalidated_cb), object); + + empathy_account_parse_unique_name (priv->unique_name, + &(priv->proto_name), &(priv->cm_name)); + + priv->icon_name = empathy_protocol_icon_name (priv->proto_name); + + tp_cli_account_connect_to_account_property_changed (priv->account, + empathy_account_properties_changed, + NULL, NULL, object, NULL); + + tp_cli_account_connect_to_removed (priv->account, + empathy_account_removed_cb, + NULL, NULL, object, NULL); + + tp_cli_dbus_properties_call_get_all (priv->account, -1, + TP_IFACE_ACCOUNT, + empathy_account_got_all_cb, + NULL, + NULL, + G_OBJECT (account)); +} + static void empathy_account_dispose (GObject *object); static void empathy_account_finalize (GObject *object); @@ -142,15 +493,24 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class) g_type_class_add_private (empathy_account_class, sizeof (EmpathyAccountPriv)); + object_class->set_property = empathy_account_set_property; object_class->get_property = empathy_account_get_property; object_class->dispose = empathy_account_dispose; object_class->finalize = empathy_account_finalize; + object_class->constructed = empathy_account_constructed; g_object_class_install_property (object_class, PROP_ENABLED, g_param_spec_boolean ("enabled", "Enabled", "Whether this account is enabled or not", FALSE, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, PROP_READY, + g_param_spec_boolean ("ready", + "Ready", + "Whether this account is ready to be used", + FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_PRESENCE, @@ -162,8 +522,22 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class) TP_CONNECTION_PRESENCE_TYPE_UNSET, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_STATUS, + g_param_spec_string ("status", + "Status", + "The Status string of the account", + NULL, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_STATUS_MESSAGE, + g_param_spec_string ("status-message", + "status-message", + "The Status message string of the account", + NULL, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_CONNECTION_STATUS, - g_param_spec_uint ("status", + g_param_spec_uint ("connection-status", "ConnectionStatus", "The accounts connections status type", 0, @@ -172,7 +546,7 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class) G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON, - g_param_spec_uint ("status-reason", + g_param_spec_uint ("connection-status-reason", "ConnectionStatusReason", "The account connections status reason", 0, @@ -192,7 +566,14 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class) "UniqueName", "The accounts unique name", NULL, - G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_DBUS_DAEMON, + g_param_spec_object ("dbus-daemon", + "dbus-daemon", + "The Tp Dbus daemon on which this account exists", + TP_TYPE_DBUS_DAEMON, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_DISPLAY_NAME, g_param_spec_string ("display-name", @@ -212,8 +593,30 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, - _empathy_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + _empathy_marshal_VOID__UINT_STRING_STRING, + G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + + signals[REMOVED] = g_signal_new ("removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +empathy_account_free_connection (EmpathyAccount *account) +{ + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (priv->connection_invalidated_id != 0) + g_signal_handler_disconnect (priv->connection, + priv->connection_invalidated_id); + priv->connection_invalidated_id = 0; + + if (priv->connection != NULL) + g_object_unref (priv->connection); + priv->connection = NULL; } void @@ -227,14 +630,7 @@ empathy_account_dispose (GObject *object) priv->dispose_has_run = TRUE; - if (priv->connection_invalidated_id != 0) - g_signal_handler_disconnect (priv->connection, - priv->connection_invalidated_id); - priv->connection_invalidated_id = 0; - - if (priv->connection != NULL) - g_object_unref (priv->connection); - priv->connection = NULL; + empathy_account_free_connection (self); /* release any references held by the object here */ if (G_OBJECT_CLASS (empathy_account_parent_class)->dispose != NULL) @@ -244,6 +640,16 @@ empathy_account_dispose (GObject *object) void empathy_account_finalize (GObject *object) { + EmpathyAccountPriv *priv = GET_PRIV (object); + + g_free (priv->status); + g_free (priv->message); + + g_free (priv->cm_name); + g_free (priv->proto_name); + g_free (priv->icon_name); + g_free (priv->display_name); + /* free any data held directly by the object here */ if (G_OBJECT_CLASS (empathy_account_parent_class)->finalize != NULL) G_OBJECT_CLASS (empathy_account_parent_class)->finalize (object); @@ -255,7 +661,7 @@ empathy_account_is_just_connected (EmpathyAccount *account) EmpathyAccountPriv *priv = GET_PRIV (account); GTimeVal val; - if (priv->status != TP_CONNECTION_STATUS_CONNECTED) + if (priv->connection_status != TP_CONNECTION_STATUS_CONNECTED) return FALSE; g_get_current_time (&val); @@ -285,6 +691,35 @@ empathy_account_get_connection (EmpathyAccount *account) } /** + * empathy_account_get_connection_for_path: + * @account: a #EmpathyAccount + * @patch: the path to connection object for #EmpathyAccount + * + * Get the connection of the account on path. This function does not return a + * new ref. It is not guaranteed that the returned connection object is ready + * + * Returns: the connection of the account. + **/ +TpConnection * +empathy_account_get_connection_for_path (EmpathyAccount *account, + const gchar *path) +{ + EmpathyAccountPriv *priv = GET_PRIV (account); + + /* double-check that the object path is valid */ + if (!tp_dbus_check_valid_object_path (path, NULL)) + return NULL; + + /* Should be a full object path, not the special "/" value */ + if (strlen (path) == 1) + return NULL; + + _empathy_account_set_connection (account, path); + + return priv->connection; +} + +/** * empathy_account_get_unique_name: * @account: a #EmpathyAccount * @@ -295,7 +730,7 @@ empathy_account_get_unique_name (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - return mc_account_get_unique_name (priv->mc_account); + return priv->unique_name; } /** @@ -309,7 +744,7 @@ empathy_account_get_display_name (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - return mc_account_get_display_name (priv->mc_account); + return priv->display_name; } gboolean @@ -317,154 +752,66 @@ empathy_account_is_valid (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - return mc_account_is_complete (priv->mc_account); -} - -void -empathy_account_set_enabled (EmpathyAccount *account, gboolean enabled) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - - mc_account_set_enabled (priv->mc_account, enabled); + return priv->valid; } -gboolean -empathy_account_is_enabled (EmpathyAccount *account) +const gchar * +empathy_account_get_connection_manager (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - return priv->enabled; + return priv->cm_name; } -void -empathy_account_unset_param (EmpathyAccount *account, const gchar *param) +const gchar * +empathy_account_get_protocol (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - mc_account_unset_param (priv->mc_account, param); + return priv->proto_name; } -gchar * -empathy_account_get_param_string (EmpathyAccount *account, const gchar *param) +const gchar * +empathy_account_get_icon_name (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - gchar *value = NULL; - mc_account_get_param_string (priv->mc_account, param, &value); - return value; + return priv->icon_name; } -gint -empathy_account_get_param_int (EmpathyAccount *account, const gchar *param) +const GHashTable * +empathy_account_get_parameters (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - int value; - mc_account_get_param_int (priv->mc_account, param, &value); - return value; + return priv->parameters; } gboolean -empathy_account_get_param_boolean (EmpathyAccount *account, const gchar *param) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - gboolean value; - - mc_account_get_param_boolean (priv->mc_account, param, &value); - return value; -} - -void -empathy_account_set_param_string (EmpathyAccount *account, - const gchar *param, - const gchar *value) +empathy_account_is_enabled (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - mc_account_set_param_string (priv->mc_account, param, value); -} -void -empathy_account_set_param_int (EmpathyAccount *account, - const gchar *param, - gint value) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - mc_account_set_param_int (priv->mc_account, param, value); + return priv->enabled; } -void -empathy_account_set_param_boolean (EmpathyAccount *account, - const gchar *param, - gboolean value) +gboolean +empathy_account_is_ready (EmpathyAccount *account) { EmpathyAccountPriv *priv = GET_PRIV (account); - mc_account_set_param_boolean (priv->mc_account, param, value); -} -void -empathy_account_set_display_name (EmpathyAccount *account, - const gchar *display_name) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - mc_account_set_display_name (priv->mc_account, display_name); + return priv->ready; } -McProfile * -empathy_account_get_profile (EmpathyAccount *account) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - return mc_account_get_profile (priv->mc_account); -} EmpathyAccount * -_empathy_account_new (McAccount *mc_account) +empathy_account_new (TpDBusDaemon *dbus, + const gchar *unique_name) { - EmpathyAccount *account; - EmpathyAccountPriv *priv; - - account = g_object_new (EMPATHY_TYPE_ACCOUNT, NULL); - priv = GET_PRIV (account); - priv->mc_account = mc_account; - - return account; -} - -void -_empathy_account_set_status (EmpathyAccount *account, - TpConnectionStatus status, - TpConnectionStatusReason reason, - TpConnectionPresenceType presence) -{ - EmpathyAccountPriv *priv = GET_PRIV (account); - TpConnectionStatus old_s = priv->status; - TpConnectionPresenceType old_p = priv->presence; - - priv->status = status; - priv->presence = presence; - - if (priv->status != old_s) - { - if (priv->status == TP_CONNECTION_STATUS_CONNECTED) - { - GTimeVal val; - g_get_current_time (&val); - - priv->connect_time = val.tv_sec; - } - - priv->reason = reason; - g_signal_emit (account, signals[STATUS_CHANGED], 0, - old_s, priv->status, reason); - - g_object_notify (G_OBJECT (account), "status"); - } - - if (priv->presence != old_p) - { - g_signal_emit (account, signals[PRESENCE_CHANGED], 0, - old_p, priv->presence); - g_object_notify (G_OBJECT (account), "presence"); - } + return EMPATHY_ACCOUNT (g_object_new (EMPATHY_TYPE_ACCOUNT, + "dbus-daemon", dbus, + "unique-name", unique_name, + NULL)); } static void @@ -473,13 +820,12 @@ empathy_account_connection_ready_cb (TpConnection *connection, gpointer user_data) { EmpathyAccount *account = EMPATHY_ACCOUNT (user_data); - EmpathyAccountPriv *priv = GET_PRIV (account); if (error != NULL) { DEBUG ("(%s) Connection failed to become ready: %s", empathy_account_get_unique_name (account), error->message); - priv->connection = NULL; + empathy_account_free_connection (account); } else { @@ -517,20 +863,22 @@ _empathy_account_connection_invalidated_cb (TpProxy *self, g_object_notify (G_OBJECT (account), "connection"); } -void +static void _empathy_account_set_connection (EmpathyAccount *account, - TpConnection *connection) + const gchar *path) { EmpathyAccountPriv *priv = GET_PRIV (account); - if (priv->connection == connection) - return; + if (priv->connection != NULL) + { + const gchar *current; - /* Connection already set, don't set the new one */ - if (connection != NULL && priv->connection != NULL) - return; + current = tp_proxy_get_object_path (priv->connection); + if (!tp_strdiff (current, path)) + return; + } - if (connection == NULL) + if (priv->connection != NULL) { g_signal_handler_disconnect (priv->connection, priv->connection_invalidated_id); @@ -538,38 +886,284 @@ _empathy_account_set_connection (EmpathyAccount *account, g_object_unref (priv->connection); priv->connection = NULL; - g_object_notify (G_OBJECT (account), "connection"); } - else + + if (tp_strdiff ("/", path)) { - priv->connection = g_object_ref (connection); - priv->connection_invalidated_id = g_signal_connect (priv->connection, - "invalidated", - G_CALLBACK (_empathy_account_connection_invalidated_cb), - account); - - /* notify a change in the connection property when it's ready */ - tp_connection_call_when_ready (priv->connection, - empathy_account_connection_ready_cb, account); + GError *error = NULL; + priv->connection = tp_connection_new (priv->dbus, NULL, path, &error); + + if (priv->connection == NULL) + { + DEBUG ("Failed to create a new TpConnection: %s", + error->message); + g_error_free (error); + } + else + { + priv->connection_invalidated_id = g_signal_connect (priv->connection, + "invalidated", + G_CALLBACK (_empathy_account_connection_invalidated_cb), account); + + DEBUG ("Readying connection for %s", priv->unique_name); + /* notify a change in the connection property when it's ready */ + tp_connection_call_when_ready (priv->connection, + empathy_account_connection_ready_cb, account); + } } + + g_object_notify (G_OBJECT (account), "connection"); +} + +static void +account_enabled_set_cb (TpProxy *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = user_data; + + if (error != NULL) + g_simple_async_result_set_from_error (result, (GError *) error); + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +gboolean +empathy_account_set_enabled_finish (EmpathyAccount *account, + GAsyncResult *result, + GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error) || + !g_simple_async_result_is_valid (result, G_OBJECT (account), + empathy_account_set_enabled_finish)) + return FALSE; + + return TRUE; } void -_empathy_account_set_enabled (EmpathyAccount *account, - gboolean enabled) +empathy_account_set_enabled_async (EmpathyAccount *account, + gboolean enabled, + GAsyncReadyCallback callback, + gpointer user_data) { EmpathyAccountPriv *priv = GET_PRIV (account); + GValue value = {0, }; + GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (account), + callback, user_data, empathy_account_set_enabled_finish); if (priv->enabled == enabled) - return; + { + g_simple_async_result_complete_in_idle (result); + return; + } + + g_value_init (&value, G_TYPE_BOOLEAN); + g_value_set_boolean (&value, enabled); + + tp_cli_dbus_properties_call_set (TP_PROXY (priv->account), + -1, TP_IFACE_ACCOUNT, "Enabled", &value, + account_enabled_set_cb, result, NULL, G_OBJECT (account)); +} + +static void +empathy_account_requested_presence_cb (TpProxy *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + if (error) + DEBUG ("Failed to set the requested presence: %s", error->message); +} + + +void +empathy_account_request_presence (EmpathyAccount *account, + TpConnectionPresenceType type, + const gchar *status, + const gchar *message) +{ + EmpathyAccountPriv *priv = GET_PRIV (account); + GValue value = {0, }; + GValueArray *arr; + + g_value_init (&value, TP_STRUCT_TYPE_SIMPLE_PRESENCE); + g_value_take_boxed (&value, dbus_g_type_specialized_construct + (TP_STRUCT_TYPE_SIMPLE_PRESENCE)); + arr = (GValueArray *) g_value_get_boxed (&value); + + g_value_set_uint (arr->values, type); + g_value_set_static_string (arr->values + 1, status); + g_value_set_static_string (arr->values + 2, message); + + tp_cli_dbus_properties_call_set (TP_PROXY (priv->account), + -1, + TP_IFACE_ACCOUNT, + "RequestedPresence", + &value, + empathy_account_requested_presence_cb, + NULL, + NULL, + G_OBJECT (account)); + + g_value_unset (&value); +} + +static void +empathy_account_updated_cb (TpAccount *proxy, + const gchar **reconnect_required, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + + if (error != NULL) + { + g_simple_async_result_set_from_error (result, (GError *) error); + } + + g_simple_async_result_complete (result); + g_object_unref (G_OBJECT (result)); +} + +void +empathy_account_update_settings_async (EmpathyAccount *account, + GHashTable *parameters, const gchar **unset_parameters, + GAsyncReadyCallback callback, gpointer user_data) +{ + EmpathyAccountPriv *priv = GET_PRIV (account); + GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (account), + callback, user_data, empathy_account_update_settings_finish); + + tp_cli_account_call_update_parameters (priv->account, + -1, + parameters, + unset_parameters, + empathy_account_updated_cb, + result, + NULL, + G_OBJECT (account)); +} + +gboolean +empathy_account_update_settings_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (account), empathy_account_update_settings_finish), FALSE); + + return TRUE; +} + +static void +account_display_name_set_cb (TpProxy *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = user_data; + + if (error != NULL) + g_simple_async_result_set_from_error (result, (GError *) error); + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +void +empathy_account_set_display_name_async (EmpathyAccount *account, + const char *display_name, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + GValue value = {0, }; + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (display_name == NULL) + { + g_simple_async_report_error_in_idle (G_OBJECT (account), + callback, user_data, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Can't set an empty display name")); + return; + } + + result = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_account_set_display_name_finish); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, display_name); + + tp_cli_dbus_properties_call_set (priv->account, -1, TP_IFACE_ACCOUNT, + "DisplayName", &value, account_display_name_set_cb, result, NULL, + G_OBJECT (account)); +} - priv->enabled = enabled; - g_object_notify (G_OBJECT (account), "enabled"); +gboolean +empathy_account_set_display_name_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error) || + !g_simple_async_result_is_valid (result, G_OBJECT (account), + empathy_account_set_display_name_finish)) + return FALSE; + + return TRUE; } -McAccount * -_empathy_account_get_mc_account (EmpathyAccount *account) +static void +empathy_account_remove_cb (TpAccount *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + + if (error != NULL) + { + g_simple_async_result_set_from_error (result, (GError *) error); + } + + g_simple_async_result_complete (result); + g_object_unref (G_OBJECT (result)); +} + +void +empathy_account_remove_async (EmpathyAccount *account, + GAsyncReadyCallback callback, gpointer user_data) { EmpathyAccountPriv *priv = GET_PRIV (account); - return priv->mc_account; + GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (account), + callback, user_data, empathy_account_remove_finish); + + tp_cli_account_call_remove (priv->account, + -1, + empathy_account_remove_cb, + result, + NULL, + G_OBJECT (account)); +} + +gboolean +empathy_account_remove_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (account), empathy_account_update_settings_finish), FALSE); + + return TRUE; } + |