Commit 37103e6e authored by Richard Hughes's avatar Richard Hughes

Download applications explicitly when required

This adds gs_plugin_update(), but removes gs_plugin_add_updates_pending() and
GsPluginRefreshFlags. The idea is that the frontend can ask the plugin loader
to download specific GsApp objects, rather than trying to wedge this into the
refresh action as some kind of payload.

Breaks internal plugin API, but makes everything simpler, which is fine with me.
parent 6fff35e0
......@@ -12,8 +12,13 @@
</key>
<key name="download-updates" type="b">
<default>true</default>
<summary>Whether to automatically download updates</summary>
<description>If enabled, GNOME Software automatically downloads updates in the background and prompts the user to install them when ready.</description>
<summary>Automatically download and install updates</summary>
<description>If enabled, GNOME Software automatically downloads software updates in the background, also installing ones that do not require a reboot.</description>
</key>
<key name="download-updates-notify" type="b">
<default>true</default>
<summary>Notify the user about software updated in the background</summary>
<description>If enabled, GNOME Software notifies the user about updates that happened whilst the user was idle.</description>
</key>
<key name="refresh-when-metered" type="b">
<default>false</default>
......
......@@ -335,15 +335,16 @@ gs_plugin_add_installed (GsPlugin *plugin,
On fast connections we should only show that for a couple of seconds,
but it's a good idea to try any avoid that if at all possible in the
plugin.
Once per day the <code>gs_plugin_refresh()</code> method is called again,
but this time with <code>GS_PLUGIN_REFRESH_FLAGS_PAYLOAD</code> set.
Once per day the <code>gs_plugin_get_updates()</code> method is called,
and then <code>gs_plugin_download_app()</code> may be called if the
user has configured automatic updates.
This is where the Flatpak plugin would download any ostree trees (but
not doing the deploy step) so that the applications can be updated live
in the details panel without having to wait for the download to complete.
In a similar way, the fwupd plugin downloads the tiny LVFS metadata with
<code>GS_PLUGIN_REFRESH_FLAGS_METADATA</code> and then downloads the
large firmware files themselves only when the
<code>GS_PLUGIN_REFRESH_FLAGS_PAYLOAD</code> flag is set.
<code>gs_plugin_refresh()</code> and then downloads the large firmware
files themselves when <code>gs_plugin_download_app()</code> or
<code>gs_plugin_download_app()</code> is called.
</para>
<para>
If the <code>@app</code> parameter is set for
......@@ -371,35 +372,25 @@ gs_plugin_add_installed (GsPlugin *plugin,
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error)
{
const gchar *metadata_fn = "/var/cache/example/metadata.xml";
const gchar *metadata_url = "http://www.example.com/new.xml";
/* this is called at startup and once per day */
if (flags &amp; GS_PLUGIN_REFRESH_FLAGS_METADATA) {
g_autoptr(GFile) file = g_file_new_for_path (metadata_fn);
/* is the metadata missing or too old */
if (gs_utils_get_file_age (file) &gt; cache_age) {
if (!gs_plugin_download_file (plugin,
NULL,
metadata_url,
metadata_fn,
cancellable,
error)) {
/* it's okay to fail here */
return FALSE;
}
g_debug ("successfully downloaded new metadata");
g_autoptr(GFile) file = g_file_new_for_path (metadata_fn);
/* is the metadata missing or too old */
if (gs_utils_get_file_age (file) &gt; cache_age) {
if (!gs_plugin_download_file (plugin,
NULL,
metadata_url,
metadata_fn,
cancellable,
error)) {
/* it's okay to fail here */
return FALSE;
}
}
/* this is called when the session is idle */
if ((flags &amp; GS_PLUGIN_REFRESH_FLAGS_PAYLOAD) == 0) {
// FIXME: download any required updates now
g_debug ("successfully downloaded new metadata");
}
return TRUE;
}
......
......@@ -271,18 +271,6 @@ gs_cmd_action_exec (GsCmdSelf *self, GsPluginAction action, const gchar *name, G
NULL, error);
}
static GsPluginRefreshFlags
gs_cmd_refresh_flag_from_string (const gchar *flag)
{
if (flag == NULL || g_strcmp0 (flag, "all") == 0)
return G_MAXINT32;
if (g_strcmp0 (flag, "metadata") == 0)
return GS_PLUGIN_REFRESH_FLAGS_METADATA;
if (g_strcmp0 (flag, "payload") == 0)
return GS_PLUGIN_REFRESH_FLAGS_PAYLOAD;
return GS_PLUGIN_REFRESH_FLAGS_NONE;
}
static void
gs_cmd_self_free (GsCmdSelf *self)
{
......@@ -404,7 +392,6 @@ main (int argc, char **argv)
g_autoptr(GsPluginJob) plugin_job = NULL;
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFRESH,
"age", (guint64) G_MAXUINT,
"refresh-flags", GS_PLUGIN_REFRESH_FLAGS_METADATA,
NULL);
ret = gs_plugin_loader_job_action (self->plugin_loader, plugin_job,
NULL, &error);
......@@ -666,12 +653,9 @@ main (int argc, char **argv)
}
}
} else if (argc >= 2 && g_strcmp0 (argv[1], "refresh") == 0) {
GsPluginRefreshFlags refresh_flags;
g_autoptr(GsPluginJob) plugin_job = NULL;
refresh_flags = gs_cmd_refresh_flag_from_string (argv[2]);
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFRESH,
"age", (guint64) cache_age,
"refresh-flags", refresh_flags,
NULL);
ret = gs_plugin_loader_job_action (self->plugin_loader, plugin_job,
NULL, &error);
......
......@@ -29,7 +29,6 @@
G_BEGIN_DECLS
GsPluginAction gs_plugin_job_get_action (GsPluginJob *self);
GsPluginRefreshFlags gs_plugin_job_get_refresh_flags (GsPluginJob *self);
GsPluginRefineFlags gs_plugin_job_get_filter_flags (GsPluginJob *self);
GsPluginRefineFlags gs_plugin_job_get_refine_flags (GsPluginJob *self);
gboolean gs_plugin_job_has_refine_flags (GsPluginJob *self,
......
......@@ -32,7 +32,6 @@ struct _GsPluginJob
GObject parent_instance;
GsPluginRefineFlags refine_flags;
GsPluginRefineFlags filter_flags;
GsPluginRefreshFlags refresh_flags;
gboolean interactive;
guint max_results;
guint timeout;
......@@ -59,7 +58,6 @@ enum {
PROP_SEARCH,
PROP_REFINE_FLAGS,
PROP_FILTER_FLAGS,
PROP_REFRESH_FLAGS,
PROP_INTERACTIVE,
PROP_AUTH,
PROP_APP,
......@@ -185,20 +183,6 @@ gs_plugin_job_get_filter_flags (GsPluginJob *self)
return self->filter_flags;
}
void
gs_plugin_job_set_refresh_flags (GsPluginJob *self, GsPluginRefreshFlags refresh_flags)
{
g_return_if_fail (GS_IS_PLUGIN_JOB (self));
self->refresh_flags = refresh_flags;
}
GsPluginRefreshFlags
gs_plugin_job_get_refresh_flags (GsPluginJob *self)
{
g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0);
return self->refresh_flags;
}
gboolean
gs_plugin_job_has_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_flags)
{
......@@ -469,9 +453,6 @@ gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSp
case PROP_FILTER_FLAGS:
g_value_set_uint64 (value, self->filter_flags);
break;
case PROP_REFRESH_FLAGS:
g_value_set_uint64 (value, self->refresh_flags);
break;
case PROP_INTERACTIVE:
g_value_set_uint64 (value, self->interactive);
break;
......@@ -529,9 +510,6 @@ gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GP
case PROP_FILTER_FLAGS:
gs_plugin_job_set_filter_flags (self, g_value_get_uint64 (value));
break;
case PROP_REFRESH_FLAGS:
gs_plugin_job_set_refresh_flags (self, g_value_get_uint64 (value));
break;
case PROP_INTERACTIVE:
gs_plugin_job_set_interactive (self, g_value_get_uint64 (value));
break;
......@@ -618,11 +596,6 @@ gs_plugin_job_class_init (GsPluginJobClass *klass)
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_FILTER_FLAGS, pspec);
pspec = g_param_spec_uint64 ("refresh-flags", NULL, NULL,
0, G_MAXUINT64, 0,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_REFRESH_FLAGS, pspec);
pspec = g_param_spec_uint64 ("interactive", NULL, NULL,
0, G_MAXUINT64, 0,
G_PARAM_READWRITE);
......@@ -684,7 +657,6 @@ gs_plugin_job_init (GsPluginJob *self)
{
self->refine_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT;
self->filter_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT;
self->refresh_flags = GS_PLUGIN_REFRESH_FLAGS_NONE;
self->list = gs_app_list_new ();
self->time_created = g_get_monotonic_time ();
}
......
......@@ -40,8 +40,6 @@ void gs_plugin_job_set_refine_flags (GsPluginJob *self,
GsPluginRefineFlags refine_flags);
void gs_plugin_job_set_filter_flags (GsPluginJob *self,
GsPluginRefineFlags filter_flags);
void gs_plugin_job_set_refresh_flags (GsPluginJob *self,
GsPluginRefreshFlags refresh_flags);
void gs_plugin_job_set_interactive (GsPluginJob *self,
gboolean interactive);
void gs_plugin_job_set_max_results (GsPluginJob *self,
......
......@@ -161,7 +161,6 @@ typedef gboolean (*GsPluginRefineWildcardFunc) (GsPlugin *plugin,
GError **error);
typedef gboolean (*GsPluginRefreshFunc) (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags refresh_flags,
GCancellable *cancellable,
GError **error);
typedef gboolean (*GsPluginFileToAppFunc) (GsPlugin *plugin,
......@@ -216,6 +215,7 @@ gs_plugin_loader_helper_free (GsPluginLoaderHelper *helper)
case GS_PLUGIN_ACTION_INSTALL:
case GS_PLUGIN_ACTION_REMOVE:
case GS_PLUGIN_ACTION_UPDATE:
case GS_PLUGIN_ACTION_DOWNLOAD:
{
GsApp *app = gs_plugin_job_get_app (helper->plugin_job);
if (app != NULL)
......@@ -597,6 +597,19 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
gs_plugin_action_to_string (action));
}
break;
case GS_PLUGIN_ACTION_DOWNLOAD:
if (g_strcmp0 (helper->function_name, "gs_plugin_download_app") == 0) {
GsPluginActionFunc plugin_func = func;
ret = plugin_func (plugin, app, cancellable, &error_local);
} else if (g_strcmp0 (helper->function_name, "gs_plugin_download") == 0) {
GsPluginUpdateFunc plugin_func = func;
ret = plugin_func (plugin, list, cancellable, &error_local);
} else {
g_critical ("function_name %s invalid for %s",
helper->function_name,
gs_plugin_action_to_string (action));
}
break;
case GS_PLUGIN_ACTION_INSTALL:
case GS_PLUGIN_ACTION_REMOVE:
case GS_PLUGIN_ACTION_SET_RATING:
......@@ -690,7 +703,6 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
GsPluginRefreshFunc plugin_func = func;
ret = plugin_func (plugin,
gs_plugin_job_get_age (helper->plugin_job),
gs_plugin_job_get_refresh_flags (helper->plugin_job),
cancellable, &error_local);
}
break;
......@@ -3089,7 +3101,6 @@ gs_plugin_loader_process_thread_cb (GTask *task,
GsAppList *list = gs_plugin_job_get_list (helper->plugin_job);
GsPluginAction action = gs_plugin_job_get_action (helper->plugin_job);
GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
GsPluginRefineFlags filter_flags;
GsPluginRefineFlags refine_flags;
gboolean add_to_pending_array = FALSE;
......@@ -3130,23 +3141,20 @@ gs_plugin_loader_process_thread_cb (GTask *task,
g_task_return_error (task, error);
return;
}
}
/* remove from pending list */
if (add_to_pending_array)
gs_plugin_loader_pending_apps_remove (plugin_loader, helper);
/* append extra things when we want the list of pending updates */
if (action == GS_PLUGIN_ACTION_GET_UPDATES &&
!g_settings_get_boolean (priv->settings, "download-updates")) {
helper->function_name = "gs_plugin_add_updates_pending";
if (!gs_plugin_loader_run_results (helper, cancellable, &error)) {
} else if (action == GS_PLUGIN_ACTION_DOWNLOAD) {
helper->function_name = "gs_plugin_download_app";
if (!gs_plugin_loader_generic_update (plugin_loader, helper,
cancellable, &error)) {
gs_utils_error_convert_gio (&error);
g_task_return_error (task, error);
return;
}
}
/* remove from pending list */
if (add_to_pending_array)
gs_plugin_loader_pending_apps_remove (plugin_loader, helper);
/* some functions are really required for proper operation */
switch (action) {
case GS_PLUGIN_ACTION_DESTROY:
......@@ -3154,6 +3162,7 @@ gs_plugin_loader_process_thread_cb (GTask *task,
case GS_PLUGIN_ACTION_GET_UPDATES:
case GS_PLUGIN_ACTION_INITIALIZE:
case GS_PLUGIN_ACTION_INSTALL:
case GS_PLUGIN_ACTION_DOWNLOAD:
case GS_PLUGIN_ACTION_LAUNCH:
case GS_PLUGIN_ACTION_REFRESH:
case GS_PLUGIN_ACTION_REMOVE:
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012-2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2012-2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -186,26 +186,6 @@ typedef enum {
#define GS_PLUGIN_REFINE_FLAGS_REQUIRE_SCREENSHOTS ((guint64) 1 << 26)
typedef guint64 GsPluginRefineFlags;
/**
* GsPluginRefreshFlags:
* @GS_PLUGIN_REFRESH_FLAGS_NONE: Generate new metadata if possible
* @GS_PLUGIN_REFRESH_FLAGS_METADATA: Download new metadata
* @GS_PLUGIN_REFRESH_FLAGS_PAYLOAD: Download any pending payload
*
* The flags used for refresh. Regeneration and downloading is only
* done if the cache is older than the %cache_age.
*
* The %GS_PLUGIN_REFRESH_FLAGS_METADATA can be used to make sure
* there's enough metadata to start the application.
* The %GS_PLUGIN_REFRESH_FLAGS_PAYLOAD flag should only be used when
* the session is idle and bandwidth is unmetered as the amount of data
* and IO may be large.
**/
#define GS_PLUGIN_REFRESH_FLAGS_NONE ((guint64) 0)
#define GS_PLUGIN_REFRESH_FLAGS_METADATA ((guint64) 1 << 0)
#define GS_PLUGIN_REFRESH_FLAGS_PAYLOAD ((guint64) 1 << 1)
typedef guint64 GsPluginRefreshFlags;
/**
* GsPluginRule:
* @GS_PLUGIN_RULE_CONFLICTS: The plugin conflicts with another
......@@ -269,6 +249,7 @@ typedef enum {
* @GS_PLUGIN_ACTION_INITIALIZE: Initialize the plugin
* @GS_PLUGIN_ACTION_DESTROY: Destroy the plugin
* @GS_PLUGIN_ACTION_PURCHASE: Purchase an app
* @GS_PLUGIN_ACTION_DOWNLOAD: Download an application
*
* The plugin action.
**/
......@@ -316,6 +297,7 @@ typedef enum {
GS_PLUGIN_ACTION_INITIALIZE,
GS_PLUGIN_ACTION_DESTROY,
GS_PLUGIN_ACTION_PURCHASE,
GS_PLUGIN_ACTION_DOWNLOAD,
/*< private >*/
GS_PLUGIN_ACTION_LAST
} GsPluginAction;
......
......@@ -192,11 +192,10 @@ gboolean gs_plugin_add_installed (GsPlugin *plugin,
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Get the list of pre-downloaded, pre-checked updates, with the write lock
* held.
* Get the list of updates.
*
* NOTE: Actually downloading the updates is normally done in
* gs_plugin_refresh() when called with %GS_PLUGIN_REFRESH_FLAGS_PAYLOAD.
* NOTE: Actually downloading the updates can be done in gs_plugin_download_app()
* or in gs_plugin_update_app().
*
* Plugins are expected to add new apps using gs_app_list_add().
*
......@@ -207,27 +206,6 @@ gboolean gs_plugin_add_updates (GsPlugin *plugin,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_add_updates_pending:
* @plugin: a #GsPlugin
* @list: a #GsAppList
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Get the list of not-yet-downloaded updates, with the write lock held.
*
* NOTE: Actually downloading the updates is normally done in
* gs_plugin_refresh() when called with %GS_PLUGIN_REFRESH_FLAGS_PAYLOAD.
*
* Plugins are expected to add new apps using gs_app_list_add().
*
* Returns: %TRUE for success or if not relevant
**/
gboolean gs_plugin_add_updates_pending (GsPlugin *plugin,
GsAppList *list,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_add_distro_upgrades:
* @plugin: a #GsPlugin
......@@ -691,6 +669,51 @@ gboolean gs_plugin_update_app (GsPlugin *plugin,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_download_app:
* @plugin: a #GsPlugin
* @app: a #GsApp
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Downloads the application and any dependencies ready to be installed or
* updated.
*
* Plugins are expected to send progress notifications to the UI using
* gs_app_set_progress() using the passed in @app.
*
* All functions can block, but should sent progress notifications, e.g. using
* gs_app_set_progress() if they will take more than tens of milliseconds
* to complete.
*
* If the @app is already downloaded, do not return an error and return %TRUE.
*
* On failure the error message returned will usually only be shown on the
* console, but they can also be retrieved using gs_plugin_loader_get_events().
*
* Returns: %TRUE for success or if not relevant
**/
gboolean gs_plugin_download_app (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_download:
* @plugin: a #GsPlugin
* @apps: a #GsAppList
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Downloads a list of applications ready to be installed or updated.
*
* Returns: %TRUE for success or if not relevant
**/
gboolean gs_plugin_download (GsPlugin *plugin,
GsAppList *apps,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_app_upgrade_download:
* @plugin: a #GsPlugin
......@@ -846,21 +869,13 @@ gboolean gs_plugin_review_dismiss (GsPlugin *plugin,
* gs_plugin_refresh:
* @plugin: a #GsPlugin
* @cache_age: the acceptable cache age in seconds, or MAXUINT for "any"
* @flags: a bitfield of #GsPluginRefreshFlags, e.g. %GS_PLUGIN_REFRESH_FLAGS_METADATA
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Refreshes the state of all the plugins.
*
* The %GS_PLUGIN_REFRESH_FLAGS_METADATA flag can be used to make sure
* Refreshes the state of all the plugins. Plugins should make sure
* there's enough metadata to start the application, for example lists of
* available applications.
*
* The %GS_PLUGIN_REFRESH_FLAGS_PAYLOAD flag should only be used when
* the session is idle and bandwidth is unmetered as the amount of data
* and IO may be large.
* This is used to pre-download package updates and firmware.
*
* All functions can block, but should sent progress notifications, e.g. using
* gs_app_set_progress() if they will take more than tens of milliseconds
* to complete.
......@@ -869,7 +884,6 @@ gboolean gs_plugin_review_dismiss (GsPlugin *plugin,
**/
gboolean gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error);
......
......@@ -1744,6 +1744,8 @@ gs_plugin_action_to_function_name (GsPluginAction action)
return "gs_plugin_refine";
if (action == GS_PLUGIN_ACTION_UPDATE)
return "gs_plugin_update";
if (action == GS_PLUGIN_ACTION_DOWNLOAD)
return "gs_plugin_download";
if (action == GS_PLUGIN_ACTION_FILE_TO_APP)
return "gs_plugin_file_to_app";
if (action == GS_PLUGIN_ACTION_URL_TO_APP)
......@@ -1812,6 +1814,8 @@ gs_plugin_action_to_string (GsPluginAction action)
return "setup";
if (action == GS_PLUGIN_ACTION_INSTALL)
return "install";
if (action == GS_PLUGIN_ACTION_DOWNLOAD)
return "download";
if (action == GS_PLUGIN_ACTION_REMOVE)
return "remove";
if (action == GS_PLUGIN_ACTION_UPDATE)
......@@ -1912,6 +1916,8 @@ gs_plugin_action_from_string (const gchar *action)
return GS_PLUGIN_ACTION_SETUP;
if (g_strcmp0 (action, "install") == 0)
return GS_PLUGIN_ACTION_INSTALL;
if (g_strcmp0 (action, "download") == 0)
return GS_PLUGIN_ACTION_DOWNLOAD;
if (g_strcmp0 (action, "remove") == 0)
return GS_PLUGIN_ACTION_REMOVE;
if (g_strcmp0 (action, "update") == 0)
......
......@@ -682,7 +682,6 @@ gs_plugin_add_recent (GsPlugin *plugin,
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error)
{
......
......@@ -28,6 +28,8 @@ void
gs_plugin_initialize (GsPlugin *plugin)
{
gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "packagekit-refine");
gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_BEFORE, "icons");
}
static gboolean
......
......@@ -815,24 +815,23 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
return TRUE;
}
gboolean
gs_plugin_download_app (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error)
{
return gs_plugin_dummy_delay (plugin, app, 5100, cancellable, error);
}
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error)
{
guint delay_ms = 100;
g_autoptr(GsApp) app = gs_app_new (NULL);
/* each one takes more time */
if (flags & GS_PLUGIN_REFRESH_FLAGS_METADATA)
delay_ms += 3000;
if (flags & GS_PLUGIN_REFRESH_FLAGS_PAYLOAD)
delay_ms += 5000;
/* do delay */
return gs_plugin_dummy_delay (plugin, app, delay_ms, cancellable, error);
return gs_plugin_dummy_delay (plugin, app, 3100, cancellable, error);
}
gboolean
......
......@@ -266,16 +266,12 @@ gs_plugin_external_appstream_refresh_url (GsPlugin *plugin,
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
g_auto(GStrv) appstream_urls = NULL;
if ((flags & GS_PLUGIN_REFRESH_FLAGS_METADATA) == 0)
return TRUE;
appstream_urls = g_settings_get_strv (priv->settings,
"external-appstream-urls");
for (guint i = 0; appstream_urls[i] != NULL; ++i) {
......
......@@ -232,16 +232,11 @@ _refresh_cache (GsPlugin *plugin,
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable,
GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&priv->mutex);
/* only for update metadata */
if ((flags & GS_PLUGIN_REFRESH_FLAGS_METADATA) == 0)
return TRUE;
return _refresh_cache (plugin, cache_age, cancellable, error);
}
......
......@@ -53,7 +53,6 @@ G_DEFINE_TYPE (GsFlatpak, gs_flatpak, G_TYPE_OBJECT)
static gboolean
gs_flatpak_refresh_appstream (GsFlatpak *self, guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable, GError **error);
static gchar *
......@@ -211,7 +210,7 @@ gs_plugin_flatpak_changed_cb (GFileMonitor *monitor,
}
/* if this is a new remote, get the AppStream data */
if (!gs_flatpak_refresh_appstream (self, G_MAXUINT, 0, NULL, &error_md)) {
if (!gs_flatpak_refresh_appstream (self, G_MAXUINT, NULL, &error_md)) {
g_warning ("failed to get initial available data: %s",
error_md->message);
}
......@@ -632,7 +631,6 @@ gs_flatpak_refresh_appstream_remote (GsFlatpak *self,
static gboolean
gs_flatpak_refresh_appstream (GsFlatpak *self, guint cache_age,
GsPluginRefreshFlags flags,
GCancellable *cancellable, GError **error)
{
gboolean ret;
......@@ -1174,10 +1172,10 @@ gs_flatpak_add_updates (GsFlatpak *self, GsAppList *list,
{
g_autoptr(GPtrArray) xrefs = NULL;
/* get all the installed apps (no network I/O) */
xrefs = flatpak_installation_list_installed_refs (self->installation,
cancellable,
error);
/* get all the updatable apps and runtimes */
xrefs = flatpak_installation_list_installed_refs_for_update (self->installation,
cancellable,
error);
if (xrefs == NULL) {
gs_flatpak_error_convert (error);
return FALSE;
......@@ -1200,22 +1198,12 @@ gs_flatpak_add_updates (GsFlatpak *self, GsAppList *list,
flatpak_ref_get_name (FLATPAK_REF (xref)));
continue;
}
if (g_strcmp0 (commit, latest_commit) == 0) {
g_debug ("no downloaded update for %s",
flatpak_ref_get_name (FLATPAK_REF (xref)));
continue;
}
/* we have an update to show */
g_debug ("%s has a downloaded update %s->%s",
flatpak_ref_get_name (FLATPAK_REF (xref)),
commit, latest_commit);
app = gs_flatpak_create_installed (self, xref, &error_local);
if (app == NULL) {
g_warning ("failed to add flatpak: %s", error_local->message);
continue;
}
main_app = get_real_app_for_update (self, app, cancellable, &error_local);
if (main_app == NULL) {
g_debug ("Couldn't get the main app for updatable app extension %s: "
......@@ -1223,76 +1211,42 @@ gs_flatpak_add_updates (GsFlatpak *self, GsAppList *list,
gs_app_get_unique_id (app), error_local->message);
main_app = g_object_ref (app);
}
gs_app_set_state (main_app, AS_APP_STATE_UPDATABLE_LIVE);
gs_app_set_update_details (main_app, NULL);
gs_app_set_update_version (main_app, NULL);
gs_app_set_update_urgency (main_app, AS_URGENCY_KIND_UNKNOWN);
gs_app_set_size_download (main_app, 0);
gs_app_list_add (list, main_app);
}
/* success */
return TRUE;
}
gboolean
gs_flatpak_add_updates_pending (GsFlatpak *self, GsAppList *list,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GPtrArray) xrefs = NULL;
/* get all the updatable apps and runtimes */
xrefs = flatpak_installation_list_installed_refs_for_update (self->installation,
cancellable,
error);
if (xrefs == NULL) {
gs_flatpak_error_convert (error);
return FALSE;
}
for (guint i = 0; i < xrefs->len; i++) {
FlatpakInstalledRef *xref = g_ptr_array_index (xrefs, i);
guint64 download_size = 0;
g_autoptr(GsApp) app = NULL;
g_autoptr(GError) error_local = NULL;
g_autoptr(GsApp) main_app = NULL;
/* we have an update to show */
g_debug ("%s has update", flatpak_ref_get_name (FLATPAK_REF (xref)));
app = gs_flatpak_create_installed (self, xref, &error_local);
if (app == NULL) {
g_warning ("failed to add flatpak: %s", error_local->message);
continue;
}
main_app = get_real_app_for_update (self, app, cancellable, &error_local);
if (main_app == NULL) {
g_debug ("Couldn't get the main app for updatable app extension %s: "
"%s; adding the app itself to the pending updates list...",
gs_app_get_unique_id (app), error_local->message);
main_app = g_object_ref (app);
}
gs_app_set_state (main_app, AS_APP_STATE_UPDATABLE_LIVE);
/* already downloaded */
if (g_strcmp0 (commit, latest_commit) != 0) {
g_debug ("%s has a downloaded update %s->%s",
flatpak_ref_get_name (FLATPAK_REF (xref)),
commit, latest_commit);
gs_app_set_update_details (main_app, NULL);
gs_app_set_update_version (main_app, NULL);
gs_app_set_update_urgency (main_app, AS_URGENCY_KIND_UNKNOWN);
gs_app_set_size_download (main_app, 0);