2 * connection-watcher.c - Source for ConnectionWatcher
3 * Copyright (C) 2010 Guillaume Desmottes
4 * @author Guillaume Desmottes <gdesmott@gnome.org>
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/account-manager.h>
26 #include <telepathy-glib/account.h>
27 #include <telepathy-glib/dbus.h>
28 #include <telepathy-glib/interfaces.h>
29 #include <telepathy-glib/gtypes.h>
30 #include <telepathy-glib/util.h>
32 #include "connection-watcher.h"
34 G_DEFINE_TYPE(ConnectionWatcher, connection_watcher, G_TYPE_OBJECT)
43 static guint signals[LAST_SIGNAL] = {0};
45 /* private structure */
46 typedef struct _ConnectionWatcherPrivate ConnectionWatcherPrivate;
48 struct _ConnectionWatcherPrivate
50 TpAccountManager *account_mgr;
51 TpDBusDaemon *bus_daemon;
54 gboolean dispose_has_run;
57 #define CONNECTION_WATCHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CONNECTION_WATCHER_TYPE, ConnectionWatcherPrivate))
60 connection_watcher_init (ConnectionWatcher *obj)
62 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (obj);
64 priv->bus_daemon = tp_dbus_daemon_dup (NULL);
65 g_assert (priv->bus_daemon != NULL);
67 priv->account_mgr = tp_account_manager_new (priv->bus_daemon);
68 priv->accounts = NULL;
71 static void connection_watcher_dispose (GObject *object);
72 static void connection_watcher_finalize (GObject *object);
75 connection_watcher_class_init (ConnectionWatcherClass *connection_watcher_class)
77 GObjectClass *object_class = G_OBJECT_CLASS (connection_watcher_class);
79 g_type_class_add_private (connection_watcher_class, sizeof (ConnectionWatcherPrivate));
81 object_class->dispose = connection_watcher_dispose;
82 object_class->finalize = connection_watcher_finalize;
84 signals[CONNECTION_ADDED] = g_signal_new ("connection-added",
85 G_TYPE_FROM_CLASS (object_class),
88 g_cclosure_marshal_VOID__OBJECT,
89 G_TYPE_NONE, 1, TP_TYPE_CONNECTION);
93 connection_watcher_dispose (GObject *object)
95 ConnectionWatcher *self = CONNECTION_WATCHER (object);
96 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
99 if (priv->dispose_has_run)
102 priv->dispose_has_run = TRUE;
104 g_object_unref (priv->account_mgr);
106 for (l = priv->accounts; l != NULL; l = g_list_next (l))
108 g_object_unref (l->data);
111 g_object_unref (priv->bus_daemon);
113 if (G_OBJECT_CLASS (connection_watcher_parent_class)->dispose)
114 G_OBJECT_CLASS (connection_watcher_parent_class)->dispose (object);
118 connection_watcher_finalize (GObject *object)
120 ConnectionWatcher *self = CONNECTION_WATCHER (object);
121 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
123 g_list_free (priv->accounts);
125 G_OBJECT_CLASS (connection_watcher_parent_class)->finalize (object);
129 connection_watcher_new (void)
131 return g_object_new (CONNECTION_WATCHER_TYPE,
136 conn_ready_cb (TpConnection *conn,
140 ConnectionWatcher *self = CONNECTION_WATCHER (user_data);
144 g_print ("connection is not ready: %s\n", error->message);
148 g_signal_emit (self, signals[CONNECTION_ADDED], 0, conn);
151 g_object_unref (conn);
155 account_invalidated_cb (TpProxy *proxy,
161 ConnectionWatcher *self = CONNECTION_WATCHER (user_data);
162 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
164 g_print ("remove invalidated account: %s\n",
165 tp_proxy_get_object_path (proxy));
167 priv->accounts = g_list_remove (priv->accounts, proxy);
168 g_object_unref (proxy);
172 create_connection (ConnectionWatcher *self,
175 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
179 if (path == NULL || !tp_strdiff (path, "/"))
182 conn = tp_connection_new (priv->bus_daemon, NULL, path, &err);
185 g_print ("Failed to create TpConnection: %s\n", err->message);
190 tp_connection_call_when_ready (conn, conn_ready_cb, self);
194 get_connection_cb (TpProxy *account,
195 const GValue *out_Value,
198 GObject *weak_object)
200 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
201 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
205 g_print ("Failed to fetch Connection property: %s\n", error->message);
206 priv->accounts = g_list_remove (priv->accounts, account);
207 g_object_unref (account);
211 create_connection (self, g_value_get_boxed (out_Value));
215 account_property_changed_cb (TpAccount *account,
216 GHashTable *properties,
218 GObject *weak_object)
220 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
222 create_connection (self, tp_asv_get_object_path (properties, "Connection"));
226 add_account (ConnectionWatcher *self,
229 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
231 priv->accounts = g_list_prepend (priv->accounts, account);
233 tp_cli_dbus_properties_call_get (account, -1,
234 TP_IFACE_ACCOUNT, "Connection", get_connection_cb,
235 self, NULL, G_OBJECT (self));
237 tp_cli_account_connect_to_account_property_changed (account,
238 account_property_changed_cb, self, NULL, G_OBJECT (self), NULL);
240 g_signal_connect (account, "invalidated",
241 G_CALLBACK (account_invalidated_cb), self);
245 account_validity_changed_cb (TpAccountManager *account_mgr,
246 const gchar *account_path,
249 GObject *weak_object)
251 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
252 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
256 account = tp_account_new (priv->bus_daemon, account_path, &err);
259 g_print ("Failed to create TpAccount: %s\n", err->message);
264 if (g_list_find (priv->accounts, account) != NULL)
267 add_account (self, account);
271 get_valid_accounts_cb (TpProxy *proxy,
272 const GValue *out_Value,
275 GObject *weak_object)
277 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
278 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
279 GPtrArray *valid_accounts;
284 g_print ("Failed to fetch ValidAccounts property: %s\n", error->message);
288 valid_accounts = g_value_get_boxed (out_Value);
289 if (valid_accounts == NULL)
292 for (i = 0; i < valid_accounts->len; i++)
298 name = g_ptr_array_index (valid_accounts, i);
299 account = tp_account_new (priv->bus_daemon, name, &err);
302 g_print ("Failed to create TpAccount: %s\n", err->message);
307 add_account (self, account);
312 connection_watcher_start (ConnectionWatcher *self)
314 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
316 tp_cli_dbus_properties_call_get (priv->account_mgr, -1,
317 TP_IFACE_ACCOUNT_MANAGER, "ValidAccounts", get_valid_accounts_cb,
318 self, NULL, G_OBJECT (self));
320 tp_cli_account_manager_connect_to_account_validity_changed (priv->account_mgr,
321 account_validity_changed_cb, NULL, NULL, G_OBJECT (self), NULL);