[gnome-software] Change how apps are queued for installation
- From: Joaquim Manuel Pereira Rocha <jrocha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Change how apps are queued for installation
- Date: Wed, 10 Jan 2018 13:13:22 +0000 (UTC)
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]