gio: Add network metered information to GNetworkMonitor
authorRichard Hughes <richard@hughsie.com>
Tue, 2 Jun 2015 14:41:48 +0000 (15:41 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 27 Jul 2015 10:44:52 +0000 (06:44 -0400)
Add a property to GNetworkMonitor indicating if the network
is metered, e.g. subject to limitations set by service providers.

The default value is FALSE

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

docs/reference/gio/gio-sections.txt
gio/gnetworkmonitor.c
gio/gnetworkmonitor.h
gio/gnetworkmonitornm.c

index d91f598..993fe06 100644 (file)
@@ -3970,6 +3970,7 @@ GNetworkMonitorInterface
 G_NETWORK_MONITOR_EXTENSION_POINT_NAME
 g_network_monitor_get_default
 g_network_monitor_get_network_available
+g_network_monitor_get_network_metered
 g_network_monitor_can_reach
 g_network_monitor_can_reach_async
 g_network_monitor_can_reach_finish
index b08de47..60c5987 100644 (file)
@@ -115,6 +115,28 @@ g_network_monitor_get_network_available (GNetworkMonitor *monitor)
 }
 
 /**
+ * g_network_monitor_get_network_metered:
+ * @monitor: the #GNetworkMonitor
+ *
+ * Checks if the network is metered. "Metered" here means that the
+ * traffic flowing through the connection is subject to limitations,
+ * for example set by service providers.
+ * See #GNetworkMonitor:network-metered for more details.
+ *
+ * Returns: whether the connection is metered
+ *
+ * Since: 2.46
+ */
+gboolean
+g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
+{
+  gboolean metered = FALSE;
+
+  g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
+  return metered;
+}
+
+/**
  * g_network_monitor_get_connectivity:
  * @monitor: the #GNetworkMonitor
  *
@@ -336,6 +358,31 @@ g_network_monitor_default_init (GNetworkMonitorInterface *iface)
                                                              G_PARAM_STATIC_STRINGS));
 
   /**
+   * GNetworkMonitor:network-metered:
+   *
+   * Whether the network is considered metered. That is, whether the
+   * system has traffic flowing through the default connection that is
+   * subject to limitations for example set by service providers.
+   *
+   * If more information is required about specific devices then the
+   * system network management API should be used instead.
+   *
+   * If this information is not available then no networks willl be
+   * marked as metered.
+   *
+   * See also #GNetworkMonitor::network-available.
+   *
+   * Since: 2.46
+   */
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boolean ("network-metered",
+                                                             P_("Network metered"),
+                                                             P_("Whether the network is metered"),
+                                                             FALSE,
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
+
+  /**
    * GNetworkMonitor:connectivity:
    *
    * More detailed information about the host's network connectivity.
index 0a6a42c..10b180a 100644 (file)
@@ -72,6 +72,9 @@ GNetworkMonitor      *g_network_monitor_get_default           (void);
 GLIB_AVAILABLE_IN_2_32
 gboolean              g_network_monitor_get_network_available (GNetworkMonitor     *monitor);
 
+GLIB_AVAILABLE_IN_2_46
+gboolean              g_network_monitor_get_network_metered   (GNetworkMonitor     *monitor);
+
 GLIB_AVAILABLE_IN_2_44
 GNetworkConnectivity  g_network_monitor_get_connectivity      (GNetworkMonitor     *monitor);
 
index d052716..c2f861a 100644 (file)
@@ -40,6 +40,7 @@ enum
   PROP_0,
 
   PROP_NETWORK_AVAILABLE,
+  PROP_NETWORK_METERED,
   PROP_CONNECTIVITY
 };
 
@@ -57,6 +58,7 @@ struct _GNetworkMonitorNMPrivate
 
   GNetworkConnectivity connectivity;
   gboolean network_available;
+  gboolean network_metered;
 };
 
 #define g_network_monitor_nm_get_type _g_network_monitor_nm_get_type
@@ -92,6 +94,10 @@ g_network_monitor_nm_get_property (GObject    *object,
       g_value_set_boolean (value, nm->priv->network_available);
       break;
 
+    case PROP_NETWORK_METERED:
+      g_value_set_boolean (value, nm->priv->network_metered);
+      break;
+
     case PROP_CONNECTIVITY:
       g_value_set_enum (value, nm->priv->connectivity);
       break;
@@ -123,6 +129,24 @@ nm_conn_to_g_conn (int nm_state)
     }
 }
 
+static gboolean
+nm_metered_to_bool (guint nm_metered)
+{
+  switch (nm_metered)
+    {
+      case 0: /* unknown */
+      case 1: /* yes */
+      case 3: /* guess-yes */
+        return TRUE;
+      case 2: /* no */
+      case 4: /* guess-no */
+        return FALSE;
+      default:
+        g_warning ("Unknown NM metered state %d", nm_metered);
+        return FALSE;
+    }
+}
+
 static void
 sync_properties (GNetworkMonitorNM *nm,
                  gboolean           emit_signals)
@@ -130,6 +154,7 @@ sync_properties (GNetworkMonitorNM *nm,
   GVariant *v;
   NMConnectivityState nm_connectivity;
   gboolean new_network_available;
+  gboolean new_network_metered;
   GNetworkConnectivity new_connectivity;
 
   v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Connectivity");
@@ -139,16 +164,31 @@ sync_properties (GNetworkMonitorNM *nm,
   if (nm_connectivity == NM_CONNECTIVITY_NONE)
     {
       new_network_available = FALSE;
+      new_network_metered = FALSE;
       new_connectivity = G_NETWORK_CONNECTIVITY_LOCAL;
     }
   else
     {
+
+      /* this is only available post 1.0 */
+      v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Metered");
+      if (v == NULL)
+        {
+          new_network_metered = FALSE;
+        }
+      else
+        {
+          new_network_metered = nm_metered_to_bool (g_variant_get_uint32 (v));
+          g_variant_unref (v);
+        }
+
       new_network_available = TRUE;
       new_connectivity = nm_conn_to_g_conn (nm_connectivity);
     }
 
   if (!emit_signals)
     {
+      nm->priv->network_metered = new_network_metered;
       nm->priv->network_available = new_network_available;
       nm->priv->connectivity = new_connectivity;
       return;
@@ -159,6 +199,11 @@ sync_properties (GNetworkMonitorNM *nm,
       nm->priv->network_available = new_network_available;
       g_object_notify (G_OBJECT (nm), "network-available");
     }
+  if (new_network_metered != nm->priv->network_metered)
+    {
+      nm->priv->network_metered = new_network_metered;
+      g_object_notify (G_OBJECT (nm), "network-available");
+    }
   if (new_connectivity != nm->priv->connectivity)
     {
       nm->priv->connectivity = new_connectivity;
@@ -307,6 +352,7 @@ g_network_monitor_nm_class_init (GNetworkMonitorNMClass *nl_class)
   gobject_class->get_property = g_network_monitor_nm_get_property;
 
   g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available");
+  g_object_class_override_property (gobject_class, PROP_NETWORK_METERED, "network-metered");
   g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity");
 }