[gnome-software] Change how apps are queued for installation



commit 22ea48b119539d927f7c188c649d2ad6e455d761
Author: Joaquim Rocha <jrocha endlessm com>
Date:   Tue Dec 19 13:54:04 2017 +0000

    Change how apps are queued for installation
    
    When installing an app in g-s while it is offline, g-s was adding it to
    the pending installation queue directly. However, if the app is coming
    from a local source like a local repository (USB drive, test repo, etc.)
    that behavior is not ideal. So it should be up to the plugins whether an
    app installation is performed or queued for later.
    
    To achieve that, this patch changes how the plugin-loader behaves by
    allowing plugins to check the state of the network themselves themselves
    (by introducing a new method gs_plugin_get_available_network), and
    checking the state of apps after calling the gs_plugin_app_install
    methods are called: if the app's state is QUEUED_FOR_INSTALL, then it
    adds the app to the installation queue.
    
    This means that in order to keep supporting this behavior in their
    platforms, plugins need to check whether apps should be queued for
    installation, set the mentioned state to them, and return TRUE (in
    the app install override).
    This patch changes that already for the PackageKit and Flatpak plugins.

 lib/gs-plugin-loader.c                    |   16 ++++++------
 lib/gs-plugin-private.h                   |    2 +
 lib/gs-plugin.c                           |   40 +++++++++++++++++++++++++++++
 lib/gs-plugin.h                           |    1 +
 plugins/flatpak/gs-flatpak.c              |   14 ++++++++++
 plugins/packagekit/gs-plugin-packagekit.c |    6 ++++
 6 files changed, 71 insertions(+), 8 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index d5cb758..8ed0833 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -71,6 +71,7 @@ typedef struct
 } GsPluginLoaderPrivate;
 
 static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader);
+static void add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app);
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsPluginLoader, gs_plugin_loader, G_TYPE_OBJECT)
 
@@ -757,6 +758,12 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
                                                        error);
        }
 
+       /* add app to the pending installation queue if necessary */
+       if (action == GS_PLUGIN_ACTION_INSTALL &&
+           app != NULL && gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL) {
+               add_app_to_install_queue (helper->plugin_loader, app);
+       }
+
        /* check the plugin didn't take too long */
        switch (action) {
        case GS_PLUGIN_ACTION_INITIALIZE:
@@ -2157,6 +2164,7 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        gs_plugin_set_language (plugin, priv->language);
        gs_plugin_set_scale (plugin, gs_plugin_loader_get_scale (plugin_loader));
        gs_plugin_set_global_cache (plugin, priv->global_cache);
+       gs_plugin_set_network_monitor (plugin, priv->network_monitor);
        g_debug ("opened plugin %s: %s", filename, gs_plugin_get_name (plugin));
 
        /* add to array */
@@ -3450,14 +3458,6 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
                        return;
                }
        }
-       if (action == GS_PLUGIN_ACTION_INSTALL &&
-           !gs_plugin_loader_get_network_available (plugin_loader)) {
-               GsAppList *list = gs_plugin_job_get_list (plugin_job);
-               add_app_to_install_queue (plugin_loader, gs_plugin_job_get_app (plugin_job));
-               task = g_task_new (plugin_loader, cancellable, callback, user_data);
-               g_task_return_pointer (task, g_object_ref (list), (GDestroyNotify) g_object_unref);
-               return;
-       }
 
        /* hardcoded, so resolve a set list */
        if (action == GS_PLUGIN_ACTION_GET_POPULAR) {
diff --git a/lib/gs-plugin-private.h b/lib/gs-plugin-private.h
index 47b4c5e..63be809 100644
--- a/lib/gs-plugin-private.h
+++ b/lib/gs-plugin-private.h
@@ -71,6 +71,8 @@ gpointer       gs_plugin_get_symbol                   (GsPlugin       *plugin,
                                                         const gchar    *function_name);
 gchar          *gs_plugin_failure_flags_to_string      (GsPluginFailureFlags failure_flags);
 gchar          *gs_plugin_refine_flags_to_string       (GsPluginRefineFlags refine_flags);
+void            gs_plugin_set_network_monitor          (GsPlugin               *plugin,
+                                                        GNetworkMonitor        *monitor);
 
 G_END_DECLS
 
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index b32ea6c..fb8c450 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -83,6 +83,7 @@ typedef struct
        guint                    priority;
        guint                    timer_id;
        GMutex                   timer_mutex;
+       GNetworkMonitor         *network_monitor;
 } GsPluginPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsPlugin, gs_plugin, G_TYPE_OBJECT)
@@ -230,6 +231,8 @@ gs_plugin_finalize (GObject *object)
                g_object_unref (priv->soup_session);
        if (priv->global_cache != NULL)
                g_object_unref (priv->global_cache);
+       if (priv->network_monitor != NULL)
+               g_object_unref (priv->network_monitor);
        g_hash_table_unref (priv->cache);
        g_hash_table_unref (priv->vfuncs);
        g_mutex_clear (&priv->cache_mutex);
@@ -805,6 +808,43 @@ gs_plugin_set_global_cache (GsPlugin *plugin, GsAppList *global_cache)
 }
 
 /**
+ * gs_plugin_set_network_monitor:
+ * @plugin: a #GsPlugin
+ * @network_monitor: a #GNetworkMonitor
+ *
+ * Sets the network monitor so that plugins can check the state of the network.
+ *
+ * Since: 3.28
+ **/
+void
+gs_plugin_set_network_monitor (GsPlugin *plugin, GNetworkMonitor *monitor)
+{
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+       g_set_object (&priv->network_monitor, monitor);
+}
+
+/**
+ * gs_plugin_get_network_available:
+ * @plugin: a #GsPlugin
+ *
+ * Gets whether a network connectivity is available.
+ *
+ * Returns: %TRUE if a network is available.
+ *
+ * Since: 3.28
+ **/
+gboolean
+gs_plugin_get_network_available (GsPlugin *plugin)
+{
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+       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);
+}
+
+/**
  * gs_plugin_has_flags:
  * @plugin: a #GsPlugin
  * @flags: a #GsPluginFlags, e.g. %GS_PLUGIN_FLAGS_RUNNING_SELF
diff --git a/lib/gs-plugin.h b/lib/gs-plugin.h
index 00fe5da..3fcc44d 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -136,6 +136,7 @@ void                 gs_plugin_report_event                 (GsPlugin       *plugin,
                                                         GsPluginEvent  *event);
 void            gs_plugin_set_allow_updates            (GsPlugin       *plugin,
                                                         gboolean        allow_updates);
+gboolean        gs_plugin_get_network_available        (GsPlugin       *plugin);
 
 G_END_DECLS
 
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 2829eef..1b46fd8 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -2659,12 +2659,26 @@ gs_flatpak_create_runtime_repo (GsFlatpak *self,
        return g_steal_pointer (&app);
 }
 
+static gboolean
+app_has_local_source (GsApp *app)
+{
+       const gchar *url = gs_app_get_origin_hostname (app);
+       return url != NULL && g_str_has_prefix (url, "file://");
+}
+
 gboolean
 gs_flatpak_app_install (GsFlatpak *self,
                        GsApp *app,
                        GCancellable *cancellable,
                        GError **error)
 {
+       /* queue for install if installation needs the network */
+       if (!app_has_local_source (app) &&
+           !gs_plugin_get_network_available (self->plugin)) {
+               gs_app_set_state (app, AS_APP_STATE_QUEUED_FOR_INSTALL);
+               return TRUE;
+       }
+
        /* ensure we have metadata and state */
        if (!gs_flatpak_refine_app (self, app,
                                    GS_PLUGIN_REFINE_FLAGS_REQUIRE_RUNTIME,
diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c
index c9fd25e..9bd7e6d 100644
--- a/plugins/packagekit/gs-plugin-packagekit.c
+++ b/plugins/packagekit/gs-plugin-packagekit.c
@@ -269,6 +269,12 @@ gs_plugin_app_install (GsPlugin *plugin,
                                              cancellable, error);
        }
 
+       /* queue for install if installation needs the network */
+       if (!gs_plugin_get_network_available (plugin)) {
+               gs_app_set_state (app, AS_APP_STATE_QUEUED_FOR_INSTALL);
+               return TRUE;
+       }
+
        /* enable the repo where the unavailable app is coming from */
        if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) {
 


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