[gnome-software: 11/18] gs-plugin-loader: Move the GsOdrsProvider to the plugin loader




commit 18ea86b6d490c7e87db29b4efe684025cb7f17cf
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed May 19 11:31:59 2021 +0100

    gs-plugin-loader: Move the GsOdrsProvider to the plugin loader
    
    This means it’s instantiated in a single place, and so all the state for
    reviews and ratings can be kept synced and not duplicated.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>

 lib/gs-plugin-loader.c |  61 ++++++++++++++++++++++
 lib/gs-plugin-loader.h |   2 +
 src/gs-details-page.c  | 130 +++++++++++++++++++++++++++++++---------------
 src/gs-details-page.h  |   4 ++
 src/gs-moderate-page.c | 138 +++++++++++++++++++++++++++++++++++--------------
 src/gs-moderate-page.h |   4 ++
 src/gs-shell.c         |   5 ++
 7 files changed, 261 insertions(+), 83 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index b71663754..466daae9d 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -24,6 +24,7 @@
 #include "gs-category-manager.h"
 #include "gs-category-private.h"
 #include "gs-ioprio.h"
+#include "gs-os-release.h"
 #include "gs-plugin-loader.h"
 #include "gs-plugin.h"
 #include "gs-plugin-event.h"
@@ -72,6 +73,7 @@ struct _GsPluginLoader
        gulong                   network_metered_notify_handler;
 
        GsCategoryManager       *category_manager;
+       GsOdrsProvider          *odrs_provider;  /* (owned) (nullable) */
 
 #ifdef HAVE_SYSPROF
        SysprofCaptureWriter    *sysprof_writer;  /* (owned) (nullable) */
@@ -2707,6 +2709,7 @@ gs_plugin_loader_dispose (GObject *object)
        g_clear_object (&plugin_loader->settings);
        g_clear_pointer (&plugin_loader->pending_apps, g_ptr_array_unref);
        g_clear_object (&plugin_loader->category_manager);
+       g_clear_object (&plugin_loader->odrs_provider);
 
 #ifdef HAVE_SYSPROF
        g_clear_pointer (&plugin_loader->sysprof_writer, sysprof_capture_writer_unref);
@@ -2831,6 +2834,13 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        gchar *match;
        gchar **projects;
        guint i;
+       const gchar *review_server;
+       g_autofree gchar *user_hash = NULL;
+       const gchar *distro;
+       g_autoptr(GError) local_error = NULL;
+       g_autoptr(GsOsRelease) os_release = NULL;
+       const guint64 odrs_review_max_cache_age_secs = 237000;  /* 1 week */
+       const guint odrs_review_n_results_max = 20;
 
 #ifdef HAVE_SYSPROF
        plugin_loader->sysprof_writer = sysprof_capture_writer_new_from_env (0);
@@ -2871,6 +2881,39 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        /* get the category manager */
        plugin_loader->category_manager = gs_category_manager_new ();
 
+       /* set up the ODRS provider */
+
+       /* get the machine+user ID hash value */
+       user_hash = gs_utils_get_user_hash (&local_error);
+       if (user_hash == NULL) {
+               g_warning ("Failed to get machine+user hash: %s", local_error->message);
+               plugin_loader->odrs_provider = NULL;
+       } else {
+               /* get the distro name (e.g. 'Fedora') but allow a fallback */
+               os_release = gs_os_release_new (&local_error);
+               if (os_release != NULL) {
+                       distro = gs_os_release_get_name (os_release);
+                       if (distro == NULL)
+                               g_warning ("no distro name specified");
+               } else {
+                       g_warning ("failed to get distro name: %s", local_error->message);
+               }
+
+               /* Fallback */
+               if (distro == NULL)
+                       distro = C_("Distribution name", "Unknown");
+
+               review_server = g_settings_get_string (plugin_loader->settings, "review-server");
+
+               if (review_server != NULL && *review_server != '\0')
+                       plugin_loader->odrs_provider = gs_odrs_provider_new (review_server,
+                                                                            user_hash,
+                                                                            distro,
+                                                                            odrs_review_max_cache_age_secs,
+                                                                            odrs_review_n_results_max,
+                                                                            
gs_plugin_loader_get_soup_session (plugin_loader));
+       }
+
        /* the settings key sets the initial override */
        plugin_loader->disallow_updates = g_hash_table_new (g_direct_hash, g_direct_equal);
        gs_plugin_loader_allow_updates_recheck (plugin_loader);
@@ -3858,6 +3901,24 @@ gs_plugin_loader_get_soup_session (GsPluginLoader *plugin_loader)
        return plugin_loader->soup_session;
 }
 
+/**
+ * gs_plugin_loader_get_odrs_provider:
+ * @plugin_loader: a #GsPluginLoader
+ *
+ * Get the singleton #GsOdrsProvider which provides access to ratings and
+ * reviews data from ODRS.
+ *
+ * Returns: (transfer none) (nullable): a #GsOdrsProvider, or %NULL if disabled
+ * Since: 41
+ */
+GsOdrsProvider *
+gs_plugin_loader_get_odrs_provider (GsPluginLoader *plugin_loader)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader), NULL);
+
+       return plugin_loader->odrs_provider;
+}
+
 /**
  * gs_plugin_loader_set_max_parallel_ops:
  * @plugin_loader: a #GsPluginLoader
diff --git a/lib/gs-plugin-loader.h b/lib/gs-plugin-loader.h
index 0f691bd9d..e4fc28103 100644
--- a/lib/gs-plugin-loader.h
+++ b/lib/gs-plugin-loader.h
@@ -14,6 +14,7 @@
 #include "gs-app.h"
 #include "gs-category.h"
 #include "gs-category-manager.h"
+#include "gs-odrs-provider.h"
 #include "gs-plugin-event.h"
 #include "gs-plugin-private.h"
 #include "gs-plugin-job.h"
@@ -73,6 +74,7 @@ GsApp         *gs_plugin_loader_app_create            (GsPluginLoader *plugin_loader,
                                                         const gchar    *unique_id);
 GsApp          *gs_plugin_loader_get_system_app        (GsPluginLoader *plugin_loader);
 SoupSession    *gs_plugin_loader_get_soup_session      (GsPluginLoader *plugin_loader);
+GsOdrsProvider *gs_plugin_loader_get_odrs_provider     (GsPluginLoader *plugin_loader);
 
 /* only useful from the self tests */
 void            gs_plugin_loader_setup_again           (GsPluginLoader *plugin_loader);
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index aeee6f1b5..789bb23f4 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -182,9 +182,13 @@ struct _GsDetailsPage
 G_DEFINE_TYPE (GsDetailsPage, gs_details_page, GS_TYPE_PAGE)
 
 typedef enum {
-       PROP_TITLE = 1,
+       PROP_ODRS_PROVIDER = 1,
+       /* Override properties: */
+       PROP_TITLE,
 } GsDetailsPageProperty;
 
+static GParamSpec *obj_props[PROP_ODRS_PROVIDER + 1]  = { NULL, };
+
 static GsDetailsPageState
 gs_details_page_get_state (GsDetailsPage *self)
 {
@@ -2655,14 +2659,6 @@ gs_details_page_setup (GsPage *page,
 {
        GsDetailsPage *self = GS_DETAILS_PAGE (page);
        GtkAdjustment *adj;
-       g_autoptr(GSettings) settings = NULL;
-       const gchar *review_server;
-       g_autofree gchar *user_hash = NULL;
-       const gchar *distro;
-       g_autoptr(GError) local_error = NULL;
-       g_autoptr(GsOsRelease) os_release = NULL;
-       const guint64 odrs_review_max_cache_age_secs = 237000;  /* 1 week */
-       const guint odrs_review_n_results_max = 20;
 
        g_return_val_if_fail (GS_IS_DETAILS_PAGE (self), TRUE);
 
@@ -2671,40 +2667,6 @@ gs_details_page_setup (GsPage *page,
        self->plugin_loader = g_object_ref (plugin_loader);
        self->cancellable = g_object_ref (cancellable);
 
-       /* set up the ODRS provider */
-
-       /* get the machine+user ID hash value */
-       user_hash = gs_utils_get_user_hash (&local_error);
-       if (user_hash == NULL) {
-               g_warning ("Failed to get machine+user hash: %s", local_error->message);
-               self->odrs_provider = NULL;
-       } else {
-               /* get the distro name (e.g. 'Fedora') but allow a fallback */
-               os_release = gs_os_release_new (&local_error);
-               if (os_release != NULL) {
-                       distro = gs_os_release_get_name (os_release);
-                       if (distro == NULL)
-                               g_warning ("no distro name specified");
-               } else {
-                       g_warning ("failed to get distro name: %s", local_error->message);
-               }
-
-               /* Fallback */
-               if (distro == NULL)
-                       distro = C_("Distribution name", "Unknown");
-
-               settings = g_settings_new ("org.gnome.software");
-               review_server = g_settings_get_string (settings, "review-server");
-
-               if (review_server != NULL && *review_server != '\0')
-                       self->odrs_provider = gs_odrs_provider_new (review_server,
-                                                                   user_hash,
-                                                                   distro,
-                                                                   odrs_review_max_cache_age_secs,
-                                                                   odrs_review_n_results_max,
-                                                                   gs_plugin_loader_get_soup_session 
(plugin_loader));
-       }
-
        g_signal_connect (self->button_review, "clicked",
                          G_CALLBACK (gs_details_page_write_review_cb),
                          self);
@@ -2808,6 +2770,31 @@ gs_details_page_get_property (GObject    *object,
                        g_assert_not_reached ();
                }
                break;
+       case PROP_ODRS_PROVIDER:
+               g_value_set_object (value, gs_details_page_get_odrs_provider (self));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gs_details_page_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+       GsDetailsPage *self = GS_DETAILS_PAGE (object);
+
+       switch ((GsDetailsPageProperty) prop_id) {
+       case PROP_TITLE:
+               /* Read only */
+               g_assert_not_reached ();
+               break;
+       case PROP_ODRS_PROVIDER:
+               gs_details_page_set_odrs_provider (self, g_value_get_object (value));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -2846,6 +2833,7 @@ gs_details_page_class_init (GsDetailsPageClass *klass)
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
        object_class->get_property = gs_details_page_get_property;
+       object_class->set_property = gs_details_page_set_property;
        object_class->dispose = gs_details_page_dispose;
 
        page_class->app_installed = gs_details_page_app_installed;
@@ -2854,6 +2842,23 @@ gs_details_page_class_init (GsDetailsPageClass *klass)
        page_class->reload = gs_details_page_reload;
        page_class->setup = gs_details_page_setup;
 
+       /**
+        * GsDetailsPage:odrs-provider: (nullable)
+        *
+        * An ODRS provider to give access to ratings and reviews information
+        * for the app being displayed.
+        *
+        * If this is %NULL, ratings and reviews will be disabled.
+        *
+        * Since: 41
+        */
+       obj_props[PROP_ODRS_PROVIDER] =
+               g_param_spec_object ("odrs-provider", NULL, NULL,
+                                    GS_TYPE_ODRS_PROVIDER,
+                                    G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+       g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
+
        g_object_class_override_property (object_class, PROP_TITLE, "title");
 
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-details-page.ui");
@@ -2993,3 +2998,42 @@ gs_details_page_new (void)
 {
        return GS_DETAILS_PAGE (g_object_new (GS_TYPE_DETAILS_PAGE, NULL));
 }
+
+/**
+ * gs_details_page_get_odrs_provider:
+ * @self: a #GsDetailsPage
+ *
+ * Get the value of #GsDetailsPage:odrs-provider.
+ *
+ * Returns: (nullable) (transfer none): a #GsOdrsProvider, or %NULL if unset
+ * Since: 41
+ */
+GsOdrsProvider *
+gs_details_page_get_odrs_provider (GsDetailsPage *self)
+{
+       g_return_val_if_fail (GS_IS_DETAILS_PAGE (self), NULL);
+
+       return self->odrs_provider;
+}
+
+/**
+ * gs_details_page_set_odrs_provider:
+ * @self: a #GsDetailsPage
+ * @odrs_provider: (nullable) (transfer none): new #GsOdrsProvider or %NULL
+ *
+ * Set the value of #GsDetailsPage:odrs-provider.
+ *
+ * Since: 41
+ */
+void
+gs_details_page_set_odrs_provider (GsDetailsPage  *self,
+                                   GsOdrsProvider *odrs_provider)
+{
+       g_return_if_fail (GS_IS_DETAILS_PAGE (self));
+       g_return_if_fail (odrs_provider == NULL || GS_IS_ODRS_PROVIDER (odrs_provider));
+
+       if (g_set_object (&self->odrs_provider, odrs_provider)) {
+               gs_details_page_refresh_reviews (self);
+               g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ODRS_PROVIDER]);
+       }
+}
diff --git a/src/gs-details-page.h b/src/gs-details-page.h
index 0c5eda1cd..d7cc1c2da 100644
--- a/src/gs-details-page.h
+++ b/src/gs-details-page.h
@@ -26,4 +26,8 @@ void           gs_details_page_set_url        (GsDetailsPage          *self,
                                                 const gchar            *url);
 GsApp          *gs_details_page_get_app        (GsDetailsPage          *self);
 
+GsOdrsProvider *gs_details_page_get_odrs_provider      (GsDetailsPage  *self);
+void            gs_details_page_set_odrs_provider      (GsDetailsPage  *self,
+                                                        GsOdrsProvider *odrs_provider);
+
 G_END_DECLS
diff --git a/src/gs-moderate-page.c b/src/gs-moderate-page.c
index 46ca7b50f..36d17b74d 100644
--- a/src/gs-moderate-page.c
+++ b/src/gs-moderate-page.c
@@ -41,6 +41,12 @@ struct _GsModeratePage
 
 G_DEFINE_TYPE (GsModeratePage, gs_moderate_page, GS_TYPE_PAGE)
 
+typedef enum {
+       PROP_ODRS_PROVIDER = 1,
+} GsModeratePageProperty;
+
+static GParamSpec *obj_props[PROP_ODRS_PROVIDER + 1]  = { NULL, };
+
 static void
 gs_moderate_page_perhaps_hide_app_row (GsModeratePage *self, GsApp *app)
 {
@@ -300,14 +306,6 @@ gs_moderate_page_setup (GsPage *page,
                         GError **error)
 {
        GsModeratePage *self = GS_MODERATE_PAGE (page);
-       g_autoptr(GSettings) settings = NULL;
-       const gchar *review_server;
-       g_autofree gchar *user_hash = NULL;
-       const gchar *distro;
-       g_autoptr(GError) local_error = NULL;
-       g_autoptr(GsOsRelease) os_release = NULL;
-       const guint64 odrs_review_max_cache_age_secs = 237000;  /* 1 week */
-       const guint odrs_review_n_results_max = 20;
 
        g_return_val_if_fail (GS_IS_MODERATE_PAGE (self), TRUE);
 
@@ -319,42 +317,43 @@ gs_moderate_page_setup (GsPage *page,
                                      gs_moderate_page_list_header_func,
                                      self, NULL);
 
-       /* set up the ODRS provider */
-
-       /* get the machine+user ID hash value */
-       /* TODO: deduplicate this with the identical code in GsDetailsPage */
-       user_hash = gs_utils_get_user_hash (&local_error);
-       if (user_hash == NULL) {
-               g_warning ("Failed to get machine+user hash: %s", local_error->message);
-               self->odrs_provider = NULL;
-       } else {
-               /* get the distro name (e.g. 'Fedora') but allow a fallback */
-               os_release = gs_os_release_new (&local_error);
-               if (os_release != NULL) {
-                       distro = gs_os_release_get_name (os_release);
-                       if (distro == NULL)
-                               g_warning ("no distro name specified");
-               } else {
-                       g_warning ("failed to get distro name: %s", local_error->message);
-               }
-
-               /* Fallback */
-               if (distro == NULL)
-                       distro = C_("Distribution name", "Unknown");
+       return TRUE;
+}
 
-               settings = g_settings_new ("org.gnome.software");
-               review_server = g_settings_get_string (settings, "review-server");
+static void
+gs_moderate_page_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+       GsModeratePage *self = GS_MODERATE_PAGE (object);
 
-               if (review_server != NULL && *review_server != '\0')
-                       self->odrs_provider = gs_odrs_provider_new (review_server,
-                                                                   user_hash,
-                                                                   distro,
-                                                                   odrs_review_max_cache_age_secs,
-                                                                   odrs_review_n_results_max,
-                                                                   gs_plugin_loader_get_soup_session 
(plugin_loader));
+       switch ((GsModeratePageProperty) prop_id) {
+       case PROP_ODRS_PROVIDER:
+               g_value_set_object (value, gs_moderate_page_get_odrs_provider (self));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
        }
+}
 
-       return TRUE;
+static void
+gs_moderate_page_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+       GsModeratePage *self = GS_MODERATE_PAGE (object);
+
+       switch ((GsModeratePageProperty) prop_id) {
+       case PROP_ODRS_PROVIDER:
+               gs_moderate_page_set_odrs_provider (self, g_value_get_object (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
 }
 
 static void
@@ -381,11 +380,31 @@ gs_moderate_page_class_init (GsModeratePageClass *klass)
        GsPageClass *page_class = GS_PAGE_CLASS (klass);
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+       object_class->get_property = gs_moderate_page_get_property;
+       object_class->set_property = gs_moderate_page_set_property;
        object_class->dispose = gs_moderate_page_dispose;
        page_class->switch_to = gs_moderate_page_switch_to;
        page_class->reload = gs_moderate_page_reload;
        page_class->setup = gs_moderate_page_setup;
 
+       /**
+        * GsModeratePage:odrs-provider: (nullable)
+        *
+        * An ODRS provider to give access to ratings and reviews information
+        * for the apps being displayed.
+        *
+        * If this is %NULL, ratings and reviews will be disabled and the page
+        * will be effectively useless.
+        *
+        * Since: 41
+        */
+       obj_props[PROP_ODRS_PROVIDER] =
+               g_param_spec_object ("odrs-provider", NULL, NULL,
+                                    GS_TYPE_ODRS_PROVIDER,
+                                    G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+       g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
+
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-moderate-page.ui");
 
        gtk_widget_class_bind_template_child (widget_class, GsModeratePage, list_box_install);
@@ -415,3 +434,42 @@ gs_moderate_page_new (void)
        self = g_object_new (GS_TYPE_MODERATE_PAGE, NULL);
        return GS_MODERATE_PAGE (self);
 }
+
+/**
+ * gs_moderate_page_get_odrs_provider:
+ * @self: a #GsModeratePage
+ *
+ * Get the value of #GsModeratePage:odrs-provider.
+ *
+ * Returns: (nullable) (transfer none): a #GsOdrsProvider, or %NULL if unset
+ * Since: 41
+ */
+GsOdrsProvider *
+gs_moderate_page_get_odrs_provider (GsModeratePage *self)
+{
+       g_return_val_if_fail (GS_IS_MODERATE_PAGE (self), NULL);
+
+       return self->odrs_provider;
+}
+
+/**
+ * gs_moderate_page_set_odrs_provider:
+ * @self: a #GsModeratePage
+ * @odrs_provider: (nullable) (transfer none): new #GsOdrsProvider or %NULL
+ *
+ * Set the value of #GsModeratePage:odrs-provider.
+ *
+ * Since: 41
+ */
+void
+gs_moderate_page_set_odrs_provider (GsModeratePage *self,
+                                    GsOdrsProvider *odrs_provider)
+{
+       g_return_if_fail (GS_IS_MODERATE_PAGE (self));
+       g_return_if_fail (odrs_provider == NULL || GS_IS_ODRS_PROVIDER (odrs_provider));
+
+       if (g_set_object (&self->odrs_provider, odrs_provider)) {
+               gs_moderate_page_reload (GS_PAGE (self));
+               g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ODRS_PROVIDER]);
+       }
+}
diff --git a/src/gs-moderate-page.h b/src/gs-moderate-page.h
index cce54d60e..12a11af03 100644
--- a/src/gs-moderate-page.h
+++ b/src/gs-moderate-page.h
@@ -19,4 +19,8 @@ G_DECLARE_FINAL_TYPE (GsModeratePage, gs_moderate_page, GS, MODERATE_PAGE, GsPag
 
 GsModeratePage *gs_moderate_page_new           (void);
 
+GsOdrsProvider *gs_moderate_page_get_odrs_provider     (GsModeratePage *self);
+void            gs_moderate_page_set_odrs_provider     (GsModeratePage *self,
+                                                        GsOdrsProvider *odrs_provider);
+
 G_END_DECLS
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 64bc01161..ec308648b 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -2086,6 +2086,7 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
 {
        g_autoptr(GtkAccelGroup) accel_group = NULL;
        GClosure *closure;
+       GsOdrsProvider *odrs_provider;
 
        g_return_if_fail (GS_IS_SHELL (shell));
 
@@ -2123,6 +2124,10 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
        g_signal_connect (shell->settings, "changed::download-updates",
                          (GCallback) gs_shell_download_updates_changed_cb, shell);
 
+       odrs_provider = gs_plugin_loader_get_odrs_provider (shell->plugin_loader);
+       gs_details_page_set_odrs_provider (GS_DETAILS_PAGE (shell->pages[GS_SHELL_MODE_DETAILS]), 
odrs_provider);
+       gs_moderate_page_set_odrs_provider (GS_MODERATE_PAGE (shell->pages[GS_SHELL_MODE_MODERATE]), 
odrs_provider);
+
        /* coldplug */
        gs_shell_rescan_events (shell);
 


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