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;
76 McProfile *mc_profile;
83 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccount)
86 empathy_account_init (EmpathyAccount *obj)
88 EmpathyAccountPriv *priv;
90 priv = G_TYPE_INSTANCE_GET_PRIVATE (obj,
91 EMPATHY_TYPE_ACCOUNT, EmpathyAccountPriv);
95 priv->status = TP_CONNECTION_STATUS_DISCONNECTED;
99 empathy_account_get_property (GObject *object,
104 EmpathyAccount *account = EMPATHY_ACCOUNT (object);
105 EmpathyAccountPriv *priv = GET_PRIV (account);
110 g_value_set_boolean (value, priv->enabled);
113 g_value_set_uint (value, priv->presence);
115 case PROP_CONNECTION_STATUS:
116 g_value_set_uint (value, priv->status);
118 case PROP_CONNECTION_STATUS_REASON:
119 g_value_set_uint (value, priv->reason);
121 case PROP_CONNECTION:
122 g_value_set_object (value,
123 empathy_account_get_connection (account));
125 case PROP_UNIQUE_NAME:
126 g_value_set_string (value,
127 empathy_account_get_unique_name (account));
129 case PROP_DISPLAY_NAME:
130 g_value_set_string (value,
131 empathy_account_get_display_name (account));
134 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
139 static void empathy_account_dispose (GObject *object);
140 static void empathy_account_finalize (GObject *object);
143 empathy_account_class_init (EmpathyAccountClass *empathy_account_class)
145 GObjectClass *object_class = G_OBJECT_CLASS (empathy_account_class);
147 g_type_class_add_private (empathy_account_class,
148 sizeof (EmpathyAccountPriv));
150 object_class->get_property = empathy_account_get_property;
151 object_class->dispose = empathy_account_dispose;
152 object_class->finalize = empathy_account_finalize;
154 g_object_class_install_property (object_class, PROP_ENABLED,
155 g_param_spec_boolean ("enabled",
157 "Whether this account is enabled or not",
159 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
161 g_object_class_install_property (object_class, PROP_PRESENCE,
162 g_param_spec_uint ("presence",
164 "The account connections presence type",
166 NUM_TP_CONNECTION_PRESENCE_TYPES,
167 TP_CONNECTION_PRESENCE_TYPE_UNSET,
168 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
170 g_object_class_install_property (object_class, PROP_CONNECTION_STATUS,
171 g_param_spec_uint ("status",
173 "The accounts connections status type",
175 NUM_TP_CONNECTION_STATUSES,
176 TP_CONNECTION_STATUS_DISCONNECTED,
177 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
179 g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON,
180 g_param_spec_uint ("status-reason",
181 "ConnectionStatusReason",
182 "The account connections status reason",
184 NUM_TP_CONNECTION_STATUS_REASONS,
185 TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
186 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
188 g_object_class_install_property (object_class, PROP_CONNECTION,
189 g_param_spec_object ("connection",
191 "The accounts connection",
193 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
195 g_object_class_install_property (object_class, PROP_UNIQUE_NAME,
196 g_param_spec_string ("unique-name",
198 "The accounts unique name",
200 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
202 g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
203 g_param_spec_string ("display-name",
205 "The accounts display name",
207 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
209 signals[STATUS_CHANGED] = g_signal_new ("status-changed",
210 G_TYPE_FROM_CLASS (object_class),
213 _empathy_marshal_VOID__UINT_UINT_UINT,
214 G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
216 signals[PRESENCE_CHANGED] = g_signal_new ("presence-changed",
217 G_TYPE_FROM_CLASS (object_class),
220 _empathy_marshal_VOID__UINT_UINT,
221 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
225 empathy_account_dispose (GObject *object)
227 EmpathyAccount *self = EMPATHY_ACCOUNT (object);
228 EmpathyAccountPriv *priv = GET_PRIV (self);
230 if (priv->dispose_has_run)
233 priv->dispose_has_run = TRUE;
235 if (priv->connection_invalidated_id != 0)
236 g_signal_handler_disconnect (priv->connection,
237 priv->connection_invalidated_id);
238 priv->connection_invalidated_id = 0;
240 if (priv->connection != NULL)
241 g_object_unref (priv->connection);
242 priv->connection = NULL;
244 if (priv->mc_profile != NULL)
245 g_object_unref (priv->mc_profile);
246 priv->mc_profile = NULL;
248 /* release any references held by the object here */
249 if (G_OBJECT_CLASS (empathy_account_parent_class)->dispose != NULL)
250 G_OBJECT_CLASS (empathy_account_parent_class)->dispose (object);
254 empathy_account_finalize (GObject *object)
256 EmpathyAccountPriv *priv = GET_PRIV (object);
258 g_free (priv->cm_name);
259 g_free (priv->proto_name);
260 g_free (priv->icon_name);
262 /* free any data held directly by the object here */
263 if (G_OBJECT_CLASS (empathy_account_parent_class)->finalize != NULL)
264 G_OBJECT_CLASS (empathy_account_parent_class)->finalize (object);
268 empathy_account_is_just_connected (EmpathyAccount *account)
270 EmpathyAccountPriv *priv = GET_PRIV (account);
273 if (priv->status != TP_CONNECTION_STATUS_CONNECTED)
276 g_get_current_time (&val);
278 return (val.tv_sec - priv->connect_time) < 10;
282 * empathy_account_get_connection:
283 * @account: a #EmpathyAccount
285 * Get the connection of the account, or NULL if account is offline or the
286 * connection is not yet ready. This function does not return a new ref.
288 * Returns: the connection of the account.
291 empathy_account_get_connection (EmpathyAccount *account)
293 EmpathyAccountPriv *priv = GET_PRIV (account);
295 if (priv->connection != NULL &&
296 tp_connection_is_ready (priv->connection))
297 return priv->connection;
303 * empathy_account_get_unique_name:
304 * @account: a #EmpathyAccount
306 * Returns: the unique name of the account.
309 empathy_account_get_unique_name (EmpathyAccount *account)
311 EmpathyAccountPriv *priv = GET_PRIV (account);
313 return mc_account_get_unique_name (priv->mc_account);
317 * empathy_account_get_display_name:
318 * @account: a #EmpathyAccount
320 * Returns: the display name of the account.
323 empathy_account_get_display_name (EmpathyAccount *account)
325 EmpathyAccountPriv *priv = GET_PRIV (account);
327 return mc_account_get_display_name (priv->mc_account);
331 empathy_account_is_valid (EmpathyAccount *account)
333 EmpathyAccountPriv *priv = GET_PRIV (account);
335 return mc_account_is_complete (priv->mc_account);
339 empathy_account_get_connection_manager (EmpathyAccount *account)
341 EmpathyAccountPriv *priv = GET_PRIV (account);
343 return priv->cm_name;
347 empathy_account_get_protocol (EmpathyAccount *account)
349 EmpathyAccountPriv *priv = GET_PRIV (account);
351 return priv->proto_name;
355 empathy_account_get_icon_name (EmpathyAccount *account)
357 EmpathyAccountPriv *priv = GET_PRIV (account);
359 return priv->icon_name;
363 empathy_account_set_enabled (EmpathyAccount *account, gboolean enabled)
365 EmpathyAccountPriv *priv = GET_PRIV (account);
367 mc_account_set_enabled (priv->mc_account, enabled);
371 empathy_account_is_enabled (EmpathyAccount *account)
373 EmpathyAccountPriv *priv = GET_PRIV (account);
375 return priv->enabled;
379 empathy_account_unset_param (EmpathyAccount *account, const gchar *param)
381 EmpathyAccountPriv *priv = GET_PRIV (account);
383 mc_account_unset_param (priv->mc_account, param);
387 empathy_account_get_param_string (EmpathyAccount *account, const gchar *param)
389 EmpathyAccountPriv *priv = GET_PRIV (account);
392 mc_account_get_param_string (priv->mc_account, param, &value);
397 empathy_account_get_param_int (EmpathyAccount *account, const gchar *param)
399 EmpathyAccountPriv *priv = GET_PRIV (account);
402 mc_account_get_param_int (priv->mc_account, param, &value);
407 empathy_account_get_param_boolean (EmpathyAccount *account, const gchar *param)
409 EmpathyAccountPriv *priv = GET_PRIV (account);
412 mc_account_get_param_boolean (priv->mc_account, param, &value);
417 empathy_account_set_param_string (EmpathyAccount *account,
421 EmpathyAccountPriv *priv = GET_PRIV (account);
422 mc_account_set_param_string (priv->mc_account, param, value);
426 empathy_account_set_param_int (EmpathyAccount *account,
430 EmpathyAccountPriv *priv = GET_PRIV (account);
431 mc_account_set_param_int (priv->mc_account, param, value);
435 empathy_account_set_param_boolean (EmpathyAccount *account,
439 EmpathyAccountPriv *priv = GET_PRIV (account);
440 mc_account_set_param_boolean (priv->mc_account, param, value);
444 empathy_account_set_display_name (EmpathyAccount *account,
445 const gchar *display_name)
447 EmpathyAccountPriv *priv = GET_PRIV (account);
448 mc_account_set_display_name (priv->mc_account, display_name);
452 _empathy_account_new (McAccount *mc_account)
454 EmpathyAccount *account;
455 EmpathyAccountPriv *priv;
457 McProtocol *protocol;
460 account = g_object_new (EMPATHY_TYPE_ACCOUNT, NULL);
461 priv = GET_PRIV (account);
462 priv->mc_account = mc_account;
464 profile = mc_account_get_profile (mc_account);
465 protocol = mc_profile_get_protocol (profile);
467 if (protocol != NULL)
469 McManager *manager = mc_protocol_get_manager (protocol);
471 priv->proto_name = g_strdup (mc_protocol_get_name (protocol));
472 priv->cm_name = g_strdup (mc_manager_get_unique_name (manager));
473 priv->icon_name = g_strdup_printf ("im-%s", priv->proto_name);
475 g_object_unref (protocol);
476 g_object_unref (manager);
478 g_object_unref (profile);
484 _empathy_account_set_status (EmpathyAccount *account,
485 TpConnectionStatus status,
486 TpConnectionStatusReason reason,
487 TpConnectionPresenceType presence)
489 EmpathyAccountPriv *priv = GET_PRIV (account);
490 TpConnectionStatus old_s = priv->status;
491 TpConnectionPresenceType old_p = priv->presence;
493 priv->status = status;
494 priv->presence = presence;
496 if (priv->status != old_s)
498 if (priv->status == TP_CONNECTION_STATUS_CONNECTED)
501 g_get_current_time (&val);
503 priv->connect_time = val.tv_sec;
506 priv->reason = reason;
507 g_signal_emit (account, signals[STATUS_CHANGED], 0,
508 old_s, priv->status, reason);
510 g_object_notify (G_OBJECT (account), "status");
513 if (priv->presence != old_p)
515 g_signal_emit (account, signals[PRESENCE_CHANGED], 0,
516 old_p, priv->presence);
517 g_object_notify (G_OBJECT (account), "presence");
522 empathy_account_connection_ready_cb (TpConnection *connection,
526 EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
527 EmpathyAccountPriv *priv = GET_PRIV (account);
531 DEBUG ("(%s) Connection failed to become ready: %s",
532 empathy_account_get_unique_name (account), error->message);
533 priv->connection = NULL;
537 DEBUG ("(%s) Connection ready",
538 empathy_account_get_unique_name (account));
539 g_object_notify (G_OBJECT (account), "connection");
544 _empathy_account_connection_invalidated_cb (TpProxy *self,
550 EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
551 EmpathyAccountPriv *priv = GET_PRIV (account);
553 if (priv->connection == NULL)
556 DEBUG ("(%s) Connection invalidated",
557 empathy_account_get_unique_name (account));
559 g_assert (priv->connection == TP_CONNECTION (self));
561 g_signal_handler_disconnect (priv->connection,
562 priv->connection_invalidated_id);
563 priv->connection_invalidated_id = 0;
565 g_object_unref (priv->connection);
566 priv->connection = NULL;
568 g_object_notify (G_OBJECT (account), "connection");
572 _empathy_account_set_connection (EmpathyAccount *account,
573 TpConnection *connection)
575 EmpathyAccountPriv *priv = GET_PRIV (account);
577 if (priv->connection == connection)
580 /* Connection already set, don't set the new one */
581 if (connection != NULL && priv->connection != NULL)
584 if (connection == NULL)
586 g_signal_handler_disconnect (priv->connection,
587 priv->connection_invalidated_id);
588 priv->connection_invalidated_id = 0;
590 g_object_unref (priv->connection);
591 priv->connection = NULL;
592 g_object_notify (G_OBJECT (account), "connection");
596 priv->connection = g_object_ref (connection);
597 priv->connection_invalidated_id = g_signal_connect (priv->connection,
599 G_CALLBACK (_empathy_account_connection_invalidated_cb),
602 /* notify a change in the connection property when it's ready */
603 tp_connection_call_when_ready (priv->connection,
604 empathy_account_connection_ready_cb, account);
609 _empathy_account_set_enabled (EmpathyAccount *account,
612 EmpathyAccountPriv *priv = GET_PRIV (account);
614 if (priv->enabled == enabled)
617 priv->enabled = enabled;
618 g_object_notify (G_OBJECT (account), "enabled");
622 _empathy_account_get_mc_account (EmpathyAccount *account)
624 EmpathyAccountPriv *priv = GET_PRIV (account);
626 return priv->mc_account;