aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy/empathy-account.c
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy/empathy-account.c')
-rw-r--r--libempathy/empathy-account.c920
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;
}
+