[gnome-software/fix-flatpak-related-progress: 1/3] flatpak: Set app to installed when a related thing is updated
- From: Matthew Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/fix-flatpak-related-progress: 1/3] flatpak: Set app to installed when a related thing is updated
- Date: Thu, 9 Jul 2020 02:40:02 +0000 (UTC)
commit 875013b1aea4109d35e5bae1f1a653d444f06824
Author: Matthew Leeds <matthew leeds endlessm com>
Date: Tue Jul 7 19:54:20 2020 -0700
flatpak: Set app to installed when a related thing is updated
When an app's locale extension is updated but the app is not, we put
progress updates on the app so they are user visible. However since
_transaction_operation_done() is only ever called for the locale, the
app never gets set to AS_APP_STATE_INSTALLED and instead gets frozen in
the "Preparing..." state when gs_plugin_loader_helper_free() sets the
progress to GS_APP_PROGRESS_UNKNOWN on it.
So set the app to installed when one of its related refs is updated, if
the app itself is being skipped.
plugins/flatpak/gs-flatpak-transaction.c | 74 +++++++++++++++++++++++++++++++-
plugins/flatpak/gs-plugin-flatpak.c | 4 ++
2 files changed, 77 insertions(+), 1 deletion(-)
---
diff --git a/plugins/flatpak/gs-flatpak-transaction.c b/plugins/flatpak/gs-flatpak-transaction.c
index d1d01025..3af449a3 100644
--- a/plugins/flatpak/gs-flatpak-transaction.c
+++ b/plugins/flatpak/gs-flatpak-transaction.c
@@ -522,13 +522,81 @@ _transaction_new_operation (FlatpakTransaction *transaction,
}
}
+#if FLATPAK_CHECK_VERSION(1, 7, 3)
+static gboolean
+later_op_also_related (GList *ops,
+ FlatpakTransactionOperation *current_op,
+ FlatpakTransactionOperation *related_to_current_op)
+{
+ /* Here we're determining if anything in @ops which comes after
+ * @current_op is related to @related_to_current_op and not skipped
+ */
+ gboolean found_later_op = FALSE, seen_current_op = FALSE;
+ for (GList *l = ops; l != NULL; l = l->next) {
+ FlatpakTransactionOperation *op = l->data;
+ GPtrArray *related_to_ops;
+ if (current_op == op) {
+ seen_current_op = TRUE;
+ continue;
+ }
+ if (!seen_current_op)
+ continue;
+
+ related_to_ops = flatpak_transaction_operation_get_related_to_ops (op);
+ for (gsize i = 0; related_to_ops != NULL && i < related_to_ops->len; i++) {
+ FlatpakTransactionOperation *related_to_op = g_ptr_array_index (related_to_ops, i);
+ if (related_to_op == related_to_current_op &&
+ !flatpak_transaction_operation_get_is_skipped (related_to_op))
+ found_later_op = TRUE;
+ }
+ }
+
+ return found_later_op;
+}
+
+static void
+set_skipped_related_apps_to_installed (GsFlatpakTransaction *self,
+ FlatpakTransaction *transaction,
+ FlatpakTransactionOperation *operation)
+{
+ /* It's possible the thing being updated/installed, @operation, is a
+ * related ref (e.g. extension or runtime) of an app which itself doesn't
+ * need an update and therefore won't have _transaction_operation_done()
+ * called for it directly. So we have to set the main app to installed
+ * here.
+ */
+ g_autolist(GObject) ops = flatpak_transaction_get_operations (transaction);
+ GPtrArray *related_to_ops = flatpak_transaction_operation_get_related_to_ops (operation);
+
+ for (gsize i = 0; related_to_ops != NULL && i < related_to_ops->len; i++) {
+ FlatpakTransactionOperation *related_to_op = g_ptr_array_index (related_to_ops, i);
+ if (flatpak_transaction_operation_get_is_skipped (related_to_op)) {
+ const gchar *ref;
+ g_autoptr(GsApp) related_to_app = NULL;
+
+ /* Check that no later op is also related to related_to_op, in
+ * which case we want to let that operation finish before setting
+ * the main app to installed.
+ */
+ if (later_op_also_related (ops, operation, related_to_op))
+ continue;
+
+ ref = flatpak_transaction_operation_get_ref (related_to_op);
+ related_to_app = _ref_to_app (self, ref);
+ if (related_to_app != NULL)
+ gs_app_set_state (related_to_app, AS_APP_STATE_INSTALLED);
+ }
+ }
+}
+#endif /* flatpak 1.7.3 */
+
static void
_transaction_operation_done (FlatpakTransaction *transaction,
FlatpakTransactionOperation *operation,
const gchar *commit,
FlatpakTransactionResult details)
{
-#if !FLATPAK_CHECK_VERSION(1,5,1)
+#if !FLATPAK_CHECK_VERSION(1,5,1) || FLATPAK_CHECK_VERSION(1,7,3)
GsFlatpakTransaction *self = GS_FLATPAK_TRANSACTION (transaction);
#endif
/* invalidate */
@@ -559,6 +627,10 @@ _transaction_operation_done (FlatpakTransaction *transaction,
gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE);
else
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+
+#if FLATPAK_CHECK_VERSION(1,7,3)
+ set_skipped_related_apps_to_installed (self, transaction, operation);
+#endif
break;
case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
/* we don't actually know if this app is re-installable */
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index 845f289f..81b9433d 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -932,6 +932,10 @@ gs_plugin_flatpak_update (GsPlugin *plugin,
gs_flatpak_error_convert (error);
return FALSE;
}
+
+ /* add to the transaction cache for quick look up -- other unrelated
+ * refs will be matched using gs_plugin_flatpak_find_app_by_ref() */
+ gs_flatpak_transaction_add_app (transaction, app);
}
/* run transaction */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]