[gnome-software] Run the distro upgrade download as a background restartable task



commit 48987cb5bb6b85dab24bfb497aa4bc76675dd964
Author: Richard Hughes <richard hughsie com>
Date:   Fri Apr 22 09:44:52 2016 +0100

    Run the distro upgrade download as a background restartable task
    
    This splits out the PackageKit upgrade action as a new plugin so that we can
    set the ONLY_DOWNLOAD flag specifically for this PkTask.
    Trying to share the PkTask in pk-plugin-packagekit.c was impossible as doing
    gs_plugin_app_upgrade_download() -> gs_plugin_app_install() meant we retried
    the download without ONLY_DOWNLOAD set, meaning we tried to do it live.
    
    This also effectively reverts d8473ce45d6725dcc3634b681d0dcb091865ab8a.

 src/plugins/Makefile.am                    |    9 ++
 src/plugins/gs-plugin-packagekit-upgrade.c |  133 ++++++++++++++++++++++++++++
 src/plugins/gs-plugin-packagekit.c         |   85 +-----------------
 3 files changed, 143 insertions(+), 84 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 73922d7..46335da 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -48,6 +48,7 @@ plugin_LTLIBRARIES +=                                 \
        libgs_plugin_packagekit-origin.la               \
        libgs_plugin_packagekit-proxy.la                \
        libgs_plugin_packagekit-history.la              \
+       libgs_plugin_packagekit-upgrade.la              \
        libgs_plugin_packagekit.la
 endif
 
@@ -254,6 +255,14 @@ libgs_plugin_packagekit_history_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_packagekit_history_la_LDFLAGS = -module -avoid-version
 libgs_plugin_packagekit_history_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 
+libgs_plugin_packagekit_upgrade_la_SOURCES =           \
+       gs-plugin-packagekit-upgrade.c                  \
+       packagekit-common.c                             \
+       packagekit-common.h
+libgs_plugin_packagekit_upgrade_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_packagekit_upgrade_la_LDFLAGS = -module -avoid-version
+libgs_plugin_packagekit_upgrade_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
 libgs_plugin_packagekit_offline_la_SOURCES = gs-plugin-packagekit-offline.c
 libgs_plugin_packagekit_offline_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_packagekit_offline_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/gs-plugin-packagekit-upgrade.c b/src/plugins/gs-plugin-packagekit-upgrade.c
new file mode 100644
index 0000000..6d231c5
--- /dev/null
+++ b/src/plugins/gs-plugin-packagekit-upgrade.c
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2016 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#define I_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
+#include <packagekit-glib2/packagekit.h>
+
+#include <gs-plugin.h>
+
+#include "packagekit-common.h"
+
+struct GsPluginData {
+       PkTask                  *task;
+};
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+       priv->task = pk_task_new ();
+       pk_task_set_only_download (priv->task, TRUE);
+       pk_client_set_background (PK_CLIENT (priv->task), TRUE);
+       pk_client_set_cache_age (PK_CLIENT (priv->task), G_MAXUINT);
+       pk_client_set_interactive (PK_CLIENT (priv->task), FALSE);
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       g_object_unref (priv->task);
+}
+
+typedef struct {
+       GsApp           *app;
+       GsPlugin        *plugin;
+} ProgressData;
+
+/**
+ * gs_plugin_packagekit_progress_cb:
+ **/
+static void
+gs_plugin_packagekit_progress_cb (PkProgress *progress,
+                                 PkProgressType type,
+                                 gpointer user_data)
+{
+       ProgressData *data = (ProgressData *) user_data;
+       GsPlugin *plugin = data->plugin;
+       if (type == PK_PROGRESS_TYPE_STATUS) {
+               GsPluginStatus plugin_status;
+               PkStatusEnum status = pk_progress_get_status (progress);
+               plugin_status = packagekit_status_enum_to_plugin_status (status);
+               if (plugin_status != GS_PLUGIN_STATUS_UNKNOWN)
+                       gs_plugin_status_update (plugin, NULL, plugin_status);
+       } else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+               gint percentage = pk_progress_get_percentage (progress);
+               if (percentage >= 0 && percentage <= 100)
+                       gs_app_set_progress (data->app, percentage);
+       }
+}
+
+/**
+ * gs_plugin_app_upgrade_download:
+ */
+gboolean
+gs_plugin_app_upgrade_download (GsPlugin *plugin,
+                               GsApp *app,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       ProgressData data;
+       g_autoptr(PkResults) results = NULL;
+
+       /* only process this app if was created by this plugin */
+       if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0)
+               return TRUE;
+
+       data.app = app;
+       data.plugin = plugin;
+
+       /* check is distro-upgrade */
+       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "app %s is not a distro upgrade",
+                            gs_app_get_id (app));
+               return FALSE;
+       }
+
+       /* ask PK to download enough packages to upgrade the system */
+       gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+       results = pk_task_upgrade_system_sync (priv->task,
+                                              gs_app_get_version (app),
+                                              PK_UPGRADE_KIND_ENUM_COMPLETE,
+                                              cancellable,
+                                              gs_plugin_packagekit_progress_cb, &data,
+                                              error);
+       if (!gs_plugin_packagekit_results_valid (results, error)) {
+               gs_app_set_state_recover (app);
+               return FALSE;
+       }
+
+       /* state is known */
+       gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
+       return TRUE;
+}
diff --git a/src/plugins/gs-plugin-packagekit.c b/src/plugins/gs-plugin-packagekit.c
index bcbe5ff..495eb89 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -50,6 +50,7 @@ gs_plugin_initialize (GsPlugin *plugin)
 {
        GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
        priv->task = pk_task_new ();
+       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
        pk_client_set_interactive (PK_CLIENT (priv->task), FALSE);
        pk_client_set_cache_age (PK_CLIENT (priv->task), G_MAXUINT);
 }
@@ -128,9 +129,6 @@ gs_plugin_add_installed (GsPlugin *plugin,
        /* update UI as this might take some time */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
                                         PK_FILTER_ENUM_NEWEST,
@@ -175,9 +173,6 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
                                          "packagekit::add-sources-related");
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
@@ -238,9 +233,6 @@ gs_plugin_add_sources (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* ask PK for the repo details */
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_SOURCE,
                                         PK_FILTER_ENUM_NOT_SUPPORTED,
@@ -297,9 +289,6 @@ gs_plugin_app_source_enable (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_enable (PK_CLIENT (priv->task),
@@ -341,9 +330,6 @@ gs_plugin_app_install (GsPlugin *plugin,
                       gs_plugin_get_name (plugin)) != 0)
                return TRUE;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* we enable the repo */
        if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) {
 
@@ -511,9 +497,6 @@ gs_plugin_app_source_disable (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_enable (PK_CLIENT (priv->task),
@@ -545,9 +528,6 @@ gs_plugin_app_source_remove (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_remove (PK_CLIENT (priv->task),
@@ -624,9 +604,6 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return FALSE;
        }
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do the action */
        gs_app_set_state (app, AS_APP_STATE_REMOVING);
        results = pk_task_remove_packages_sync (priv->task,
@@ -650,60 +627,6 @@ gs_plugin_app_remove (GsPlugin *plugin,
 }
 
 /**
- * gs_plugin_app_upgrade_download:
- */
-gboolean
-gs_plugin_app_upgrade_download (GsPlugin *plugin,
-                               GsApp *app,
-                               GCancellable *cancellable,
-                               GError **error)
-{
-       GsPluginData *priv = gs_plugin_get_data (plugin);
-       ProgressData data;
-       g_autoptr(PkResults) results = NULL;
-
-       /* only process this app if was created by this plugin */
-       if (g_strcmp0 (gs_app_get_management_plugin (app),
-                      gs_plugin_get_name (plugin)) != 0)
-               return TRUE;
-
-       data.app = app;
-       data.plugin = plugin;
-       data.ptask = NULL;
-
-       /* check is distro-upgrade */
-       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "app %s is not a distro upgrade",
-                            gs_app_get_id (app));
-               return FALSE;
-       }
-
-       /* low priority background operation */
-       pk_client_set_background (PK_CLIENT (priv->task), TRUE);
-
-       /* ask PK to download enough packages to upgrade the system */
-       gs_app_set_state (app, AS_APP_STATE_INSTALLING);
-       results = pk_client_upgrade_system (PK_CLIENT (priv->task),
-                                           pk_bitfield_from_enums (PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD, 
-1),
-                                           gs_app_get_version (app),
-                                           PK_UPGRADE_KIND_ENUM_COMPLETE,
-                                           cancellable,
-                                           gs_plugin_packagekit_progress_cb, &data,
-                                           error);
-       if (!gs_plugin_packagekit_results_valid (results, error)) {
-               gs_app_set_state_recover (app);
-               return FALSE;
-       }
-
-       /* state is known */
-       gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
-       return TRUE;
-}
-
-/**
  * gs_plugin_add_search_files:
  */
 gboolean
@@ -722,9 +645,6 @@ gs_plugin_add_search_files (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST,
@@ -762,9 +682,6 @@ gs_plugin_add_search_what_provides (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST,


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