[tracker/network-status: 1/2] libtracker-miner: Add TrackerNetworkProvider class



commit ec18024007bfc48f3cc38dd7c7216390fc55434e
Author: Adrien Bustany <abustany gnome org>
Date:   Fri Apr 30 11:42:11 2010 -0400

    libtracker-miner: Add TrackerNetworkProvider class
    
    The TrackerNetworkProvider class provides functions to get information
    about the network status, such as if there is an active connection or
    not, and what the connection type is (GPRS, 3G, WIFI etc.). It can be
    used by web miners using web services to avoid heavy transfers when
    being connected on a slow and/or expensive connection.

 configure.ac                                       |   32 ++
 src/libtracker-miner/Makefile.am                   |   18 +-
 src/libtracker-miner/tracker-miner.h               |    1 +
 src/libtracker-miner/tracker-miner.vapi            |   16 +
 .../tracker-network-provider-dummy.c               |  168 ++++++++++
 .../tracker-network-provider-network-manager.c     |  321 ++++++++++++++++++++
 src/libtracker-miner/tracker-network-provider.c    |  145 +++++++++
 src/libtracker-miner/tracker-network-provider.h    |  103 +++++++
 8 files changed, 803 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 562ac15..bb60b71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -161,6 +161,7 @@ TAGLIB_REQUIRED=1.6
 GNOME_KEYRING_REQUIRED=2.26
 LIBGRSS_REQUIRED=0.3
 REST_REQUIRED=0.6
+NETWORK_MANAGER_REQUIRED=0.8
 
 # Library Checks
 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED])
@@ -801,6 +802,36 @@ fi
 AM_CONDITIONAL(HAVE_GNOME_KEYRING, test "x$have_gnome_keyring" = "xyes")
 
 ##################################################################
+# Enable NetworkManager for network status detection (for web miners)
+##################################################################
+
+AC_ARG_ENABLE(network_manager,
+	      AS_HELP_STRING([--enable-network-manager],
+			     [enable NetworkManager support to detect network status [[default=auto]]]),,
+	      [enable_network_manager=auto])
+
+if test "x$enable_network_manager" != "xno"; then
+	PKG_CHECK_MODULES(NETWORK_MANAGER,
+	                  [ libnm-glib >= $NETWORK_MANAGER_REQUIRED ],
+	                  [have_network_manager=yes],
+	                  [have_network_manager=no])
+	AC_SUBST(NETWORK_MANAGER_LIBS)
+	AC_SUBST(NETWORK_MANAGER_CFLAGS)
+
+	if test "x$have_network_manager" = "xyes"; then
+		AC_DEFINE(HAVE_NETWORK_MANAGER, [], [Define if we have NetworkManager for network status detection])
+	fi
+fi
+
+if test "x$enable_network_manager" = "xyes"; then
+   if test "x$have_network_manager" != "xyes"; then
+      AC_MSG_ERROR([Couldn't find libnm-glib >= $NETWORK_MANAGER_REQUIRED.])
+   fi
+fi
+
+AM_CONDITIONAL(HAVE_NETWORK_MANAGER, test "x$have_network_manager" = "xyes")
+
+##################################################################
 # Flickr miner
 ##################################################################
 
@@ -1783,6 +1814,7 @@ Build Configuration:
 	Support for file monitoring:            $have_file_monitor
 	Support for accent stripping (unac):  	$have_unac
 	Support for Cyrillic languages (enca): 	$have_enca
+	Support for network status detection:	$have_network_manager
 
 Applications:
 
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index b7df329..3cb0635 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -32,6 +32,7 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = 	\
 	tracker-miner-web-dbus.h			\
 	tracker-monitor.c				\
 	tracker-monitor.h				\
+	tracker-network-provider.c			\
 	tracker-password-provider.c			\
 	tracker-storage.c				\
 	tracker-thumbnailer.c				\
@@ -45,13 +46,14 @@ libtracker_minerinclude_HEADERS = 			\
 	tracker-miner-fs.h				\
 	tracker-miner-manager.h				\
 	tracker-miner-web.h				\
+	tracker-network-provider.h			\
 	tracker-password-provider.h			\
 	tracker-storage.h				\
 	tracker-thumbnailer.h
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LDFLAGS = 	\
 	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-	-export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage|password_provider)_.*'
+	-export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage|password_provider|network_provider)_.*'
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD = 	\
 	$(top_builddir)/src/libtracker-common/libtracker-common.la \
@@ -80,6 +82,20 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES += 	\
 	tracker-password-provider-keyfile.c
 endif
 
+if HAVE_NETWORK_MANAGER
+libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES +=	\
+	tracker-network-provider-network-manager.c
+
+libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD +=	\
+	$(NETWORK_MANAGER_LIBS)
+
+INCLUDES +=						\
+	$(NETWORK_MANAGER_CFLAGS)
+else
+libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES +=	\
+	tracker-network-provider-dummy.c
+endif
+
 tracker-marshal.h: tracker-marshal.list
 	$(AM_V_GEN)$(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --header > $@
 
diff --git a/src/libtracker-miner/tracker-miner.h b/src/libtracker-miner/tracker-miner.h
index 5660602..d00be97 100644
--- a/src/libtracker-miner/tracker-miner.h
+++ b/src/libtracker-miner/tracker-miner.h
@@ -25,6 +25,7 @@
 #include <libtracker-miner/tracker-crawler.h>
 #include <libtracker-miner/tracker-storage.h>
 #include <libtracker-miner/tracker-thumbnailer.h>
+#include <libtracker-miner/tracker-network-provider.h>
 #include <libtracker-miner/tracker-password-provider.h>
 #include <libtracker-miner/tracker-miner-object.h>
 #include <libtracker-miner/tracker-miner-fs.h>
diff --git a/src/libtracker-miner/tracker-miner.vapi b/src/libtracker-miner/tracker-miner.vapi
index cdc6b55..462af53 100644
--- a/src/libtracker-miner/tracker-miner.vapi
+++ b/src/libtracker-miner/tracker-miner.vapi
@@ -98,6 +98,22 @@ namespace Tracker {
 		public string get_password (string service, out string username) throws GLib.Error;
 		public void store_password (string service, string description, string username, string password) throws GLib.Error;
 	}
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public interface NetworkProvider : GLib.Object {
+		public string get_name ();
+		public NetworkProviderStatus get_status ();
+		public signal void status_changed (NetworkProviderStatus status);
+		public static unowned Tracker.NetworkProvider @get ();
+	}
+	[CCode (cprefix = "TRACKER_NETWORK_PROVIDER_", cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public enum NetworkProviderStatus {
+		DISCONNECTED,
+		UNKNOWN,
+		GPRS,
+		EDGE,
+		@3G,
+		LAN
+	}
 	[CCode (cprefix = "TRACKER_MINER_WEB_ERROR_", cheader_filename = "libtracker-miner/tracker-miner.h")]
 	public errordomain MinerWebError {
 		WRONG_CREDENTIALS,
diff --git a/src/libtracker-miner/tracker-network-provider-dummy.c b/src/libtracker-miner/tracker-network-provider-dummy.c
new file mode 100644
index 0000000..7b26ba9
--- /dev/null
+++ b/src/libtracker-miner/tracker-network-provider-dummy.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include "tracker-network-provider.h"
+
+#define TRACKER_TYPE_NETWORK_PROVIDER_DUMMY         (tracker_network_provider_dummy_get_type())
+#define TRACKER_NETWORK_PROVIDER_DUMMY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_NETWORK_PROVIDER_DUMMY, TrackerNetworkProviderDummy))
+#define TRACKER_NETWORK_PROVIDER_DUMMY_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_NETWORK_PROVIDER_DUMMY, TrackerNetworkProviderDummyClass))
+#define TRACKER_IS_NETWORK_PROVIDER_DUMMY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_NETWORK_PROVIDER_DUMMY))
+#define TRACKER_IS_NETWORK_PROVIDER_DUMMY_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_NETWORK_PROVIDER_DUMMY))
+#define TRACKER_NETWORK_PROVIDER_DUMMY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_NETWORK_PROVIDER_DUMMY, TrackerNetworkProviderDummyClass))
+
+#define TRACKER_NETWORK_PROVIDER_DUMMY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_NETWORK_PROVIDER_DUMMY, TrackerNetworkProviderDummyPrivate))
+
+#define NETWORK_PROVIDER_DUMMY_NAME "Dummy"
+
+typedef struct TrackerNetworkProviderDummy TrackerNetworkProviderDummy;
+typedef struct TrackerNetworkProviderDummyClass TrackerNetworkProviderDummyClass;
+typedef struct TrackerNetworkProviderDummyPrivate TrackerNetworkProviderDummyPrivate;
+
+struct TrackerNetworkProviderDummy {
+	GObject parent;
+};
+
+struct TrackerNetworkProviderDummyClass {
+	GObjectClass parent_class;
+};
+
+struct TrackerNetworkProviderDummyPrivate {
+	gchar *name;
+};
+
+GType        tracker_network_provider_dummy_get_type (void) G_GNUC_CONST;
+static void  tracker_network_provider_iface_init     (TrackerNetworkProviderIface *iface);
+static void  network_provider_set_property           (GObject                     *object,
+                                                      guint                        prop_id,
+                                                      const GValue                *value,
+                                                      GParamSpec                  *pspec);
+static void  network_provider_get_property           (GObject                     *object,
+                                                      guint                        prop_id,
+                                                      GValue                      *value,
+                                                      GParamSpec                  *pspec);
+static TrackerNetworkProviderStatus
+             network_provider_dummy_get_status       (TrackerNetworkProvider      *provider);
+
+enum {
+	PROP_0,
+	PROP_NAME
+};
+
+G_DEFINE_TYPE_WITH_CODE (TrackerNetworkProviderDummy,
+                         tracker_network_provider_dummy,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (TRACKER_TYPE_NETWORK_PROVIDER,
+                                                tracker_network_provider_iface_init))
+
+static void
+tracker_network_provider_dummy_class_init (TrackerNetworkProviderDummyClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->set_property = network_provider_set_property;
+	object_class->get_property = network_provider_get_property;
+
+	g_object_class_override_property (object_class, PROP_NAME, "name");
+
+	g_type_class_add_private (object_class, sizeof (TrackerNetworkProviderDummyPrivate));
+}
+
+static void
+tracker_network_provider_dummy_init (TrackerNetworkProviderDummy *provider)
+{
+}
+
+static void
+tracker_network_provider_iface_init (TrackerNetworkProviderIface *iface)
+{
+	iface->get_status = network_provider_dummy_get_status;
+}
+
+static void
+network_provider_set_property (GObject       *object,
+                               guint          prop_id,
+                               const GValue  *value,
+                               GParamSpec    *pspec)
+{
+	TrackerNetworkProviderDummyPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_DUMMY_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_free (priv->name);
+		priv->name = g_value_dup_string (value);
+		g_object_notify (object, "name");
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+network_provider_get_property (GObject     *object,
+                               guint        prop_id,
+                               GValue      *value,
+                               GParamSpec  *pspec)
+{
+	TrackerNetworkProviderDummyPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_DUMMY_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_value_set_string (value, priv->name);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static TrackerNetworkProviderStatus
+network_provider_dummy_get_status (TrackerNetworkProvider *provider)
+{
+	return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+}
+
+TrackerNetworkProvider *
+tracker_network_provider_get (void)
+{
+	static TrackerNetworkProvider *instance = NULL;
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+	g_static_mutex_lock (&mutex);
+
+	if (!instance) {
+		instance = g_object_new (TRACKER_TYPE_NETWORK_PROVIDER_DUMMY,
+		                         "name", NETWORK_PROVIDER_DUMMY_NAME,
+		                         NULL);
+	}
+
+	g_static_mutex_unlock (&mutex);
+
+	return instance;
+}
diff --git a/src/libtracker-miner/tracker-network-provider-network-manager.c b/src/libtracker-miner/tracker-network-provider-network-manager.c
new file mode 100644
index 0000000..baf3fb1
--- /dev/null
+++ b/src/libtracker-miner/tracker-network-provider-network-manager.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include <libnm-glib/nm-client.h>
+#include <libnm-glib/nm-device-ethernet.h>
+#include <libnm-glib/nm-device-wifi.h>
+#include <libnm-glib/nm-gsm-device.h>
+#include <libnm-glib/nm-cdma-device.h>
+
+#include "tracker-network-provider.h"
+
+#define TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER         (tracker_network_provider_network_manager_get_type())
+#define TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER, TrackerNetworkProviderNetworkManager))
+#define TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER, TrackerNetworkProviderNetworkManagerClass))
+#define TRACKER_IS_NETWORK_PROVIDER_NETWORK_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER))
+#define TRACKER_IS_NETWORK_PROVIDER_NETWORK_MANAGER_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER))
+#define TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER, TrackerNetworkProviderNetworkManagerClass))
+
+#define TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER, TrackerNetworkProviderNetworkManagerPrivate))
+
+#define NETWORK_PROVIDER_NETWORK_MANAGER_NAME "NetworkManager"
+
+typedef struct TrackerNetworkProviderNetworkManager TrackerNetworkProviderNetworkManager;
+typedef struct TrackerNetworkProviderNetworkManagerClass TrackerNetworkProviderNetworkManagerClass;
+typedef struct TrackerNetworkProviderNetworkManagerPrivate TrackerNetworkProviderNetworkManagerPrivate;
+
+struct TrackerNetworkProviderNetworkManager {
+	GObject parent;
+};
+
+struct TrackerNetworkProviderNetworkManagerClass {
+	GObjectClass parent_class;
+};
+
+struct TrackerNetworkProviderNetworkManagerPrivate {
+	gchar *name;
+
+	NMClient *client;
+	TrackerNetworkProviderStatus last_emitted_status;
+};
+
+GType        tracker_network_provider_network_manager_get_type (void) G_GNUC_CONST;
+static void  tracker_network_provider_iface_init               (TrackerNetworkProviderIface *iface);
+static void  network_provider_finalize                         (GObject                *object);
+static void  network_provider_set_property                     (GObject                *object,
+                                                                guint                   prop_id,
+                                                                const GValue           *value,
+                                                                GParamSpec             *pspec);
+static void  network_provider_get_property                     (GObject                *object,
+                                                                guint                   prop_id,
+                                                                GValue                 *value,
+                                                                GParamSpec             *pspec);
+static void  network_provider_connections_changed              (GObject                *object,
+                                                                GParamSpec             *pspec,
+                                                                gpointer                user_data);
+static TrackerNetworkProviderStatus
+             network_provider_get_status                       (TrackerNetworkProvider *provider);
+
+enum {
+	PROP_0,
+	PROP_NAME
+};
+
+G_DEFINE_TYPE_WITH_CODE (TrackerNetworkProviderNetworkManager,
+                         tracker_network_provider_network_manager,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (TRACKER_TYPE_NETWORK_PROVIDER,
+                                                tracker_network_provider_iface_init))
+
+static void
+tracker_network_provider_network_manager_class_init (TrackerNetworkProviderNetworkManagerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->set_property = network_provider_set_property;
+	object_class->get_property = network_provider_get_property;
+	object_class->finalize     = network_provider_finalize;
+
+	g_object_class_override_property (object_class, PROP_NAME, "name");
+
+	g_type_class_add_private (object_class, sizeof (TrackerNetworkProviderNetworkManagerPrivate));
+}
+
+static void
+tracker_network_provider_network_manager_init (TrackerNetworkProviderNetworkManager *provider)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (provider);
+
+	priv->client = nm_client_new ();
+	priv->last_emitted_status = TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	g_signal_connect (priv->client, "notify::state",
+	                  G_CALLBACK (network_provider_connections_changed),
+	                  provider);
+}
+
+static void
+tracker_network_provider_iface_init (TrackerNetworkProviderIface *iface)
+{
+	iface->get_status = network_provider_get_status;
+}
+
+/*
+ * Returns the first NMActiveConnection with the "default" property set, or
+ * NULL if none is found.
+ */
+static NMActiveConnection*
+find_default_active_connection (NMClient *client)
+{
+	const GPtrArray *active_connections;
+	gint i;
+	NMActiveConnection *active_connection = NULL;
+
+	active_connections = nm_client_get_active_connections (client);
+
+	for (i = 0; i < active_connections->len; i++) {
+		active_connection = g_ptr_array_index (active_connections, i);
+
+		if (nm_active_connection_get_default (active_connection)) {
+			break;
+		}
+	}
+
+	return active_connection;
+}
+
+static void
+network_provider_finalize (GObject *object)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (object);
+
+	g_object_unref (priv->client);
+	g_free (priv->name);
+}
+
+static void
+network_provider_set_property (GObject       *object,
+                               guint          prop_id,
+                               const GValue  *value,
+                               GParamSpec    *pspec)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_free (priv->name);
+		priv->name = g_value_dup_string (value);
+		g_object_notify (object, "name");
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+network_provider_get_property (GObject     *object,
+                               guint        prop_id,
+                               GValue      *value,
+                               GParamSpec  *pspec)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_value_set_string (value, priv->name);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+network_provider_connections_changed (GObject    *object,
+                                      GParamSpec *pspec,
+                                      gpointer    user_data)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+	TrackerNetworkProvider *provider;
+	TrackerNetworkProviderStatus status;
+
+	g_return_if_fail (TRACKER_IS_NETWORK_PROVIDER_NETWORK_MANAGER (user_data));
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (object);
+
+	provider = user_data;
+	status = tracker_network_provider_get_status (provider);
+
+	if (status == priv->last_emitted_status) {
+		return;
+	}
+
+	priv->last_emitted_status = status;
+
+	g_signal_emit_by_name (provider, "status-changed", status);
+}
+
+static TrackerNetworkProviderStatus
+network_provider_get_status (TrackerNetworkProvider *provider)
+{
+	TrackerNetworkProviderNetworkManagerPrivate *priv;
+	NMActiveConnection *default_active_connection;
+	const GPtrArray *devices;
+	NMDevice *device;
+
+	priv = TRACKER_NETWORK_PROVIDER_NETWORK_MANAGER_GET_PRIVATE (provider);
+
+	if (!nm_client_get_manager_running (priv->client)) {
+		return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+	}
+
+	switch (nm_client_get_state (priv->client)) {
+	case NM_STATE_UNKNOWN:
+		return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+	case NM_STATE_CONNECTED:
+		break;
+	default:
+		return TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	}
+
+	default_active_connection = find_default_active_connection (priv->client);
+
+	if (!default_active_connection) {
+		return TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	}
+
+	switch (nm_active_connection_get_state (default_active_connection)) {
+	case NM_ACTIVE_CONNECTION_STATE_UNKNOWN:
+		return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+	case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
+		break;
+	default:
+		return TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	}
+
+	devices = nm_active_connection_get_devices (default_active_connection);
+
+	if (!devices->len) {
+		return TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	}
+
+	/* Pick the first device, I don't know when there are more than one */
+	device = g_ptr_array_index (devices, 0);
+
+	switch (nm_device_get_state (device)) {
+	case NM_DEVICE_STATE_UNKNOWN:
+		return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+		break;
+	case NM_DEVICE_STATE_ACTIVATED:
+		break;
+	default:
+		return TRACKER_NETWORK_PROVIDER_DISCONNECTED;
+	}
+
+	if (NM_IS_DEVICE_ETHERNET (device) || NM_IS_DEVICE_WIFI (device)) {
+		return TRACKER_NETWORK_PROVIDER_LAN;
+	}
+
+	if (NM_IS_SERIAL_DEVICE (device)) {
+		if (NM_IS_GSM_DEVICE (device)) {
+			return TRACKER_NETWORK_PROVIDER_GPRS;
+		}
+
+		if (NM_IS_CDMA_DEVICE (device)) {
+			return TRACKER_NETWORK_PROVIDER_3G;
+		}
+	}
+
+	/* We know the device is activated, but we don't know the type of device */
+	return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+}
+
+TrackerNetworkProvider *
+tracker_network_provider_get (void)
+{
+	static TrackerNetworkProvider *instance = NULL;
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+	g_static_mutex_lock (&mutex);
+
+	if (!instance) {
+		instance = g_object_new (TRACKER_TYPE_NETWORK_PROVIDER_NETWORK_MANAGER,
+		                         "name", NETWORK_PROVIDER_NETWORK_MANAGER_NAME,
+		                         NULL);
+	}
+
+	g_static_mutex_unlock (&mutex);
+
+	return instance;
+}
+
diff --git a/src/libtracker-miner/tracker-network-provider.c b/src/libtracker-miner/tracker-network-provider.c
new file mode 100644
index 0000000..143414e
--- /dev/null
+++ b/src/libtracker-miner/tracker-network-provider.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "tracker-network-provider.h"
+
+/**
+ * SECTION:tracker-network-provider
+ * @short_description: Network status interface for cross platform backends
+ * @include: libtracker-miner/tracker-miner.h
+ *
+ * The #TrackerNetworkProvider allows different backends to be written for
+ * retrieving network connectivity status information. This can be used to
+ * avoid heavy transfers when on a slow connection, or on a connection where
+ * costs may apply. Currently, there are two implementations. The
+ * NetworkManager one uses NetworkManager, and the Dummy one will always expose
+ * the network as connected, no matter what the connectivity status actually
+ * is.
+ *
+ * Since: 0.9
+ **/
+
+static void
+tracker_network_provider_init (gpointer object_class)
+{
+	static gboolean is_initialized = FALSE;
+
+	if (!is_initialized) {
+		g_object_interface_install_property (object_class,
+		                                     g_param_spec_string ("name",
+		                                                          "Network provider name",
+		                                                          "Network provider name",
+		                                                          NULL,
+		                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		/**
+		 * TrackerNetworkProvider::status-changed:
+		 * @provider: the TrackerNetworkProvider
+		 * @status: a TrackerNetworkProviderStatus describing the new network
+		 * status
+		 *
+		 * the ::status-changed signal is emitted whenever the backend informs
+		 * that the network status changed.
+		 **/
+		g_signal_new ("status-changed",
+		              TRACKER_TYPE_NETWORK_PROVIDER,
+		              G_SIGNAL_RUN_LAST,
+		              0,
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__UINT,
+		              G_TYPE_NONE, 1,
+		              G_TYPE_UINT);
+		is_initialized = TRUE;
+	}
+}
+
+/**
+ * tracker_network_provider_get_type:
+ *
+ * Returns: a #GType representing a %TrackerNetworkProvider.
+ **/
+GType
+tracker_network_provider_get_type (void)
+{
+	static GType iface_type = 0;
+
+	if (iface_type == 0) {
+		static const GTypeInfo info = {
+			sizeof (TrackerNetworkProviderIface),
+			tracker_network_provider_init,
+			NULL
+		};
+
+		iface_type = g_type_register_static (G_TYPE_INTERFACE,
+		                                     "TrackerNetworkProvider",
+		                                     &info,
+		                                     0);
+	}
+
+	return iface_type;
+}
+
+/**
+ * tracker_network_provider_get_name:
+ * @provider: a TrackerNetworkProvider
+ *
+ * At the moment there are only two providers, "Dummy" and
+ * "NetworkManager". Either of these is what will be returned unless new
+ * providers are written.
+ *
+ * Returns: a newly allocated string representing the #Object:name
+ * which must be freed with g_free().
+ **/
+gchar *
+tracker_network_provider_get_name (TrackerNetworkProvider *provider)
+{
+	gchar *name;
+
+	g_return_val_if_fail (TRACKER_IS_NETWORK_PROVIDER (provider), NULL);
+
+	g_object_get (provider, "name", &name, NULL);
+
+	return name;
+}
+
+/**
+ * tracker_network_provider_get_status:
+ * @provider: a TrackerNetworkProvider
+ *
+ * This function calls the network provider's "get_status" implementation.
+ *
+ * Returns: a TrackerNetworkProviderStatus decribing the current network
+ * status.
+ **/
+TrackerNetworkProviderStatus
+tracker_network_provider_get_status (TrackerNetworkProvider *provider)
+{
+	TrackerNetworkProviderIface *iface;
+
+	g_return_val_if_fail (TRACKER_IS_NETWORK_PROVIDER (provider), TRACKER_NETWORK_PROVIDER_UNKNOWN);
+
+	iface = TRACKER_NETWORK_PROVIDER_GET_INTERFACE (provider);
+
+	if (!iface || !iface->get_status) {
+		return TRACKER_NETWORK_PROVIDER_UNKNOWN;
+	}
+
+	return iface->get_status (provider);
+}
diff --git a/src/libtracker-miner/tracker-network-provider.h b/src/libtracker-miner/tracker-network-provider.h
new file mode 100644
index 0000000..5ac69c7
--- /dev/null
+++ b/src/libtracker-miner/tracker-network-provider.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __LIBTRACKER_MINER_NETWORK_PROVIDER_H__
+#define __LIBTRACKER_MINER_NETWORK_PROVIDER_H__
+
+#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "Only <libtracker-miner/tracker-miner.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_NETWORK_PROVIDER             (tracker_network_provider_get_type())
+#define TRACKER_NETWORK_PROVIDER(o)               (G_TYPE_CHECK_INSTANCE_CAST ((o),    TRACKER_TYPE_NETWORK_PROVIDER, TrackerNetworkProvider))
+#define TRACKER_IS_NETWORK_PROVIDER(o)            (G_TYPE_CHECK_INSTANCE_TYPE ((o),    TRACKER_TYPE_NETWORK_PROVIDER))
+#define TRACKER_NETWORK_PROVIDER_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), TRACKER_TYPE_NETWORK_PROVIDER, TrackerNetworkProviderIface))
+
+typedef struct TrackerNetworkProvider TrackerNetworkProvider;
+
+/**
+ * TrackerNetworkProviderStatus:
+ * Enumerates the different types of connections that the device might use when
+ * connected to internet. Note that not all providers might provide this
+ * information.
+ *
+ * @TRACKER_NETWORK_PROVIDER_DISCONNECTED: Network is disconnected
+ * @TRACKER_NETWORK_PROVIDER_UNKNOWN: Network status is unknown
+ * @TRACKER_NETWORK_PROVIDER_GPRS: Network is connected over a GPRS connection
+ * @TRACKER_NETWORK_PROVIDER_EDGE: Network is connected over an EDGE connection
+ * @TRACKER_NETWORK_PROVIDER_3G: Network is connected over a 3G or faster
+ * (HSDPA, UMTS, ...) connection
+ * @TRACKER_NETWORK_PROVIDER_LAN: Network is connected over a local network
+ * connection. This can be ethernet, wifi, etc.
+ *
+ * Since: 0.9
+ **/
+typedef enum {
+	TRACKER_NETWORK_PROVIDER_DISCONNECTED,
+	TRACKER_NETWORK_PROVIDER_UNKNOWN,
+	TRACKER_NETWORK_PROVIDER_GPRS,
+	TRACKER_NETWORK_PROVIDER_EDGE,
+	TRACKER_NETWORK_PROVIDER_3G,
+	TRACKER_NETWORK_PROVIDER_LAN
+} TrackerNetworkProviderStatus;
+
+/**
+ * TrackerNetworkProviderIface
+ * @parent_iface: parent object interface
+ * @get_status: get the network status
+ *
+ * Since: 0.9
+ **/
+typedef struct {
+	GTypeInterface parent_iface;
+
+	TrackerNetworkProviderStatus (* get_status) (TrackerNetworkProvider *provider);
+} TrackerNetworkProviderIface;
+
+GType tracker_network_provider_get_type     (void) G_GNUC_CONST;
+
+gchar * tracker_network_provider_get_name   (TrackerNetworkProvider *provider);
+TrackerNetworkProviderStatus
+        tracker_network_provider_get_status (TrackerNetworkProvider *provider);
+
+/**
+ * tracker_network_provider_get:
+ *
+ * This function <emphasis>MUST</emphasis> be defined by the implementation of
+ * TrackerNetworkProvider.
+ *
+ * For example, tracker-network-provider-network-manager.c should include this
+ * function for a NetworkManager implementation.
+ *
+ * Only one implementation can exist at once.
+ *
+ * Returns: a %TrackerNetworkProvider.
+ *
+ * Since: 0.9
+ **/
+TrackerNetworkProvider *
+tracker_network_provider_get                (void);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_MINER_NETWORK_PROVIDER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]