[gnome-software: 66/72] gs-plugin-job-refine: Move across run_refine() code from plugin loader
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 66/72] gs-plugin-job-refine: Move across run_refine() code from plugin loader
- Date: Wed, 15 Dec 2021 13:00:56 +0000 (UTC)
commit fbca93ea04c3c75abb7d0ec518f132a5c0e6382a
Author: Philip Withnall <pwithnall endlessos org>
Date: Wed Nov 24 15:49:49 2021 +0000
gs-plugin-job-refine: Move across run_refine() code from plugin loader
Move the code and make minimal adjustments so it compiles:
* Replace use of `GsPluginLoaderHelper` with explicit function
arguments.
* Use `gs_plugin_loader_get_plugins()` and
`gs_plugin_loader_get_odrs_provider()` to access private members.
* Replace `gs_plugin_loader_call_vfunc()` with an explicit call to the
`refine_async()` vfunc on each `GsPluginClass`.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
Helps: #1472
lib/gs-plugin-job-refine.c | 291 ++++++++++++++++++++++++++++++++++++++++++++-
lib/gs-plugin-loader.c | 260 ----------------------------------------
2 files changed, 290 insertions(+), 261 deletions(-)
---
diff --git a/lib/gs-plugin-job-refine.c b/lib/gs-plugin-job-refine.c
index 5433e083e..fbc2a39f1 100644
--- a/lib/gs-plugin-job-refine.c
+++ b/lib/gs-plugin-job-refine.c
@@ -42,6 +42,9 @@
#include <glib-object.h>
#include <glib/gi18n.h>
+#include "gs-app.h"
+#include "gs-app-collation.h"
+#include "gs-app-private.h"
#include "gs-enums.h"
#include "gs-plugin-job-private.h"
#include "gs-plugin-job-refine.h"
@@ -147,6 +150,292 @@ app_is_valid_filter (GsApp *app,
return gs_plugin_loader_app_is_valid (app, self->flags);
}
+static gint
+review_score_sort_cb (gconstpointer a, gconstpointer b)
+{
+ AsReview *ra = *((AsReview **) a);
+ AsReview *rb = *((AsReview **) b);
+ if (as_review_get_priority (ra) < as_review_get_priority (rb))
+ return 1;
+ if (as_review_get_priority (ra) > as_review_get_priority (rb))
+ return -1;
+ return 0;
+}
+
+static gboolean
+app_is_non_wildcard (GsApp *app, gpointer user_data)
+{
+ return !gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD);
+}
+
+static void plugin_refine_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+
+static gboolean
+run_refine_filter (GsPluginJobRefine *self,
+ GsPluginLoader *plugin_loader,
+ GsAppList *list,
+ GsPluginRefineFlags refine_flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsOdrsProvider *odrs_provider;
+ GPtrArray *plugins; /* (element-type GsPlugin) */
+
+ /* run each plugin */
+ plugins = gs_plugin_loader_get_plugins (plugin_loader);
+
+ for (guint i = 0; i < plugins->len; i++) {
+ GsPlugin *plugin = g_ptr_array_index (plugins, i);
+ GsPluginClass *plugin_class = GS_PLUGIN_GET_CLASS (plugin);
+ g_autoptr(GAsyncResult) refine_result = NULL;
+
+ if (!gs_plugin_get_enabled (plugin))
+ continue;
+ if (plugin_class->refine_async == NULL)
+ continue;
+
+ /* run the batched plugin symbol */
+ plugin_class->refine_async (plugin, list, refine_flags,
+ cancellable, plugin_refine_cb, &refine_result);
+
+ /* FIXME: Make this sync until the calling function is rearranged
+ * to be async. */
+ while (refine_result == NULL)
+ g_main_context_iteration (g_main_context_get_thread_default (), TRUE);
+
+ if (!plugin_class->refine_finish (plugin, refine_result, error))
+ return FALSE;
+
+ gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
+ }
+
+ /* Add ODRS data if needed */
+ odrs_provider = gs_plugin_loader_get_odrs_provider (plugin_loader);
+
+ if (odrs_provider != NULL) {
+ if (!gs_odrs_provider_refine (odrs_provider,
+ list, refine_flags, cancellable, error))
+ return FALSE;
+ }
+
+ /* filter any wildcard apps left in the list */
+ gs_app_list_filter (list, app_is_non_wildcard, NULL);
+ return TRUE;
+}
+
+static void
+plugin_refine_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GAsyncResult **result_out = user_data;
+
+ g_assert (*result_out == NULL);
+ *result_out = g_object_ref (result);
+ g_main_context_wakeup (g_main_context_get_thread_default ());
+}
+
+static gboolean
+run_refine_internal (GsPluginJobRefine *self,
+ GsPluginLoader *plugin_loader,
+ GsAppList *list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autoptr(GsAppList) previous_list = NULL;
+
+ if (list != gs_plugin_job_get_list (GS_PLUGIN_JOB (self))) {
+ previous_list = g_object_ref (gs_plugin_job_get_list (GS_PLUGIN_JOB (self)));
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), list);
+ }
+
+ /* try to adopt each application with a plugin */
+ gs_plugin_loader_run_adopt (plugin_loader, list);
+
+ /* run each plugin */
+ if (!run_refine_filter (self, plugin_loader, list,
+ GS_PLUGIN_REFINE_FLAGS_NONE,
+ cancellable, error)) {
+ if (previous_list != NULL)
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), previous_list);
+ return FALSE;
+ }
+
+ /* ensure these are sorted by score */
+ if (gs_plugin_job_has_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS)) {
+ GPtrArray *reviews;
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ reviews = gs_app_get_reviews (app);
+ g_ptr_array_sort (reviews, review_score_sort_cb);
+ }
+ }
+
+ /* refine addons one layer deep */
+ if (gs_plugin_job_has_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS)) {
+ g_autoptr(GsAppList) addons_list = NULL;
+ gs_plugin_job_remove_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS);
+ addons_list = gs_app_list_new ();
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ GsAppList *addons = gs_app_get_addons (app);
+ for (guint j = 0; j < gs_app_list_length (addons); j++) {
+ GsApp *addon = gs_app_list_index (addons, j);
+ g_debug ("refining app %s addon %s",
+ gs_app_get_id (app),
+ gs_app_get_id (addon));
+ gs_app_list_add (addons_list, addon);
+ }
+ }
+ if (gs_app_list_length (addons_list) > 0) {
+ if (!run_refine_internal (self, plugin_loader,
+ addons_list, cancellable,
+ error)) {
+ if (previous_list != NULL)
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), previous_list);
+ return FALSE;
+ }
+ }
+ }
+
+ /* also do runtime */
+ if (gs_plugin_job_has_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_RUNTIME)) {
+ g_autoptr(GsAppList) list2 = gs_app_list_new ();
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *runtime;
+ GsApp *app = gs_app_list_index (list, i);
+ runtime = gs_app_get_runtime (app);
+ if (runtime != NULL)
+ gs_app_list_add (list2, runtime);
+ }
+ if (gs_app_list_length (list2) > 0) {
+ if (!run_refine_internal (self, plugin_loader,
+ list2, cancellable,
+ error)) {
+ if (previous_list != NULL)
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), previous_list);
+ return FALSE;
+ }
+ }
+ }
+
+ /* also do related packages one layer deep */
+ if (gs_plugin_job_has_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED)) {
+ g_autoptr(GsAppList) related_list = NULL;
+ gs_plugin_job_remove_refine_flags (GS_PLUGIN_JOB (self),
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED);
+ related_list = gs_app_list_new ();
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ GsAppList *related = gs_app_get_related (app);
+ for (guint j = 0; j < gs_app_list_length (related); j++) {
+ GsApp *app2 = gs_app_list_index (related, j);
+ g_debug ("refining related: %s[%s]",
+ gs_app_get_id (app2),
+ gs_app_get_source_default (app2));
+ gs_app_list_add (related_list, app2);
+ }
+ }
+ if (gs_app_list_length (related_list) > 0) {
+ if (!run_refine_internal (self, plugin_loader,
+ related_list, cancellable,
+ error)) {
+ if (previous_list != NULL)
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), previous_list);
+ return FALSE;
+ }
+ }
+ }
+
+ if (previous_list != NULL)
+ gs_plugin_job_set_list (GS_PLUGIN_JOB (self), previous_list);
+
+ /* success */
+ return TRUE;
+}
+
+static gboolean
+app_thaw_notify_idle (gpointer data)
+{
+ GsApp *app = GS_APP (data);
+ g_object_thaw_notify (G_OBJECT (app));
+ g_object_unref (app);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+run_refine (GsPluginJobRefine *self,
+ GsPluginLoader *plugin_loader,
+ GsAppList *list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret;
+ g_autoptr(GsAppList) freeze_list = NULL;
+
+ /* nothing to do */
+ if (gs_app_list_length (list) == 0)
+ return TRUE;
+
+ /* freeze all apps */
+ freeze_list = gs_app_list_copy (list);
+ for (guint i = 0; i < gs_app_list_length (freeze_list); i++) {
+ GsApp *app = gs_app_list_index (freeze_list, i);
+ g_object_freeze_notify (G_OBJECT (app));
+ }
+
+ /* first pass */
+ ret = run_refine_internal (self, plugin_loader, list, cancellable, error);
+ if (!ret)
+ goto out;
+
+ /* remove any addons that have the same source as the parent app */
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ g_autoptr(GPtrArray) to_remove = g_ptr_array_new ();
+ GsApp *app = gs_app_list_index (list, i);
+ GsAppList *addons = gs_app_get_addons (app);
+
+ /* find any apps with the same source */
+ const gchar *pkgname_parent = gs_app_get_source_default (app);
+ if (pkgname_parent == NULL)
+ continue;
+ for (guint j = 0; j < gs_app_list_length (addons); j++) {
+ GsApp *addon = gs_app_list_index (addons, j);
+ if (g_strcmp0 (gs_app_get_source_default (addon),
+ pkgname_parent) == 0) {
+ g_debug ("%s has the same pkgname of %s as %s",
+ gs_app_get_unique_id (app),
+ pkgname_parent,
+ gs_app_get_unique_id (addon));
+ g_ptr_array_add (to_remove, addon);
+ }
+ }
+
+ /* remove any addons with the same source */
+ for (guint j = 0; j < to_remove->len; j++) {
+ GsApp *addon = g_ptr_array_index (to_remove, j);
+ gs_app_remove_addon (app, addon);
+ }
+ }
+
+out:
+ /* now emit all the changed signals */
+ for (guint i = 0; i < gs_app_list_length (freeze_list); i++) {
+ GsApp *app = gs_app_list_index (freeze_list, i);
+ g_idle_add (app_thaw_notify_idle, g_object_ref (app));
+ }
+ return ret;
+}
+
static void
gs_plugin_job_refine_run_async (GsPluginJob *job,
GsPluginLoader *plugin_loader,
@@ -170,7 +459,7 @@ gs_plugin_job_refine_run_async (GsPluginJob *job,
/* run refine() on each one if required */
if (self->flags != 0) {
- if (!gs_plugin_loader_run_refine (helper, result_list, cancellable, &local_error)) {
+ if (!run_refine (self, plugin_loader, result_list, cancellable, &local_error)) {
gs_utils_error_convert_gio (&local_error);
g_task_return_error (task, g_steal_pointer (&local_error));
return;
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 0cc6e319e..6d2c7a732 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -573,18 +573,6 @@ gs_plugin_loader_run_adopt (GsPluginLoader *plugin_loader, GsAppList *list)
}
}
-static gint
-gs_plugin_loader_review_score_sort_cb (gconstpointer a, gconstpointer b)
-{
- AsReview *ra = *((AsReview **) a);
- AsReview *rb = *((AsReview **) b);
- if (as_review_get_priority (ra) < as_review_get_priority (rb))
- return 1;
- if (as_review_get_priority (ra) > as_review_get_priority (rb))
- return -1;
- return 0;
-}
-
static gboolean
gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
GsPlugin *plugin,
@@ -836,254 +824,6 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
return TRUE;
}
-static gboolean
-gs_plugin_loader_app_is_non_wildcard (GsApp *app, gpointer user_data)
-{
- return !gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD);
-}
-
-static gboolean
-gs_plugin_loader_run_refine_filter (GsPluginLoaderHelper *helper,
- GsAppList *list,
- GsPluginRefineFlags refine_flags,
- GCancellable *cancellable,
- GError **error)
-{
- GsPluginLoader *plugin_loader = helper->plugin_loader;
-
- /* run each plugin */
- for (guint i = 0; i < plugin_loader->plugins->len; i++) {
- GsPlugin *plugin = g_ptr_array_index (plugin_loader->plugins, i);
- g_autoptr(GsAppList) app_list = NULL;
-
- /* run the batched plugin symbol then refine wildcards per-app */
- helper->function_name = "gs_plugin_refine";
- if (!gs_plugin_loader_call_vfunc (helper, plugin, NULL, list,
- refine_flags, cancellable, error)) {
- return FALSE;
- }
-
- gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
- }
-
- /* Add ODRS data if needed */
- if (plugin_loader->odrs_provider != NULL) {
- if (!gs_odrs_provider_refine (plugin_loader->odrs_provider,
- list, refine_flags, cancellable, error))
- return FALSE;
- }
-
- /* filter any wildcard apps left in the list */
- gs_app_list_filter (list, gs_plugin_loader_app_is_non_wildcard, NULL);
- return TRUE;
-}
-
-static gboolean
-gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
- GsAppList *list,
- GCancellable *cancellable,
- GError **error)
-{
- g_autoptr(GsAppList) previous_list = NULL;
-
- if (list != gs_plugin_job_get_list (helper->plugin_job)) {
- previous_list = g_object_ref (gs_plugin_job_get_list (helper->plugin_job));
- gs_plugin_job_set_list (helper->plugin_job, list);
- }
-
- /* try to adopt each application with a plugin */
- gs_plugin_loader_run_adopt (helper->plugin_loader, list);
-
- /* run each plugin */
- if (!gs_plugin_loader_run_refine_filter (helper, list,
- gs_plugin_job_get_refine_flags (helper->plugin_job),
- cancellable, error)) {
- if (previous_list != NULL)
- gs_plugin_job_set_list (helper->plugin_job, previous_list);
- return FALSE;
- }
-
- /* ensure these are sorted by score */
- if (gs_plugin_job_has_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS)) {
- GPtrArray *reviews;
- for (guint i = 0; i < gs_app_list_length (list); i++) {
- GsApp *app = gs_app_list_index (list, i);
- reviews = gs_app_get_reviews (app);
- g_ptr_array_sort (reviews,
- gs_plugin_loader_review_score_sort_cb);
- }
- }
-
- /* refine addons one layer deep */
- if (gs_plugin_job_has_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS)) {
- g_autoptr(GsAppList) addons_list = NULL;
- gs_plugin_job_remove_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS |
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS |
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS);
- addons_list = gs_app_list_new ();
- for (guint i = 0; i < gs_app_list_length (list); i++) {
- GsApp *app = gs_app_list_index (list, i);
- GsAppList *addons = gs_app_get_addons (app);
- for (guint j = 0; j < gs_app_list_length (addons); j++) {
- GsApp *addon = gs_app_list_index (addons, j);
- g_debug ("refining app %s addon %s",
- gs_app_get_id (app),
- gs_app_get_id (addon));
- gs_app_list_add (addons_list, addon);
- }
- }
- if (gs_app_list_length (addons_list) > 0) {
- if (!gs_plugin_loader_run_refine_internal (helper,
- addons_list,
- cancellable,
- error)) {
- if (previous_list != NULL)
- gs_plugin_job_set_list (helper->plugin_job, previous_list);
- return FALSE;
- }
- }
- }
-
- /* also do runtime */
- if (gs_plugin_job_has_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_RUNTIME)) {
- g_autoptr(GsAppList) list2 = gs_app_list_new ();
- for (guint i = 0; i < gs_app_list_length (list); i++) {
- GsApp *runtime;
- GsApp *app = gs_app_list_index (list, i);
- runtime = gs_app_get_runtime (app);
- if (runtime != NULL)
- gs_app_list_add (list2, runtime);
- }
- if (gs_app_list_length (list2) > 0) {
- if (!gs_plugin_loader_run_refine_internal (helper,
- list2,
- cancellable,
- error)) {
- if (previous_list != NULL)
- gs_plugin_job_set_list (helper->plugin_job, previous_list);
- return FALSE;
- }
- }
- }
-
- /* also do related packages one layer deep */
- if (gs_plugin_job_has_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED)) {
- g_autoptr(GsAppList) related_list = NULL;
- gs_plugin_job_remove_refine_flags (helper->plugin_job,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED);
- related_list = gs_app_list_new ();
- for (guint i = 0; i < gs_app_list_length (list); i++) {
- GsApp *app = gs_app_list_index (list, i);
- GsAppList *related = gs_app_get_related (app);
- for (guint j = 0; j < gs_app_list_length (related); j++) {
- GsApp *app2 = gs_app_list_index (related, j);
- g_debug ("refining related: %s[%s]",
- gs_app_get_id (app2),
- gs_app_get_source_default (app2));
- gs_app_list_add (related_list, app2);
- }
- }
- if (gs_app_list_length (related_list) > 0) {
- if (!gs_plugin_loader_run_refine_internal (helper,
- related_list,
- cancellable,
- error)) {
- if (previous_list != NULL)
- gs_plugin_job_set_list (helper->plugin_job, previous_list);
- return FALSE;
- }
- }
- }
-
- if (previous_list != NULL)
- gs_plugin_job_set_list (helper->plugin_job, previous_list);
-
- /* success */
- return TRUE;
-}
-
-static gboolean
-app_thaw_notify_idle (gpointer data)
-{
- GsApp *app = GS_APP (data);
- g_object_thaw_notify (G_OBJECT (app));
- g_object_unref (app);
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-gs_plugin_loader_run_refine (GsPluginLoaderHelper *helper,
- GsAppList *list,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret;
- g_autoptr(GsAppList) freeze_list = NULL;
- g_autoptr(GsPluginLoaderHelper) helper2 = NULL;
- g_autoptr(GsPluginJob) plugin_job = NULL;
-
- /* nothing to do */
- if (gs_app_list_length (list) == 0)
- return TRUE;
-
- /* freeze all apps */
- freeze_list = gs_app_list_copy (list);
- for (guint i = 0; i < gs_app_list_length (freeze_list); i++) {
- GsApp *app = gs_app_list_index (freeze_list, i);
- g_object_freeze_notify (G_OBJECT (app));
- }
-
- /* first pass */
- plugin_job = gs_plugin_job_refine_new (list, gs_plugin_job_get_refine_flags (helper->plugin_job));
- helper2 = gs_plugin_loader_helper_new (helper->plugin_loader, plugin_job);
- helper2->function_name_parent = helper->function_name;
- ret = gs_plugin_loader_run_refine_internal (helper2, list, cancellable, error);
- if (!ret)
- goto out;
-
- /* remove any addons that have the same source as the parent app */
- for (guint i = 0; i < gs_app_list_length (list); i++) {
- g_autoptr(GPtrArray) to_remove = g_ptr_array_new ();
- GsApp *app = gs_app_list_index (list, i);
- GsAppList *addons = gs_app_get_addons (app);
-
- /* find any apps with the same source */
- const gchar *pkgname_parent = gs_app_get_source_default (app);
- if (pkgname_parent == NULL)
- continue;
- for (guint j = 0; j < gs_app_list_length (addons); j++) {
- GsApp *addon = gs_app_list_index (addons, j);
- if (g_strcmp0 (gs_app_get_source_default (addon),
- pkgname_parent) == 0) {
- g_debug ("%s has the same pkgname of %s as %s",
- gs_app_get_unique_id (app),
- pkgname_parent,
- gs_app_get_unique_id (addon));
- g_ptr_array_add (to_remove, addon);
- }
- }
-
- /* remove any addons with the same source */
- for (guint j = 0; j < to_remove->len; j++) {
- GsApp *addon = g_ptr_array_index (to_remove, j);
- gs_app_remove_addon (app, addon);
- }
- }
-
-out:
- /* now emit all the changed signals */
- for (guint i = 0; i < gs_app_list_length (freeze_list); i++) {
- GsApp *app = gs_app_list_index (freeze_list, i);
- g_idle_add (app_thaw_notify_idle, g_object_ref (app));
- }
- return ret;
-}
-
static void
gs_plugin_loader_job_sorted_truncation_again (GsPluginLoaderHelper *helper)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]