1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
3 * Copyright (C) 2009 Collabora Ltd.
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.
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.
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
19 * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
23 #include "empathy-connectivity.h"
26 #include <nm-client.h>
30 #include <dbus/dbus-glib.h>
33 #include <telepathy-glib/util.h>
35 #include "empathy-utils.h"
36 #include "empathy-marshal.h"
38 #define DEBUG_FLAG EMPATHY_DEBUG_CONNECTIVITY
39 #include "empathy-debug.h"
41 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyConnectivity)
46 gulong state_change_signal_id
;
55 } EmpathyConnectivityPriv
;
67 static guint signals
[LAST_SIGNAL
];
68 static EmpathyConnectivity
*connectivity_singleton
= NULL
;
70 G_DEFINE_TYPE (EmpathyConnectivity
, empathy_connectivity
, G_TYPE_OBJECT
);
73 connectivity_change_state (EmpathyConnectivity
*connectivity
,
76 EmpathyConnectivityPriv
*priv
;
78 priv
= GET_PRIV (connectivity
);
80 if (priv
->connected
== new_state
)
83 priv
->connected
= new_state
;
85 g_signal_emit (connectivity
, signals
[STATE_CHANGE
], 0,
91 connectivity_nm_state_change_cb (NMClient
*client
,
92 const GParamSpec
*pspec
,
93 EmpathyConnectivity
*connectivity
)
95 EmpathyConnectivityPriv
*priv
;
96 gboolean new_nm_connected
;
99 priv
= GET_PRIV (connectivity
);
104 state
= nm_client_get_state (priv
->nm_client
);
105 new_nm_connected
= !(state
== NM_STATE_CONNECTING
106 || state
== NM_STATE_DISCONNECTED
);
108 DEBUG ("New NetworkManager network state %d (connected: %s)", state
,
109 new_nm_connected
? "true" : "false");
111 connectivity_change_state (connectivity
, new_nm_connected
);
117 connectivity_connman_state_changed_cb (DBusGProxy
*proxy
,
118 const gchar
*new_state
,
119 EmpathyConnectivity
*connectivity
)
121 EmpathyConnectivityPriv
*priv
;
122 gboolean new_connected
;
124 priv
= GET_PRIV (connectivity
);
129 new_connected
= !tp_strdiff (new_state
, "online");
131 DEBUG ("New ConnMan network state %s", new_state
);
133 connectivity_change_state (connectivity
, new_connected
);
137 connectivity_connman_check_state_cb (DBusGProxy
*proxy
,
138 DBusGProxyCall
*call_id
,
141 EmpathyConnectivity
*connectivity
= (EmpathyConnectivity
*) user_data
;
142 GError
*error
= NULL
;
145 if (dbus_g_proxy_end_call (proxy
, call_id
, &error
,
146 G_TYPE_STRING
, &state
, G_TYPE_INVALID
))
148 connectivity_connman_state_changed_cb (proxy
, state
,
154 DEBUG ("Failed to call GetState: %s", error
->message
);
155 connectivity_connman_state_changed_cb (proxy
, "offline",
161 connectivity_connman_check_state (EmpathyConnectivity
*connectivity
)
163 EmpathyConnectivityPriv
*priv
;
165 priv
= GET_PRIV (connectivity
);
167 dbus_g_proxy_begin_call (priv
->proxy
, "GetState",
168 connectivity_connman_check_state_cb
, connectivity
, NULL
,
174 empathy_connectivity_init (EmpathyConnectivity
*connectivity
)
176 EmpathyConnectivityPriv
*priv
;
178 DBusGConnection
*connection
;
179 GError
*error
= NULL
;
182 priv
= G_TYPE_INSTANCE_GET_PRIVATE (connectivity
,
183 EMPATHY_TYPE_CONNECTIVITY
, EmpathyConnectivityPriv
);
185 connectivity
->priv
= priv
;
187 priv
->use_conn
= TRUE
;
190 priv
->nm_client
= nm_client_new ();
191 if (priv
->nm_client
!= NULL
)
193 priv
->state_change_signal_id
= g_signal_connect (priv
->nm_client
,
194 "notify::" NM_CLIENT_STATE
,
195 G_CALLBACK (connectivity_nm_state_change_cb
), connectivity
);
197 connectivity_nm_state_change_cb (priv
->nm_client
, NULL
, connectivity
);
201 DEBUG ("Failed to get NetworkManager proxy");
206 connection
= dbus_g_bus_get (DBUS_BUS_SYSTEM
, &error
);
207 if (connection
!= NULL
)
209 priv
->proxy
= dbus_g_proxy_new_for_name (connection
,
210 "org.moblin.connman", "/",
211 "org.moblin.connman.Manager");
213 dbus_g_object_register_marshaller (
214 _empathy_marshal_VOID__STRING
,
215 G_TYPE_NONE
, G_TYPE_STRING
, G_TYPE_INVALID
);
217 dbus_g_proxy_add_signal (priv
->proxy
, "StateChanged",
218 G_TYPE_STRING
, G_TYPE_INVALID
);
220 dbus_g_proxy_connect_signal (priv
->proxy
, "StateChanged",
221 G_CALLBACK (connectivity_connman_state_changed_cb
),
224 connectivity_connman_check_state (connectivity
);
228 DEBUG ("Failed to get system bus connection: %s", error
->message
);
229 g_error_free (error
);
233 #if !defined(HAVE_NM) && !defined(HAVE_CONNMAN)
234 priv
->connected
= TRUE
;
239 connectivity_finalize (GObject
*object
)
242 EmpathyConnectivity
*connectivity
= EMPATHY_CONNECTIVITY (object
);
243 EmpathyConnectivityPriv
*priv
= GET_PRIV (connectivity
);
245 if (priv
->nm_client
!= NULL
)
247 g_signal_handler_disconnect (priv
->nm_client
,
248 priv
->state_change_signal_id
);
249 priv
->state_change_signal_id
= 0;
250 g_object_unref (priv
->nm_client
);
251 priv
->nm_client
= NULL
;
256 EmpathyConnectivity
*connectivity
= EMPATHY_CONNECTIVITY (object
);
257 EmpathyConnectivityPriv
*priv
= GET_PRIV (connectivity
);
259 if (priv
->proxy
!= NULL
)
261 dbus_g_proxy_disconnect_signal (priv
->proxy
, "StateChanged",
262 G_CALLBACK (connectivity_connman_state_changed_cb
), connectivity
);
264 g_object_unref (priv
->proxy
);
269 G_OBJECT_CLASS (empathy_connectivity_parent_class
)->finalize (object
);
273 connectivity_dispose (GObject
*object
)
275 G_OBJECT_CLASS (empathy_connectivity_parent_class
)->dispose (object
);
279 connectivity_constructor (GType type
,
280 guint n_construct_params
,
281 GObjectConstructParam
*construct_params
)
285 if (!connectivity_singleton
)
287 retval
= G_OBJECT_CLASS (empathy_connectivity_parent_class
)->constructor
288 (type
, n_construct_params
, construct_params
);
290 connectivity_singleton
= EMPATHY_CONNECTIVITY (retval
);
291 g_object_add_weak_pointer (retval
, (gpointer
) &connectivity_singleton
);
295 retval
= g_object_ref (connectivity_singleton
);
302 connectivity_get_property (GObject
*object
,
307 EmpathyConnectivity
*connectivity
= EMPATHY_CONNECTIVITY (object
);
312 g_value_set_boolean (value
, empathy_connectivity_get_use_conn (
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
322 connectivity_set_property (GObject
*object
,
327 EmpathyConnectivity
*connectivity
= EMPATHY_CONNECTIVITY (object
);
332 empathy_connectivity_set_use_conn (connectivity
,
333 g_value_get_boolean (value
));
336 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
342 empathy_connectivity_class_init (EmpathyConnectivityClass
*klass
)
344 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
346 oclass
->finalize
= connectivity_finalize
;
347 oclass
->dispose
= connectivity_dispose
;
348 oclass
->constructor
= connectivity_constructor
;
349 oclass
->get_property
= connectivity_get_property
;
350 oclass
->set_property
= connectivity_set_property
;
352 signals
[STATE_CHANGE
] =
353 g_signal_new ("state-change",
354 G_TYPE_FROM_CLASS (klass
),
358 _empathy_marshal_VOID__BOOLEAN
,
360 1, G_TYPE_BOOLEAN
, NULL
);
362 g_object_class_install_property (oclass
,
364 g_param_spec_boolean ("use-conn",
365 "Use connectivity managers",
366 "Set presence according to connectivity managers",
368 G_PARAM_CONSTRUCT
| G_PARAM_READWRITE
));
370 g_type_class_add_private (oclass
, sizeof (EmpathyConnectivityPriv
));
375 EmpathyConnectivity
*
376 empathy_connectivity_dup_singleton (void)
378 return g_object_new (EMPATHY_TYPE_CONNECTIVITY
, NULL
);
382 empathy_connectivity_is_online (EmpathyConnectivity
*connectivity
)
384 EmpathyConnectivityPriv
*priv
= GET_PRIV (connectivity
);
386 return priv
->connected
;
390 empathy_connectivity_get_use_conn (EmpathyConnectivity
*connectivity
)
392 EmpathyConnectivityPriv
*priv
= GET_PRIV (connectivity
);
394 return priv
->use_conn
;
398 empathy_connectivity_set_use_conn (EmpathyConnectivity
*connectivity
,
401 EmpathyConnectivityPriv
*priv
= GET_PRIV (connectivity
);
403 if (use_conn
== priv
->use_conn
)
406 DEBUG ("use_conn gconf key changed; new value = %s",
407 use_conn
? "true" : "false");
409 priv
->use_conn
= use_conn
;
411 #if defined(HAVE_NM) || defined(HAVE_CONNMAN)
415 connectivity_nm_state_change_cb (priv
->nm_client
, NULL
, connectivity
);
416 #elif defined(HAVE_CONNMAN)
417 connectivity_connman_check_state (connectivity
);
423 connectivity_change_state (connectivity
, TRUE
);
426 g_object_notify (G_OBJECT (connectivity
), "use-conn");