[gnome-software/1166-repository-dialog-design-updates: 31/39] gs-plugin: Add dedicated vfunc-s to manipulate repositories




commit 8efdd1ce1f373eb7675730cb016ed088788ee43b
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jul 13 19:12:42 2021 +0200

    gs-plugin: Add dedicated vfunc-s to manipulate repositories
    
    This way it can be distinguished what operations the plugin supports
    for the repositories and it's explicit what the caller wants to do
    with the repository, instead of leaving the decision on the plugin.

 lib/gs-app.c           |   8 ++-
 lib/gs-plugin-loader.c |  22 +++++++--
 lib/gs-plugin-types.h  |   8 +++
 lib/gs-plugin-vfuncs.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/gs-plugin.c        |  24 +++++++++
 src/gs-repos-dialog.c  |   5 +-
 src/gs-shell.c         |   4 ++
 7 files changed, 194 insertions(+), 7 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index b7c75818a..3aaa97612 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -1283,8 +1283,12 @@ gs_app_set_state (GsApp *app, GsAppState state)
                 * actions that usually change the state, we assign it to the
                 * appropriate action here */
                GsPluginAction action = GS_PLUGIN_ACTION_UNKNOWN;
-               if (priv->state == GS_APP_STATE_QUEUED_FOR_INSTALL)
-                       action = GS_PLUGIN_ACTION_INSTALL;
+               if (priv->state == GS_APP_STATE_QUEUED_FOR_INSTALL) {
+                       if (priv->kind == AS_COMPONENT_KIND_REPOSITORY)
+                               action = GS_PLUGIN_ACTION_INSTALL_REPO;
+                       else
+                               action = GS_PLUGIN_ACTION_INSTALL;
+               }
                gs_app_set_pending_action_internal (app, action);
 
                gs_app_queue_notify (app, obj_props[PROP_STATE]);
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 5f4f00eb5..ca3bd379c 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -239,6 +239,10 @@ gs_plugin_loader_helper_free (GsPluginLoaderHelper *helper)
        case GS_PLUGIN_ACTION_REMOVE:
        case GS_PLUGIN_ACTION_UPDATE:
        case GS_PLUGIN_ACTION_DOWNLOAD:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
+       case GS_PLUGIN_ACTION_REMOVE_REPO:
+       case GS_PLUGIN_ACTION_ENABLE_REPO:
+       case GS_PLUGIN_ACTION_DISABLE_REPO:
                {
                        GsApp *app;
                        GsAppList *list;
@@ -674,6 +678,10 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
        case GS_PLUGIN_ACTION_UPDATE_CANCEL:
        case GS_PLUGIN_ACTION_ADD_SHORTCUT:
        case GS_PLUGIN_ACTION_REMOVE_SHORTCUT:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
+       case GS_PLUGIN_ACTION_REMOVE_REPO:
+       case GS_PLUGIN_ACTION_ENABLE_REPO:
+       case GS_PLUGIN_ACTION_DISABLE_REPO:
                {
                        GsPluginActionFunc plugin_func = func;
                        ret = plugin_func (plugin, app, cancellable, &error_local);
@@ -807,7 +815,7 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
        }
 
        /* add app to the pending installation queue if necessary */
-       if (action == GS_PLUGIN_ACTION_INSTALL &&
+       if ((action == GS_PLUGIN_ACTION_INSTALL || action == GS_PLUGIN_ACTION_INSTALL_REPO) &&
            app != NULL && gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) {
                add_app_to_install_queue (plugin_loader, app);
        }
@@ -3126,8 +3134,9 @@ gs_plugin_loader_network_changed_cb (GNetworkMonitor *monitor,
                g_mutex_unlock (&plugin_loader->pending_apps_mutex);
                for (guint i = 0; i < gs_app_list_length (queue); i++) {
                        GsApp *app = gs_app_list_index (queue, i);
+                       GsPluginAction action = gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY ? 
GS_PLUGIN_ACTION_INSTALL_REPO : GS_PLUGIN_ACTION_INSTALL;
                        g_autoptr(GsPluginJob) plugin_job = NULL;
-                       plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL,
+                       plugin_job = gs_plugin_job_newv (action,
                                                         "app", app,
                                                         NULL);
                        gs_plugin_loader_job_process_async (plugin_loader, plugin_job,
@@ -3369,6 +3378,10 @@ gs_plugin_loader_process_thread_cb (GTask *task,
        case GS_PLUGIN_ACTION_SEARCH:
        case GS_PLUGIN_ACTION_SETUP:
        case GS_PLUGIN_ACTION_UPDATE:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
+       case GS_PLUGIN_ACTION_REMOVE_REPO:
+       case GS_PLUGIN_ACTION_ENABLE_REPO:
+       case GS_PLUGIN_ACTION_DISABLE_REPO:
                if (!helper->anything_ran) {
                        g_set_error (&error,
                                     GS_PLUGIN_ERROR,
@@ -3443,6 +3456,8 @@ gs_plugin_loader_process_thread_cb (GTask *task,
        switch (action) {
        case GS_PLUGIN_ACTION_INSTALL:
        case GS_PLUGIN_ACTION_REMOVE:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
+       case GS_PLUGIN_ACTION_REMOVE_REPO:
                gs_plugin_job_add_refine_flags (helper->plugin_job,
                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN |
                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION);
@@ -3716,7 +3731,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
        }
 
        /* deal with the install queue */
-       if (action == GS_PLUGIN_ACTION_REMOVE) {
+       if (action == GS_PLUGIN_ACTION_REMOVE || action == GS_PLUGIN_ACTION_REMOVE_REPO) {
                if (remove_app_from_install_queue (plugin_loader, gs_plugin_job_get_app (plugin_job))) {
                        GsAppList *list = gs_plugin_job_get_list (plugin_job);
                        task = g_task_new (plugin_loader, cancellable, callback, user_data);
@@ -3897,6 +3912,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
 
        switch (action) {
        case GS_PLUGIN_ACTION_INSTALL:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
        case GS_PLUGIN_ACTION_UPDATE:
        case GS_PLUGIN_ACTION_UPGRADE_DOWNLOAD:
                /* these actions must be performed by the thread pool because we
diff --git a/lib/gs-plugin-types.h b/lib/gs-plugin-types.h
index 53bfdc7b8..4674ad228 100644
--- a/lib/gs-plugin-types.h
+++ b/lib/gs-plugin-types.h
@@ -221,6 +221,10 @@ typedef enum {
  * @GS_PLUGIN_ACTION_DOWNLOAD:                 Download an application
  * @GS_PLUGIN_ACTION_GET_ALTERNATES:           Get the alternates for a specific application
  * @GS_PLUGIN_ACTION_GET_LANGPACKS:            Get appropriate language pack
+ * @GS_PLUGIN_ACTION_INSTALL_REPO:             Install a repository (Since: 41)
+ * @GS_PLUGIN_ACTION_REMOVE_REPO:              Remove a repository (Since: 41)
+ * @GS_PLUGIN_ACTION_ENABLE_REPO:              Enable a repository (Since: 41)
+ * @GS_PLUGIN_ACTION_DISABLE_REPO:             Disable a repository (Since: 41)
  *
  * The plugin action.
  **/
@@ -259,6 +263,10 @@ typedef enum {
        GS_PLUGIN_ACTION_DOWNLOAD,
        GS_PLUGIN_ACTION_GET_ALTERNATES,
        GS_PLUGIN_ACTION_GET_LANGPACKS,
+       GS_PLUGIN_ACTION_INSTALL_REPO,
+       GS_PLUGIN_ACTION_REMOVE_REPO,
+       GS_PLUGIN_ACTION_ENABLE_REPO,
+       GS_PLUGIN_ACTION_DISABLE_REPO,
        GS_PLUGIN_ACTION_LAST  /*< skip >*/
 } GsPluginAction;
 
diff --git a/lib/gs-plugin-vfuncs.h b/lib/gs-plugin-vfuncs.h
index e9dcb226d..23b7829db 100644
--- a/lib/gs-plugin-vfuncs.h
+++ b/lib/gs-plugin-vfuncs.h
@@ -803,4 +803,134 @@ gboolean   gs_plugin_add_langpacks                (GsPlugin       *plugin,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
 
+/**
+ * gs_plugin_install_repo:
+ * @plugin: a #GsPlugin
+ * @repo: a #GsApp representing a repository
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Install the repository. This is a voluntary function, the plugin implements
+ * it only if it supports it. If implemented, its pair function gs_plugin_remove_repo()
+ * should be implemented as well.
+ *
+ * Plugins are expected to send progress notifications to the UI using
+ * gs_app_set_progress() using the passed in @repo.
+ *
+ * All functions can block, but should sent progress notifications, e.g. using
+ * gs_app_set_progress() if they will take more than tens of milliseconds
+ * to complete.
+ *
+ * On failure the error message returned will usually only be shown on the
+ * console, but they can also be retrieved using gs_plugin_loader_get_events().
+ *
+ * NOTE: Once the action is complete, the plugin must set the new state of @repo
+ * to either %GS_APP_STATE_INSTALLED or %GS_APP_STATE_AVAILABLE.
+ *
+ * Returns: %TRUE for success or if not relevant
+ *
+ * Since: 41
+ **/
+gboolean        gs_plugin_install_repo                 (GsPlugin       *plugin,
+                                                        GsApp          *repo,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
+
+/**
+ * gs_plugin_remove_repo:
+ * @plugin: a #GsPlugin
+ * @repo: a #GsApp representing a repository
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Remove the repository. This is a voluntary function, the plugin implements
+ * it only if it supports it. If implemented, its pair function gs_plugin_install_repo()
+ * should be implemented as well.
+ *
+ * Plugins are expected to send progress notifications to the UI using
+ * gs_app_set_progress() using the passed in @app.
+ *
+ * All functions can block, but should sent progress notifications, e.g. using
+ * gs_app_set_progress() if they will take more than tens of milliseconds
+ * to complete.
+ *
+ * On failure the error message returned will usually only be shown on the
+ * console, but they can also be retrieved using gs_plugin_loader_get_events().
+ *
+ * NOTE: Once the action is complete, the plugin must set the new state of @app
+ * to %GS_APP_STATE_AVAILABLE or %GS_APP_STATE_UNKNOWN if not known.
+ *
+ * Returns: %TRUE for success or if not relevant
+ *
+ * Since: 41
+ **/
+gboolean        gs_plugin_remove_repo                  (GsPlugin       *plugin,
+                                                        GsApp          *repo,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
+/**
+ * gs_plugin_enable_repo:
+ * @plugin: a #GsPlugin
+ * @repo: a #GsApp representing a repository
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Enable the repository. This is a voluntary function, the plugin implements
+ * it only if it supports it. If implemented, its pair function gs_plugin_disable_repo()
+ * should be implemented as well.
+ *
+ * Plugins are expected to send progress notifications to the UI using
+ * gs_app_set_progress() using the passed in @repo.
+ *
+ * All functions can block, but should sent progress notifications, e.g. using
+ * gs_app_set_progress() if they will take more than tens of milliseconds
+ * to complete.
+ *
+ * On failure the error message returned will usually only be shown on the
+ * console, but they can also be retrieved using gs_plugin_loader_get_events().
+ *
+ * NOTE: Once the action is complete, the plugin must set the new state of @repo
+ * to %GS_APP_STATE_INSTALLED.
+ *
+ * Returns: %TRUE for success or if not relevant
+ *
+ * Since: 41
+ **/
+gboolean        gs_plugin_enable_repo                  (GsPlugin       *plugin,
+                                                        GsApp          *repo,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
+
+/**
+ * gs_plugin_disable_repo:
+ * @plugin: a #GsPlugin
+ * @repo: a #GsApp representing a repository
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Disable the repository. This is a voluntary function, the plugin implements
+ * it only if it supports it. If implemented, its pair function gs_plugin_enable_repo()
+ * should be implemented as well.
+ *
+ * Plugins are expected to send progress notifications to the UI using
+ * gs_app_set_progress() using the passed in @app.
+ *
+ * All functions can block, but should sent progress notifications, e.g. using
+ * gs_app_set_progress() if they will take more than tens of milliseconds
+ * to complete.
+ *
+ * On failure the error message returned will usually only be shown on the
+ * console, but they can also be retrieved using gs_plugin_loader_get_events().
+ *
+ * NOTE: Once the action is complete, the plugin must set the new state of @app
+ * to %GS_APP_STATE_AVAILABLE.
+ *
+ * Returns: %TRUE for success or if not relevant
+ *
+ * Since: 41
+ **/
+gboolean        gs_plugin_disable_repo                 (GsPlugin       *plugin,
+                                                        GsApp          *repo,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 G_END_DECLS
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index 3ef285b8f..47e1ec7d5 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1646,6 +1646,14 @@ gs_plugin_action_to_function_name (GsPluginAction action)
                return "gs_plugin_add_alternates";
        if (action == GS_PLUGIN_ACTION_GET_LANGPACKS)
                return "gs_plugin_add_langpacks";
+       if (action == GS_PLUGIN_ACTION_INSTALL_REPO)
+               return "gs_plugin_install_repo";
+       if (action == GS_PLUGIN_ACTION_REMOVE_REPO)
+               return "gs_plugin_remove_repo";
+       if (action == GS_PLUGIN_ACTION_ENABLE_REPO)
+               return "gs_plugin_enable_repo";
+       if (action == GS_PLUGIN_ACTION_DISABLE_REPO)
+               return "gs_plugin_disable_repo";
        return NULL;
 }
 
@@ -1728,6 +1736,14 @@ gs_plugin_action_to_string (GsPluginAction action)
                return "get-alternates";
        if (action == GS_PLUGIN_ACTION_GET_LANGPACKS)
                return "get-langpacks";
+       if (action == GS_PLUGIN_ACTION_INSTALL_REPO)
+               return "repo-install";
+       if (action == GS_PLUGIN_ACTION_REMOVE_REPO)
+               return "repo-remove";
+       if (action == GS_PLUGIN_ACTION_ENABLE_REPO)
+               return "repo-enable";
+       if (action == GS_PLUGIN_ACTION_DISABLE_REPO)
+               return "repo-disable";
        return NULL;
 }
 
@@ -1810,6 +1826,14 @@ gs_plugin_action_from_string (const gchar *action)
                return GS_PLUGIN_ACTION_GET_ALTERNATES;
        if (g_strcmp0 (action, "get-langpacks") == 0)
                return GS_PLUGIN_ACTION_GET_LANGPACKS;
+       if (g_strcmp0 (action, "repo-install") == 0)
+               return GS_PLUGIN_ACTION_INSTALL_REPO;
+       if (g_strcmp0 (action, "repo-remove") == 0)
+               return GS_PLUGIN_ACTION_REMOVE_REPO;
+       if (g_strcmp0 (action, "repo-enable") == 0)
+               return GS_PLUGIN_ACTION_ENABLE_REPO;
+       if (g_strcmp0 (action, "repo-disable") == 0)
+               return GS_PLUGIN_ACTION_DISABLE_REPO;
        return GS_PLUGIN_ACTION_UNKNOWN;
 }
 
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
index 282410809..d5a4547ee 100644
--- a/src/gs-repos-dialog.c
+++ b/src/gs-repos-dialog.c
@@ -206,7 +206,7 @@ enable_repo (GsReposDialog *dialog, GsApp *repo)
        g_autoptr(InstallRemoveData) install_data = NULL;
 
        install_data = g_slice_new0 (InstallRemoveData);
-       install_data->action = GS_PLUGIN_ACTION_INSTALL;
+       install_data->action = GS_PLUGIN_ACTION_ENABLE_REPO;
        install_data->repo = g_object_ref (repo);
        install_data->dialog = g_object_ref (dialog);
 
@@ -291,16 +291,17 @@ remove_confirm_repo (GsReposDialog *dialog, GsApp *repo)
        GtkStyleContext *context;
 
        remove_data = g_slice_new0 (InstallRemoveData);
-       remove_data->action = GS_PLUGIN_ACTION_REMOVE;
        remove_data->repo = g_object_ref (repo);
        remove_data->dialog = g_object_ref (dialog);
 
        if (repo_supports_removal (repo)) {
+               remove_data->action = GS_PLUGIN_ACTION_REMOVE_REPO;
                /* TRANSLATORS: this is a prompt message, and '%s' is a
                 * repository name, e.g. 'GNOME Nightly' */
                title = g_strdup_printf (_("Remove ā€œ%sā€?"),
                                         gs_app_get_name (repo));
        } else {
+               remove_data->action = GS_PLUGIN_ACTION_DISABLE_REPO;
                /* TRANSLATORS: this is a prompt message, and '%s' is a
                 * repository name, e.g. 'GNOME Nightly' */
                title = g_strdup_printf (_("Disable ā€œ%sā€?"),
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 00e8ecefa..4eb6e4599 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -1987,12 +1987,16 @@ gs_shell_show_event (GsShell *shell, GsPluginEvent *event)
        case GS_PLUGIN_ACTION_DOWNLOAD:
                return gs_shell_show_event_refresh (shell, event);
        case GS_PLUGIN_ACTION_INSTALL:
+       case GS_PLUGIN_ACTION_INSTALL_REPO:
+       case GS_PLUGIN_ACTION_ENABLE_REPO:
                return gs_shell_show_event_install (shell, event);
        case GS_PLUGIN_ACTION_UPDATE:
                return gs_shell_show_event_update (shell, event);
        case GS_PLUGIN_ACTION_UPGRADE_DOWNLOAD:
                return gs_shell_show_event_upgrade (shell, event);
        case GS_PLUGIN_ACTION_REMOVE:
+       case GS_PLUGIN_ACTION_REMOVE_REPO:
+       case GS_PLUGIN_ACTION_DISABLE_REPO:
                return gs_shell_show_event_remove (shell, event);
        case GS_PLUGIN_ACTION_LAUNCH:
                return gs_shell_show_event_launch (shell, event);


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