From a80e7db1a8f26dc558085844dcb8003edb6eca74 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Tue, 2 Jun 2015 15:41:48 +0100 Subject: [PATCH] gio: Add network metered information to GNetworkMonitor 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 | 1 + gio/gnetworkmonitor.c | 47 +++++++++++++++++++++++++++++ gio/gnetworkmonitor.h | 3 ++ gio/gnetworkmonitornm.c | 46 ++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index d91f59815..993fe0659 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -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 diff --git a/gio/gnetworkmonitor.c b/gio/gnetworkmonitor.c index b08de473a..60c59874b 100644 --- a/gio/gnetworkmonitor.c +++ b/gio/gnetworkmonitor.c @@ -114,6 +114,28 @@ g_network_monitor_get_network_available (GNetworkMonitor *monitor) return available; } +/** + * 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 @@ -335,6 +357,31 @@ g_network_monitor_default_init (GNetworkMonitorInterface *iface) G_PARAM_READABLE | 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: * diff --git a/gio/gnetworkmonitor.h b/gio/gnetworkmonitor.h index 0a6a42cdb..10b180ac7 100644 --- a/gio/gnetworkmonitor.h +++ b/gio/gnetworkmonitor.h @@ -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); diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c index d052716d2..c2f861a97 100644 --- a/gio/gnetworkmonitornm.c +++ b/gio/gnetworkmonitornm.c @@ -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"); }