]> git.0d.be Git - empathy.git/blob - libempathy/empathy-connectivity.c
empathy-connectivity: init priv->connected to TRUE if we're not using NM
[empathy.git] / libempathy / empathy-connectivity.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /*
3  * Copyright (C) 2009 Collabora Ltd.
4  *
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.
9  *
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.
14  *
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
18  *
19  * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
20  */
21
22 #include "config.h"
23 #include "empathy-connectivity.h"
24
25 #ifdef HAVE_NM
26 #include <nm-client.h>
27 #endif
28
29 #include "empathy-utils.h"
30 #include "empathy-marshal.h"
31
32 #define DEBUG_FLAG EMPATHY_DEBUG_CONNECTIVITY
33 #include "empathy-debug.h"
34
35 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyConnectivity)
36
37 typedef struct {
38 #ifdef HAVE_NM
39   NMClient *nm_client;
40 #endif
41
42   gboolean connected;
43   gboolean use_conn;
44   gboolean dispose_run;
45 } EmpathyConnectivityPriv;
46
47 enum {
48   STATE_CHANGE,
49   LAST_SIGNAL
50 };
51
52 enum {
53   PROP_0,
54   PROP_USE_CONN,
55 };
56
57 static guint signals[LAST_SIGNAL];
58 static EmpathyConnectivity *connectivity_singleton = NULL;
59
60 G_DEFINE_TYPE (EmpathyConnectivity, empathy_connectivity, G_TYPE_OBJECT);
61
62 #ifdef HAVE_NM
63 static void
64 connectivity_nm_state_change_cb (NMClient *client,
65     const GParamSpec *pspec,
66     EmpathyConnectivity *connectivity)
67 {
68   EmpathyConnectivityPriv *priv;
69   gboolean old_nm_connected;
70   gboolean new_nm_connected;
71   NMState state;
72
73   priv = GET_PRIV (connectivity);
74
75   if (!priv->use_conn)
76     return;
77
78   state = nm_client_get_state (priv->nm_client);
79   old_nm_connected = priv->connected;
80   new_nm_connected = !(state == NM_STATE_CONNECTING
81       || state == NM_STATE_DISCONNECTED);
82
83   DEBUG ("New NetworkManager network state %d", state);
84
85   priv->connected = new_nm_connected;
86
87   g_signal_emit (connectivity, signals[STATE_CHANGE], 0,
88       old_nm_connected, new_nm_connected);
89 }
90 #endif
91
92 static void
93 empathy_connectivity_init (EmpathyConnectivity *connectivity)
94 {
95   EmpathyConnectivityPriv *priv;
96
97   priv = G_TYPE_INSTANCE_GET_PRIVATE (connectivity,
98       EMPATHY_TYPE_CONNECTIVITY, EmpathyConnectivityPriv);
99
100   connectivity->priv = priv;
101   priv->dispose_run = FALSE;
102
103 #ifdef HAVE_NM
104   priv->nm_client = nm_client_new ();
105   if (priv->nm_client != NULL)
106     {
107       g_signal_connect (priv->nm_client, "notify::" NM_CLIENT_STATE,
108           G_CALLBACK (connectivity_nm_state_change_cb), connectivity);
109     }
110   else
111     {
112       DEBUG ("Failed to get NetworkManager proxy");
113     }
114 #else
115   priv->connected = TRUE;
116 #endif
117 }
118
119 static void
120 connectivity_finalize (GObject *object)
121 {
122 #ifdef HAVE_NM
123   EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
124   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
125
126   if (priv->nm_client != NULL)
127     {
128       g_signal_handlers_disconnect_by_func (priv->nm_client,
129           connectivity_nm_state_change_cb, connectivity);
130       g_object_unref (priv->nm_client);
131       priv->nm_client = NULL;
132     }
133 #endif
134
135   G_OBJECT_CLASS (empathy_connectivity_parent_class)->finalize (object);
136 }
137
138 static void
139 connectivity_dispose (GObject *object)
140 {
141   EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
142   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
143
144   if (priv->dispose_run)
145     return;
146
147   priv->dispose_run = TRUE;
148
149   G_OBJECT_CLASS (empathy_connectivity_parent_class)->dispose (object);
150 }
151
152 static GObject *
153 connectivity_constructor (GType type,
154     guint n_construct_params,
155     GObjectConstructParam *construct_params)
156 {
157   GObject *retval;
158
159   if (!connectivity_singleton)
160     {
161       retval = G_OBJECT_CLASS (empathy_connectivity_parent_class)->constructor
162         (type, n_construct_params, construct_params);
163
164       connectivity_singleton = EMPATHY_CONNECTIVITY (retval);
165       g_object_add_weak_pointer (retval, (gpointer) &connectivity_singleton);
166     }
167   else
168     {
169       retval = g_object_ref (connectivity_singleton);
170     }
171
172   return retval;
173 }
174
175 static void
176 connectivity_get_property (GObject *object,
177     guint param_id,
178     GValue *value,
179     GParamSpec *pspec)
180 {
181   EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
182
183   switch (param_id)
184     {
185     case PROP_USE_CONN:
186       g_value_set_boolean (value, empathy_connectivity_get_use_conn (
187               connectivity));
188       break;
189     default:
190       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
191       break;
192     };
193 }
194
195 static void
196 connectivity_set_property (GObject *object,
197     guint param_id,
198     const GValue *value,
199     GParamSpec *pspec)
200 {
201   EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
202
203   switch (param_id)
204     {
205     case PROP_USE_CONN:
206       empathy_connectivity_set_use_conn (connectivity,
207           g_value_get_boolean (value));
208       break;
209     default:
210       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
211       break;
212     };
213 }
214
215 static void
216 empathy_connectivity_class_init (EmpathyConnectivityClass *klass)
217 {
218   GObjectClass *oclass = G_OBJECT_CLASS (klass);
219
220   oclass->finalize = connectivity_finalize;
221   oclass->dispose = connectivity_dispose;
222   oclass->constructor = connectivity_constructor;
223   oclass->get_property = connectivity_get_property;
224   oclass->set_property = connectivity_set_property;
225
226   signals[STATE_CHANGE] =
227     g_signal_new ("state-change",
228         G_TYPE_FROM_CLASS (klass),
229         G_SIGNAL_RUN_LAST,
230         0,
231         NULL, NULL,
232         _empathy_marshal_VOID__BOOLEAN_BOOLEAN,
233         G_TYPE_NONE,
234         2, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, NULL);
235
236   g_object_class_install_property (oclass,
237       PROP_USE_CONN,
238       g_param_spec_boolean ("use-conn",
239           "Use connectivity managers",
240           "Set presence according to connectivity managers",
241           TRUE,
242           G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
243
244   g_type_class_add_private (oclass, sizeof (EmpathyConnectivityPriv));
245 }
246
247 /* public methods */
248
249 EmpathyConnectivity *
250 empathy_connectivity_dup_singleton (void)
251 {
252   return g_object_new (EMPATHY_TYPE_CONNECTIVITY, NULL);
253 }
254
255 gboolean
256 empathy_connectivity_is_online (EmpathyConnectivity *connectivity)
257 {
258   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
259
260   if (priv->use_conn)
261     {
262       return priv->connected;
263     }
264   else
265     {
266       return TRUE;
267     }
268 }
269
270 gboolean
271 empathy_connectivity_get_use_conn (EmpathyConnectivity *connectivity)
272 {
273   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
274
275   return priv->use_conn;
276 }
277
278 void
279 empathy_connectivity_set_use_conn (EmpathyConnectivity *connectivity,
280     gboolean use_conn)
281 {
282   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
283
284   if (use_conn == priv->use_conn)
285     return;
286
287   DEBUG ("use_conn gconf key changed; new value = %s",
288       use_conn ? "true" : "false");
289
290   priv->use_conn = use_conn;
291
292 #ifdef HAVE_NM
293   if (use_conn)
294     {
295       connectivity_nm_state_change_cb (priv->nm_client, NULL, connectivity);
296 #else
297   if (FALSE)
298     {
299 #endif
300     }
301   else
302     {
303       g_signal_emit (connectivity, signals[STATE_CHANGE], 0,
304           FALSE, TRUE);
305     }
306
307   g_object_notify (G_OBJECT (connectivity), "use-conn");
308 }