[gnome-software/mwleeds/hardcoded-pwa-list: 229/232] epiphany: Bring some harmony to the different app IDs
- From: Phaedrus Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/mwleeds/hardcoded-pwa-list: 229/232] epiphany: Bring some harmony to the different app IDs
- Date: Mon, 21 Mar 2022 23:15:39 +0000 (UTC)
commit 0471d2dabd6463f09c7beae464794b235ed9418e
Author: Phaedrus Leeds <mwleeds protonmail com>
Date: Wed Mar 16 16:14:15 2022 -0700
epiphany: Bring some harmony to the different app IDs
For most plugins, an app always has a certain app ID regardless of
whether it's installed or not and the app ID never changes (aside from
when apps are renamed in a Flatpak update). But for web apps, the app ID
in the appstream metainfo file can't be the final installed app ID,
which has to have the parent app as a prefix, and there's no way to
predict the parent app ID. Even if we could assume that webapps would
only be installed by Epiphany (and we can't) we couldn't assume which
variant ("org.gnome.Epiphany" vs "org.gnome.Epiphany.Devel"). So the app
ID in the appstream data will be something like
"org.gnome.Software.WebApp_${checksum}.desktop" whereas the installed
app ID would resemble "org.gnome.Epiphany.WebApp_${checksum}.desktop".
This could cause issues, because in gnome-software generally we assume
that there's a one-to-one mapping between the app ID and the GsApp
object (except when a duplicate GsApp is created and then later filtered
out). For example, after an app is installed we don't want to create a
new GsApp object for it in list_installed_apps_thread_cb(); we want to
use the GsApp object that was created by the appstream plugin and used
for the details page.
So try to solve such issues by using the AppStream app ID to create
GsApp objects, storing the installed app ID on the object, and using one
or the other as needed.
plugins/epiphany/gs-plugin-epiphany.c | 63 +++++++++++++++++++++++++++--------
1 file changed, 50 insertions(+), 13 deletions(-)
---
diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c
index b1619e380..face4e705 100644
--- a/plugins/epiphany/gs-plugin-epiphany.c
+++ b/plugins/epiphany/gs-plugin-epiphany.c
@@ -40,6 +40,7 @@ struct _GsPluginEpiphany
GDBusConnection *connection; /* (owned) */
guint changed_id;
GMutex installed_apps_mutex;
+ GHashTable *url_id_map; /* (owned) */
};
G_DEFINE_TYPE (GsPluginEpiphany, gs_plugin_epiphany, GS_TYPE_PLUGIN)
@@ -93,6 +94,8 @@ gs_plugin_epiphany_changed_cb (GFileMonitor *monitor,
{
GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (user_data);
+ gs_plugin_cache_invalidate (GS_PLUGIN (self));
+
/* With the current API this is the only way to reload the list of
* installed apps.
*/
@@ -125,6 +128,13 @@ gs_plugin_epiphany_setup_async (GsPlugin *plugin,
if (connection)
self->connection = g_object_ref (connection);
+ /* This is a mapping from URL to app ID, where the app ID comes from an
+ * appstream file. This allows us to use the AppStream app ID rather
+ * than the one provided by Epiphany for GsApp objects of installed
+ * apps.
+ */
+ self->url_id_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
/* Watch for changes to the set of installed apps in the main thread.
* This will also trigger when other apps' dynamic launchers are
* installed or removed but that is expected to be infrequent.
@@ -331,6 +341,7 @@ gs_plugin_epiphany_dispose (GObject *object)
g_clear_object (&self->monitor);
g_clear_object (&self->worker);
g_clear_object (&self->connection);
+ g_clear_pointer (&self->url_id_map, g_hash_table_unref);
G_OBJECT_CLASS (gs_plugin_epiphany_parent_class)->dispose (object);
}
@@ -517,6 +528,7 @@ list_installed_apps_thread_cb (GTask *task,
const gchar *desktop_path;
const gchar *name;
const gchar *url = NULL;
+ const gchar *metainfo_app_id;
g_autofree char *icon_path = NULL;
const gchar *exec;
int argc;
@@ -574,7 +586,14 @@ list_installed_apps_thread_cb (GTask *task,
desktop_size = g_file_info_get_size (file_info);
}
- app = gs_epiphany_create_app (self, desktop_file_id);
+ /* Create the GsApp using the app id from the appstream
+ * metainfo, but store the app id provided by epiphany for
+ * later use
+ */
+ metainfo_app_id = g_hash_table_lookup (self->url_id_map, url);
+ app = gs_epiphany_create_app (self, metainfo_app_id ? metainfo_app_id : desktop_file_id);
+ gs_app_set_metadata (app, "epiphany::installed-app-id", desktop_file_id);
+
gs_app_set_state (app, GS_APP_STATE_INSTALLED);
gs_app_set_name (app, GS_APP_QUALITY_NORMAL, name);
gs_app_set_launchable (app, AS_LAUNCHABLE_KIND_URL, url);
@@ -629,14 +648,18 @@ list_installed_apps_thread_cb (GTask *task,
gs_plugin_cache_lookup_by_state (GS_PLUGIN (self), installed_cache, GS_APP_STATE_INSTALLED);
for (guint i = 0; i < gs_app_list_length (installed_cache); i++) {
GsApp *app = gs_app_list_index (installed_cache, i);
- const char *app_id = gs_app_get_id (app);
g_autoptr(GsApp) app_cached = NULL;
+ const char *installed_app_id;
+ const char *app_id;
+
+ installed_app_id = gs_app_get_metadata_item (app, "epiphany::installed-app-id");
+ app_id = installed_app_id ? installed_app_id : gs_app_get_id (app);
if (g_strv_contains ((const char * const *)webapps, app_id))
continue;
gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
- gs_plugin_cache_remove (GS_PLUGIN (self), app_id);
+ gs_plugin_cache_remove (GS_PLUGIN (self), gs_app_get_id (app));
}
g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref);
@@ -652,17 +675,14 @@ gs_plugin_epiphany_list_installed_apps_finish (GsPlugin *plugin,
}
static void
-gs_epiphany_refine_app (GsApp *app)
+gs_epiphany_refine_app (GsApp *app,
+ const char *url)
{
- const char *url;
g_autoptr(GUri) uri = NULL;
- url = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_URL);
- if (url == NULL || *url == '\0') {
- /* A launchable URL is required by the AppStream spec */
- g_warning ("Web app %s missing launchable url", gs_app_get_id (app));
- return;
- } else if (!(uri = g_uri_parse (url, G_URI_FLAGS_NONE, NULL))) {
+ g_return_if_fail (url != NULL && *url != '\0');
+
+ if (!(uri = g_uri_parse (url, G_URI_FLAGS_NONE, NULL))) {
g_warning ("Failed to parse URL for web app %s: %s", gs_app_get_id (app), url);
return;
}
@@ -710,13 +730,24 @@ refine_thread_cb (GTask *task,
for (guint i = 0; i < gs_app_list_length (list); i++) {
GsApp *app = gs_app_list_index (list, i);
+ const char *url;
/* not us */
if (gs_app_get_kind (app) != AS_COMPONENT_KIND_WEB_APP ||
gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE)
continue;
- gs_epiphany_refine_app (app);
+ url = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_URL);
+ if (url == NULL || *url == '\0') {
+ /* A launchable URL is required by the AppStream spec */
+ g_warning ("Web app %s missing launchable url", gs_app_get_id (app));
+ continue;
+ }
+
+ g_hash_table_insert (self->url_id_map, g_strdup (url),
+ g_strdup (gs_app_get_id (app)));
+
+ gs_epiphany_refine_app (app, url);
gs_epiphany_refine_app_state (GS_PLUGIN (self), app);
/* Usually the way to refine wildcard apps is to create a new
@@ -729,6 +760,7 @@ refine_thread_cb (GTask *task,
if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD)) {
gs_app_remove_quirk (app, GS_APP_QUIRK_IS_WILDCARD);
gs_app_set_management_plugin (app, GS_PLUGIN (self));
+ gs_plugin_cache_add (GS_PLUGIN (self), gs_app_get_id (app), app);
}
}
@@ -885,13 +917,18 @@ gs_plugin_app_remove (GsPlugin *plugin,
GError **error)
{
GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (plugin);
+ const char *installed_app_id;
+ const char *app_id;
if (!gs_app_has_management_plugin (app, plugin))
return TRUE;
+ installed_app_id = gs_app_get_metadata_item (app, "epiphany::installed-app-id");
+ app_id = installed_app_id ? installed_app_id : gs_app_get_id (app);
+
gs_app_set_state (app, GS_APP_STATE_REMOVING);
if (!gs_ephy_web_app_provider_call_uninstall_sync (self->epiphany_proxy,
- gs_app_get_id (app),
+ app_id,
cancellable,
error)) {
gs_epiphany_error_convert (error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]