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);
74 static void account_invalidated_cb (TpProxy *proxy,
81 connection_watcher_class_init (ConnectionWatcherClass *connection_watcher_class)
83 GObjectClass *object_class = G_OBJECT_CLASS (connection_watcher_class);
85 g_type_class_add_private (connection_watcher_class, sizeof (ConnectionWatcherPrivate));
87 object_class->dispose = connection_watcher_dispose;
88 object_class->finalize = connection_watcher_finalize;
90 signals[CONNECTION_ADDED] = g_signal_new ("connection-added",
91 G_TYPE_FROM_CLASS (object_class),
94 g_cclosure_marshal_VOID__OBJECT,
95 G_TYPE_NONE, 1, TP_TYPE_CONNECTION);
99 connection_watcher_dispose (GObject *object)
101 ConnectionWatcher *self = CONNECTION_WATCHER (object);
102 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
105 if (priv->dispose_has_run)
108 priv->dispose_has_run = TRUE;
110 g_object_unref (priv->account_mgr);
112 for (l = priv->accounts; l != NULL; l = g_list_next (l))
114 g_signal_handlers_disconnect_by_func (l->data, account_invalidated_cb,
116 g_object_unref (l->data);
119 g_object_unref (priv->bus_daemon);
121 if (G_OBJECT_CLASS (connection_watcher_parent_class)->dispose)
122 G_OBJECT_CLASS (connection_watcher_parent_class)->dispose (object);
126 connection_watcher_finalize (GObject *object)
128 ConnectionWatcher *self = CONNECTION_WATCHER (object);
129 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
131 g_list_free (priv->accounts);
133 G_OBJECT_CLASS (connection_watcher_parent_class)->finalize (object);
137 connection_watcher_new (void)
139 return g_object_new (CONNECTION_WATCHER_TYPE,
144 conn_ready_cb (TpConnection *conn,
148 ConnectionWatcher *self = CONNECTION_WATCHER (user_data);
152 g_print ("connection is not ready: %s\n", error->message);
156 g_signal_emit (self, signals[CONNECTION_ADDED], 0, conn);
159 g_object_unref (conn);
163 account_invalidated_cb (TpProxy *proxy,
169 ConnectionWatcher *self = CONNECTION_WATCHER (user_data);
170 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
172 g_print ("remove invalidated account: %s\n",
173 tp_proxy_get_object_path (proxy));
175 priv->accounts = g_list_remove (priv->accounts, proxy);
176 g_object_unref (proxy);
180 create_connection (ConnectionWatcher *self,
183 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
187 if (path == NULL || !tp_strdiff (path, "/"))
190 conn = tp_connection_new (priv->bus_daemon, NULL, path, &err);
193 g_print ("Failed to create TpConnection: %s\n", err->message);
198 tp_connection_call_when_ready (conn, conn_ready_cb, self);
202 get_connection_cb (TpProxy *account,
203 const GValue *out_Value,
206 GObject *weak_object)
208 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
209 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
213 g_print ("Failed to fetch Connection property: %s\n", error->message);
214 priv->accounts = g_list_remove (priv->accounts, account);
215 g_object_unref (account);
219 create_connection (self, g_value_get_boxed (out_Value));
223 account_property_changed_cb (TpAccount *account,
224 GHashTable *properties,
226 GObject *weak_object)
228 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
230 create_connection (self, tp_asv_get_object_path (properties, "Connection"));
234 add_account (ConnectionWatcher *self,
237 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
239 priv->accounts = g_list_prepend (priv->accounts, account);
241 tp_cli_dbus_properties_call_get (account, -1,
242 TP_IFACE_ACCOUNT, "Connection", get_connection_cb,
243 self, NULL, G_OBJECT (self));
245 tp_cli_account_connect_to_account_property_changed (account,
246 account_property_changed_cb, self, NULL, G_OBJECT (self), NULL);
248 g_signal_connect (account, "invalidated",
249 G_CALLBACK (account_invalidated_cb), self);
253 account_validity_changed_cb (TpAccountManager *account_mgr,
254 const gchar *account_path,
257 GObject *weak_object)
259 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
260 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
264 account = tp_account_new (priv->bus_daemon, account_path, &err);
267 g_print ("Failed to create TpAccount: %s\n", err->message);
272 if (g_list_find (priv->accounts, account) != NULL)
275 add_account (self, account);
279 get_valid_accounts_cb (TpProxy *proxy,
280 const GValue *out_Value,
283 GObject *weak_object)
285 ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
286 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
287 GPtrArray *valid_accounts;
292 g_print ("Failed to fetch ValidAccounts property: %s\n", error->message);
296 valid_accounts = g_value_get_boxed (out_Value);
297 if (valid_accounts == NULL)
300 for (i = 0; i < valid_accounts->len; i++)
306 name = g_ptr_array_index (valid_accounts, i);
307 account = tp_account_new (priv->bus_daemon, name, &err);
310 g_print ("Failed to create TpAccount: %s\n", err->message);
315 add_account (self, account);
320 connection_watcher_start (ConnectionWatcher *self)
322 ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
324 tp_cli_dbus_properties_call_get (priv->account_mgr, -1,
325 TP_IFACE_ACCOUNT_MANAGER, "ValidAccounts", get_valid_accounts_cb,
326 self, NULL, G_OBJECT (self));
328 tp_cli_account_manager_connect_to_account_validity_changed (priv->account_mgr,
329 account_validity_changed_cb, NULL, NULL, G_OBJECT (self), NULL);