From 94e285f2615beb6f536abcb7601232510b9c9f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Correa=20G=C3=B3mez?= Date: Thu, 14 Sep 2023 19:47:41 +0200 Subject: [PATCH] Port gs_plugin_update to new async variant This was quite trivial, and the only change in cycles 44 and 45, so a great success overall --- meson.build | 2 +- src/gs-plugin-apk/gs-plugin-apk.c | 84 ++++++++++++++++++++++++++----- tests/gs-self-test.c | 5 +- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/meson.build b/meson.build index 55a0439..14e0472 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( meson_version: '>=0.58' ) -gnome_software_dep = dependency('gnome-software', version: '>=43.0') +gnome_software_dep = dependency('gnome-software', version: '>=44.0') plugin_install_dir = gnome_software_dep.get_variable('plugindir') cargs = ['-DG_LOG_DOMAIN="GsPluginApk"', '-DI_KNOW_THE_GNOME_SOFTWARE_API_IS_SUBJECT_TO_CHANGE'] diff --git a/src/gs-plugin-apk/gs-plugin-apk.c b/src/gs-plugin-apk/gs-plugin-apk.c index de7244b..aa0eb7b 100644 --- a/src/gs-plugin-apk/gs-plugin-apk.c +++ b/src/gs-plugin-apk/gs-plugin-apk.c @@ -479,23 +479,55 @@ gs_plugin_apk_prepare_update (GsPlugin *plugin, return added; } -gboolean -gs_plugin_update (GsPlugin *plugin, - GsAppList *list, - GCancellable *cancellable, - GError **error) +static void +upgrade_apk_packages_cb (GObject *object_source, + GAsyncResult *res, + gpointer user_data); + +static void +gs_plugin_apk_update_apps_async (GsPlugin *plugin, + GsAppList *list, + GsPluginUpdateAppsFlags flags, + GsPluginProgressCallback progress_callback, + gpointer progress_user_data, + GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, + gpointer app_needs_user_action_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { GsPluginApk *self = GS_PLUGIN_APK (plugin); - g_autoptr (GError) local_error = NULL; - g_autoptr (GsAppList) list_installing = gs_app_list_new (); + g_autoptr (GTask) task = NULL; + GsAppList *list_installing = gs_app_list_new (); unsigned int num_sources; g_autofree const gchar **source_array = NULL; + g_debug ("Updating apps"); + + task = g_task_new (plugin, cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_apk_update_apps_async); + + if (!(flags & GS_PLUGIN_UPDATE_APPS_FLAGS_NO_DOWNLOAD)) + { + // This needs polkit changes. Ideally we'd download first, and + // apply from cache then. We should probably test this out in + // pmOS release upgrader script first + g_warning ("We don't implement 'NO_DOWNLOAD'"); + } + + if (flags & GS_PLUGIN_UPDATE_APPS_FLAGS_NO_APPLY) + { + g_task_return_boolean (task, TRUE); + return; + } + /* update UI as this might take some time */ gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING); num_sources = gs_plugin_apk_prepare_update (plugin, list, list_installing); + g_debug ("Found %u apps to update", num_sources); + source_array = g_new0 (const gchar *, num_sources + 1); for (int i = 0; i < num_sources;) { @@ -508,8 +540,22 @@ gs_plugin_update (GsPlugin *plugin, } } - if (!apk_polkit2_call_upgrade_packages_sync (self->proxy, source_array, - cancellable, &local_error)) + g_task_set_task_data (task, g_steal_pointer (&list_installing), g_object_unref); + apk_polkit2_call_upgrade_packages (self->proxy, source_array, cancellable, + upgrade_apk_packages_cb, g_steal_pointer (&task)); +} + +static void +upgrade_apk_packages_cb (GObject *object_source, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr (GTask) task = G_TASK (g_steal_pointer (&user_data)); + GsPluginApk *self = g_task_get_source_object (task); + GsAppList *list_installing = g_task_get_task_data (task); + g_autoptr (GError) local_error = NULL; + + if (!apk_polkit2_call_upgrade_packages_finish (self->proxy, res, &local_error)) { /* When and upgrade transaction failed, it could be out of two reasons: * - The world constraints couldn't match. In that case, nothing was @@ -522,14 +568,14 @@ gs_plugin_update (GsPlugin *plugin, * and which didn't, so also recover everything and hope the refine * takes care of fixing things in the aftermath. */ g_dbus_error_strip_remote_error (local_error); - g_propagate_error (error, g_steal_pointer (&local_error)); for (int i = 0; i < gs_app_list_length (list_installing); i++) { GsApp *app = gs_app_list_index (list_installing, i); gs_app_set_state_recover (app); } - return FALSE; + g_task_return_error (task, g_steal_pointer (&local_error)); + return; } for (int i = 0; i < gs_app_list_length (list_installing); i++) @@ -538,8 +584,18 @@ gs_plugin_update (GsPlugin *plugin, gs_app_set_state (app, GS_APP_STATE_INSTALLED); } - gs_plugin_updates_changed (plugin); - return TRUE; + g_debug ("All apps updated correctly"); + + gs_plugin_updates_changed (GS_PLUGIN (self)); + g_task_return_boolean (task, TRUE); +} + +static gboolean +gs_plugin_apk_update_apps_finish (GsPlugin *plugin, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); } void @@ -1327,6 +1383,8 @@ gs_plugin_apk_class_init (GsPluginApkClass *klass) plugin_class->install_repository_finish = gs_plugin_apk_install_repository_finish; plugin_class->remove_repository_async = gs_plugin_apk_remove_repository_async; plugin_class->remove_repository_finish = gs_plugin_apk_remove_repository_finish; + plugin_class->update_apps_async = gs_plugin_apk_update_apps_async; + plugin_class->update_apps_finish = gs_plugin_apk_update_apps_finish; } GType diff --git a/tests/gs-self-test.c b/tests/gs-self-test.c index 1691e52..16cacb0 100644 --- a/tests/gs-self-test.c +++ b/tests/gs-self-test.c @@ -143,9 +143,8 @@ gs_plugins_apk_updates (GsPluginLoader *plugin_loader) gs_app_list_add (update_list, foreign_app); // No management plugin, should get ignored! // Execute update! g_object_unref (plugin_job); - plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPDATE, - "list", update_list, - NULL); + plugin_job = gs_plugin_job_update_apps_new (update_list, + GS_PLUGIN_UPDATE_APPS_FLAGS_NO_DOWNLOAD); ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); gs_test_flush_main_context (); g_assert_no_error (error);