#include <nm-client.h>
#endif
+#ifdef HAVE_CONNMAN
+#include <dbus/dbus-glib.h>
+#endif
+
+#include <telepathy-glib/util.h>
+
#include "empathy-utils.h"
-#include "empathy-marshal.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CONNECTIVITY
#include "empathy-debug.h"
typedef struct {
#ifdef HAVE_NM
NMClient *nm_client;
+ gulong state_change_signal_id;
+#endif
+
+#ifdef HAVE_CONNMAN
+ DBusGProxy *proxy;
#endif
gboolean connected;
gboolean use_conn;
- gboolean dispose_run;
} EmpathyConnectivityPriv;
enum {
G_DEFINE_TYPE (EmpathyConnectivity, empathy_connectivity, G_TYPE_OBJECT);
+static void
+connectivity_change_state (EmpathyConnectivity *connectivity,
+ gboolean new_state)
+{
+ EmpathyConnectivityPriv *priv;
+
+ priv = GET_PRIV (connectivity);
+
+ if (priv->connected == new_state)
+ return;
+
+ priv->connected = new_state;
+
+ g_signal_emit (connectivity, signals[STATE_CHANGE], 0,
+ priv->connected);
+}
+
#ifdef HAVE_NM
+
+#if !defined(NM_CHECK_VERSION)
+#define NM_CHECK_VERSION(x,y,z) 0
+#endif
+
static void
connectivity_nm_state_change_cb (NMClient *client,
const GParamSpec *pspec,
EmpathyConnectivity *connectivity)
{
EmpathyConnectivityPriv *priv;
- gboolean old_nm_connected;
gboolean new_nm_connected;
NMState state;
return;
state = nm_client_get_state (priv->nm_client);
- old_nm_connected = priv->connected;
- new_nm_connected = state == NM_STATE_CONNECTED;
new_nm_connected = !(state == NM_STATE_CONNECTING
+#if NM_CHECK_VERSION(0,8,992)
+ || state == NM_STATE_DISCONNECTING
+#endif
+ || state == NM_STATE_ASLEEP
|| state == NM_STATE_DISCONNECTED);
- DEBUG ("New NetworkManager network state %d", state);
+ DEBUG ("New NetworkManager network state %d (connected: %s)", state,
+ new_nm_connected ? "true" : "false");
- priv->connected = new_nm_connected;
+ connectivity_change_state (connectivity, new_nm_connected);
+}
+#endif
- g_signal_emit (connectivity, signals[STATE_CHANGE], 0,
- old_nm_connected, new_nm_connected);
+#ifdef HAVE_CONNMAN
+static void
+connectivity_connman_state_changed_cb (DBusGProxy *proxy,
+ const gchar *new_state,
+ EmpathyConnectivity *connectivity)
+{
+ EmpathyConnectivityPriv *priv;
+ gboolean new_connected;
+
+ priv = GET_PRIV (connectivity);
+
+ if (!priv->use_conn)
+ return;
+
+ new_connected = !tp_strdiff (new_state, "online");
+
+ DEBUG ("New ConnMan network state %s", new_state);
+
+ connectivity_change_state (connectivity, new_connected);
+}
+
+static void
+connectivity_connman_check_state_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call_id,
+ gpointer user_data)
+{
+ EmpathyConnectivity *connectivity = (EmpathyConnectivity *) user_data;
+ GError *error = NULL;
+ gchar *state;
+
+ if (dbus_g_proxy_end_call (proxy, call_id, &error,
+ G_TYPE_STRING, &state, G_TYPE_INVALID))
+ {
+ connectivity_connman_state_changed_cb (proxy, state,
+ connectivity);
+ g_free (state);
+ }
+ else
+ {
+ DEBUG ("Failed to call GetState: %s", error->message);
+ connectivity_connman_state_changed_cb (proxy, "offline",
+ connectivity);
+ }
+}
+
+static void
+connectivity_connman_check_state (EmpathyConnectivity *connectivity)
+{
+ EmpathyConnectivityPriv *priv;
+
+ priv = GET_PRIV (connectivity);
+
+ dbus_g_proxy_begin_call (priv->proxy, "GetState",
+ connectivity_connman_check_state_cb, connectivity, NULL,
+ G_TYPE_INVALID);
}
#endif
empathy_connectivity_init (EmpathyConnectivity *connectivity)
{
EmpathyConnectivityPriv *priv;
+#ifdef HAVE_CONNMAN
+ DBusGConnection *connection;
+ GError *error = NULL;
+#endif
priv = G_TYPE_INSTANCE_GET_PRIVATE (connectivity,
EMPATHY_TYPE_CONNECTIVITY, EmpathyConnectivityPriv);
connectivity->priv = priv;
- priv->dispose_run = FALSE;
+
+ priv->use_conn = TRUE;
#ifdef HAVE_NM
priv->nm_client = nm_client_new ();
if (priv->nm_client != NULL)
{
- g_signal_connect (priv->nm_client, "notify::" NM_CLIENT_STATE,
+ priv->state_change_signal_id = g_signal_connect (priv->nm_client,
+ "notify::" NM_CLIENT_STATE,
G_CALLBACK (connectivity_nm_state_change_cb), connectivity);
+
+ connectivity_nm_state_change_cb (priv->nm_client, NULL, connectivity);
}
else
{
DEBUG ("Failed to get NetworkManager proxy");
}
#endif
+
+#ifdef HAVE_CONNMAN
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (connection != NULL)
+ {
+ priv->proxy = dbus_g_proxy_new_for_name (connection,
+ "net.connman", "/",
+ "net.connman.Manager");
+
+ dbus_g_object_register_marshaller (
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
+
+ dbus_g_proxy_add_signal (priv->proxy, "StateChanged",
+ G_TYPE_STRING, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (priv->proxy, "StateChanged",
+ G_CALLBACK (connectivity_connman_state_changed_cb),
+ connectivity, NULL);
+
+ connectivity_connman_check_state (connectivity);
+ }
+ else
+ {
+ DEBUG ("Failed to get system bus connection: %s", error->message);
+ g_error_free (error);
+ }
+#endif
+
+#if !defined(HAVE_NM) && !defined(HAVE_CONNMAN)
+ priv->connected = TRUE;
+#endif
}
static void
connectivity_finalize (GObject *object)
{
#ifdef HAVE_NM
- EmpathyConnectivity *manager = EMPATHY_CONNECTIVITY (object);
- EmpathyConnectivityPriv *priv = GET_PRIV (manager);
+ EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
+ EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
if (priv->nm_client != NULL)
{
- g_signal_handlers_disconnect_by_func (priv->nm_client,
- connectivity_nm_state_change_cb, manager);
+ g_signal_handler_disconnect (priv->nm_client,
+ priv->state_change_signal_id);
+ priv->state_change_signal_id = 0;
g_object_unref (priv->nm_client);
priv->nm_client = NULL;
}
#endif
+#ifdef HAVE_CONNMAN
+ EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object);
+ EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
+
+ if (priv->proxy != NULL)
+ {
+ dbus_g_proxy_disconnect_signal (priv->proxy, "StateChanged",
+ G_CALLBACK (connectivity_connman_state_changed_cb), connectivity);
+
+ g_object_unref (priv->proxy);
+ priv->proxy = NULL;
+ }
+#endif
+
G_OBJECT_CLASS (empathy_connectivity_parent_class)->finalize (object);
}
static void
connectivity_dispose (GObject *object)
{
- EmpathyConnectivity *manager = EMPATHY_CONNECTIVITY (object);
- EmpathyConnectivityPriv *priv = GET_PRIV (manager);
-
- if (priv->dispose_run)
- return;
-
- priv->dispose_run = TRUE;
-
G_OBJECT_CLASS (empathy_connectivity_parent_class)->dispose (object);
}
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _empathy_marshal_VOID__BOOLEAN_BOOLEAN,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
- 2, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, NULL);
+ 1, G_TYPE_BOOLEAN, NULL);
g_object_class_install_property (oclass,
PROP_USE_CONN,
{
EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
- if (priv->use_conn)
- {
-#ifdef HAVE_NM
- return priv->connected;
-#else
- return TRUE;
-#endif
- }
- else
- {
- return TRUE;
- }
+ return priv->connected;
}
gboolean
if (use_conn == priv->use_conn)
return;
- DEBUG ("use_conn gconf key changed; new value = %s",
+ DEBUG ("use_conn GSetting key changed; new value = %s",
use_conn ? "true" : "false");
priv->use_conn = use_conn;
-#ifdef HAVE_NM
+#if defined(HAVE_NM) || defined(HAVE_CONNMAN)
if (use_conn)
{
+#if defined(HAVE_NM)
connectivity_nm_state_change_cb (priv->nm_client, NULL, connectivity);
-#else
- if (FALSE)
- {
+#elif defined(HAVE_CONNMAN)
+ connectivity_connman_check_state (connectivity);
#endif
}
else
+#endif
{
- g_signal_emit (connectivity, signals[STATE_CHANGE], 0,
- FALSE, TRUE);
+ connectivity_change_state (connectivity, TRUE);
}
g_object_notify (G_OBJECT (connectivity), "use-conn");