1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
3 * Copyright (C) 2008 Collabora Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
24 #include <libmissioncontrol/mc-account-monitor.h>
26 #include "empathy-account-manager.h"
27 #include "empathy-marshal.h"
28 #include "empathy-utils.h"
30 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountManager)
33 McAccountMonitor *monitor;
39 } EmpathyAccountManagerPriv;
43 TpConnectionStatus connection;
55 ACCOUNT_CONNECTION_CHANGED,
56 ACCOUNT_PRESENCE_CHANGED,
60 static guint signals[LAST_SIGNAL];
61 static EmpathyAccountManager *manager = NULL;
63 G_DEFINE_TYPE (EmpathyAccountManager, empathy_account_manager, G_TYPE_OBJECT);
66 account_data_new (McPresence presence, TpConnectionStatus connection,
71 retval = g_slice_new0 (AccountData);
72 retval->presence = presence;
73 retval->connection = connection;
74 retval->is_enabled = is_enabled;
75 retval->source_id = 0;
81 account_data_new_default (MissionControl *mc,
85 TpConnectionStatus actual_c;
88 actual_p = mission_control_get_presence_actual (mc, &err);
90 actual_p = MC_PRESENCE_UNSET;
94 actual_c = mission_control_get_connection_status (mc,
97 actual_c = TP_CONNECTION_STATUS_DISCONNECTED;
100 return account_data_new (actual_p, actual_c, mc_account_is_enabled (account));
104 account_data_free (AccountData *data)
106 if (data->source_id > 0) {
107 g_source_remove (data->source_id);
111 g_slice_free (AccountData, data);
115 account_created_cb (McAccountMonitor *mon,
117 EmpathyAccountManager *manager)
120 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
122 account = mc_account_lookup (account_name);
127 data = account_data_new_default (priv->mc, account);
129 g_hash_table_insert (priv->accounts, account, data);
131 g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account);
136 account_deleted_cb (McAccountMonitor *mon,
138 EmpathyAccountManager *manager)
141 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
143 account = mc_account_lookup (account_name);
146 g_signal_emit (manager, signals[ACCOUNT_DELETED], 0, account);
148 g_hash_table_remove (priv->accounts, account);
149 g_object_unref (account);
154 account_changed_cb (McAccountMonitor *mon,
156 EmpathyAccountManager *manager)
160 account = mc_account_lookup (account_name);
163 g_signal_emit (manager, signals[ACCOUNT_CHANGED], 0, account);
164 g_object_unref (account);
169 account_disabled_cb (McAccountMonitor *mon,
171 EmpathyAccountManager *manager)
174 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
177 account = mc_account_lookup (account_name);
180 data = g_hash_table_lookup (priv->accounts, account);
182 data->is_enabled = FALSE;
184 g_signal_emit (manager, signals[ACCOUNT_DISABLED], 0, account);
189 account_enabled_cb (McAccountMonitor *mon,
191 EmpathyAccountManager *manager)
194 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
197 account = mc_account_lookup (account_name);
200 data = g_hash_table_lookup (priv->accounts, account);
202 data->is_enabled = TRUE;
204 g_signal_emit (manager, signals[ACCOUNT_ENABLED], 0, account);
205 g_object_unref (account);
210 update_connection_numbers (EmpathyAccountManager *manager,
211 TpConnectionStatus conn,
212 TpConnectionStatus old_c)
214 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
216 if (conn == TP_CONNECTION_STATUS_CONNECTED) {
218 if (old_c == TP_CONNECTION_STATUS_CONNECTING) {
223 if (conn == TP_CONNECTION_STATUS_CONNECTING) {
225 if (old_c == TP_CONNECTION_STATUS_CONNECTED) {
230 if (conn == TP_CONNECTION_STATUS_DISCONNECTED) {
231 if (old_c == TP_CONNECTION_STATUS_CONNECTED) {
234 if (old_c == TP_CONNECTION_STATUS_CONNECTING) {
241 remove_data_timeout (gpointer _data)
243 AccountData *data = _data;
251 account_status_changed_cb (MissionControl *mc,
252 TpConnectionStatus connection,
254 TpConnectionStatusReason reason,
255 const gchar *unique_name,
256 EmpathyAccountManager *manager)
259 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
262 TpConnectionStatus old_c;
264 account = mc_account_lookup (unique_name);
267 data = g_hash_table_lookup (priv->accounts, account);
270 old_p = data->presence;
271 old_c = data->connection;
273 if (old_p != presence) {
274 data->presence = presence;
275 g_signal_emit (manager, signals[ACCOUNT_PRESENCE_CHANGED], 0,
276 account, presence, old_p);
279 if (old_c != connection) {
280 data->connection = connection;
281 update_connection_numbers (manager, connection, old_c);
283 g_signal_emit (manager, signals[ACCOUNT_CONNECTION_CHANGED], 0,
284 account, reason, connection, old_c);
286 if (old_c == TP_CONNECTION_STATUS_CONNECTING &&
287 connection == TP_CONNECTION_STATUS_CONNECTED) {
288 if (data->source_id > 0) {
289 g_source_remove (data->source_id);
293 data->source_id = g_timeout_add_seconds (10,
299 g_object_unref (account);
304 empathy_account_manager_init (EmpathyAccountManager *manager)
306 EmpathyAccountManagerPriv *priv =
307 G_TYPE_INSTANCE_GET_PRIVATE (manager,
308 EMPATHY_TYPE_ACCOUNT_MANAGER, EmpathyAccountManagerPriv);
309 GList *mc_accounts, *l;
312 manager->priv = priv;
313 priv->monitor = mc_account_monitor_new ();
314 priv->mc = empathy_mission_control_new ();
315 priv->connected = priv->connecting = 0;
317 priv->accounts = g_hash_table_new_full (empathy_account_hash,
318 empathy_account_equal,
320 (GDestroyNotify) account_data_free);
322 mc_accounts = mc_accounts_list ();
324 for (l = mc_accounts; l; l = l->next) {
325 data = account_data_new_default (priv->mc, l->data);
327 g_hash_table_insert (priv->accounts, g_object_ref (l->data),
331 g_signal_connect (priv->monitor, "account-created",
332 G_CALLBACK (account_created_cb), manager);
333 g_signal_connect (priv->monitor, "account-deleted",
334 G_CALLBACK (account_deleted_cb), manager);
335 g_signal_connect (priv->monitor, "account-disabled",
336 G_CALLBACK (account_disabled_cb), manager);
337 g_signal_connect (priv->monitor, "account-enabled",
338 G_CALLBACK (account_enabled_cb), manager);
339 g_signal_connect (priv->monitor, "account-changed",
340 G_CALLBACK (account_changed_cb), manager);
342 dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc), "AccountStatusChanged",
343 G_CALLBACK (account_status_changed_cb),
348 disconnect_monitor_signals (McAccountMonitor *monitor,
351 g_signal_handlers_disconnect_by_func (monitor,
352 account_created_cb, obj);
353 g_signal_handlers_disconnect_by_func (monitor,
354 account_deleted_cb, obj);
355 g_signal_handlers_disconnect_by_func (monitor,
356 account_disabled_cb, obj);
357 g_signal_handlers_disconnect_by_func (monitor,
358 account_enabled_cb, obj);
359 g_signal_handlers_disconnect_by_func (monitor,
360 account_changed_cb, obj);
364 do_finalize (GObject *obj)
366 EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (obj);
367 EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
369 dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
370 "AccountStatusChanged",
371 G_CALLBACK (account_status_changed_cb),
374 disconnect_monitor_signals (priv->monitor, obj);
376 g_object_unref (priv->monitor);
377 g_object_unref (priv->mc);
379 g_hash_table_destroy (priv->accounts);
381 G_OBJECT_CLASS (empathy_account_manager_parent_class)->finalize (obj);
385 empathy_account_manager_class_init (EmpathyAccountManagerClass *klass)
387 GObjectClass *oclass = G_OBJECT_CLASS (klass);
389 oclass->finalize = do_finalize;
391 signals[ACCOUNT_CREATED] =
392 g_signal_new ("account-created",
393 G_TYPE_FROM_CLASS (klass),
397 g_cclosure_marshal_VOID__OBJECT,
401 signals[ACCOUNT_DELETED] =
402 g_signal_new ("account-deleted",
403 G_TYPE_FROM_CLASS (klass),
407 g_cclosure_marshal_VOID__OBJECT,
411 signals[ACCOUNT_ENABLED] =
412 g_signal_new ("account-enabled",
413 G_TYPE_FROM_CLASS (klass),
417 g_cclosure_marshal_VOID__OBJECT,
421 signals[ACCOUNT_DISABLED] =
422 g_signal_new ("account-disabled",
423 G_TYPE_FROM_CLASS (klass),
427 g_cclosure_marshal_VOID__OBJECT,
431 signals[ACCOUNT_CHANGED] =
432 g_signal_new ("account-changed",
433 G_TYPE_FROM_CLASS (klass),
437 g_cclosure_marshal_VOID__OBJECT,
441 signals[ACCOUNT_CONNECTION_CHANGED] =
442 g_signal_new ("account-connection-changed",
443 G_TYPE_FROM_CLASS (klass),
447 _empathy_marshal_VOID__OBJECT_INT_UINT_UINT,
450 G_TYPE_INT, /* reason */
451 G_TYPE_UINT, /* actual connection */
452 G_TYPE_UINT); /* previous connection */
454 signals[ACCOUNT_PRESENCE_CHANGED] =
455 g_signal_new ("account-presence-changed",
456 G_TYPE_FROM_CLASS (klass),
460 _empathy_marshal_VOID__OBJECT_INT_INT,
463 G_TYPE_INT, /* actual presence */
464 G_TYPE_INT); /* previous presence */
466 g_type_class_add_private (oclass, sizeof (EmpathyAccountManagerPriv));
471 EmpathyAccountManager *
472 empathy_account_manager_new (void)
475 manager = g_object_new (EMPATHY_TYPE_ACCOUNT_MANAGER, NULL);
476 g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager);
478 g_object_ref (manager);
485 empathy_account_manager_get_connected_accounts (EmpathyAccountManager *manager)
487 EmpathyAccountManagerPriv *priv;
489 g_assert (EMPATHY_IS_ACCOUNT_MANAGER (manager));
491 priv = GET_PRIV (manager);
493 return priv->connected;
497 empathy_account_manager_get_connecting_accounts (EmpathyAccountManager *manager)
499 EmpathyAccountManagerPriv *priv;
501 g_assert (EMPATHY_IS_ACCOUNT_MANAGER (manager));
503 priv = GET_PRIV (manager);
505 return priv->connecting;
509 empathy_account_manager_is_account_just_connected (EmpathyAccountManager *manager,
512 EmpathyAccountManagerPriv *priv;
515 g_assert (EMPATHY_IS_ACCOUNT_MANAGER (manager));
517 priv = GET_PRIV (manager);
518 data = g_hash_table_lookup (priv->accounts, account);
522 return (data->source_id > 0);