[gnome-software/mwleeds/hardcoded-pwa-list: 18/18] make stuff better




commit 371464fdf9214a63c874ae8072da0f974bb5cc8e
Author: Phaedrus Leeds <mwleeds protonmail com>
Date:   Thu Mar 24 10:49:34 2022 -0700

    make stuff better

 plugins/epiphany/gs-plugin-epiphany.c | 93 ++++++++++++++++++++++++-----------
 1 file changed, 64 insertions(+), 29 deletions(-)
---
diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c
index e155dcb21..05e53df6b 100644
--- a/plugins/epiphany/gs-plugin-epiphany.c
+++ b/plugins/epiphany/gs-plugin-epiphany.c
@@ -39,7 +39,9 @@ struct _GsPluginEpiphany
        GFileMonitor *monitor; /* (owned) */
        GDBusConnection *connection; /* (owned) */
        guint changed_id;
-       GMutex installed_apps_mutex;
+       GMutex installed_apps_mutex; /* protects installed_apps_cached */
+       /* installed_apps_cached: whether the plugin cache has all installed apps */
+       gboolean installed_apps_cached;
        GHashTable *url_id_map; /* (owned) */
 };
 
@@ -94,8 +96,12 @@ gs_plugin_epiphany_changed_cb (GFileMonitor      *monitor,
 {
        GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (user_data);
 
-       gs_plugin_cache_invalidate (GS_PLUGIN (self));
-       g_hash_table_remove_all (self->url_id_map);
+       {
+         g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->installed_apps_mutex);
+         gs_plugin_cache_invalidate (GS_PLUGIN (self));
+         g_hash_table_remove_all (self->url_id_map);
+         self->installed_apps_cached = FALSE;
+       }
 
        /* With the current API this is the only way to reload the list of
         * installed apps.
@@ -356,14 +362,29 @@ gs_plugin_epiphany_finalize (GObject *object)
        G_OBJECT_CLASS (gs_plugin_epiphany_parent_class)->finalize (object);
 }
 
+static gboolean refresh_installed_apps_cache (GsPluginEpiphany  *self,
+                                             GCancellable      *cancellable,
+                                             GError           **error);
+
+/* Run in @worker */
 static void
 gs_epiphany_refine_app_state (GsPlugin *plugin,
                              GsApp    *app)
 {
+       GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (plugin);
+
+       assert_in_worker (self);
+
        if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) {
                g_autoptr(GsApp) cached_app = NULL;
+               g_autoptr(GError) local_error = NULL;
                const char *appstream_source;
 
+               if (!refresh_installed_apps_cache (self, NULL, &local_error)) {
+                       g_warning ("Failed to refresh installed apps cache: %s", local_error->message);
+                       return;
+               }
+
                /* If we have a cached app, set the state from there. Otherwise
                 * only set the state to available if the app came from
                 * appstream data, because there's no way to re-install an app
@@ -387,8 +408,6 @@ gs_plugin_adopt_app (GsPlugin *plugin,
            gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_PACKAGE) {
                gs_app_set_management_plugin (app, plugin);
        }
-
-       gs_epiphany_refine_app_state (plugin, app);
 }
 
 static void list_installed_apps_thread_cb (GTask        *task,
@@ -504,30 +523,28 @@ gs_epiphany_create_app (GsPluginEpiphany *self,
 }
 
 /* Run in @worker */
-static void
-list_installed_apps_thread_cb (GTask        *task,
-                               gpointer      source_object,
-                               gpointer      task_data,
-                               GCancellable *cancellable)
+static gboolean
+refresh_installed_apps_cache (GsPluginEpiphany  *self,
+                             GCancellable      *cancellable,
+                             GError           **error)
 {
-       GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (source_object);
-       g_autoptr(GsAppList) list = gs_app_list_new ();
-       g_autoptr(GsAppList) installed_cache = gs_app_list_new ();
-       g_autoptr(GError) local_error = NULL;
        g_autoptr(GVariant) webapps_v = NULL;
        g_auto(GStrv) webapps = NULL;
-       g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->installed_apps_mutex);
        guint n_webapps;
+       g_autoptr(GsAppList) installed_cache = gs_app_list_new ();
+       g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->installed_apps_mutex);
 
        assert_in_worker (self);
 
+       if (self->installed_apps_cached)
+               return TRUE;
+
        if (!gs_ephy_web_app_provider_call_get_installed_apps_sync (self->epiphany_proxy,
                                                                    &webapps,
                                                                    cancellable,
-                                                                   &local_error)) {
-               gs_epiphany_error_convert (&local_error);
-               g_task_return_error (task, g_steal_pointer (&local_error));
-               return;
+                                                                   error)) {
+               gs_epiphany_error_convert (error);
+               return FALSE;
        }
 
        n_webapps = g_strv_length (webapps);
@@ -605,6 +622,8 @@ list_installed_apps_thread_cb (GTask        *task,
                metainfo_app_id = g_strconcat ("org.gnome.Software.WebApp_", url_hash, ".desktop", NULL);
                g_debug ("Creating GsApp for webapp with URL %s using app ID %s (desktop file id: %s)",
                         url, metainfo_app_id, desktop_file_id);
+
+               /* App gets added to the plugin cache here */
                app = gs_epiphany_create_app (self, metainfo_app_id);
 
                gs_app_set_state (app, GS_APP_STATE_INSTALLED);
@@ -652,7 +671,6 @@ list_installed_apps_thread_cb (GTask        *task,
                if (desktop_size > 0 || icon_size > 0) {
                        gs_app_set_size_installed (app, desktop_size + icon_size);
                }
-               gs_app_list_add (list, app);
        }
 
        /* Update the state on any apps that were uninstalled outside
@@ -673,16 +691,36 @@ list_installed_apps_thread_cb (GTask        *task,
                if (g_strv_contains ((const char * const *)webapps, installed_app_id))
                        continue;
 
-               /* The app may not be available if it was installed via Epiphany */
+               gs_plugin_cache_remove (GS_PLUGIN (self), gs_app_get_id (app));
+
                appstream_source = gs_app_get_metadata_item (app, "appstream::source-file");
                if (appstream_source)
                        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
                else
                        gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
+       }
 
-               gs_plugin_cache_remove (GS_PLUGIN (self), gs_app_get_id (app));
+       self->installed_apps_cached = TRUE;
+       return TRUE;
+}
+
+/* Run in @worker */
+static void
+list_installed_apps_thread_cb (GTask        *task,
+                               gpointer      source_object,
+                               gpointer      task_data,
+                               GCancellable *cancellable)
+{
+       GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (source_object);
+       g_autoptr(GsAppList) list = gs_app_list_new ();
+       g_autoptr(GError) local_error = NULL;
+
+       if (!refresh_installed_apps_cache (self, cancellable, &local_error)) {
+               g_task_return_error (task, g_steal_pointer (&local_error));
+               return;
        }
 
+       gs_plugin_cache_lookup_by_state (GS_PLUGIN (self), list, GS_APP_STATE_INSTALLED);
        g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref);
 }
 
@@ -944,7 +982,6 @@ gs_plugin_app_remove (GsPlugin      *plugin,
        GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (plugin);
        const char *installed_app_id;
        const char *url;
-       const char *appstream_source;
 
        if (!gs_app_has_management_plugin (app, plugin))
                return TRUE;
@@ -973,12 +1010,10 @@ gs_plugin_app_remove (GsPlugin      *plugin,
        if (url != NULL && *url != '\0')
                g_hash_table_remove (self->url_id_map, url);
 
-       /* The app may not be available if it was installed via Epiphany */
-       appstream_source = gs_app_get_metadata_item (app, "appstream::source-file");
-       if (appstream_source)
-               gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
-       else
-               gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
+       /* The app is not necessarily available; it may have been installed
+        * directly in Epiphany
+        */
+       gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
 
        return TRUE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]