[gnome-software] Use the new 'Offline' interface to do offline updates



commit 72d7b3faf6f4cd6fea1eae57e637b1948291c99f
Author: Richard Hughes <richard hughsie com>
Date:   Thu Sep 4 14:38:26 2014 +0100

    Use the new 'Offline' interface to do offline updates
    
    This removes a ton of duplicated and hacky pkexec code.

 configure.ac                            |    2 +-
 src/gs-application.c                    |    8 +-
 src/gs-offline-updates.c                |  243 +++----------------------------
 src/gs-offline-updates.h                |    9 -
 src/gs-shell-updates.c                  |   21 ++-
 src/gs-update-dialog.c                  |    4 +-
 src/gs-update-monitor.c                 |   24 ++--
 src/plugins/gs-plugin-systemd-updates.c |   45 ++----
 8 files changed, 81 insertions(+), 275 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 99bf0c5..d1faf30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,7 +60,7 @@ dnl ---------------------------------------------------------------------------
 dnl - Check library dependencies
 dnl ---------------------------------------------------------------------------
 PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.13.1 gio-unix-2.0)
-PKG_CHECK_MODULES(PACKAGEKIT, packagekit-glib2 >= 0.8.12)
+PKG_CHECK_MODULES(PACKAGEKIT, packagekit-glib2 >= 1.0.0)
 PKG_CHECK_MODULES(APPSTREAM, appstream-glib >= 0.2.4)
 PKG_CHECK_MODULES(SQLITE, sqlite3)
 PKG_CHECK_MODULES(SOUP, libsoup-2.4)
diff --git a/src/gs-application.c b/src/gs-application.c
index eb4f008..e052bd6 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -28,6 +28,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gio/gdesktopappinfo.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gs-dbus-helper.h"
 #include "gs-box.h"
@@ -432,7 +433,12 @@ clear_offline_updates (GSimpleAction *action,
                       GVariant      *parameter,
                       gpointer       data)
 {
-       gs_offline_updates_clear_status ();
+       GError *error = NULL;
+       if (!pk_offline_clear_results (NULL, &error)) {
+               g_warning ("Failure clearing offline update message: %s",
+                          error->message);
+               g_error_free (error);
+       }
 }
 
 static void
diff --git a/src/gs-offline-updates.c b/src/gs-offline-updates.c
index 9fdcd56..9004327 100644
--- a/src/gs-offline-updates.c
+++ b/src/gs-offline-updates.c
@@ -27,210 +27,6 @@
 #include "gs-offline-updates.h"
 #include "gs-utils.h"
 
-static void
-child_exit_cb (GPid pid, gint status, gpointer user_data)
-{
-       GCallback child_exited = user_data;
-
-       g_spawn_close_pid (pid);
-
-       if (child_exited != NULL)
-               child_exited ();
-}
-
-static gboolean
-gs_spawn_pkexec (const gchar *command, const gchar *parameter, GCallback child_exited, GError **error)
-{
-       GPid pid;
-       const gchar *argv[4];
-       gboolean ret;
-
-       argv[0] = "pkexec";
-       argv[1] = command;
-       argv[2] = parameter;
-       argv[3] = NULL;
-       g_debug ("calling %s %s %s",
-                argv[0], argv[1], argv[2] != NULL ? argv[2] : "");
-       ret = g_spawn_async (NULL, (gchar**)argv, NULL,
-                            G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
-                            NULL, NULL, &pid, error);
-       if (!ret)
-               return FALSE;
-
-       g_child_watch_add (pid, child_exit_cb, child_exited);
-       return TRUE;
-}
-
-void
-gs_offline_updates_clear_status (void)
-{
-       gboolean ret;
-       GError *error = NULL;
-
-       ret = gs_spawn_pkexec (LIBEXECDIR "/pk-clear-offline-update", NULL, NULL, &error);
-       if (!ret) {
-               g_warning ("Failure clearing offline update message: %s",
-                          error->message);
-               g_error_free (error);
-       }
-}
-
-void
-gs_offline_updates_trigger (GCallback child_exited)
-{
-       gboolean ret;
-       GError *error = NULL;
-
-       ret = gs_spawn_pkexec (LIBEXECDIR "/pk-trigger-offline-update", NULL, child_exited, &error);
-       if (!ret) {
-               g_warning ("Failure triggering offline update: %s",
-                          error->message);
-               g_error_free (error);
-       }
-}
-
-void
-gs_offline_updates_cancel (void)
-{
-       gboolean ret;
-       GError *error = NULL;
-
-       ret = gs_spawn_pkexec (LIBEXECDIR "/pk-trigger-offline-update",
-                              "--cancel", NULL, &error);
-       if (!ret) {
-               g_warning ("Failure cancelling offline update: %s",
-                          error->message);
-               g_error_free (error);
-       }
-}
-
-#define PK_OFFLINE_UPDATE_RESULTS_GROUP                "PackageKit Offline Update Results"
-#define PK_OFFLINE_UPDATE_RESULTS_FILENAME     "/var/lib/PackageKit/offline-update-competed"
-
-gboolean
-gs_offline_updates_results_available (void)
-{
-       return g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS);
-}
-
-gboolean
-gs_offline_updates_get_time_completed (guint64 *time_completed)
-{
-       GFile *file;
-       GFileInfo *info;
-       gboolean result = FALSE;
-
-       file = g_file_new_for_path (PK_OFFLINE_UPDATE_RESULTS_FILENAME);
-       info = g_file_query_info (file,
-                                 G_FILE_ATTRIBUTE_TIME_MODIFIED,
-                                 G_FILE_QUERY_INFO_NONE,
-                                 NULL,
-                                 NULL);
-       if (info != NULL) {
-               *time_completed = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
-               result = TRUE;
-               g_object_unref (info);
-       }
-
-       g_object_unref (file);
-
-       return result;
-}
-
-gboolean
-gs_offline_updates_get_status (gboolean  *success,
-                              guint     *num_packages,
-                              gchar    **error_code,
-                              gchar    **error_details)
-{
-       GKeyFile *key_file = NULL;
-       gchar *packages = NULL;
-       gchar *code = NULL;
-       gchar *details = NULL;
-       gboolean result = FALSE;
-       gboolean ret;
-       GError *error = NULL;
-       gint i;
-
-       g_debug ("get offline update status");
-
-       *success = FALSE;
-       *num_packages = 0;
-       if (error_code)
-               *error_code = 0;
-       if (error_details)
-               *error_details = NULL;
-
-       if (!gs_offline_updates_results_available ())
-               goto out;
-
-       key_file = g_key_file_new ();
-       ret = g_key_file_load_from_file (key_file,
-                                        PK_OFFLINE_UPDATE_RESULTS_FILENAME,
-                                        G_KEY_FILE_NONE,
-                                        &error);
-       if (!ret) {
-               g_warning ("failed to open %s: %s",
-                          PK_OFFLINE_UPDATE_RESULTS_FILENAME,
-                          error->message);
-               g_error_free (error);
-               goto out;
-       }
-
-       *success = g_key_file_get_boolean (key_file,
-                                          PK_OFFLINE_UPDATE_RESULTS_GROUP,
-                                          "Success",
-                                          NULL);
-
-       if (*success) {
-               packages = g_key_file_get_string (key_file,
-                                                 PK_OFFLINE_UPDATE_RESULTS_GROUP,
-                                                 "Packages",
-                                                 NULL);
-
-               if (packages == NULL) {
-                       g_warning ("No 'Packages' in %s",
-                                  PK_OFFLINE_UPDATE_RESULTS_FILENAME);
-                       goto out;
-               }
-
-               for (i = 0; packages[i] != '\0'; i++) {
-                       if (packages[i] == ',')
-                               (*num_packages)++;
-               }
-
-       } else {
-
-               code = g_key_file_get_string (key_file,
-                                             PK_OFFLINE_UPDATE_RESULTS_GROUP,
-                                             "ErrorCode",
-                                             NULL);
-               details = g_key_file_get_string (key_file,
-                                                PK_OFFLINE_UPDATE_RESULTS_GROUP,
-                                                "ErrorDetails",
-                                                NULL);
-       }
-
-       result = TRUE;
-
-out:
-       g_debug ("success %d, packages %s, error %s %s",
-                *success, packages, code, details);
-       if (error_code)
-               *error_code = code;
-       else
-               g_free (code);
-       if (error_details)
-               *error_details = details;
-       else
-               g_free (details);
-       g_free (packages);
-       if (key_file != NULL)
-               g_key_file_free (key_file);
-
-       return result;
-}
-
 void
 gs_offline_updates_show_error (void)
 {
@@ -238,22 +34,25 @@ gs_offline_updates_show_error (void)
        gboolean show_geeky = FALSE;
        GString *msg;
        GtkWidget *dialog;
-       gboolean success;
-       guint num_packages;
-       gchar *error_code;
-       gchar *error_details;
-       PkErrorEnum error_enum = PK_ERROR_ENUM_UNKNOWN;
+       GError *error = NULL;
+       PkResults *results = NULL;
+       PkError *pk_error = NULL;
 
-       if (!gs_offline_updates_get_status (&success, &num_packages, &error_code, &error_details))
-               return;
+       results = pk_offline_get_results (NULL);
+       if (results == NULL)
+               goto out;
+       pk_error = pk_results_get_error_code (results);
+       if (pk_error == NULL)
+               goto out;
 
-       if (error_code != NULL)
-               error_enum = pk_error_enum_from_string (error_code);
+       /* can this happen in reality? */
+       if (pk_results_get_exit_code (results) == PK_EXIT_ENUM_SUCCESS)
+               goto out;
 
        /* TRANSLATORS: this is when the offline update failed */
        title = _("Failed To Update");
        msg = g_string_new ("");
-       switch (error_enum) {
+       switch (pk_error_get_code (pk_error)) {
        case PK_ERROR_ENUM_UNFINISHED_TRANSACTION:
                /* TRANSLATORS: the transaction could not be completed
                 * as a previous transaction was unfinished */
@@ -324,7 +123,7 @@ gs_offline_updates_show_error (void)
                                         * package manager no mortal is supposed to understand,
                                         * but google might know what they mean */
                                        _("Detailed errors from the package manager follow:"),
-                                       error_details);
+                                       pk_error_get_details (pk_error));
        }
        dialog = gtk_message_dialog_new (NULL,
                                         0,
@@ -338,11 +137,17 @@ gs_offline_updates_show_error (void)
                                  dialog);
        gtk_widget_show (dialog);
 
-       gs_offline_updates_clear_status ();
+       if (!pk_offline_clear_results (NULL, &error)) {
+               g_warning ("Failure clearing offline update message: %s",
+                          error->message);
+               g_error_free (error);
+       }
        g_string_free (msg, TRUE);
-
-       g_free (error_code);
-       g_free (error_details);
+out:
+       if (pk_error != NULL)
+               g_object_unref (pk_error);
+       if (results != NULL)
+               g_object_unref (results);
 }
 
 /* vim: set noexpandtab: */
diff --git a/src/gs-offline-updates.h b/src/gs-offline-updates.h
index 6059929..be75c2e 100644
--- a/src/gs-offline-updates.h
+++ b/src/gs-offline-updates.h
@@ -26,15 +26,6 @@
 
 G_BEGIN_DECLS
 
-void     gs_offline_updates_trigger            (GCallback  child_exited);
-void     gs_offline_updates_cancel             (void);
-void     gs_offline_updates_clear_status       (void);
-gboolean gs_offline_updates_results_available  (void);
-gboolean gs_offline_updates_get_time_completed (guint64   *time_completed);
-gboolean gs_offline_updates_get_status         (gboolean  *success,
-                                                guint     *num_packages,
-                                                gchar    **error_code,
-                                                gchar    **error_details);
 void     gs_offline_updates_show_error         (void);
 
 
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index ed3fdfb..5d7bb31 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gs-shell.h"
 #include "gs-shell-updates.h"
@@ -35,9 +36,6 @@
 
 #include <gdesktop-enums.h>
 #include <langinfo.h>
-/* this isn't ideal, as PK should be abstracted away in a plugin, but
- * GNetworkMonitor doesn't provide us with a connection type */
-#include <packagekit-glib2/packagekit.h>
 
 static void    gs_shell_updates_finalize       (GObject        *object);
 
@@ -836,16 +834,27 @@ gs_shell_updates_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
 }
 
 static void
-offline_updates_triggered_cb (void)
+gs_offline_updates_cancel (void)
 {
-       gs_reboot (gs_offline_updates_cancel);
+       GError *error = NULL;
+       if (!pk_offline_cancel (NULL, &error)) {
+               g_warning ("failed to cancel the offline update: %s", error->message);
+               g_error_free (error);
+               return;
+       }
 }
 
 static void
 gs_shell_updates_button_update_all_cb (GtkButton      *button,
                                       GsShellUpdates *updates)
 {
-       gs_offline_updates_trigger (offline_updates_triggered_cb);
+       GError *error = NULL;
+       if (!pk_offline_trigger (PK_OFFLINE_ACTION_REBOOT, NULL, &error)) {
+               g_warning ("failed to trigger an offline update: %s", error->message);
+               g_error_free (error);
+               return;
+       }
+       gs_reboot (gs_offline_updates_cancel);
 }
 
 /**
diff --git a/src/gs-update-dialog.c b/src/gs-update-dialog.c
index 1aa8c17..1e6def0 100644
--- a/src/gs-update-dialog.c
+++ b/src/gs-update-dialog.c
@@ -23,6 +23,7 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gs-update-dialog.h"
 #include "gs-app-row.h"
@@ -166,7 +167,8 @@ gs_update_dialog_show_installed_updates (GsUpdateDialog *dialog, GList *installe
        /* TRANSLATORS: this is the title of the installed updates dialog window */
        gtk_window_set_title (GTK_WINDOW (dialog), _("Installed Updates"));
 
-       if (gs_offline_updates_get_time_completed (&time_updates_installed)) {
+       time_updates_installed = pk_offline_get_results_mtime (NULL);
+       if (time_updates_installed > 0) {
                GDateTime *date;
                GtkWidget *header;
                gchar *date_str;
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
index e85de0d..379a137 100644
--- a/src/gs-update-monitor.c
+++ b/src/gs-update-monitor.c
@@ -132,22 +132,24 @@ show_installed_updates_notification (GsUpdateMonitor *monitor)
 {
        const gchar *message;
        const gchar *title;
-       gboolean success;
-       guint num_packages = 1;
        GNotification *notification;
        GIcon *icon;
+       PkResults *results;
 
-       if (!gs_offline_updates_get_status (&success, &num_packages, NULL, NULL))
+       results = pk_offline_get_results (NULL);
+       if (results == NULL)
                return;
-
-       if (success) {
+       if (pk_results_get_exit_code (results) == PK_EXIT_ENUM_SUCCESS) {
+               GPtrArray *packages;
+               packages = pk_results_get_package_array (results);
                title = ngettext ("Software Update Installed",
                                  "Software Updates Installed",
-                                 num_packages);
+                                 packages->len);
                /* TRANSLATORS: message when we've done offline updates */
                message = ngettext ("An important OS update has been installed.",
                                    "Important OS updates have been installed.",
-                                   num_packages);
+                                   packages->len);
+               g_ptr_array_unref (packages);
        } else {
 
                title = _("Software Updates Failed");
@@ -160,7 +162,7 @@ show_installed_updates_notification (GsUpdateMonitor *monitor)
        icon = g_themed_icon_new ("gnome-software-symbolic");
        g_notification_set_icon (notification, icon);
        g_object_unref (icon);
-       if (success)
+       if (pk_results_get_exit_code (results) == PK_EXIT_ENUM_SUCCESS)
                g_notification_add_button_with_target (notification, _("Review"), "app.set-mode", "s", 
"updated");
        else
                g_notification_add_button (notification, _("Show Details"), "app.show-offline-update-error");
@@ -168,6 +170,7 @@ show_installed_updates_notification (GsUpdateMonitor *monitor)
 
        g_application_send_notification (monitor->application, "offline-updates", notification);
        g_object_unref (notification);
+       g_object_unref (results);
 }
 
 static gboolean
@@ -180,7 +183,8 @@ check_offline_update_cb (gpointer user_data)
        g_settings_get (monitor->settings,
                        "install-timestamp", "x", &time_last_notified);
 
-       if (gs_offline_updates_get_time_completed (&time_update_completed)) {
+       time_update_completed = pk_offline_get_results_mtime (NULL);
+       if (time_update_completed > 0) {
                if (time_last_notified < time_update_completed)
                        show_installed_updates_notification (monitor);
 
@@ -603,7 +607,7 @@ gs_update_monitor_class_init (GsUpdateMonitorClass *klass)
 static void
 remove_stale_notifications (GsUpdateMonitor *monitor)
 {
-       if (gs_offline_updates_results_available ()) {
+       if (pk_offline_get_results_mtime (NULL) > 0) {
                g_debug ("Withdrawing stale notifications");
 
                g_application_withdraw_notification (monitor->application,
diff --git a/src/plugins/gs-plugin-systemd-updates.c b/src/plugins/gs-plugin-systemd-updates.c
index 31dd1a8..ad23dd6 100644
--- a/src/plugins/gs-plugin-systemd-updates.c
+++ b/src/plugins/gs-plugin-systemd-updates.c
@@ -41,8 +41,6 @@ gs_plugin_get_name (void)
        return "systemd-updates";
 }
 
-#define PK_PREPARED_UPDATE_FN  "/var/lib/PackageKit/prepared-update"
-
 /**
  * gs_plugin_initialize:
  */
@@ -81,24 +79,13 @@ gs_plugin_systemd_updates_changed_cb (GFileMonitor *monitor,
 static gboolean
 gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 {
-       GFile *file;
-       gboolean ret = TRUE;
-
-       file = g_file_new_for_path (PK_PREPARED_UPDATE_FN);
-       plugin->priv->monitor = g_file_monitor_file (file,
-                                                    G_FILE_MONITOR_NONE,
-                                                    cancellable,
-                                                    error);
-       if (plugin->priv->monitor == NULL) {
-               ret = FALSE;
-               goto out;
-       }
+       plugin->priv->monitor = pk_offline_get_prepared_monitor (cancellable, error);
+       if (plugin->priv->monitor == NULL)
+               return FALSE;
        g_signal_connect (plugin->priv->monitor, "changed",
                          G_CALLBACK (gs_plugin_systemd_updates_changed_cb),
                          plugin);
-out:
-       g_object_unref (file);
-       return ret;
+       return TRUE;
 }
 
 /**
@@ -110,11 +97,11 @@ gs_plugin_add_updates (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
+       GError *error_local = NULL;
        GsApp *app;
        gboolean ret;
        gchar **package_ids = NULL;
        gchar **split;
-       gchar *data = NULL;
        guint i;
 
        /* watch the file in case it comes or goes */
@@ -125,19 +112,22 @@ gs_plugin_add_updates (GsPlugin *plugin,
                        goto out;
        }
 
-       /* does the file exist ? */
-       if (!g_file_test (PK_PREPARED_UPDATE_FN, G_FILE_TEST_EXISTS)) {
-               ret = TRUE;
+       /* get the id's if the file exists */
+       package_ids = pk_offline_get_prepared_ids (&error_local);
+       if (package_ids == NULL) {
+               if (g_error_matches (error_local,
+                                    PK_OFFLINE_ERROR,
+                                    PK_OFFLINE_ERROR_NO_DATA)) {
+                       g_error_free (error_local);
+                       ret = TRUE;
+               } else {
+                       g_propagate_error (error, error_local);
+                       ret = FALSE;
+               }
                goto out;
        }
 
-       /* get the list of packages to update */
-       ret = g_file_get_contents (PK_PREPARED_UPDATE_FN, &data, NULL, error);
-       if (!ret)
-               goto out;
-
        /* add them to the new array */
-       package_ids = g_strsplit (data, "\n", -1);
        for (i = 0; package_ids[i] != NULL; i++) {
                app = gs_app_new (NULL);
                gs_app_set_management_plugin (app, "PackageKit");
@@ -151,7 +141,6 @@ gs_plugin_add_updates (GsPlugin *plugin,
                g_strfreev (split);
        }
 out:
-       g_free (data);
        g_strfreev (package_ids);
        return ret;
 }


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