[gnome-software: 7/9] Fix how pending apps are installed from the installed page




commit 600f85a8a8a2207af637a788e257b65faadb84de
Author: Joaquim Rocha <jrocha endlessm com>
Date:   Wed Jun 20 17:03:28 2018 +0200

    Fix how pending apps are installed from the installed page
    
    In the installed page, whenever the list of pending apps changes, the
    page will try to install any app in it. This was fine when there were
    no limited number of concurrent installations, but right now this may
    be a problem (if an app that gets installed by the page goes in the
    pending list, then this may trigger another install call from the page
    and so on...).
    
    Since the page only cares about installing the apps for when the list
    of pending apps is loaded from disk (on start up), to prevent the issue
    mentioned above these changes only install the pending apps on start up.
    It also skips calling refine on all the pending apps after start up,
    since apps are added to the pending apps list usually after being very
    recently refined (i.e. we only need to refine them on start up, so this
    patch may make things a bit faster in this regard).
    
    (Rebased from downstream Endless OS by Philip Withnall)

 src/gs-installed-page.c | 78 +++++++++++++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 28 deletions(-)
---
diff --git a/src/gs-installed-page.c b/src/gs-installed-page.c
index 1ac6a3f59..c67b9915b 100644
--- a/src/gs-installed-page.c
+++ b/src/gs-installed-page.c
@@ -62,8 +62,10 @@ typedef enum {
 
 static GParamSpec *obj_props[PROP_IS_NARROW + 1] = { NULL, };
 
-static void gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
-                                                       GsInstalledPage *self);
+static void gs_installed_page_pending_apps_refined_cb (GObject *source,
+                                                      GAsyncResult *res,
+                                                      gpointer user_data);
+static GsPluginRefineFlags gs_installed_page_get_refine_flags (GsInstalledPage *self);
 static void gs_installed_page_notify_state_changed_cb (GsApp *app,
                                                       GParamSpec *pspec,
                                                       GsInstalledPage *self);
@@ -400,6 +402,8 @@ gs_installed_page_get_installed_cb (GObject *source_object,
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object);
        g_autoptr(GError) error = NULL;
        g_autoptr(GsAppList) list = NULL;
+       g_autoptr(GsAppList) pending = gs_plugin_loader_get_pending (plugin_loader);
+       g_autoptr(GsPluginJob) plugin_job = NULL;
 
        gtk_spinner_stop (GTK_SPINNER (self->spinner_install));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_install), "view");
@@ -421,7 +425,15 @@ gs_installed_page_get_installed_cb (GObject *source_object,
                gs_installed_page_add_app (self, list, app);
        }
 out:
-       gs_installed_page_pending_apps_changed_cb (plugin_loader, self);
+       if (gs_app_list_length (pending) > 0) {
+               plugin_job = gs_plugin_job_refine_new (pending,
+                                                      gs_installed_page_get_refine_flags (self));
+               gs_plugin_loader_job_process_async (self->plugin_loader, plugin_job,
+                                                   self->cancellable,
+                                                   gs_installed_page_pending_apps_refined_cb,
+                                                   self);
+
+       }
 }
 
 static void
@@ -677,27 +689,17 @@ gs_installed_page_has_app (GsInstalledPage *self,
 }
 
 static void
-gs_installed_page_pending_apps_refined_cb (GObject *source,
-                                          GAsyncResult *res,
-                                          gpointer user_data)
+gs_installed_page_add_pending_apps (GsInstalledPage *self,
+                                   GsAppList *list,
+                                   gboolean should_install)
 {
-       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
-       GsInstalledPage *self = GS_INSTALLED_PAGE (user_data);
        guint pending_apps_count = 0;
-       g_autoptr(GError) error = NULL;
-       g_autoptr(GsAppList) list = gs_plugin_loader_job_process_finish (plugin_loader,
-                                                                        res,
-                                                                        &error);
-       if (list == NULL) {
-               if (!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
-                       g_warning ("failed to refine pending apps: %s", error->message);
-               return;
-       }
 
        for (guint i = 0; i < gs_app_list_length (list); ++i) {
                GsApp *app = gs_app_list_index (list, i);
-               if (gs_app_is_installed (app))
+               if (gs_app_is_installed (app)) {
                        continue;
+               }
 
                /* never show OS upgrades, we handle the scheduling and
                 * cancellation in GsUpgradeBanner */
@@ -707,9 +709,10 @@ gs_installed_page_pending_apps_refined_cb (GObject *source,
                if (gs_app_get_state (app) == GS_APP_STATE_AVAILABLE)
                        gs_app_set_state (app, GS_APP_STATE_QUEUED_FOR_INSTALL);
 
-               if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL &&
-                   gs_plugin_loader_get_network_available (plugin_loader) &&
-                   !gs_plugin_loader_get_network_metered (plugin_loader))
+               if (should_install &&
+                   gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL &&
+                   gs_plugin_loader_get_network_available (self->plugin_loader) &&
+                   !gs_plugin_loader_get_network_metered (self->plugin_loader))
                        gs_page_install_app (GS_PAGE (self), app,
                                             GS_SHELL_INTERACTION_FULL,
                                             gs_app_get_cancellable (app));
@@ -726,18 +729,37 @@ gs_installed_page_pending_apps_refined_cb (GObject *source,
        }
 }
 
+static void
+gs_installed_page_pending_apps_refined_cb (GObject *source,
+                                          GAsyncResult *res,
+                                          gpointer user_data)
+{
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+       GsInstalledPage *self = GS_INSTALLED_PAGE (user_data);
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GsAppList) list = gs_plugin_loader_job_process_finish (plugin_loader,
+                                                                        res,
+                                                                        &error);
+       if (list == NULL) {
+               if (!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
+                       g_warning ("failed to refine pending apps: %s", error->message);
+               return;
+       }
+
+       /* we add the pending apps and install them because this is called after we
+        * populate the page, and there may be pending apps coming from the saved list
+        * (i.e. after loading the saved pending apps from the disk) */
+       gs_installed_page_add_pending_apps (self, list, TRUE);
+}
+
 static void
 gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
                                            GsInstalledPage *self)
 {
        g_autoptr(GsAppList) pending = gs_plugin_loader_get_pending (plugin_loader);
-       g_autoptr(GsPluginJob) plugin_job = gs_plugin_job_refine_new (pending,
-                                                                     gs_installed_page_get_refine_flags 
(self));
-       gs_plugin_job_set_interactive (plugin_job, FALSE);
-       gs_plugin_loader_job_process_async (self->plugin_loader, plugin_job,
-                                           self->cancellable,
-                                           gs_installed_page_pending_apps_refined_cb,
-                                           self);
+       /* we don't call install every time the pending apps list changes because
+        * it may be queued in the plugin loader */
+       gs_installed_page_add_pending_apps (self, pending, FALSE);
 }
 
 static gboolean


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