[gnome-software/961-gsapp-state-not-updated-after-repository-enable-disable: 101/101] GsApp: State not updated after repository enable/disable
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/961-gsapp-state-not-updated-after-repository-enable-disable: 101/101] GsApp: State not updated after repository enable/disable
- Date: Fri, 19 Feb 2021 08:41:04 +0000 (UTC)
commit 41c26e1f550eac581256a59af3e9be6a868b69d3
Author: Milan Crha <mcrha redhat com>
Date: Tue Feb 2 07:51:28 2021 +0100
GsApp: State not updated after repository enable/disable
Let the other plugins know that a repository was enabled/disabled,
thus they can refresh their cache accordingly.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/961
lib/gs-plugin-loader.c | 18 ++++++
lib/gs-plugin.c | 99 +++++++++++++++++++++++++++++++
lib/gs-plugin.h | 9 ++-
lib/gs-self-test.c | 2 +
plugins/core/gs-plugin-appstream.c | 7 +++
plugins/core/gs-self-test.c | 1 +
plugins/dpkg/gs-self-test.c | 1 +
plugins/dummy/gs-self-test.c | 1 +
plugins/fedora-langpacks/gs-self-test.c | 1 +
plugins/flatpak/gs-flatpak.c | 6 ++
plugins/flatpak/gs-self-test.c | 1 +
plugins/fwupd/gs-plugin-fwupd.c | 3 +
plugins/fwupd/gs-self-test.c | 1 +
plugins/modalias/gs-self-test.c | 1 +
plugins/packagekit/gs-plugin-packagekit.c | 10 ++++
plugins/packagekit/gs-self-test.c | 1 +
plugins/repos/gs-self-test.c | 1 +
plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 2 +
plugins/snap/gs-self-test.c | 1 +
src/gs-application.c | 19 ++++++
src/gs-self-test.c | 1 +
21 files changed, 185 insertions(+), 1 deletion(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 2dad71f86..8d7be842a 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -2125,6 +2125,21 @@ gs_plugin_loader_reload_cb (GsPlugin *plugin,
g_object_ref (plugin_loader));
}
+static void
+gs_plugin_loader_repository_changed_cb (GsPlugin *plugin,
+ GsApp *repository,
+ GsPluginLoader *plugin_loader)
+{
+ GApplication *application = g_application_get_default ();
+
+ /* Can be NULL when running the self tests */
+ if (application) {
+ g_signal_emit_by_name (application,
+ "repository-changed",
+ repository);
+ }
+}
+
static void
gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
const gchar *filename)
@@ -2156,6 +2171,9 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
g_signal_connect (plugin, "allow-updates",
G_CALLBACK (gs_plugin_loader_allow_updates_cb),
plugin_loader);
+ g_signal_connect (plugin, "repository-changed",
+ G_CALLBACK (gs_plugin_loader_repository_changed_cb),
+ plugin_loader);
gs_plugin_set_soup_session (plugin, plugin_loader->soup_session);
gs_plugin_set_locale (plugin, plugin_loader->locale);
gs_plugin_set_language (plugin, plugin_loader->language);
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index d91cd496b..69d1e5733 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -90,6 +90,7 @@ enum {
SIGNAL_REPORT_EVENT,
SIGNAL_ALLOW_UPDATES,
SIGNAL_BASIC_AUTH_START,
+ SIGNAL_REPOSITORY_CHANGED,
SIGNAL_LAST
};
@@ -2024,6 +2025,13 @@ gs_plugin_class_init (GsPluginClass *klass)
G_STRUCT_OFFSET (GsPluginClass, basic_auth_start),
NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
+
+ signals [SIGNAL_REPOSITORY_CHANGED] =
+ g_signal_new ("repository-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsPluginClass, repository_changed),
+ NULL, NULL, g_cclosure_marshal_generic,
+ G_TYPE_NONE, 1, GS_TYPE_APP);
}
static void
@@ -2065,3 +2073,94 @@ gs_plugin_new (void)
plugin = g_object_new (GS_TYPE_PLUGIN, NULL);
return plugin;
}
+
+typedef struct {
+ GsPlugin *plugin;
+ GsApp *repository;
+} GsPluginRepositoryChangedHelper;
+
+static gboolean
+gs_plugin_repository_changed_cb (gpointer user_data)
+{
+ GsPluginRepositoryChangedHelper *helper = user_data;
+ g_signal_emit (helper->plugin,
+ signals[SIGNAL_REPOSITORY_CHANGED], 0,
+ helper->repository);
+ g_clear_object (&helper->repository);
+ g_clear_object (&helper->plugin);
+ g_slice_free (GsPluginRepositoryChangedHelper, helper);
+ return FALSE;
+}
+
+/**
+ * gs_plugin_repository_changed:
+ * @plugin: a #GsPlugin
+ * @repository: a #GsApp representing the repository
+ *
+ * Emit the "repository-changed" signal in the main thread.
+ *
+ * Since: 40
+ **/
+void
+gs_plugin_repository_changed (GsPlugin *plugin,
+ GsApp *repository)
+{
+ GsPluginRepositoryChangedHelper *helper;
+ g_autoptr(GSource) idle_source = NULL;
+
+ g_return_if_fail (GS_IS_PLUGIN (plugin));
+ g_return_if_fail (GS_IS_APP (repository));
+
+ helper = g_slice_new0 (GsPluginRepositoryChangedHelper);
+ helper->plugin = g_object_ref (plugin);
+ helper->repository = g_object_ref (repository);
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (idle_source, gs_plugin_repository_changed_cb, helper, NULL);
+ g_source_attach (idle_source, NULL);
+}
+
+/**
+ * gs_plugin_update_cache_state_for_repository:
+ * @plugin: a #GsPlugin
+ * @repository: a #GsApp representing a repository, which changed
+ *
+ * Update state of the all cached #GsApp instances related
+ * to the @repository.
+ *
+ * Since: 40
+ **/
+void
+gs_plugin_update_cache_state_for_repository (GsPlugin *plugin,
+ GsApp *repository)
+{
+ GsPluginPrivate *priv;
+ GHashTableIter iter;
+ g_autoptr(GMutexLocker) locker = NULL;
+ gpointer value;
+ const gchar *repo_id;
+ GsAppState repo_state;
+
+ g_return_if_fail (GS_IS_PLUGIN (plugin));
+ g_return_if_fail (GS_IS_APP (repository));
+
+ priv = gs_plugin_get_instance_private (plugin);
+ repo_id = gs_app_get_id (repository);
+ repo_state = gs_app_get_state (repository);
+
+ locker = g_mutex_locker_new (&priv->cache_mutex);
+
+ g_hash_table_iter_init (&iter, priv->cache);
+ while (g_hash_table_iter_next (&iter, NULL, &value)) {
+ GsApp *app = value;
+ GsAppState app_state = gs_app_get_state (app);
+
+ if (((app_state == GS_APP_STATE_AVAILABLE &&
+ repo_state != GS_APP_STATE_INSTALLED) ||
+ (app_state == GS_APP_STATE_UNAVAILABLE &&
+ repo_state == GS_APP_STATE_INSTALLED)) &&
+ g_strcmp0 (gs_app_get_origin (app), repo_id) == 0) {
+ gs_app_set_state (app, repo_state == GS_APP_STATE_INSTALLED ? GS_APP_STATE_AVAILABLE
: GS_APP_STATE_UNAVAILABLE);
+ }
+ }
+}
diff --git a/lib/gs-plugin.h b/lib/gs-plugin.h
index 175b30612..d66ec3190 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -43,7 +43,9 @@ struct _GsPluginClass
const gchar *realm,
GCallback callback,
gpointer user_data);
- gpointer padding[25];
+ void (*repository_changed) (GsPlugin *plugin,
+ GsApp *repository);
+ gpointer padding[24];
};
typedef struct GsPluginData GsPluginData;
@@ -127,5 +129,10 @@ void gs_plugin_basic_auth_start (GsPlugin *plugin,
const gchar *realm,
GCallback callback,
gpointer user_data);
+void gs_plugin_repository_changed (GsPlugin *plugin,
+ GsApp *repository);
+void gs_plugin_update_cache_state_for_repository
+ (GsPlugin *plugin,
+ GsApp *repository);
G_END_DECLS
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index af862b047..fc5bf3999 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -823,6 +823,8 @@ main (int argc, char **argv)
#endif
NULL);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
+
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c
index 5effadd73..2f8e3e592 100644
--- a/plugins/core/gs-plugin-appstream.c
+++ b/plugins/core/gs-plugin-appstream.c
@@ -36,6 +36,7 @@ void
gs_plugin_initialize (GsPlugin *plugin)
{
GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+ GApplication *application = g_application_get_default ();
/* XbSilo needs external locking as we destroy the silo and build a new
* one when something changes */
@@ -46,6 +47,12 @@ gs_plugin_initialize (GsPlugin *plugin)
/* require settings */
priv->settings = g_settings_new ("org.gnome.software");
+
+ /* Can be NULL when running the self tests */
+ if (application) {
+ g_signal_connect_object (application, "repository-changed",
+ G_CALLBACK (gs_plugin_update_cache_state_for_repository), plugin, G_CONNECT_SWAPPED);
+ }
}
void
diff --git a/plugins/core/gs-self-test.c b/plugins/core/gs-self-test.c
index 53be465a9..2e5cdc55f 100644
--- a/plugins/core/gs-self-test.c
+++ b/plugins/core/gs-self-test.c
@@ -213,6 +213,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* Use a common cache directory for all tests, since the appstream
* plugin uses it and cannot be reinitialised for each test. */
diff --git a/plugins/dpkg/gs-self-test.c b/plugins/dpkg/gs-self-test.c
index e3a76b230..811015175 100644
--- a/plugins/dpkg/gs-self-test.c
+++ b/plugins/dpkg/gs-self-test.c
@@ -73,6 +73,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/plugins/dummy/gs-self-test.c b/plugins/dummy/gs-self-test.c
index cdadfc6da..8634b99e0 100644
--- a/plugins/dummy/gs-self-test.c
+++ b/plugins/dummy/gs-self-test.c
@@ -751,6 +751,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
g_setenv ("GS_XMLB_VERBOSE", "1", TRUE);
/* set all the things required as a dummy test harness */
diff --git a/plugins/fedora-langpacks/gs-self-test.c b/plugins/fedora-langpacks/gs-self-test.c
index df15e33d5..d4ead59b5 100644
--- a/plugins/fedora-langpacks/gs-self-test.c
+++ b/plugins/fedora-langpacks/gs-self-test.c
@@ -72,6 +72,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 07f29c08b..4828921a7 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -1484,6 +1484,9 @@ gs_flatpak_app_install_source (GsFlatpak *self, GsApp *app,
/* success */
gs_app_set_state (app, GS_APP_STATE_INSTALLED);
+
+ gs_plugin_repository_changed (self->plugin, app);
+
return TRUE;
}
@@ -2938,6 +2941,9 @@ gs_flatpak_app_remove_source (GsFlatpak *self,
g_rw_lock_reader_unlock (&self->silo_lock);
gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
+
+ gs_plugin_repository_changed (self->plugin, app);
+
return TRUE;
}
diff --git a/plugins/flatpak/gs-self-test.c b/plugins/flatpak/gs-self-test.c
index 9408d14d8..441be11ff 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -1859,6 +1859,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
g_setenv ("GS_XMLB_VERBOSE", "1", TRUE);
g_setenv ("GS_SELF_TEST_PLUGIN_ERROR_FAIL_HARD", "1", TRUE);
diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c
index b46f572ba..eab12dda1 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -944,6 +944,9 @@ gs_plugin_fwupd_modify_source (GsPlugin *plugin, GsApp *app, gboolean enabled,
}
gs_app_set_state (app, enabled ?
GS_APP_STATE_INSTALLED : GS_APP_STATE_AVAILABLE);
+
+ gs_plugin_repository_changed (plugin, app);
+
return TRUE;
}
diff --git a/plugins/fwupd/gs-self-test.c b/plugins/fwupd/gs-self-test.c
index 2c0bf10b2..625afb7e9 100644
--- a/plugins/fwupd/gs-self-test.c
+++ b/plugins/fwupd/gs-self-test.c
@@ -81,6 +81,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/plugins/modalias/gs-self-test.c b/plugins/modalias/gs-self-test.c
index 92bf88f00..d566c5a27 100644
--- a/plugins/modalias/gs-self-test.c
+++ b/plugins/modalias/gs-self-test.c
@@ -61,6 +61,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
g_setenv ("GS_SELF_TEST_DUMMY_ENABLE", "1", TRUE);
xml = g_strdup_printf ("<?xml version=\"1.0\"?>\n"
diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c
index 0c7309c88..013fddac4 100644
--- a/plugins/packagekit/gs-plugin-packagekit.c
+++ b/plugins/packagekit/gs-plugin-packagekit.c
@@ -181,6 +181,7 @@ gs_plugin_app_origin_repo_enable (GsPlugin *plugin,
{
GsPluginData *priv = gs_plugin_get_data (plugin);
g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);
+ g_autoptr(GsApp) repo_app = NULL;
g_autoptr(PkResults) results = NULL;
g_autoptr(PkError) error_code = NULL;
const gchar *repo_id;
@@ -219,6 +220,11 @@ gs_plugin_app_origin_repo_enable (GsPlugin *plugin,
* UNAVAILABLE state to AVAILABLE */
gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
+ /* Construct a simple fake GsApp for the repository, used only by the signal handler */
+ repo_app = gs_app_new (repo_id);
+ gs_app_set_state (repo_app, GS_APP_STATE_INSTALLED);
+ gs_plugin_repository_changed (plugin, repo_app);
+
return TRUE;
}
@@ -260,6 +266,8 @@ gs_plugin_repo_enable (GsPlugin *plugin,
/* state is known */
gs_app_set_state (app, GS_APP_STATE_INSTALLED);
+ gs_plugin_repository_changed (plugin, app);
+
return TRUE;
}
@@ -499,6 +507,8 @@ gs_plugin_repo_disable (GsPlugin *plugin,
/* state is known */
gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
+ gs_plugin_repository_changed (plugin, app);
+
return TRUE;
}
diff --git a/plugins/packagekit/gs-self-test.c b/plugins/packagekit/gs-self-test.c
index 5dbaf0a7b..8bc86e6e4 100644
--- a/plugins/packagekit/gs-self-test.c
+++ b/plugins/packagekit/gs-self-test.c
@@ -250,6 +250,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/plugins/repos/gs-self-test.c b/plugins/repos/gs-self-test.c
index ff5b3e726..9b7675b66 100644
--- a/plugins/repos/gs-self-test.c
+++ b/plugins/repos/gs-self-test.c
@@ -53,6 +53,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* dummy data */
reposdir = gs_test_get_filename (TESTDATADIR, "yum.repos.d");
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index a3117aeae..b3d7754dc 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -1112,6 +1112,8 @@ gs_plugin_repo_enable (GsPlugin *plugin,
else
gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
+ gs_plugin_repository_changed (plugin, app);
+
return TRUE;
}
diff --git a/plugins/snap/gs-self-test.c b/plugins/snap/gs-self-test.c
index 41696c114..7d3661c59 100644
--- a/plugins/snap/gs-self-test.c
+++ b/plugins/snap/gs-self-test.c
@@ -351,6 +351,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
diff --git a/src/gs-application.c b/src/gs-application.c
index 0117a4e0d..a5f151040 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -67,6 +67,7 @@ static GParamSpec *obj_props[PROP_DEBUG + 1] = { NULL, };
enum {
INSTALL_RESOURCES_DONE,
+ REPOSITORY_CHANGED,
LAST_SIGNAL
};
@@ -1274,6 +1275,24 @@ gs_application_class_init (GsApplicationClass *klass)
NULL,
G_TYPE_NONE, 2,
G_TYPE_STRING, G_TYPE_ERROR);
+
+ /**
+ * GsApplication::repository-changed:
+ * @repository: a #GsApp of the repository
+ *
+ * Emitted when the repository changed, usually when it is enabled or disabled.
+ *
+ * Since: 40
+ */
+ signals[REPOSITORY_CHANGED] = g_signal_new (
+ "repository-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_ACTION | G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1,
+ GS_TYPE_APP);
}
/**
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index b664656c0..b52a47d84 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -49,6 +49,7 @@ main (int argc, char **argv)
#endif
NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]