Commit 22ea48b1 authored by Joaquim Rocha's avatar Joaquim Rocha

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.
parent cb7fca19
......@@ -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) {
......
......@@ -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
......
......@@ -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);
......@@ -804,6 +807,43 @@ gs_plugin_set_global_cache (GsPlugin *plugin, GsAppList *global_cache)
g_set_object (&priv->global_cache, 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
......
......@@ -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
......
......@@ -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,
......
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment