[gnome-software] Move the network monitor to the plugin loader



commit c1f24c2771354f199dbb7b8b802c8da71de3c0f0
Author: Richard Hughes <richard hughsie com>
Date:   Sun Nov 27 21:26:28 2016 +0000

    Move the network monitor to the plugin loader
    
    We need this in more state and it's inelegant to have the signal connection
    magic in more than one place.

 src/gs-application.c    |   38 --------------
 src/gs-plugin-loader.c  |  123 +++++++++++++++++++++++++++++++++++------------
 src/gs-plugin-loader.h  |    4 +-
 src/gs-self-test.c      |    1 -
 src/gs-shell-updates.c  |   50 +++++--------------
 src/gs-update-monitor.c |   31 ++++--------
 6 files changed, 118 insertions(+), 129 deletions(-)
---
diff --git a/src/gs-application.c b/src/gs-application.c
index 4aa8269..22b262d 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -69,8 +69,6 @@ struct _GsApplication {
        GsDbusHelper    *dbus_helper;
 #endif
        GsShellSearchProvider *search_provider;
-       GNetworkMonitor *network_monitor;
-       gulong           network_changed_handler;
        GSettings       *settings;
 };
 
@@ -125,34 +123,6 @@ gs_application_init (GsApplication *application)
        };
 
        g_application_add_main_option_entries (G_APPLICATION (application), options);
-
-       application->network_changed_handler = 0;
-}
-
-static void
-network_changed_cb (GNetworkMonitor *monitor,
-                   gboolean available,
-                   GsApplication *app)
-{
-       gs_plugin_loader_set_network_status (app->plugin_loader, available);
-}
-
-static void
-gs_application_monitor_network (GsApplication *app)
-{
-       GNetworkMonitor *network_monitor;
-
-       network_monitor = g_network_monitor_get_default ();
-       if (network_monitor == NULL || app->network_changed_handler != 0)
-               return;
-       app->network_monitor = g_object_ref (network_monitor);
-
-       app->network_changed_handler = g_signal_connect (app->network_monitor, "network-changed",
-                                                        G_CALLBACK (network_changed_cb), app);
-
-       network_changed_cb (app->network_monitor,
-                           g_network_monitor_get_network_available (app->network_monitor),
-                           app);
 }
 
 static void
@@ -287,9 +257,6 @@ gs_application_initialize_ui (GsApplication *app)
 
        gs_shell_setup (app->shell, app->plugin_loader, app->cancellable);
        gtk_application_add_window (GTK_APPLICATION (app), gs_shell_get_window (app->shell));
-
-       /* monitor the network as the many UI operations need the network */
-       gs_application_monitor_network (app);
 }
 
 static void
@@ -793,11 +760,6 @@ gs_application_dispose (GObject *object)
        g_clear_object (&app->shell);
        g_clear_object (&app->provider);
        g_clear_object (&app->update_monitor);
-       if (app->network_changed_handler != 0) {
-               g_signal_handler_disconnect (app->network_monitor, app->network_changed_handler);
-               app->network_changed_handler = 0;
-       }
-       g_clear_object (&app->network_monitor);
 #ifdef HAVE_PACKAGEKIT
        g_clear_object (&app->dbus_helper);
 #endif
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 0732903..aae41b9 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -62,10 +62,14 @@ typedef struct
 
        guint                    updates_changed_id;
        guint                    reload_id;
-       gboolean                 online; 
        GHashTable              *disallow_updates;      /* GsPlugin : const char *name */
+
+       GNetworkMonitor         *network_monitor;
+       gulong                   network_changed_handler;
 } GsPluginLoaderPrivate;
 
+static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader);
+
 G_DEFINE_TYPE_WITH_PRIVATE (GsPluginLoader, gs_plugin_loader, G_TYPE_OBJECT)
 
 enum {
@@ -80,6 +84,7 @@ enum {
        PROP_0,
        PROP_EVENTS,
        PROP_ALLOW_UPDATES,
+       PROP_NETWORK_AVAILABLE,
        PROP_LAST
 };
 
@@ -2904,7 +2909,7 @@ gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
        }
 
        if (action == GS_PLUGIN_ACTION_INSTALL &&
-           !priv->online) {
+           !gs_plugin_loader_get_network_available (plugin_loader)) {
                add_app_to_install_queue (plugin_loader, app);
                task = g_task_new (plugin_loader, cancellable, callback, user_data);
                g_task_return_boolean (task, TRUE);
@@ -3774,6 +3779,9 @@ gs_plugin_loader_get_property (GObject *object, guint prop_id,
        case PROP_ALLOW_UPDATES:
                g_value_set_boolean (value, gs_plugin_loader_get_allow_updates (plugin_loader));
                break;
+       case PROP_NETWORK_AVAILABLE:
+               g_value_set_boolean (value, gs_plugin_loader_get_network_available (plugin_loader));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -3812,6 +3820,12 @@ gs_plugin_loader_dispose (GObject *object)
                g_source_remove (priv->updates_changed_id);
                priv->updates_changed_id = 0;
        }
+       if (priv->network_changed_handler != 0) {
+               g_signal_handler_disconnect (priv->network_monitor,
+                                            priv->network_changed_handler);
+               priv->network_changed_handler = 0;
+       }
+       g_clear_object (&priv->network_monitor);
        g_clear_object (&priv->soup_session);
        g_clear_object (&priv->profile);
        g_clear_object (&priv->settings);
@@ -3862,6 +3876,11 @@ gs_plugin_loader_class_init (GsPluginLoaderClass *klass)
                                      G_PARAM_READABLE);
        g_object_class_install_property (object_class, PROP_ALLOW_UPDATES, pspec);
 
+       pspec = g_param_spec_boolean ("network-available", NULL, NULL,
+                                     FALSE,
+                                     G_PARAM_READABLE);
+       g_object_class_install_property (object_class, PROP_NETWORK_AVAILABLE, pspec);
+
        signals [SIGNAL_STATUS_CHANGED] =
                g_signal_new ("status-changed",
                              G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
@@ -3968,6 +3987,9 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        g_mutex_init (&priv->pending_apps_mutex);
        g_mutex_init (&priv->events_by_id_mutex);
 
+       /* monitor the network as the many UI operations need the network */
+       gs_plugin_loader_monitor_network (plugin_loader);
+
        /* by default we only show project-less apps or compatible projects */
        tmp = g_getenv ("GNOME_SOFTWARE_COMPATIBLE_PROJECTS");
        if (tmp == NULL) {
@@ -4014,45 +4036,84 @@ gs_plugin_loader_app_installed_cb (GObject *source,
        }
 }
 
-void
-gs_plugin_loader_set_network_status (GsPluginLoader *plugin_loader,
-                                    gboolean online)
+gboolean
+gs_plugin_loader_get_network_available (GsPluginLoader *plugin_loader)
 {
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
-       GsApp *app;
-       guint i;
-       g_autoptr(GsAppList) queue = NULL;
+       if (priv->network_monitor == NULL) {
+               g_debug ("no network monitor, so returning network-available=TRUE");
+               return TRUE;
+       }
+       return g_network_monitor_get_network_available (priv->network_monitor);
+}
 
-       if (priv->online == online)
-               return;
+gboolean
+gs_plugin_loader_get_network_metered (GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       if (priv->network_monitor == NULL) {
+               g_debug ("no network monitor, so returning network-metered=FALSE");
+               return FALSE;
+       }
+       return g_network_monitor_get_network_metered (priv->network_monitor);
+}
 
-       g_debug ("network status change: %s", online ? "online" : "offline");
+static void
+gs_plugin_loader_network_changed_cb (GNetworkMonitor *monitor,
+                                    gboolean available,
+                                    GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
 
-       priv->online = online;
+       g_debug ("network status change: %s [%s]",
+                available ? "online" : "offline",
+                g_network_monitor_get_network_metered (priv->network_monitor) ? "metered" : "metered");
 
-       if (!online)
-               return;
+       g_object_notify (G_OBJECT (plugin_loader), "network-available");
 
-       g_mutex_lock (&priv->pending_apps_mutex);
-       queue = gs_app_list_new ();
-       for (i = 0; i < priv->pending_apps->len; i++) {
-               app = g_ptr_array_index (priv->pending_apps, i);
-               if (gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL)
-                       gs_app_list_add (queue, app);
-       }
-       g_mutex_unlock (&priv->pending_apps_mutex);
-       for (i = 0; i < gs_app_list_length (queue); i++) {
-               app = gs_app_list_index (queue, i);
-               gs_plugin_loader_app_action_async (plugin_loader,
-                                                  app,
-                                                  GS_PLUGIN_ACTION_INSTALL,
-                                                  GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS,
-                                                  NULL,
-                                                  gs_plugin_loader_app_installed_cb,
-                                                  g_object_ref (app));
+       if (available) {
+               g_autoptr(GsAppList) queue = NULL;
+               g_mutex_lock (&priv->pending_apps_mutex);
+               queue = gs_app_list_new ();
+               for (guint i = 0; i < priv->pending_apps->len; i++) {
+                       GsApp *app = g_ptr_array_index (priv->pending_apps, i);
+                       if (gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL)
+                               gs_app_list_add (queue, app);
+               }
+               g_mutex_unlock (&priv->pending_apps_mutex);
+               for (guint i = 0; i < gs_app_list_length (queue); i++) {
+                       GsApp *app = gs_app_list_index (queue, i);
+                       gs_plugin_loader_app_action_async (plugin_loader,
+                                                          app,
+                                                          GS_PLUGIN_ACTION_INSTALL,
+                                                          GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS,
+                                                          NULL,
+                                                          gs_plugin_loader_app_installed_cb,
+                                                          g_object_ref (app));
+               }
        }
 }
 
+static void
+gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       GNetworkMonitor *network_monitor;
+
+       network_monitor = g_network_monitor_get_default ();
+       if (network_monitor == NULL || priv->network_changed_handler != 0)
+               return;
+       priv->network_monitor = g_object_ref (network_monitor);
+
+       priv->network_changed_handler =
+               g_signal_connect (priv->network_monitor, "network-changed",
+                                 G_CALLBACK (gs_plugin_loader_network_changed_cb), plugin_loader);
+
+       gs_plugin_loader_network_changed_cb (priv->network_monitor,
+                           g_network_monitor_get_network_available (priv->network_monitor),
+                           plugin_loader);
+}
+
 /******************************************************************************/
 
 static void
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index bed8ecb..bbb7479 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -252,8 +252,8 @@ void                 gs_plugin_loader_refresh_async         (GsPluginLoader 
*plugin_loader,
                                                         gpointer        user_data);
 GsAppList      *gs_plugin_loader_get_pending           (GsPluginLoader *plugin_loader);
 gboolean        gs_plugin_loader_get_allow_updates     (GsPluginLoader *plugin_loader);
-void            gs_plugin_loader_set_network_status    (GsPluginLoader *plugin_loader,
-                                                        gboolean        online);
+gboolean        gs_plugin_loader_get_network_available (GsPluginLoader *plugin_loader);
+gboolean        gs_plugin_loader_get_network_metered   (GsPluginLoader *plugin_loader);
 gboolean        gs_plugin_loader_get_plugin_supported  (GsPluginLoader *plugin_loader,
                                                         const gchar    *plugin_func);
 
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 6460b84..b143c25 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -1473,7 +1473,6 @@ main (int argc, char **argv)
 
        /* we can only load this once per process */
        plugin_loader = gs_plugin_loader_new ();
-       gs_plugin_loader_set_network_status (plugin_loader, TRUE);
        g_signal_connect (plugin_loader, "status-changed",
                          G_CALLBACK (gs_plugin_loader_status_changed_cb), NULL);
        gs_plugin_loader_set_location (plugin_loader, "./plugins/.libs");
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index 212e438..6d2f47b 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -78,8 +78,6 @@ struct _GsShellUpdates
        gboolean                 all_updates_are_live;
        gboolean                 any_require_reboot;
        GsShell                 *shell;
-       GNetworkMonitor         *network_monitor;
-       gulong                   network_changed_handler;
        GsPluginStatus           last_status;
        GsShellUpdatesState      state;
        GsShellUpdatesFlags      result_flags;
@@ -319,8 +317,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *self)
                if (self->result_flags != GS_SHELL_UPDATES_FLAG_NONE) {
                        gtk_widget_show (self->button_refresh);
                } else {
-                       if (self->network_monitor != NULL &&
-                           g_network_monitor_get_network_metered (self->network_monitor) &&
+                       if (gs_plugin_loader_get_network_metered (self->plugin_loader) &&
                            !self->has_agreed_to_mobile_data)
                                allow_mobile_refresh = FALSE;
                        gtk_widget_set_visible (self->button_refresh, allow_mobile_refresh);
@@ -360,21 +357,15 @@ gs_shell_updates_update_ui_state (GsShellUpdates *self)
                        break;
                }
 
-               /* we just don't know */
-               if (self->network_monitor == NULL) {
-                       gtk_stack_set_visible_child_name (GTK_STACK (self->stack_updates), "uptodate");
-                       break;
-               }
-
                /* check we have a "free" network connection */
-               if (g_network_monitor_get_network_available (self->network_monitor) &&
-                          !g_network_monitor_get_network_metered (self->network_monitor)) {
+               if (gs_plugin_loader_get_network_available (self->plugin_loader) &&
+                   !gs_plugin_loader_get_network_metered (self->plugin_loader)) {
                        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_updates), "uptodate");
                        break;
                }
 
                /* expensive network connection */
-               if (g_network_monitor_get_network_metered (self->network_monitor)) {
+               if (gs_plugin_loader_get_network_metered (self->plugin_loader)) {
                        if (self->has_agreed_to_mobile_data) {
                                gtk_stack_set_visible_child_name (GTK_STACK (self->stack_updates), 
"uptodate");
                        } else {
@@ -465,10 +456,11 @@ gs_shell_updates_decrement_refresh_count (GsShellUpdates *self)
        gs_shell_profile_dump (self->shell);
 }
 
+
 static void
-gs_shell_updates_notify_network_state_cb (GNetworkMonitor *network_monitor,
-                                         gboolean available,
-                                         GsShellUpdates *self)
+gs_shell_updates_network_available_notify_cb (GsPluginLoader *plugin_loader,
+                                             GParamSpec *pspec,
+                                             GsShellUpdates *self)
 {
        gs_shell_updates_update_ui_state (self);
 }
@@ -834,19 +826,13 @@ gs_shell_updates_button_refresh_cb (GtkWidget *widget,
                return;
        }
 
-       /* we don't know the network state */
-       if (self->network_monitor == NULL) {
-               gs_shell_updates_get_new_updates (self);
-               return;
-       }
-
        /* check we have a "free" network connection */
-       if (g_network_monitor_get_network_available (self->network_monitor) &&
-           !g_network_monitor_get_network_metered (self->network_monitor)) {
+       if (gs_plugin_loader_get_network_available (self->plugin_loader) &&
+           !gs_plugin_loader_get_network_metered (self->plugin_loader)) {
                gs_shell_updates_get_new_updates (self);
 
        /* expensive network connection */
-       } else if (g_network_monitor_get_network_metered (self->network_monitor)) {
+       } else if (gs_plugin_loader_get_network_metered (self->plugin_loader)) {
                if (self->has_agreed_to_mobile_data) {
                        gs_shell_updates_get_new_updates (self);
                        return;
@@ -1337,6 +1323,9 @@ gs_shell_updates_setup (GsShellUpdates *self,
        g_signal_connect_object (self->plugin_loader, "notify::allow-updates",
                                 G_CALLBACK (gs_shell_updates_allow_updates_notify_cb),
                                 self, 0);
+       g_signal_connect_object (self->plugin_loader, "notify::network-available",
+                                G_CALLBACK (gs_shell_updates_network_available_notify_cb),
+                                self, 0);
        self->builder = g_object_ref (builder);
        self->cancellable = g_object_ref (cancellable);
 
@@ -1395,12 +1384,6 @@ gs_shell_updates_setup (GsShellUpdates *self,
        if (!gs_plugin_loader_get_allow_updates (self->plugin_loader))
                self->state = GS_SHELL_UPDATES_STATE_MANAGED;
 
-       if (self->network_monitor != NULL) {
-               self->network_changed_handler = g_signal_connect (self->network_monitor, "network-changed",
-                                               G_CALLBACK (gs_shell_updates_notify_network_state_cb),
-                                               self);
-       }
-
        /* chain up */
        gs_page_setup (GS_PAGE (self),
                       shell,
@@ -1413,10 +1396,6 @@ gs_shell_updates_dispose (GObject *object)
 {
        GsShellUpdates *self = GS_SHELL_UPDATES (object);
 
-       if (self->network_changed_handler != 0) {
-               g_signal_handler_disconnect (self->network_monitor, self->network_changed_handler);
-               self->network_changed_handler = 0;
-       }
        if (self->cancellable_refresh != NULL) {
                g_cancellable_cancel (self->cancellable_refresh);
                g_clear_object (&self->cancellable_refresh);
@@ -1465,7 +1444,6 @@ gs_shell_updates_init (GsShellUpdates *self)
 
        gtk_widget_init_template (GTK_WIDGET (self));
 
-       self->network_monitor = g_network_monitor_get_default ();
        self->state = GS_SHELL_UPDATES_STATE_STARTUP;
        self->settings = g_settings_new ("org.gnome.software");
        self->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
index 61e496e..d2a46c5 100644
--- a/src/gs-update-monitor.c
+++ b/src/gs-update-monitor.c
@@ -45,7 +45,6 @@ struct _GsUpdateMonitor {
        guint            check_startup_id;              /* 60s after startup */
        guint            check_hourly_id;               /* and then every hour */
        guint            check_daily_id;                /* every 3rd day */
-       GNetworkMonitor *network_monitor;               /* network type detection */
        guint            notification_blocked_id;       /* rate limit notifications */
 };
 
@@ -345,19 +344,15 @@ check_updates (GsUpdateMonitor *monitor)
        g_autoptr(GDateTime) now_refreshed = NULL;
        GsPluginRefreshFlags refresh_flags = GS_PLUGIN_REFRESH_FLAGS_METADATA;
 
-       /* we don't know the network state */
-       if (monitor->network_monitor == NULL)
-               return;
-
        /* never check for updates when offline */
-       if (!g_network_monitor_get_network_available (monitor->network_monitor))
+       if (!gs_plugin_loader_get_network_available (monitor->plugin_loader))
                return;
 
        refresh_on_metered = g_settings_get_boolean (monitor->settings,
                                                     "refresh-when-metered");
 
        if (!refresh_on_metered &&
-           g_network_monitor_get_network_metered (monitor->network_monitor))
+           gs_plugin_loader_get_network_metered (monitor->plugin_loader))
                return;
 
        /* never refresh when the battery is low */
@@ -511,9 +506,9 @@ check_updates_upower_changed_cb (GDBusProxy *proxy,
 }
 
 static void
-notify_network_state_cb (GNetworkMonitor *network_monitor,
-                        gboolean active,
-                        GsUpdateMonitor *monitor)
+network_available_notify_cb (GsPluginLoader *plugin_loader,
+                            GParamSpec *pspec,
+                            GsUpdateMonitor *monitor)
 {
        check_updates (monitor);
 }
@@ -710,11 +705,6 @@ gs_update_monitor_init (GsUpdateMonitor *monitor)
                g_timeout_add_seconds (60, check_updates_on_startup_cb, monitor);
 
        monitor->cancellable = g_cancellable_new ();
-       monitor->network_monitor = g_network_monitor_get_default ();
-       if (monitor->network_monitor != NULL) {
-               g_signal_connect (monitor->network_monitor, "network-changed",
-                                 G_CALLBACK (notify_network_state_cb), monitor);
-       }
 
        /* connect to UPower to get the system power state */
        monitor->proxy_upower = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
@@ -759,16 +749,13 @@ gs_update_monitor_dispose (GObject *object)
                g_source_remove (monitor->cleanup_notifications_id);
                monitor->cleanup_notifications_id = 0;
        }
-       if (monitor->network_monitor != NULL) {
-               g_signal_handlers_disconnect_by_func (monitor->network_monitor,
-                                                     notify_network_state_cb,
-                                                     monitor);
-               monitor->network_monitor = NULL;
-       }
        if (monitor->plugin_loader != NULL) {
                g_signal_handlers_disconnect_by_func (monitor->plugin_loader,
                                                      updates_changed_cb,
                                                      monitor);
+               g_signal_handlers_disconnect_by_func (monitor->plugin_loader,
+                                                     network_available_notify_cb,
+                                                     monitor);
                monitor->plugin_loader = NULL;
        }
        g_clear_object (&monitor->settings);
@@ -810,6 +797,8 @@ gs_update_monitor_new (GsApplication *application)
                          G_CALLBACK (updates_changed_cb), monitor);
        g_signal_connect (monitor->plugin_loader, "notify::allow-updates",
                          G_CALLBACK (allow_updates_notify_cb), monitor);
+       g_signal_connect (monitor->plugin_loader, "notify::network-available",
+                         G_CALLBACK (network_available_notify_cb), monitor);
 
        return monitor;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]