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



commit d4305150776b3d610e6368865cbc1a15e6ff5f31
Author: Richard Hughes <richard hughsie com>
Date:   Fri Apr 22 09:54:19 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 commit b67a8e0456ff078d82e1bceb59011d8daead24f9.

 src/plugins/Makefile.am                    |    9 ++
 src/plugins/gs-plugin-packagekit-upgrade.c |  141 ++++++++++++++++++++++++++++
 src/plugins/gs-plugin-packagekit.c         |   83 +----------------
 3 files changed, 151 insertions(+), 82 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index ad4112a..a256cec 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
 
@@ -215,6 +216,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..b3d1b5d
--- /dev/null
+++ b/src/plugins/gs-plugin-packagekit-upgrade.c
@@ -0,0 +1,141 @@
+/* -*- 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 GsPluginPrivate {
+       PkTask                  *task;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+       return "packagekit-upgrade";
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       /* create private area */
+       plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+       plugin->priv->task = pk_task_new ();
+       pk_task_set_only_download (plugin->priv->task, TRUE);
+       pk_client_set_background (PK_CLIENT (plugin->priv->task), TRUE);
+       pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT);
+       pk_client_set_interactive (PK_CLIENT (plugin->priv->task), FALSE);
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+       g_object_unref (plugin->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_plugin_progress_update (plugin, data->app, percentage);
+       }
+}
+
+/**
+ * gs_plugin_app_upgrade_download:
+ */
+gboolean
+gs_plugin_app_upgrade_download (GsPlugin *plugin,
+                               GsApp *app,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+       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 (plugin->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 14b53e1..189e1f1 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -60,6 +60,7 @@ gs_plugin_initialize (GsPlugin *plugin)
        /* create private area */
        plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
        plugin->priv->task = pk_task_new ();
+       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
        pk_client_set_interactive (PK_CLIENT (plugin->priv->task), FALSE);
        pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT);
 }
@@ -139,9 +140,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 (plugin->priv->task), FALSE);
-
        /* do sync call */
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
                                         PK_FILTER_ENUM_NEWEST,
@@ -185,9 +183,6 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        ptask = as_profile_start_literal (plugin->profile, "packagekit::add-sources-related");
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
                                         PK_FILTER_ENUM_NEWEST,
@@ -246,9 +241,6 @@ gs_plugin_add_sources (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* ask PK for the repo details */
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_SOURCE,
                                         PK_FILTER_ENUM_NOT_SUPPORTED,
@@ -304,9 +296,6 @@ gs_plugin_app_source_enable (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_enable (PK_CLIENT (plugin->priv->task),
@@ -346,9 +335,6 @@ gs_plugin_app_install (GsPlugin *plugin,
        if (g_strcmp0 (gs_app_get_management_plugin (app), plugin->name) != 0)
                return TRUE;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* we enable the repo */
        if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) {
 
@@ -515,9 +501,6 @@ gs_plugin_app_source_disable (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_enable (PK_CLIENT (plugin->priv->task),
@@ -548,9 +531,6 @@ gs_plugin_app_source_remove (GsPlugin *plugin,
        data.plugin = plugin;
        data.ptask = NULL;
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_remove (PK_CLIENT (plugin->priv->task),
@@ -625,9 +605,6 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return FALSE;
        }
 
-       /* high priority foreground operation */
-       pk_client_set_background (PK_CLIENT (plugin->priv->task), FALSE);
-
        /* do the action */
        gs_app_set_state (app, AS_APP_STATE_REMOVING);
        results = pk_task_remove_packages_sync (plugin->priv->task,
@@ -651,58 +628,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)
-{
-       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), plugin->name) != 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 (plugin->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 (plugin->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
@@ -720,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 (plugin->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,
@@ -759,9 +681,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 (plugin->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]