]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-connectivity.c
local-xmpp-assistant-widget: increase row-spacing
[empathy.git] / libempathy / empathy-connectivity.c
index 8cc1d26bb11a03688ca8bf79bcdd2b4930f51163..f84505f9bd9426d5ba99ec32d0190216ef811eb0 100644 (file)
 #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"
@@ -40,6 +45,10 @@ typedef struct {
   gulong state_change_signal_id;
 #endif
 
+#ifdef HAVE_CONNMAN
+  DBusGProxy *proxy;
+#endif
+
   gboolean connected;
   gboolean use_conn;
 } EmpathyConnectivityPriv;
@@ -77,6 +86,11 @@ connectivity_change_state (EmpathyConnectivity *connectivity,
 }
 
 #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,
@@ -93,18 +107,85 @@ connectivity_nm_state_change_cb (NMClient *client,
 
   state = nm_client_get_state (priv->nm_client);
   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");
 
   connectivity_change_state (connectivity, new_nm_connected);
 }
 #endif
 
+#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
+
 static void
 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);
@@ -127,7 +208,37 @@ empathy_connectivity_init (EmpathyConnectivity *connectivity)
     {
       DEBUG ("Failed to get NetworkManager proxy");
     }
-#else
+#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
 }
@@ -149,6 +260,20 @@ connectivity_finalize (GObject *object)
     }
 #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);
 }
 
@@ -238,7 +363,7 @@ empathy_connectivity_class_init (EmpathyConnectivityClass *klass)
         G_SIGNAL_RUN_LAST,
         0,
         NULL, NULL,
-        _empathy_marshal_VOID__BOOLEAN,
+        g_cclosure_marshal_generic,
         G_TYPE_NONE,
         1, G_TYPE_BOOLEAN, NULL);
 
@@ -266,14 +391,7 @@ empathy_connectivity_is_online (EmpathyConnectivity *connectivity)
 {
   EmpathyConnectivityPriv *priv = GET_PRIV (connectivity);
 
-  if (priv->use_conn)
-    {
-      return priv->connected;
-    }
-  else
-    {
-      return TRUE;
-    }
+  return priv->connected;
 }
 
 gboolean
@@ -293,21 +411,22 @@ empathy_connectivity_set_use_conn (EmpathyConnectivity *connectivity,
   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
     {
       connectivity_change_state (connectivity, TRUE);
     }