Log In
New Account
  
Home My Page Project Cloud Code Snippets Project Openings Azimuth
Summary Tasks News SCM Files
1 /*
2  * connection-watcher.c - Source for ConnectionWatcher
3  * Copyright (C) 2010 Guillaume Desmottes
4  * @author Guillaume Desmottes <gdesmott@gnome.org>
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  */
22 #include <stdio.h>
23 #include <stdlib.h>
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)
36 /* signal enum */
37 enum
38 {
39     CONNECTION_ADDED,
40     LAST_SIGNAL
41 };
43 static guint signals[LAST_SIGNAL] = {0};
45 /* private structure */
46 typedef struct _ConnectionWatcherPrivate ConnectionWatcherPrivate;
48 struct _ConnectionWatcherPrivate
49 {
50   TpAccountManager *account_mgr;
51   TpDBusDaemon *bus_daemon;
52   GList *accounts;
54   gboolean dispose_has_run;
55 };
57 #define CONNECTION_WATCHER_GET_PRIVATE(o)     (G_TYPE_INSTANCE_GET_PRIVATE ((o), CONNECTION_WATCHER_TYPE, ConnectionWatcherPrivate))
59 static void
60 connection_watcher_init (ConnectionWatcher *obj)
61 {
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;
69 }
71 static void connection_watcher_dispose (GObject *object);
72 static void connection_watcher_finalize (GObject *object);
74 static void account_invalidated_cb (TpProxy *proxy,
75     guint domain,
76     gint code,
77     gchar *message,
78     gpointer user_data);
80 static void
81 connection_watcher_class_init (ConnectionWatcherClass *connection_watcher_class)
82 {
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),
92     G_SIGNAL_RUN_LAST,
93     0, NULL, NULL,
94     g_cclosure_marshal_VOID__OBJECT,
95     G_TYPE_NONE, 1, TP_TYPE_CONNECTION);
96 }
98 void
99 connection_watcher_dispose (GObject *object)
101   ConnectionWatcher *self = CONNECTION_WATCHER (object);
102   ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
103   GList *l;
105   if (priv->dispose_has_run)
106     return;
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))
113     {
114       g_signal_handlers_disconnect_by_func (l->data, account_invalidated_cb,
115           self);
116       g_object_unref (l->data);
117     }
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);
125 void
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);
136 ConnectionWatcher *
137 connection_watcher_new (void)
139   return g_object_new (CONNECTION_WATCHER_TYPE,
140       NULL);
143 static void
144 conn_ready_cb (TpConnection *conn,
145     const GError *error,
146     gpointer user_data)
148   ConnectionWatcher *self = CONNECTION_WATCHER (user_data);
150   if (error != NULL)
151     {
152       g_print ("connection is not ready: %s\n", error->message);
153       goto out;
154     }
156   g_signal_emit (self, signals[CONNECTION_ADDED], 0, conn);
158 out:
159   g_object_unref (conn);
162 static void
163 account_invalidated_cb (TpProxy *proxy,
164     guint domain,
165     gint code,
166     gchar *message,
167     gpointer user_data)
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);
179 static void
180 create_connection (ConnectionWatcher *self,
181     const gchar *path)
183   ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
184   TpConnection *conn;
185   GError *err = NULL;
187   if (path == NULL || !tp_strdiff (path, "/"))
188     return;
190   conn = tp_connection_new (priv->bus_daemon, NULL, path, &err);
191   if (conn == NULL)
192     {
193       g_print ("Failed to create TpConnection: %s\n", err->message);
194       g_error_free (err);
195       return;
196     }
198   tp_connection_call_when_ready (conn, conn_ready_cb, self);
201 static void
202 get_connection_cb (TpProxy *account,
203     const GValue *out_Value,
204     const GError *error,
205     gpointer user_data,
206     GObject *weak_object)
208   ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
209   ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
211   if (error != NULL)
212     {
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);
216       return;
217     }
219   create_connection (self, g_value_get_boxed (out_Value));
222 static void
223 account_property_changed_cb (TpAccount *account,
224     GHashTable *properties,
225     gpointer user_data,
226     GObject *weak_object)
228   ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
230   create_connection (self, tp_asv_get_object_path (properties, "Connection"));
233 static void
234 add_account (ConnectionWatcher *self,
235     TpAccount *account)
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);
252 static void
253 account_validity_changed_cb (TpAccountManager *account_mgr,
254     const gchar *account_path,
255     gboolean valid,
256     gpointer user_data,
257     GObject *weak_object)
259   ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
260   ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
261   GError *err = NULL;
262   TpAccount *account;
264   account = tp_account_new (priv->bus_daemon, account_path, &err);
265   if (account == NULL)
266     {
267       g_print ("Failed to create TpAccount: %s\n", err->message);
268       g_error_free (err);
269       return;
270     }
272   if (g_list_find (priv->accounts, account) != NULL)
273     return;
275   add_account (self, account);
278 static void
279 get_valid_accounts_cb (TpProxy *proxy,
280     const GValue *out_Value,
281     const GError *error,
282     gpointer user_data,
283     GObject *weak_object)
285   ConnectionWatcher *self = CONNECTION_WATCHER (weak_object);
286   ConnectionWatcherPrivate *priv = CONNECTION_WATCHER_GET_PRIVATE (self);
287   GPtrArray *valid_accounts;
288   guint i;
290   if (error != NULL)
291     {
292       g_print ("Failed to fetch ValidAccounts property: %s\n", error->message);
293       return;
294     }
296   valid_accounts = g_value_get_boxed (out_Value);
297   if (valid_accounts == NULL)
298     return;
300   for (i = 0; i < valid_accounts->len; i++)
301     {
302       const gchar *name;
303       TpAccount *account;
304       GError *err = NULL;
306       name = g_ptr_array_index (valid_accounts, i);
307       account = tp_account_new (priv->bus_daemon, name, &err);
308       if (account == NULL)
309         {
310           g_print ("Failed to create TpAccount: %s\n", err->message);
311           g_error_free (err);
312           continue;
313         }
315       add_account (self, account);
316     }
319 void
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);

Terms of Use    Privacy Policy    Contribution Guidelines    Feedback

Powered By GForge Collaborative Development Environment