gio: add network connectivity state to GNetworkMonitor
authorDan Winship <danw@gnome.org>
Wed, 16 Apr 2014 14:39:12 +0000 (10:39 -0400)
committerBastien Nocera <hadess@hadess.net>
Fri, 5 Dec 2014 16:37:41 +0000 (17:37 +0100)
Add a property to GNetworkMonitor indicating the level of network
connectivity: none/local, limited, stuck behind a portal, or full.

The default implementation just returns none or full depending on the
value of is-available.

https://bugzilla.gnome.org/show_bug.cgi?id=664562

gio/gioenums.h
gio/gnetworkmonitor.c
gio/gnetworkmonitor.h
gio/gnetworkmonitorbase.c
gio/tests/network-monitor.c

index 488e04bc1f072be6c5c87888458f1a2ed732807a..6176777a84d9fcafc16f95ac09370734f27f8674 100644 (file)
@@ -1819,6 +1819,30 @@ typedef enum {
   G_NOTIFICATION_PRIORITY_URGENT
 } GNotificationPriority;
 
+/**
+ * GNetworkConnectivity:
+ * @G_NETWORK_CONNECTIVITY_LOCAL: The host is not configured with a
+ *   route to the Internet; it may or may not be connected to a local
+ *   network.
+ * @G_NETWORK_CONNECTIVITY_LIMITED: The host is connected to a network, but
+ *   does not appear to be able to reach the full Internet, perhaps
+ *   due to upstream network problems.
+ * @G_NETWORK_CONNECTIVITY_PORTAL: The host is behind a captive portal and
+ *   cannot reach the full Internet.
+ * @G_NETWORK_CONNECTIVITY_FULL: The host is connected to a network, and
+ *   appears to be able to reach the full Internet.
+ *
+ * The host's network connectivity state, as reported by #GNetworkMonitor.
+ *
+ * Since: 2.42
+ */
+typedef enum {
+  G_NETWORK_CONNECTIVITY_LOCAL       = 1,
+  G_NETWORK_CONNECTIVITY_LIMITED     = 2,
+  G_NETWORK_CONNECTIVITY_PORTAL      = 3,
+  G_NETWORK_CONNECTIVITY_FULL        = 4
+} GNetworkConnectivity;
+
 G_END_DECLS
 
 #endif /* __GIO_ENUMS_H__ */
index 79c7bd94f50bb06104224a3b8cb8830e44b6cb49..ae902b90696062c035c2fe36882afbad448e2061 100644 (file)
@@ -98,6 +98,44 @@ g_network_monitor_get_network_available (GNetworkMonitor *monitor)
   return available;
 }
 
+/**
+ * g_network_monitor_get_connectivity:
+ * @monitor: the #GNetworkMonitor
+ *
+ * Gets a more detailed networking state than
+ * g_network_monitor_get_network_available().
+ *
+ * If #GNetworkMonitor:network-available is %FALSE, then the
+ * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
+ *
+ * If #GNetworkMonitor:network-available is %TRUE, then the
+ * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
+ * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
+ * the host has a default route, but appears to be unable to actually
+ * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
+ * host is trapped behind a "captive portal" that requires some sort
+ * of login or acknowledgement before allowing full Internet access).
+ *
+ * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
+ * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
+ * reachable but others are not. In this case, applications can
+ * attempt to connect to remote servers, but should gracefully fall
+ * back to their "offline" behavior if the connection attempt fails.
+ *
+ * Return value: the network connectivity state
+ *
+ * Since: 2.42
+ */
+GNetworkConnectivity
+g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
+{
+  GNetworkConnectivity connectivity;
+
+  g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
+
+  return connectivity;
+}
+
 /**
  * g_network_monitor_can_reach:
  * @monitor: a #GNetworkMonitor
@@ -280,4 +318,22 @@ g_network_monitor_default_init (GNetworkMonitorInterface *iface)
                                                              FALSE,
                                                              G_PARAM_READABLE |
                                                              G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GNetworkMonitor:connectivity:
+   *
+   * More detailed information about the host's network connectivity.
+   * See g_network_monitor_get_connectivity() and
+   * #GNetworkConnectivity for more details.
+   *
+   * Since: 2.42
+   */
+  g_object_interface_install_property (iface,
+                                       g_param_spec_enum ("connectivity",
+                                                          P_("Network connectivity"),
+                                                          P_("Level of network connectivity"),
+                                                          G_TYPE_NETWORK_CONNECTIVITY,
+                                                          G_NETWORK_CONNECTIVITY_FULL,
+                                                          G_PARAM_READABLE |
+                                                          G_PARAM_STATIC_STRINGS));
 }
index d3c8cbe812d44e24f9949c9d3f08c7bfd86f8e97..d9e0ad094501b521b160206c6f41198c03238aea 100644 (file)
@@ -37,7 +37,7 @@ G_BEGIN_DECLS
  */
 #define G_NETWORK_MONITOR_EXTENSION_POINT_NAME "gio-network-monitor"
 
-#define G_TYPE_NETWORK_MONITOR         (g_network_monitor_get_type ())
+#define G_TYPE_NETWORK_MONITOR             (g_network_monitor_get_type ())
 #define G_NETWORK_MONITOR(o)               (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR, GNetworkMonitor))
 #define G_IS_NETWORK_MONITOR(o)            (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR))
 #define G_NETWORK_MONITOR_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_NETWORK_MONITOR, GNetworkMonitorInterface))
@@ -65,28 +65,31 @@ struct _GNetworkMonitorInterface {
 };
 
 GLIB_AVAILABLE_IN_2_32
-GType            g_network_monitor_get_type              (void) G_GNUC_CONST;
+GType                 g_network_monitor_get_type              (void) G_GNUC_CONST;
 GLIB_AVAILABLE_IN_2_32
-GNetworkMonitor *g_network_monitor_get_default           (void);
+GNetworkMonitor      *g_network_monitor_get_default           (void);
 
 GLIB_AVAILABLE_IN_2_32
-gboolean         g_network_monitor_get_network_available (GNetworkMonitor     *monitor);
+gboolean              g_network_monitor_get_network_available (GNetworkMonitor     *monitor);
+
+GLIB_AVAILABLE_IN_2_42
+GNetworkConnectivity  g_network_monitor_get_connectivity      (GNetworkMonitor     *monitor);
 
 GLIB_AVAILABLE_IN_2_32
-gboolean         g_network_monitor_can_reach             (GNetworkMonitor     *monitor,
-                                                         GSocketConnectable  *connectable,
-                                                         GCancellable        *cancellable,
-                                                         GError             **error);
+gboolean              g_network_monitor_can_reach             (GNetworkMonitor     *monitor,
+                                                               GSocketConnectable  *connectable,
+                                                               GCancellable        *cancellable,
+                                                               GError             **error);
 GLIB_AVAILABLE_IN_2_32
-void             g_network_monitor_can_reach_async       (GNetworkMonitor     *monitor,
-                                                         GSocketConnectable  *connectable,
-                                                         GCancellable        *cancellable,
-                                                         GAsyncReadyCallback  callback,
-                                                         gpointer             user_data);
+void                  g_network_monitor_can_reach_async       (GNetworkMonitor     *monitor,
+                                                               GSocketConnectable  *connectable,
+                                                               GCancellable        *cancellable,
+                                                               GAsyncReadyCallback  callback,
+                                                               gpointer             user_data);
 GLIB_AVAILABLE_IN_2_32
-gboolean         g_network_monitor_can_reach_finish      (GNetworkMonitor     *monitor,
-                                                         GAsyncResult        *result,
-                                                         GError             **error);
+gboolean              g_network_monitor_can_reach_finish      (GNetworkMonitor     *monitor,
+                                                               GAsyncResult        *result,
+                                                               GError             **error);
 
 G_END_DECLS
 
index ead9e6436e1474ab470422c1a2049f8e540309bf..f0af80405da0d5a2c3976b2c0e41115ca63a61e7 100644 (file)
@@ -38,7 +38,8 @@ enum
 {
   PROP_0,
 
-  PROP_NETWORK_AVAILABLE
+  PROP_NETWORK_AVAILABLE,
+  PROP_CONNECTIVITY
 };
 
 struct _GNetworkMonitorBasePrivate
@@ -114,12 +115,20 @@ g_network_monitor_base_get_property (GObject    *object,
 
   switch (prop_id)
     {
-      case PROP_NETWORK_AVAILABLE:
-        g_value_set_boolean (value, monitor->priv->is_available);
-        break;
-
-      default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    case PROP_NETWORK_AVAILABLE:
+      g_value_set_boolean (value, monitor->priv->is_available);
+      break;
+
+    case PROP_CONNECTIVITY:
+      g_value_set_enum (value,
+                        monitor->priv->is_available ?
+                        G_NETWORK_CONNECTIVITY_FULL :
+                        G_NETWORK_CONNECTIVITY_LOCAL);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
     }
 
 }
@@ -151,6 +160,7 @@ g_network_monitor_base_class_init (GNetworkMonitorBaseClass *monitor_class)
   gobject_class->finalize     = g_network_monitor_base_finalize;
 
   g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available");
+  g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity");
 }
 
 static gboolean
index 08d6008dfdbb3b0b438d0fadf11c84754df764ec..04f75f1ada8254aa517624d977474af506539d6f 100644 (file)
@@ -491,6 +491,14 @@ watch_network_changed (GNetworkMonitor *monitor,
   g_print ("Network is %s\n", available ? "up" : "down");
 }
 
+static void
+watch_connectivity_changed (GNetworkMonitor *monitor,
+                           GParamSpec      *pspec,
+                           gpointer         user_data)
+{
+  g_print ("Connectivity is %d\n", g_network_monitor_get_connectivity (monitor));
+}
+
 static void
 do_watch_network (void)
 {
@@ -501,7 +509,10 @@ do_watch_network (void)
 
   g_signal_connect (monitor, "network-changed",
                     G_CALLBACK (watch_network_changed), NULL);
+  g_signal_connect (monitor, "notify::connectivity",
+                    G_CALLBACK (watch_connectivity_changed), NULL);
   watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL);
+  watch_connectivity_changed (monitor, NULL, NULL);
 
   loop = g_main_loop_new (NULL, FALSE);
   g_main_loop_run (loop);