From 34978e4b2f88d9cb6adb4448022643850a3081dd Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 16 Apr 2014 10:39:12 -0400 Subject: gio: add network connectivity state to GNetworkMonitor 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. FIXME bug number --- gio/gioenums.h | 25 ++++++++++++++++++ gio/gnetworkmonitor.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ gio/gnetworkmonitor.h | 33 +++++++++++++----------- gio/gnetworkmonitorbase.c | 24 ++++++++++++------ 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/gio/gioenums.h b/gio/gioenums.h index 9a7631f91..ea757ea06 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -1783,6 +1783,31 @@ typedef enum { G_SUBPROCESS_FLAGS_INHERIT_FDS = (1u << 7) } GSubprocessFlags; +/** + * 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, + G_NETWORK_CONNECTIVITY_LIMITED, + G_NETWORK_CONNECTIVITY_PORTAL, + G_NETWORK_CONNECTIVITY_FULL +} GNetworkConnectivity; + + G_END_DECLS #endif /* __GIO_ENUMS_H__ */ diff --git a/gio/gnetworkmonitor.c b/gio/gnetworkmonitor.c index 79c7bd94f..77ecc6135 100644 --- a/gio/gnetworkmonitor.c +++ b/gio/gnetworkmonitor.c @@ -98,6 +98,52 @@ 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 = (GNetworkConnectivity) -1; + + g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL); + + if (connectivity == (GNetworkConnectivity) -1) + { + if (g_network_monitor_get_network_available (monitor)) + connectivity = G_NETWORK_CONNECTIVITY_FULL; + else + connectivity = G_NETWORK_CONNECTIVITY_LOCAL; + } + + return connectivity; +} + /** * g_network_monitor_can_reach: * @monitor: a #GNetworkMonitor @@ -280,4 +326,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)); } diff --git a/gio/gnetworkmonitor.h b/gio/gnetworkmonitor.h index c9f22b85d..58973917e 100644 --- a/gio/gnetworkmonitor.h +++ b/gio/gnetworkmonitor.h @@ -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 diff --git a/gio/gnetworkmonitorbase.c b/gio/gnetworkmonitorbase.c index 5ff2f364b..d55aecbd2 100644 --- a/gio/gnetworkmonitorbase.c +++ b/gio/gnetworkmonitorbase.c @@ -67,7 +67,8 @@ enum { PROP_0, - PROP_NETWORK_AVAILABLE + PROP_NETWORK_AVAILABLE, + PROP_CONNECTIVITY }; struct _GNetworkMonitorBasePrivate @@ -147,12 +148,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; } } @@ -185,6 +194,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"); } /* Assumes base->priv->mutex is locked */ -- cgit v1.2.1