[gnome-software] Update all related applications on a proxy application



commit 390a1f94fc7bbd8586051f00165357d4833451f1
Author: Richard Hughes <richard hughsie com>
Date:   Wed Dec 14 11:07:17 2016 +0000

    Update all related applications on a proxy application
    
    A proxy application is an application that operates on the behalf of other
    applications. Is is designed so that we can have a virtual application that can
    update one or more applications at the same time.
    
    A good example of the proxy app feature in practice is the "OS Updates" item
    seen on PackageKit-based distros for when packages need updating that have no
    matching AppStream entry.
    
    This also updates the systemd-updates plugin to use the new plugin loader
    feature which makes the code easier to understand and the update process less
    magic.

 src/gs-plugin-loader.c                  |   55 ++++++++++++++++++------------
 src/gs-plugin-vfuncs.h                  |    4 ++
 src/plugins/gs-plugin-systemd-updates.c |   49 +++++++--------------------
 3 files changed, 50 insertions(+), 58 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 466e993..c47fa0a 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -4384,29 +4384,40 @@ gs_plugin_loader_update_thread_cb (GTask *task,
 
                /* for each app */
                for (j = 0; j < gs_app_list_length (job->list); j++) {
-                       GsApp *app = gs_app_list_index (job->list, j);
-                       g_autoptr(AsProfileTask) ptask = NULL;
-                       g_autoptr(GError) error_local = NULL;
+                       GsApp *app_tmp = gs_app_list_index (job->list, j);
+                       g_autoptr(GPtrArray) apps = NULL;
 
-                       g_set_object (&job->app, app);
-                       ptask = as_profile_start (priv->profile,
-                                                 "GsPlugin::%s(%s){%s}",
-                                                 gs_plugin_get_name (plugin),
-                                                 job->function_name,
-                                                 gs_app_get_id (app));
-                       g_assert (ptask != NULL);
-                       gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
-                       ret = plugin_app_func (plugin, app,
-                                              cancellable,
-                                              &error_local);
-                       gs_plugin_loader_action_stop (plugin_loader, plugin);
-                       if (!ret) {
-                               if (!gs_plugin_error_handle_failure (job,
-                                                                    plugin,
-                                                                    error_local,
-                                                                    &error)) {
-                                       g_task_return_error (task, error);
-                                       return;
+                       /* operate on the parent app or the related apps */
+                       if (gs_app_has_quirk (app_tmp, AS_APP_QUIRK_IS_PROXY)) {
+                               apps = g_ptr_array_ref (gs_app_get_related (app_tmp));
+                       } else {
+                               apps = g_ptr_array_new ();
+                               g_ptr_array_add (apps, app_tmp);
+                       }
+                       for (guint k = 0; k < apps->len; k++) {
+                               g_autoptr(GError) error_local = NULL;
+                               g_autoptr(AsProfileTask) ptask = NULL;
+                               GsApp *app = g_ptr_array_index (apps, k);
+                               g_set_object (&job->app, app);
+                               ptask = as_profile_start (priv->profile,
+                                                         "GsPlugin::%s(%s){%s}",
+                                                         gs_plugin_get_name (plugin),
+                                                         job->function_name,
+                                                         gs_app_get_id (app));
+                               g_assert (ptask != NULL);
+                               gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
+                               ret = plugin_app_func (plugin, app,
+                                                      cancellable,
+                                                      &error_local);
+                               gs_plugin_loader_action_stop (plugin_loader, plugin);
+                               if (!ret) {
+                                       if (!gs_plugin_error_handle_failure (job,
+                                                                            plugin,
+                                                                            error_local,
+                                                                            &error)) {
+                                               g_task_return_error (task, error);
+                                               return;
+                                       }
                                }
                        }
                }
diff --git a/src/gs-plugin-vfuncs.h b/src/gs-plugin-vfuncs.h
index 713d351..a69f3ae 100644
--- a/src/gs-plugin-vfuncs.h
+++ b/src/gs-plugin-vfuncs.h
@@ -639,6 +639,10 @@ gboolean    gs_plugin_app_set_rating               (GsPlugin       *plugin,
  * NOTE: Once the action is complete, the plugin must set the new state of @app
  * to %AS_APP_STATE_INSTALLED or %AS_APP_STATE_UNKNOWN if not known.
  *
+ * If %AS_APP_QUIRK_IS_PROXY is set on the application then the actual #GsApp
+ * set in @app will be the related application of the parent. Plugins do not
+ * need to manually iterate on the related list of applications.
+ *
  * Returns: %TRUE for success or if not relevant
  **/
 gboolean        gs_plugin_update_app                   (GsPlugin       *plugin,
diff --git a/src/plugins/gs-plugin-systemd-updates.c b/src/plugins/gs-plugin-systemd-updates.c
index e6cf528..97cc1b4 100644
--- a/src/plugins/gs-plugin-systemd-updates.c
+++ b/src/plugins/gs-plugin-systemd-updates.c
@@ -156,54 +156,31 @@ gs_plugin_add_updates (GsPlugin *plugin,
        return TRUE;
 }
 
-static gboolean
-gs_plugin_systemd_updates_requires_trigger (GsApp *app)
+gboolean
+gs_plugin_update_app (GsPlugin *plugin,
+                     GsApp *app,
+                     GCancellable *cancellable,
+                     GError **error)
 {
-       GPtrArray *related;
-       guint i;
-
-       /* look at related apps too */
-       related = gs_app_get_related (app);
-       for (i = 0; i < related->len; i++) {
-               GsApp *app_tmp = g_ptr_array_index (related, i);
-               if (gs_plugin_systemd_updates_requires_trigger (app_tmp))
-                       return TRUE;
-       }
-
        /* if we can process this online do not require a trigger */
        if (gs_app_get_state (app) != AS_APP_STATE_UPDATABLE)
-               return FALSE;
+               return TRUE;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0)
+               return TRUE;
+
+       /* trigger offline update */
+       if (!pk_offline_trigger (PK_OFFLINE_ACTION_REBOOT,
+                                cancellable, error)) {
+               gs_plugin_packagekit_error_convert (error);
                return FALSE;
+       }
 
        /* success! */
        return TRUE;
 }
 
-gboolean
-gs_plugin_update (GsPlugin *plugin,
-                 GsAppList *apps,
-                 GCancellable *cancellable,
-                 GError **error)
-{
-       guint i;
-
-       /* any apps to process offline */
-       for (i = 0; i < gs_app_list_length (apps); i++) {
-               GsApp *app = gs_app_list_index (apps, i);
-               if (gs_plugin_systemd_updates_requires_trigger (app)) {
-                       if (!pk_offline_trigger (PK_OFFLINE_ACTION_REBOOT,
-                                                cancellable, error)) {
-                               gs_plugin_packagekit_error_convert (error);
-                               return FALSE;
-                       }
-                       return TRUE;
-               }
-       }
-       return TRUE;
-}
 
 gboolean
 gs_plugin_update_cancel (GsPlugin *plugin,


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