[gnome-initial-setup/82-support-wi-fi-devices-appearing-dynamically: 1/2] network: react to devices being connected
- From: Will Thompson <wjt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-initial-setup/82-support-wi-fi-devices-appearing-dynamically: 1/2] network: react to devices being connected
- Date: Mon, 20 Jan 2020 11:19:51 +0000 (UTC)
commit 9e1b61a8c766fdd3ac67193bfae1047f3befd5fa
Author: Will Thompson <will willthompson co uk>
Date: Mon Jan 20 09:25:46 2020 +0000
network: react to devices being connected
If the built-in Wi-Fi device takes longer to initialize than does the
gnome-initial-setup session, no device will be found when the page is
first initialized, and the page will not be shown, even if the device
has come up by the point the user reaches this point in the initial
setup flow. This has been seen on 2-3 models the Endless hardware
enablement team has worked with.
To fix this, monitor NetworkManager for new devices, and latch onto the
first managed Wi-Fi device we ever see.
Previously, the decision about whether to show or hide the page was made
once, when the page was constructed; with this change, it is now made
whenever we decide whether the page is complete. To avoid confusing the
user, if we have ever shown them the page, we continue to show it even
if the connection comes up – otherwise they cannot go Back and pick a
different network.
Note that we still do not handle the case of the current Wi-Fi device
being removed, which may be significant if the device doesn't have a
built-in Wi-Fi adapter and the user is plugging and unplugging a USB
one. In particular, unplugging and replugging the same device yields a
different D-Bus object and NMDevice, so the page will be empty even once
the device is re-plugged. However, this is not a regression!
We also still don't handle multiple Wi-Fi devices.
https://gitlab.gnome.org/GNOME/gnome-initial-setup/issues/82
.../pages/network/gis-network-page.c | 138 +++++++++++++++++----
1 file changed, 114 insertions(+), 24 deletions(-)
---
diff --git a/gnome-initial-setup/pages/network/gis-network-page.c
b/gnome-initial-setup/pages/network/gis-network-page.c
index cf0a5dd..6141390 100644
--- a/gnome-initial-setup/pages/network/gis-network-page.c
+++ b/gnome-initial-setup/pages/network/gis-network-page.c
@@ -56,6 +56,9 @@ struct _GisNetworkPagePrivate {
GtkSizeGroup *icons;
guint refresh_timeout_id;
+
+ /* TRUE if the page has ever been shown to the user. */
+ gboolean ever_shown;
};
typedef struct _GisNetworkPagePrivate GisNetworkPagePrivate;
@@ -604,11 +607,31 @@ static void
sync_complete (GisNetworkPage *page)
{
GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (page);
+ gboolean has_device;
gboolean activated;
+ gboolean visible;
+
+ has_device = priv->nm_device != NULL;
+ activated = priv->nm_device != NULL
+ && nm_device_get_state (priv->nm_device) == NM_DEVICE_STATE_ACTIVATED;
+
+ if (priv->ever_shown) {
+ visible = TRUE;
+ } else if (!has_device) {
+ g_debug ("No network device found, hiding network page");
+ visible = FALSE;
+ } else if (activated) {
+ g_debug ("Activated network device found, hiding network page");
+ visible = FALSE;
+ } else {
+ visible = TRUE;
+ }
- activated = (nm_device_get_state (priv->nm_device) == NM_DEVICE_STATE_ACTIVATED);
gis_page_set_complete (GIS_PAGE (page), activated);
- schedule_refresh_wireless_list (page);
+ gtk_widget_set_visible (GTK_WIDGET (page), visible);
+
+ if (has_device)
+ schedule_refresh_wireless_list (page);
}
static void
@@ -626,7 +649,8 @@ find_best_device (GisNetworkPage *page)
/* FIXME: deal with multiple devices and devices being removed */
if (priv->nm_device != NULL) {
- g_debug ("Already displaying %s", nm_device_get_description (priv->nm_device));
+ g_debug ("Already showing network device %s",
+ nm_device_get_description (priv->nm_device));
return;
}
@@ -641,18 +665,89 @@ find_best_device (GisNetworkPage *page)
if (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI) {
/* FIXME deal with multiple, dynamic devices */
priv->nm_device = g_object_ref (device);
- g_debug ("Displaying %s", nm_device_get_description (priv->nm_device));
+ g_debug ("Showing network device %s",
+ nm_device_get_description (priv->nm_device));
g_signal_connect (priv->nm_device, "notify::state",
G_CALLBACK (device_state_changed), page);
g_signal_connect (priv->nm_client, "notify::active-connections",
G_CALLBACK (active_connections_changed), page);
- sync_complete (page);
-
break;
}
}
+
+ sync_complete (page);
+}
+static void
+device_notify_managed (NMDevice *device,
+ GParamSpec *param,
+ void *user_data)
+{
+ GisNetworkPage *page = GIS_NETWORK_PAGE (user_data);
+
+ find_best_device (page);
+}
+
+static void
+client_device_added (NMClient *client,
+ NMDevice *device,
+ void *user_data)
+{
+ GisNetworkPage *page = GIS_NETWORK_PAGE (user_data);
+
+ g_signal_connect_object (device,
+ "notify::managed",
+ G_CALLBACK (device_notify_managed),
+ G_OBJECT (page),
+ 0);
+
+ find_best_device (page);
+}
+
+static void
+client_device_removed (NMClient *client,
+ NMDevice *device,
+ void *user_data)
+{
+ GisNetworkPage *page = GIS_NETWORK_PAGE (user_data);
+
+ /* TODO: reset page if priv->nm_device == device */
+ find_best_device (page);
+}
+
+static void
+monitor_network_devices (GisNetworkPage *page)
+{
+ GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (page);
+ const GPtrArray *devices;
+ guint i;
+
+ g_assert (priv->nm_client != NULL);
+ devices = nm_client_get_devices (priv->nm_client);
+ g_return_if_fail (devices != NULL);
+ for (i = 0; devices != NULL && i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+
+ g_signal_connect_object (device,
+ "notify::managed",
+ G_CALLBACK (device_notify_managed),
+ G_OBJECT (page),
+ 0);
+ }
+
+ g_signal_connect_object (priv->nm_client,
+ "device-added",
+ G_CALLBACK (client_device_added),
+ G_OBJECT (page),
+ 0);
+ g_signal_connect_object (priv->nm_client,
+ "device-removed",
+ G_CALLBACK (client_device_removed),
+ G_OBJECT (page),
+ 0);
+
+ find_best_device (page);
}
static void
@@ -660,13 +755,13 @@ gis_network_page_constructed (GObject *object)
{
GisNetworkPage *page = GIS_NETWORK_PAGE (object);
GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (page);
- gboolean visible = FALSE;
GError *error = NULL;
G_OBJECT_CLASS (gis_network_page_parent_class)->constructed (object);
gis_page_set_skippable (GIS_PAGE (page), TRUE);
+ priv->ever_shown = g_getenv ("GIS_ALWAYS_SHOW_NETWORK_PAGE") != NULL;
priv->icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_list_box_set_selection_mode (GTK_LIST_BOX (priv->network_list), GTK_SELECTION_NONE);
@@ -680,28 +775,14 @@ gis_network_page_constructed (GObject *object)
g_warning ("Can't create NetworkManager client, hiding network page: %s",
error->message);
g_error_free (error);
- goto out;
+ sync_complete (page);
+ return;
}
g_object_bind_property (priv->nm_client, "wireless-enabled",
priv->turn_on_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
- find_best_device (page);
-
- if (g_getenv ("GIS_ALWAYS_SHOW_NETWORK_PAGE") != NULL) {
- /* Allow to always show the network page, for debugging purposes */
- visible = TRUE;
- } else if (priv->nm_device == NULL) {
- g_debug ("No network device found, hiding network page");
- } else if (nm_device_get_state (priv->nm_device) == NM_DEVICE_STATE_ACTIVATED) {
- g_debug ("Activated network device found, hiding network page");
- } else {
- visible = TRUE;
- }
-
-out:
- gtk_widget_set_visible (GTK_WIDGET (page), visible);
+ monitor_network_devices (page);
}
static void
@@ -725,6 +806,14 @@ gis_network_page_locale_changed (GisPage *page)
gis_page_set_title (GIS_PAGE (page), _("Network"));
}
+static void
+gis_network_page_shown (GisPage *page)
+{
+ GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (GIS_NETWORK_PAGE (page));
+
+ priv->ever_shown = TRUE;
+}
+
static void
gis_network_page_class_init (GisNetworkPageClass *klass)
{
@@ -742,6 +831,7 @@ gis_network_page_class_init (GisNetworkPageClass *klass)
page_class->page_id = PAGE_ID;
page_class->locale_changed = gis_network_page_locale_changed;
+ page_class->shown = gis_network_page_shown;
object_class->constructed = gis_network_page_constructed;
object_class->dispose = gis_network_page_dispose;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]