2 * empathy-account.c - Source for EmpathyAccount
3 * Copyright (C) 2009 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <telepathy-glib/enums.h>
27 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
28 #include <libempathy/empathy-debug.h>
30 #include "empathy-account.h"
31 #include "empathy-account-priv.h"
32 #include "empathy-utils.h"
33 #include "empathy-marshal.h"
42 static guint signals[LAST_SIGNAL];
48 PROP_CONNECTION_STATUS,
49 PROP_CONNECTION_STATUS_REASON,
55 G_DEFINE_TYPE(EmpathyAccount, empathy_account, G_TYPE_OBJECT)
57 /* private structure */
58 typedef struct _EmpathyAccountPriv EmpathyAccountPriv;
60 struct _EmpathyAccountPriv
62 gboolean dispose_has_run;
64 TpConnection *connection;
65 guint connection_invalidated_id;
67 TpConnectionStatus status;
68 TpConnectionStatusReason reason;
69 TpConnectionPresenceType presence;
72 /* Timestamp when the connection got connected in seconds since the epoch */
75 McAccount *mc_account;
78 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccount)
81 empathy_account_init (EmpathyAccount *obj)
83 EmpathyAccountPriv *priv;
85 priv = G_TYPE_INSTANCE_GET_PRIVATE (obj,
86 EMPATHY_TYPE_ACCOUNT, EmpathyAccountPriv);
90 priv->status = TP_CONNECTION_STATUS_DISCONNECTED;
94 empathy_account_get_property (GObject *object,
99 EmpathyAccount *account = EMPATHY_ACCOUNT (object);
100 EmpathyAccountPriv *priv = GET_PRIV (account);
105 g_value_set_boolean (value, priv->enabled);
108 g_value_set_uint (value, priv->presence);
110 case PROP_CONNECTION_STATUS:
111 g_value_set_uint (value, priv->status);
113 case PROP_CONNECTION_STATUS_REASON:
114 g_value_set_uint (value, priv->reason);
116 case PROP_CONNECTION:
117 g_value_set_object (value,
118 empathy_account_get_connection (account));
120 case PROP_UNIQUE_NAME:
121 g_value_set_string (value,
122 empathy_account_get_unique_name (account));
124 case PROP_DISPLAY_NAME:
125 g_value_set_string (value,
126 empathy_account_get_display_name (account));
129 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
134 static void empathy_account_dispose (GObject *object);
135 static void empathy_account_finalize (GObject *object);
138 empathy_account_class_init (EmpathyAccountClass *empathy_account_class)
140 GObjectClass *object_class = G_OBJECT_CLASS (empathy_account_class);
142 g_type_class_add_private (empathy_account_class,
143 sizeof (EmpathyAccountPriv));
145 object_class->get_property = empathy_account_get_property;
146 object_class->dispose = empathy_account_dispose;
147 object_class->finalize = empathy_account_finalize;
149 g_object_class_install_property (object_class, PROP_ENABLED,
150 g_param_spec_boolean ("enabled",
152 "Whether this account is enabled or not",
154 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
156 g_object_class_install_property (object_class, PROP_PRESENCE,
157 g_param_spec_uint ("presence",
159 "The account connections presence type",
161 NUM_TP_CONNECTION_PRESENCE_TYPES,
162 TP_CONNECTION_PRESENCE_TYPE_UNSET,
163 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
165 g_object_class_install_property (object_class, PROP_CONNECTION_STATUS,
166 g_param_spec_uint ("status",
168 "The accounts connections status type",
170 NUM_TP_CONNECTION_STATUSES,
171 TP_CONNECTION_STATUS_DISCONNECTED,
172 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
174 g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON,
175 g_param_spec_uint ("status-reason",
176 "ConnectionStatusReason",
177 "The account connections status reason",
179 NUM_TP_CONNECTION_STATUS_REASONS,
180 TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
181 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
183 g_object_class_install_property (object_class, PROP_CONNECTION,
184 g_param_spec_object ("connection",
186 "The accounts connection",
188 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
190 g_object_class_install_property (object_class, PROP_UNIQUE_NAME,
191 g_param_spec_string ("unique-name",
193 "The accounts unique name",
195 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
197 g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
198 g_param_spec_string ("display-name",
200 "The accounts display name",
202 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
204 signals[STATUS_CHANGED] = g_signal_new ("status-changed",
205 G_TYPE_FROM_CLASS (object_class),
208 _empathy_marshal_VOID__UINT_UINT_UINT,
209 G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
211 signals[PRESENCE_CHANGED] = g_signal_new ("presence-changed",
212 G_TYPE_FROM_CLASS (object_class),
215 _empathy_marshal_VOID__UINT_UINT,
216 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
220 empathy_account_dispose (GObject *object)
222 EmpathyAccount *self = EMPATHY_ACCOUNT (object);
223 EmpathyAccountPriv *priv = GET_PRIV (self);
225 if (priv->dispose_has_run)
228 priv->dispose_has_run = TRUE;
230 if (priv->connection_invalidated_id != 0)
231 g_signal_handler_disconnect (priv->connection,
232 priv->connection_invalidated_id);
233 priv->connection_invalidated_id = 0;
235 if (priv->connection != NULL)
236 g_object_unref (priv->connection);
237 priv->connection = NULL;
239 /* release any references held by the object here */
240 if (G_OBJECT_CLASS (empathy_account_parent_class)->dispose != NULL)
241 G_OBJECT_CLASS (empathy_account_parent_class)->dispose (object);
245 empathy_account_finalize (GObject *object)
247 /* free any data held directly by the object here */
248 if (G_OBJECT_CLASS (empathy_account_parent_class)->finalize != NULL)
249 G_OBJECT_CLASS (empathy_account_parent_class)->finalize (object);
253 empathy_account_is_just_connected (EmpathyAccount *account)
255 EmpathyAccountPriv *priv = GET_PRIV (account);
258 if (priv->status != TP_CONNECTION_STATUS_CONNECTED)
261 g_get_current_time (&val);
263 return (val.tv_sec - priv->connect_time) < 10;
267 * empathy_account_get_connection:
268 * @account: a #EmpathyAccount
270 * Get the connection of the account, or NULL if account is offline or the
271 * connection is not yet ready. This function does not return a new ref.
273 * Returns: the connection of the account.
276 empathy_account_get_connection (EmpathyAccount *account)
278 EmpathyAccountPriv *priv = GET_PRIV (account);
280 if (priv->connection != NULL &&
281 tp_connection_is_ready (priv->connection))
282 return priv->connection;
288 * empathy_account_get_unique_name:
289 * @account: a #EmpathyAccount
291 * Returns: the unique name of the account.
294 empathy_account_get_unique_name (EmpathyAccount *account)
296 EmpathyAccountPriv *priv = GET_PRIV (account);
298 return mc_account_get_unique_name (priv->mc_account);
302 * empathy_account_get_display_name:
303 * @account: a #EmpathyAccount
305 * Returns: the display name of the account.
308 empathy_account_get_display_name (EmpathyAccount *account)
310 EmpathyAccountPriv *priv = GET_PRIV (account);
312 return mc_account_get_display_name (priv->mc_account);
316 empathy_account_is_valid (EmpathyAccount *account)
318 EmpathyAccountPriv *priv = GET_PRIV (account);
320 return mc_account_is_complete (priv->mc_account);
324 empathy_account_set_enabled (EmpathyAccount *account, gboolean enabled)
326 EmpathyAccountPriv *priv = GET_PRIV (account);
328 mc_account_set_enabled (priv->mc_account, enabled);
332 empathy_account_is_enabled (EmpathyAccount *account)
334 EmpathyAccountPriv *priv = GET_PRIV (account);
336 return priv->enabled;
340 empathy_account_unset_param (EmpathyAccount *account, const gchar *param)
342 EmpathyAccountPriv *priv = GET_PRIV (account);
344 mc_account_unset_param (priv->mc_account, param);
348 empathy_account_get_param_string (EmpathyAccount *account, const gchar *param)
350 EmpathyAccountPriv *priv = GET_PRIV (account);
353 mc_account_get_param_string (priv->mc_account, param, &value);
358 empathy_account_get_param_int (EmpathyAccount *account, const gchar *param)
360 EmpathyAccountPriv *priv = GET_PRIV (account);
363 mc_account_get_param_int (priv->mc_account, param, &value);
368 empathy_account_get_param_boolean (EmpathyAccount *account, const gchar *param)
370 EmpathyAccountPriv *priv = GET_PRIV (account);
373 mc_account_get_param_boolean (priv->mc_account, param, &value);
378 empathy_account_set_param_string (EmpathyAccount *account,
382 EmpathyAccountPriv *priv = GET_PRIV (account);
383 mc_account_set_param_string (priv->mc_account, param, value);
387 empathy_account_set_param_int (EmpathyAccount *account,
391 EmpathyAccountPriv *priv = GET_PRIV (account);
392 mc_account_set_param_int (priv->mc_account, param, value);
396 empathy_account_set_param_boolean (EmpathyAccount *account,
400 EmpathyAccountPriv *priv = GET_PRIV (account);
401 mc_account_set_param_boolean (priv->mc_account, param, value);
405 empathy_account_set_display_name (EmpathyAccount *account,
406 const gchar *display_name)
408 EmpathyAccountPriv *priv = GET_PRIV (account);
409 mc_account_set_display_name (priv->mc_account, display_name);
413 empathy_account_get_profile (EmpathyAccount *account)
415 EmpathyAccountPriv *priv = GET_PRIV (account);
416 return mc_account_get_profile (priv->mc_account);
420 _empathy_account_new (McAccount *mc_account)
422 EmpathyAccount *account;
423 EmpathyAccountPriv *priv;
425 account = g_object_new (EMPATHY_TYPE_ACCOUNT, NULL);
426 priv = GET_PRIV (account);
427 priv->mc_account = mc_account;
433 _empathy_account_set_status (EmpathyAccount *account,
434 TpConnectionStatus status,
435 TpConnectionStatusReason reason,
436 TpConnectionPresenceType presence)
438 EmpathyAccountPriv *priv = GET_PRIV (account);
439 TpConnectionStatus old_s = priv->status;
440 TpConnectionPresenceType old_p = priv->presence;
442 priv->status = status;
443 priv->presence = presence;
445 if (priv->status != old_s)
447 if (priv->status == TP_CONNECTION_STATUS_CONNECTED)
450 g_get_current_time (&val);
452 priv->connect_time = val.tv_sec;
455 priv->reason = reason;
456 g_signal_emit (account, signals[STATUS_CHANGED], 0,
457 old_s, priv->status, reason);
459 g_object_notify (G_OBJECT (account), "status");
462 if (priv->presence != old_p)
464 g_signal_emit (account, signals[PRESENCE_CHANGED], 0,
465 old_p, priv->presence);
466 g_object_notify (G_OBJECT (account), "presence");
471 empathy_account_connection_ready_cb (TpConnection *connection,
475 EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
476 EmpathyAccountPriv *priv = GET_PRIV (account);
480 DEBUG ("(%s) Connection failed to become ready: %s",
481 empathy_account_get_unique_name (account), error->message);
482 priv->connection = NULL;
486 DEBUG ("(%s) Connection ready",
487 empathy_account_get_unique_name (account));
488 g_object_notify (G_OBJECT (account), "connection");
493 _empathy_account_connection_invalidated_cb (TpProxy *self,
499 EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
500 EmpathyAccountPriv *priv = GET_PRIV (account);
502 if (priv->connection == NULL)
505 DEBUG ("(%s) Connection invalidated",
506 empathy_account_get_unique_name (account));
508 g_assert (priv->connection == TP_CONNECTION (self));
510 g_signal_handler_disconnect (priv->connection,
511 priv->connection_invalidated_id);
512 priv->connection_invalidated_id = 0;
514 g_object_unref (priv->connection);
515 priv->connection = NULL;
517 g_object_notify (G_OBJECT (account), "connection");
521 _empathy_account_set_connection (EmpathyAccount *account,
522 TpConnection *connection)
524 EmpathyAccountPriv *priv = GET_PRIV (account);
526 if (priv->connection == connection)
529 /* Connection already set, don't set the new one */
530 if (connection != NULL && priv->connection != NULL)
533 if (connection == NULL)
535 g_signal_handler_disconnect (priv->connection,
536 priv->connection_invalidated_id);
537 priv->connection_invalidated_id = 0;
539 g_object_unref (priv->connection);
540 priv->connection = NULL;
541 g_object_notify (G_OBJECT (account), "connection");
545 priv->connection = g_object_ref (connection);
546 priv->connection_invalidated_id = g_signal_connect (priv->connection,
548 G_CALLBACK (_empathy_account_connection_invalidated_cb),
551 /* notify a change in the connection property when it's ready */
552 tp_connection_call_when_ready (priv->connection,
553 empathy_account_connection_ready_cb, account);
558 _empathy_account_set_enabled (EmpathyAccount *account,
561 EmpathyAccountPriv *priv = GET_PRIV (account);
563 if (priv->enabled == enabled)
566 priv->enabled = enabled;
567 g_object_notify (G_OBJECT (account), "enabled");
571 _empathy_account_get_mc_account (EmpathyAccount *account)
573 EmpathyAccountPriv *priv = GET_PRIV (account);
574 return priv->mc_account;