]> git.0d.be Git - empathy.git/blob - libempathy/empathy-account.c
Initial port of Account and AccountManager to MC5
[empathy.git] / libempathy / empathy-account.c
1 /*
2  * empathy-account.c - Source for EmpathyAccount
3  * Copyright (C) 2009 Collabora Ltd.
4  * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <telepathy-glib/enums.h>
26 #include <telepathy-glib/dbus.h>
27 #include <telepathy-glib/account.h>
28 #include <telepathy-glib/gtypes.h>
29 #include <telepathy-glib/util.h>
30
31 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
32 #include <libempathy/empathy-debug.h>
33
34 #include "empathy-account.h"
35 #include "empathy-utils.h"
36 #include "empathy-marshal.h"
37
38 #define UNIQUE_NAME_PREFIX "/org/freedesktop/Telepathy/Account/"
39
40 /* signals */
41 enum {
42   STATUS_CHANGED,
43   PRESENCE_CHANGED,
44   LAST_SIGNAL
45 };
46
47 static guint signals[LAST_SIGNAL];
48
49 /* properties */
50 enum {
51   PROP_ENABLED = 1,
52   PROP_PRESENCE,
53   PROP_READY,
54   PROP_CONNECTION_STATUS,
55   PROP_CONNECTION_STATUS_REASON,
56   PROP_CONNECTION,
57   PROP_UNIQUE_NAME,
58   PROP_DBUS_DAEMON,
59   PROP_DISPLAY_NAME
60 };
61
62 G_DEFINE_TYPE(EmpathyAccount, empathy_account, G_TYPE_OBJECT)
63
64 /* private structure */
65 typedef struct _EmpathyAccountPriv EmpathyAccountPriv;
66
67 struct _EmpathyAccountPriv
68 {
69   gboolean dispose_has_run;
70
71   TpConnection *connection;
72   guint connection_invalidated_id;
73
74   TpConnectionStatus status;
75   TpConnectionStatusReason reason;
76   TpConnectionPresenceType presence;
77
78   gboolean enabled;
79   gboolean valid;
80   gboolean ready;
81   /* Timestamp when the connection got connected in seconds since the epoch */
82   glong connect_time;
83
84   gchar *cm_name;
85   gchar *proto_name;
86   gchar *icon_name;
87
88   gchar *unique_name;
89   gchar *display_name;
90   TpDBusDaemon *dbus;
91
92   TpAccount *account;
93   GHashTable *parameters;
94 };
95
96 #define GET_PRIV(obj)  EMPATHY_GET_PRIV (obj, EmpathyAccount)
97
98 static void _empathy_account_set_connection (EmpathyAccount *account,
99     TpConnection *connection);
100
101 static void
102 empathy_account_init (EmpathyAccount *obj)
103 {
104   EmpathyAccountPriv *priv;
105
106   priv =  G_TYPE_INSTANCE_GET_PRIVATE (obj,
107     EMPATHY_TYPE_ACCOUNT, EmpathyAccountPriv);
108
109   obj->priv = priv;
110
111   priv->status = TP_CONNECTION_STATUS_DISCONNECTED;
112 }
113
114 static void
115 empathy_account_set_property (GObject *object,
116     guint prop_id,
117     const GValue *value,
118     GParamSpec *pspec)
119 {
120   EmpathyAccount *account = EMPATHY_ACCOUNT (object);
121   EmpathyAccountPriv *priv = GET_PRIV (account);
122
123   switch (prop_id)
124     {
125       case PROP_ENABLED:
126         empathy_account_set_enabled (account, g_value_get_boolean (value));
127         break;
128       case PROP_UNIQUE_NAME:
129         priv->unique_name = g_value_dup_string (value);
130         break;
131       case PROP_DBUS_DAEMON:
132         priv->dbus = g_value_get_object (value);
133         break;
134       default:
135         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136         break;
137     }
138 }
139
140 static void
141 empathy_account_get_property (GObject *object,
142     guint prop_id,
143     GValue *value,
144     GParamSpec *pspec)
145 {
146   EmpathyAccount *account = EMPATHY_ACCOUNT (object);
147   EmpathyAccountPriv *priv = GET_PRIV (account);
148
149   switch (prop_id)
150     {
151       case PROP_ENABLED:
152         g_value_set_boolean (value, priv->enabled);
153         break;
154       case PROP_READY:
155         g_value_set_boolean (value, priv->enabled);
156         break;
157       case PROP_PRESENCE:
158         g_value_set_uint (value, priv->presence);
159         break;
160       case PROP_CONNECTION_STATUS:
161         g_value_set_uint (value, priv->status);
162         break;
163       case PROP_CONNECTION_STATUS_REASON:
164         g_value_set_uint (value, priv->reason);
165         break;
166       case PROP_CONNECTION:
167         g_value_set_object (value,
168             empathy_account_get_connection (account));
169         break;
170       case PROP_UNIQUE_NAME:
171         g_value_set_string (value,
172             empathy_account_get_unique_name (account));
173         break;
174       case PROP_DISPLAY_NAME:
175         g_value_set_string (value,
176             empathy_account_get_display_name (account));
177         break;
178       case PROP_DBUS_DAEMON:
179         g_value_set_string (value,
180             empathy_account_get_display_name (account));
181         break;
182       default:
183         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
184         break;
185     }
186 }
187
188 static void
189 empathy_account_update (EmpathyAccount *account, GHashTable *properties)
190 {
191   EmpathyAccountPriv *priv = GET_PRIV (account);
192   const gchar *conn_path;
193   GValueArray *arr;
194   TpConnectionStatus old_s = priv->status;
195   TpConnectionPresenceType old_p = priv->presence;
196
197   if (g_hash_table_lookup (properties, "ConnectionStatus") != NULL)
198     priv->status = tp_asv_get_int32 (properties, "ConnectionStatus", NULL);
199
200   if (g_hash_table_lookup (properties, "ConnectionStatusReason") != NULL)
201     priv->reason = tp_asv_get_int32 (properties,
202       "ConnectionStatusReason", NULL);
203
204   if (g_hash_table_lookup (properties, "CurrentPresence") != NULL)
205     {
206       arr = tp_asv_get_boxed (properties, "CurrentPresence",
207         TP_STRUCT_TYPE_SIMPLE_PRESENCE);
208       priv->presence = g_value_get_uint (g_value_array_get_nth (arr, 0));
209     }
210
211   if (g_hash_table_lookup (properties, "DisplayName") != NULL)
212     priv->display_name =
213       g_strdup (tp_asv_get_string (properties, "DisplayName"));
214
215   if (g_hash_table_lookup (properties, "Enabled") != NULL)
216     empathy_account_set_enabled (account,
217       tp_asv_get_boolean (properties, "Enabled", NULL));
218
219   if (g_hash_table_lookup (properties, "Valid") != NULL)
220     priv->valid = tp_asv_get_boolean (properties, "Valid", NULL);
221
222   if (g_hash_table_lookup (properties, "Parameters") != NULL)
223     {
224       GHashTable *parameters;
225
226       parameters = tp_asv_get_boxed (properties, "Parameters",
227         TP_HASH_TYPE_STRING_VARIANT_MAP);
228
229       priv->parameters = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP,
230         parameters);
231     }
232
233   if (!priv->ready)
234     {
235       priv->ready = TRUE;
236       g_object_notify (G_OBJECT (account), "ready");
237     }
238
239   if (priv->status != old_s)
240     {
241       if (priv->status == TP_CONNECTION_STATUS_CONNECTED)
242         {
243           GTimeVal val;
244           g_get_current_time (&val);
245
246           priv->connect_time = val.tv_sec;
247         }
248
249       g_signal_emit (account, signals[STATUS_CHANGED], 0,
250         old_s, priv->status, priv->reason);
251
252       g_object_notify (G_OBJECT (account), "status");
253     }
254
255   if (priv->presence != old_p)
256     {
257       g_signal_emit (account, signals[PRESENCE_CHANGED], 0,
258         old_p, priv->presence);
259       g_object_notify (G_OBJECT (account), "presence");
260     }
261
262   if (g_hash_table_lookup (properties, "Connection") != NULL)
263     {
264       conn_path = tp_asv_get_object_path (properties, "Connection");
265
266       if (tp_strdiff (conn_path, "/") && priv->connection == NULL)
267         {
268           TpConnection *conn;
269           GError *error = NULL;
270           conn = tp_connection_new (priv->dbus, NULL, conn_path, &error);
271
272           if (conn == NULL)
273             {
274               DEBUG ("Failed to create a new TpConnection: %s",
275                 error->message);
276               g_error_free (error);
277             }
278
279           _empathy_account_set_connection (account, conn);
280         }
281     }
282 }
283
284 static void
285 empathy_account_properties_changed (TpAccount *proxy,
286     GHashTable *properties,
287     gpointer user_data,
288     GObject *weak_object)
289 {
290   EmpathyAccount *account = EMPATHY_ACCOUNT (weak_object);
291   EmpathyAccountPriv *priv = GET_PRIV (account);
292
293   if (!priv->ready)
294     return;
295
296   empathy_account_update (account, properties);
297 }
298
299 static void
300 empathy_account_got_all_cb (TpProxy *proxy,
301     GHashTable *properties,
302     const GError *error,
303     gpointer user_data,
304     GObject *weak_object)
305 {
306   EmpathyAccount *account = EMPATHY_ACCOUNT (weak_object);
307
308   if (error != NULL)
309     {
310       printf ("Unhappy\n");
311       return;
312     }
313
314   empathy_account_update (account, properties);
315 }
316
317 static gboolean
318 empathy_account_parse_unique_name (const gchar *bus_name,
319   gchar **protocol, gchar **manager)
320 {
321   const gchar *proto, *proto_end;
322   const gchar *cm, *cm_end;
323
324   g_return_val_if_fail (
325     g_str_has_prefix (bus_name, UNIQUE_NAME_PREFIX), FALSE);
326
327   cm = bus_name + strlen (UNIQUE_NAME_PREFIX);
328
329   for (cm_end = cm; *cm_end != '/' && *cm_end != '\0'; cm_end++)
330     /* pass */;
331
332   if (*cm_end == '\0')
333     return FALSE;
334
335   if (cm_end == '\0')
336     return FALSE;
337
338   proto = cm_end + 1;
339
340   for (proto_end = proto; *proto_end != '/' && *proto_end != '\0'; proto_end++)
341     /* pass */;
342
343   if (*proto_end == '\0')
344     return FALSE;
345
346   if (protocol != NULL)
347     *protocol = g_strndup (proto, proto_end - proto);
348
349   if (manager != NULL)
350     *manager = g_strndup (cm, cm_end - cm);
351
352   return TRUE;
353 }
354
355 static void
356 empathy_account_constructed (GObject *object)
357 {
358   EmpathyAccount *account = EMPATHY_ACCOUNT (object);
359   EmpathyAccountPriv *priv = GET_PRIV (account);
360
361   priv->account = tp_account_new (priv->dbus, priv->unique_name, NULL);
362
363   empathy_account_parse_unique_name (priv->unique_name,
364     &(priv->proto_name), &(priv->cm_name));
365
366   priv->icon_name = g_strdup_printf ("im-%s", priv->proto_name);
367
368   tp_cli_account_connect_to_account_property_changed (priv->account,
369     empathy_account_properties_changed,
370     NULL, NULL, object, NULL);
371
372   tp_cli_dbus_properties_call_get_all (priv->account, -1,
373     TP_IFACE_ACCOUNT,
374     empathy_account_got_all_cb,
375     NULL,
376     NULL,
377     G_OBJECT (account));
378 }
379
380 static void empathy_account_dispose (GObject *object);
381 static void empathy_account_finalize (GObject *object);
382
383 static void
384 empathy_account_class_init (EmpathyAccountClass *empathy_account_class)
385 {
386   GObjectClass *object_class = G_OBJECT_CLASS (empathy_account_class);
387
388   g_type_class_add_private (empathy_account_class,
389     sizeof (EmpathyAccountPriv));
390
391   object_class->set_property = empathy_account_set_property;
392   object_class->get_property = empathy_account_get_property;
393   object_class->dispose = empathy_account_dispose;
394   object_class->finalize = empathy_account_finalize;
395   object_class->constructed = empathy_account_constructed;
396
397   g_object_class_install_property (object_class, PROP_ENABLED,
398     g_param_spec_boolean ("enabled",
399       "Enabled",
400       "Whether this account is enabled or not",
401       FALSE,
402       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
403
404   g_object_class_install_property (object_class, PROP_READY,
405     g_param_spec_boolean ("ready",
406       "Ready",
407       "Whether this account is ready to be used",
408       FALSE,
409       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
410
411   g_object_class_install_property (object_class, PROP_PRESENCE,
412     g_param_spec_uint ("presence",
413       "Presence",
414       "The account connections presence type",
415       0,
416       NUM_TP_CONNECTION_PRESENCE_TYPES,
417       TP_CONNECTION_PRESENCE_TYPE_UNSET,
418       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
419
420   g_object_class_install_property (object_class, PROP_CONNECTION_STATUS,
421     g_param_spec_uint ("status",
422       "ConnectionStatus",
423       "The accounts connections status type",
424       0,
425       NUM_TP_CONNECTION_STATUSES,
426       TP_CONNECTION_STATUS_DISCONNECTED,
427       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
428
429   g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON,
430     g_param_spec_uint ("status-reason",
431       "ConnectionStatusReason",
432       "The account connections status reason",
433       0,
434       NUM_TP_CONNECTION_STATUS_REASONS,
435       TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
436       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
437
438   g_object_class_install_property (object_class, PROP_CONNECTION,
439     g_param_spec_object ("connection",
440       "Connection",
441       "The accounts connection",
442       TP_TYPE_CONNECTION,
443       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
444
445   g_object_class_install_property (object_class, PROP_UNIQUE_NAME,
446     g_param_spec_string ("unique-name",
447       "UniqueName",
448       "The accounts unique name",
449       NULL,
450       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
451
452   g_object_class_install_property (object_class, PROP_DBUS_DAEMON,
453     g_param_spec_object ("dbus-daemon",
454       "dbus-daemon",
455       "The Tp Dbus daemon on which this account exists",
456       TP_TYPE_DBUS_DAEMON,
457       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
458
459   g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
460     g_param_spec_string ("display-name",
461       "DisplayName",
462       "The accounts display name",
463       NULL,
464       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
465
466   signals[STATUS_CHANGED] = g_signal_new ("status-changed",
467     G_TYPE_FROM_CLASS (object_class),
468     G_SIGNAL_RUN_LAST,
469     0, NULL, NULL,
470     _empathy_marshal_VOID__UINT_UINT_UINT,
471     G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
472
473   signals[PRESENCE_CHANGED] = g_signal_new ("presence-changed",
474     G_TYPE_FROM_CLASS (object_class),
475     G_SIGNAL_RUN_LAST,
476     0, NULL, NULL,
477     _empathy_marshal_VOID__UINT_UINT,
478     G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
479 }
480
481 void
482 empathy_account_dispose (GObject *object)
483 {
484   EmpathyAccount *self = EMPATHY_ACCOUNT (object);
485   EmpathyAccountPriv *priv = GET_PRIV (self);
486
487   if (priv->dispose_has_run)
488     return;
489
490   priv->dispose_has_run = TRUE;
491
492   if (priv->connection_invalidated_id != 0)
493     g_signal_handler_disconnect (priv->connection,
494         priv->connection_invalidated_id);
495   priv->connection_invalidated_id = 0;
496
497   if (priv->connection != NULL)
498     g_object_unref (priv->connection);
499   priv->connection = NULL;
500
501   /* release any references held by the object here */
502   if (G_OBJECT_CLASS (empathy_account_parent_class)->dispose != NULL)
503     G_OBJECT_CLASS (empathy_account_parent_class)->dispose (object);
504 }
505
506 void
507 empathy_account_finalize (GObject *object)
508 {
509   EmpathyAccountPriv *priv = GET_PRIV (object);
510
511   g_free (priv->cm_name);
512   g_free (priv->proto_name);
513   g_free (priv->icon_name);
514   g_free (priv->display_name);
515
516   /* free any data held directly by the object here */
517   if (G_OBJECT_CLASS (empathy_account_parent_class)->finalize != NULL)
518     G_OBJECT_CLASS (empathy_account_parent_class)->finalize (object);
519 }
520
521 gboolean
522 empathy_account_is_just_connected (EmpathyAccount *account)
523 {
524   EmpathyAccountPriv *priv = GET_PRIV (account);
525   GTimeVal val;
526
527   if (priv->status != TP_CONNECTION_STATUS_CONNECTED)
528     return FALSE;
529
530   g_get_current_time (&val);
531
532   return (val.tv_sec - priv->connect_time) < 10;
533 }
534
535 /**
536  * empathy_account_get_connection:
537  * @account: a #EmpathyAccount
538  *
539  * Get the connection of the account, or NULL if account is offline or the
540  * connection is not yet ready. This function does not return a new ref.
541  *
542  * Returns: the connection of the account.
543  **/
544 TpConnection *
545 empathy_account_get_connection (EmpathyAccount *account)
546 {
547   EmpathyAccountPriv *priv = GET_PRIV (account);
548
549   if (priv->connection != NULL &&
550       tp_connection_is_ready (priv->connection))
551     return priv->connection;
552
553   return NULL;
554 }
555
556 /**
557  * empathy_account_get_unique_name:
558  * @account: a #EmpathyAccount
559  *
560  * Returns: the unique name of the account.
561  **/
562 const gchar *
563 empathy_account_get_unique_name (EmpathyAccount *account)
564 {
565   EmpathyAccountPriv *priv = GET_PRIV (account);
566
567   return priv->unique_name;
568 }
569
570 /**
571  * empathy_account_get_display_name:
572  * @account: a #EmpathyAccount
573  *
574  * Returns: the display name of the account.
575  **/
576 const gchar *
577 empathy_account_get_display_name (EmpathyAccount *account)
578 {
579   EmpathyAccountPriv *priv = GET_PRIV (account);
580
581   return priv->display_name;
582 }
583
584 gboolean
585 empathy_account_is_valid (EmpathyAccount *account)
586 {
587   //EmpathyAccountPriv *priv = GET_PRIV (account);
588
589   /* FIXME */
590   return FALSE;
591 }
592
593 const gchar *
594 empathy_account_get_connection_manager (EmpathyAccount *account)
595 {
596   EmpathyAccountPriv *priv = GET_PRIV (account);
597
598   return priv->cm_name;
599 }
600
601 const gchar *
602 empathy_account_get_protocol (EmpathyAccount *account)
603 {
604   EmpathyAccountPriv *priv = GET_PRIV (account);
605
606   return priv->proto_name;
607 }
608
609 const gchar *
610 empathy_account_get_icon_name (EmpathyAccount *account)
611 {
612   EmpathyAccountPriv *priv = GET_PRIV (account);
613
614   return priv->icon_name;
615 }
616
617 gboolean
618 empathy_account_is_enabled (EmpathyAccount *account)
619 {
620   EmpathyAccountPriv *priv = GET_PRIV (account);
621
622   return priv->enabled;
623 }
624
625 void
626 empathy_account_unset_param (EmpathyAccount *account, const gchar *param)
627 {
628   //EmpathyAccountPriv *priv = GET_PRIV (account);
629
630   //mc_account_unset_param (priv->mc_account, param);
631 }
632
633 const gchar *
634 empathy_account_get_param_string (EmpathyAccount *account, const gchar *param)
635 {
636   EmpathyAccountPriv *priv = GET_PRIV (account);
637
638   return tp_asv_get_string (priv->parameters, param);
639 }
640
641 gint
642 empathy_account_get_param_int (EmpathyAccount *account, const gchar *param)
643 {
644   EmpathyAccountPriv *priv = GET_PRIV (account);
645
646   return tp_asv_get_int32 (priv->parameters, param, NULL);
647 }
648
649 gboolean
650 empathy_account_get_param_boolean (EmpathyAccount *account, const gchar *param)
651 {
652   EmpathyAccountPriv *priv = GET_PRIV (account);
653
654   return tp_asv_get_boolean (priv->parameters, param, NULL);
655 }
656
657 void
658 empathy_account_set_param_string (EmpathyAccount *account,
659   const gchar *param,
660   const gchar *value)
661 {
662   //EmpathyAccountPriv *priv = GET_PRIV (account);
663   //mc_account_set_param_string (priv->mc_account, param, value);
664 }
665
666 void
667 empathy_account_set_param_int (EmpathyAccount *account,
668   const gchar *param,
669   gint value)
670 {
671   //EmpathyAccountPriv *priv = GET_PRIV (account);
672   //mc_account_set_param_int (priv->mc_account, param, value);
673 }
674
675 void
676 empathy_account_set_param_boolean (EmpathyAccount *account,
677   const gchar *param,
678   gboolean value)
679 {
680   //EmpathyAccountPriv *priv = GET_PRIV (account);
681   //mc_account_set_param_boolean (priv->mc_account, param, value);
682 }
683
684 void
685 empathy_account_set_display_name (EmpathyAccount *account,
686     const gchar *display_name)
687 {
688   //EmpathyAccountPriv *priv = GET_PRIV (account);
689   //mc_account_set_display_name (priv->mc_account, display_name);
690 }
691
692
693 EmpathyAccount *
694 empathy_account_new (TpDBusDaemon *dbus, const gchar *unique_name)
695 {
696   return EMPATHY_ACCOUNT (g_object_new (EMPATHY_TYPE_ACCOUNT,
697     "dbus-daemon", dbus,
698     "unique-name", unique_name,
699     NULL));
700 }
701
702 #if 0
703 EmpathyAccount *
704 _empathy_account_new (McAccount *mc_account)
705 {
706   EmpathyAccount *account;
707   EmpathyAccountPriv *priv;
708   McProfile *profile;
709   McProtocol *protocol;
710
711
712   account = g_object_new (EMPATHY_TYPE_ACCOUNT, NULL);
713   priv = GET_PRIV (account);
714   priv->mc_account = mc_account;
715
716   profile =  mc_account_get_profile (mc_account);
717   protocol = mc_profile_get_protocol (profile);
718
719   if (protocol != NULL)
720     {
721       McManager *manager = mc_protocol_get_manager (protocol);
722
723       priv->proto_name = g_strdup (mc_protocol_get_name (protocol));
724       priv->cm_name = g_strdup (mc_manager_get_unique_name (manager));
725
726       g_object_unref (protocol);
727       g_object_unref (manager);
728     }
729   g_object_unref (profile);
730
731   return account;
732 }
733
734 void
735 _empathy_account_set_status (EmpathyAccount *account,
736     TpConnectionStatus status,
737     TpConnectionStatusReason reason,
738     TpConnectionPresenceType presence)
739 {
740   EmpathyAccountPriv *priv = GET_PRIV (account);
741   TpConnectionStatus old_s = priv->status;
742   TpConnectionPresenceType old_p = priv->presence;
743
744   priv->status = status;
745   priv->presence = presence;
746
747 }
748 #endif
749
750 static void
751 empathy_account_connection_ready_cb (TpConnection *connection,
752     const GError *error,
753     gpointer user_data)
754 {
755   EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
756   EmpathyAccountPriv *priv = GET_PRIV (account);
757
758   if (error != NULL)
759     {
760       DEBUG ("(%s) Connection failed to become ready: %s",
761         empathy_account_get_unique_name (account), error->message);
762       priv->connection = NULL;
763     }
764   else
765     {
766       DEBUG ("(%s) Connection ready",
767         empathy_account_get_unique_name (account));
768       g_object_notify (G_OBJECT (account), "connection");
769     }
770 }
771
772 static void
773 _empathy_account_connection_invalidated_cb (TpProxy *self,
774   guint    domain,
775   gint     code,
776   gchar   *message,
777   gpointer user_data)
778 {
779   EmpathyAccount *account = EMPATHY_ACCOUNT (user_data);
780   EmpathyAccountPriv *priv = GET_PRIV (account);
781
782   if (priv->connection == NULL)
783     return;
784
785   DEBUG ("(%s) Connection invalidated",
786     empathy_account_get_unique_name (account));
787
788   g_assert (priv->connection == TP_CONNECTION (self));
789
790   g_signal_handler_disconnect (priv->connection,
791     priv->connection_invalidated_id);
792   priv->connection_invalidated_id = 0;
793
794   g_object_unref (priv->connection);
795   priv->connection = NULL;
796
797   g_object_notify (G_OBJECT (account), "connection");
798 }
799
800 static void
801 _empathy_account_set_connection (EmpathyAccount *account,
802     TpConnection *connection)
803 {
804   EmpathyAccountPriv *priv = GET_PRIV (account);
805
806   if (priv->connection == connection)
807     return;
808
809   /* Connection already set, don't set the new one */
810   if (connection != NULL && priv->connection != NULL)
811     return;
812
813   if (connection == NULL)
814     {
815       g_signal_handler_disconnect (priv->connection,
816         priv->connection_invalidated_id);
817       priv->connection_invalidated_id = 0;
818
819       g_object_unref (priv->connection);
820       priv->connection = NULL;
821       g_object_notify (G_OBJECT (account), "connection");
822     }
823   else
824     {
825       priv->connection = g_object_ref (connection);
826       priv->connection_invalidated_id = g_signal_connect (priv->connection,
827           "invalidated",
828           G_CALLBACK (_empathy_account_connection_invalidated_cb),
829           account);
830
831       DEBUG ("Readying connection for %s", priv->unique_name);
832       /* notify a change in the connection property when it's ready */
833       tp_connection_call_when_ready (priv->connection,
834         empathy_account_connection_ready_cb, account);
835     }
836 }
837
838 void
839 empathy_account_set_enabled (EmpathyAccount *account,
840     gboolean enabled)
841 {
842   EmpathyAccountPriv *priv = GET_PRIV (account);
843
844   if (priv->enabled == enabled)
845     return;
846
847   priv->enabled = enabled;
848   g_object_notify (G_OBJECT (account), "enabled");
849 }
850
851 #if 0
852 McAccount *
853 _empathy_account_get_mc_account (EmpathyAccount *account)
854 {
855   EmpathyAccountPriv *priv = GET_PRIV (account);
856
857   return priv->mc_account;
858 }
859 #endif