[gnome-software/961-gsapp-state-not-updated-after-repository-enable-disable] 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] GsApp: State not updated after repository enable/disable
- Date: Tue, 2 Feb 2021 08:25:50 +0000 (UTC)
commit 00621f977aa609732e2376cd270cfadd799c6c71
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 | 13 ++++
lib/gs-plugin.c | 99 +++++++++++++++++++++++++++++++
lib/gs-plugin.h | 9 ++-
lib/gs-self-test.c | 1 +
plugins/core/gs-plugin-appstream.c | 3 +
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, 175 insertions(+), 1 deletion(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index b951cdc70..7f9d00f62 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -2181,6 +2181,16 @@ 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)
+{
+ g_signal_emit_by_name (g_application_get_default (),
+ "repository-changed",
+ repository);
+}
+
static void
gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
const gchar *filename)
@@ -2213,6 +2223,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, priv->soup_session);
gs_plugin_set_locale (plugin, priv->locale);
gs_plugin_set_language (plugin, priv->language);
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index cf1d788df..de22bbf9b 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
};
@@ -2028,6 +2029,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
@@ -2069,3 +2077,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 e2119317d..288126c75 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -44,7 +44,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;
@@ -128,5 +130,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 5c353987f..9c66bed58 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -807,6 +807,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/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c
index f8fa1864e..06e639018 100644
--- a/plugins/core/gs-plugin-appstream.c
+++ b/plugins/core/gs-plugin-appstream.c
@@ -46,6 +46,9 @@ gs_plugin_initialize (GsPlugin *plugin)
/* require settings */
priv->settings = g_settings_new ("org.gnome.software");
+
+ g_signal_connect_object (g_application_get_default (), "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 364c6c20c..6cd043f2b 100644
--- a/plugins/core/gs-self-test.c
+++ b/plugins/core/gs-self-test.c
@@ -211,6 +211,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 bc8da5015..fa5397f01 100644
--- a/plugins/dummy/gs-self-test.c
+++ b/plugins/dummy/gs-self-test.c
@@ -750,6 +750,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 ae2344ced..c8f561520 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 c528fb5d0..e13e2590d 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -1474,6 +1474,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;
}
@@ -2917,6 +2920,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 f07dc65fd..7f7437263 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -1857,6 +1857,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 2a99d9957..ff2a71754 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -947,6 +947,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 ffd308493..b3702e4aa 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 5cbb39c34..b099447a8 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 7f158ed25..5c4f8f64c 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;
}
@@ -500,6 +508,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 38c3d9906..0d26dfad6 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 d3aa69e1e..f192322ef 100644
--- a/plugins/snap/gs-self-test.c
+++ b/plugins/snap/gs-self-test.c
@@ -350,6 +350,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 92dd3cd67..c6fce42e2 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -59,6 +59,7 @@ G_DEFINE_TYPE (GsApplication, gs_application, GTK_TYPE_APPLICATION);
enum {
INSTALL_RESOURCES_DONE,
+ REPOSITORY_CHANGED,
LAST_SIGNAL
};
@@ -1188,6 +1189,24 @@ gs_application_class_init (GsApplicationClass *class)
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 (class),
+ G_SIGNAL_ACTION | G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1,
+ GS_TYPE_APP);
}
GsApplication *
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 43d94c5e6..961153640 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -50,6 +50,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]