[gnome-software: 12/21] gs-plugin: Add D-Bus connection properties




commit 03bb2f20e3a4b2bc2791aa4dedf86fbaf0c43a9e
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed Mar 30 16:00:03 2022 +0100

    gs-plugin: Add D-Bus connection properties
    
    These must be set at construction time, forcing the caller to setup bus
    connections already. This avoids having to set them up during setup of
    the plugin itself. This should be an overall simplification of plugins’
    code.
    
    By providing D-Bus connections to plugins, rather than having plugins
    construct them themselves, it becomes easy to pass mock D-Bus
    connections in during unit tests.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    Fixes: #1694

 lib/gs-plugin-loader.c  |   5 +-
 lib/gs-plugin-private.h |   9 ++-
 lib/gs-plugin.c         | 155 ++++++++++++++++++++++++++++++++++++++++++++----
 lib/gs-self-test.c      |   6 +-
 4 files changed, 162 insertions(+), 13 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index b92b6b3de..94a7e0442 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -1880,7 +1880,10 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        g_autoptr(GError) error = NULL;
 
        /* create plugin from file */
-       plugin = gs_plugin_create (filename, &error);
+       plugin = gs_plugin_create (filename,
+                                  plugin_loader->session_bus_connection,
+                                  plugin_loader->system_bus_connection,
+                                  &error);
        if (plugin == NULL) {
                g_warning ("Failed to load %s: %s", filename, error->message);
                return;
diff --git a/lib/gs-plugin-private.h b/lib/gs-plugin-private.h
index 59e7c9737..3a4485648 100644
--- a/lib/gs-plugin-private.h
+++ b/lib/gs-plugin-private.h
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include <gio/gio.h>
 #include <glib-object.h>
 #include <gmodule.h>
 
@@ -15,8 +16,11 @@
 
 G_BEGIN_DECLS
 
-GsPlugin       *gs_plugin_new                          (void);
+GsPlugin       *gs_plugin_new                          (GDBusConnection *session_bus_connection,
+                                                        GDBusConnection *system_bus_connection);
 GsPlugin       *gs_plugin_create                       (const gchar    *filename,
+                                                        GDBusConnection *session_bus_connection,
+                                                        GDBusConnection *system_bus_connection,
                                                         GError         **error);
 const gchar    *gs_plugin_error_to_string              (GsPluginError   error);
 const gchar    *gs_plugin_action_to_string             (GsPluginAction  action);
@@ -47,4 +51,7 @@ gchar         *gs_plugin_refine_flags_to_string       (GsPluginRefineFlags refine_flags);
 void            gs_plugin_set_network_monitor          (GsPlugin               *plugin,
                                                         GNetworkMonitor        *monitor);
 
+GDBusConnection        *gs_plugin_get_session_bus_connection   (GsPlugin       *self);
+GDBusConnection        *gs_plugin_get_system_bus_connection    (GsPlugin       *self);
+
 G_END_DECLS
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index f25a5afd5..eace3354f 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -69,6 +69,9 @@ typedef struct
        guint                    timer_id;
        GMutex                   timer_mutex;
        GNetworkMonitor         *network_monitor;
+
+       GDBusConnection         *session_bus_connection;  /* (owned) (not nullable) */
+       GDBusConnection         *system_bus_connection;  /* (owned) (not nullable) */
 } GsPluginPrivate;
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GsPlugin, gs_plugin, G_TYPE_OBJECT)
@@ -77,9 +80,11 @@ G_DEFINE_QUARK (gs-plugin-error-quark, gs_plugin_error)
 
 typedef enum {
        PROP_FLAGS = 1,
+       PROP_SESSION_BUS_CONNECTION,
+       PROP_SYSTEM_BUS_CONNECTION,
 } GsPluginProperty;
 
-static GParamSpec *obj_props[PROP_FLAGS + 1] = { NULL, };
+static GParamSpec *obj_props[PROP_SYSTEM_BUS_CONNECTION + 1] = { NULL, };
 
 enum {
        SIGNAL_UPDATES_CHANGED,
@@ -151,16 +156,23 @@ gs_plugin_set_name (GsPlugin *plugin, const gchar *name)
 /**
  * gs_plugin_create:
  * @filename: an absolute filename
+ * @session_bus_connection: (not nullable) (transfer none): a session bus
+ *   connection to use
+ * @system_bus_connection: (not nullable) (transfer none): a system bus
+ *   connection to use
  * @error: a #GError, or %NULL
  *
  * Creates a new plugin from an external module.
  *
- * Returns: the #GsPlugin or %NULL
+ * Returns: (transfer full): the #GsPlugin, or %NULL on error
  *
- * Since: 3.22
+ * Since: 43
  **/
 GsPlugin *
-gs_plugin_create (const gchar *filename, GError **error)
+gs_plugin_create (const gchar      *filename,
+                  GDBusConnection  *session_bus_connection,
+                  GDBusConnection  *system_bus_connection,
+                  GError          **error)
 {
        GsPlugin *plugin = NULL;
        GsPluginPrivate *priv;
@@ -198,7 +210,10 @@ gs_plugin_create (const gchar *filename, GError **error)
        plugin_type = query_type_function ();
        g_assert (g_type_is_a (plugin_type, GS_TYPE_PLUGIN));
 
-       plugin = g_object_new (plugin_type, NULL);
+       plugin = g_object_new (plugin_type,
+                              "session-bus-connection", session_bus_connection,
+                              "system-bus-connection", system_bus_connection,
+                              NULL);
        priv = gs_plugin_get_instance_private (plugin);
        priv->module = g_steal_pointer (&module);
 
@@ -206,6 +221,18 @@ gs_plugin_create (const gchar *filename, GError **error)
        return plugin;
 }
 
+static void
+gs_plugin_dispose (GObject *object)
+{
+       GsPlugin *plugin = GS_PLUGIN (object);
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+
+       g_clear_object (&priv->session_bus_connection);
+       g_clear_object (&priv->system_bus_connection);
+
+       G_OBJECT_CLASS (gs_plugin_parent_class)->dispose (object);
+}
+
 static void
 gs_plugin_finalize (GObject *object)
 {
@@ -1686,6 +1713,19 @@ gs_plugin_refine_flags_to_string (GsPluginRefineFlags refine_flags)
        return g_strjoinv (",", (gchar**) cstrs->pdata);
 }
 
+static void
+gs_plugin_constructed (GObject *object)
+{
+       GsPlugin *plugin = GS_PLUGIN (object);
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+
+       G_OBJECT_CLASS (gs_plugin_parent_class)->constructed (object);
+
+       /* Check all required properties have been set. */
+       g_assert (priv->session_bus_connection != NULL);
+       g_assert (priv->system_bus_connection != NULL);
+}
+
 static void
 gs_plugin_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
@@ -1697,6 +1737,16 @@ gs_plugin_set_property (GObject *object, guint prop_id, const GValue *value, GPa
                priv->flags = g_value_get_flags (value);
                g_object_notify_by_pspec (G_OBJECT (plugin), obj_props[PROP_FLAGS]);
                break;
+       case PROP_SESSION_BUS_CONNECTION:
+               /* Construct only */
+               g_assert (priv->session_bus_connection == NULL);
+               priv->session_bus_connection = g_value_dup_object (value);
+               break;
+       case PROP_SYSTEM_BUS_CONNECTION:
+               /* Construct only */
+               g_assert (priv->system_bus_connection == NULL);
+               priv->system_bus_connection = g_value_dup_object (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1713,6 +1763,12 @@ gs_plugin_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
        case PROP_FLAGS:
                g_value_set_flags (value, priv->flags);
                break;
+       case PROP_SESSION_BUS_CONNECTION:
+               g_value_set_object (value, priv->session_bus_connection);
+               break;
+       case PROP_SYSTEM_BUS_CONNECTION:
+               g_value_set_object (value, priv->system_bus_connection);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1724,8 +1780,10 @@ gs_plugin_class_init (GsPluginClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+       object_class->constructed = gs_plugin_constructed;
        object_class->set_property = gs_plugin_set_property;
        object_class->get_property = gs_plugin_get_property;
+       object_class->dispose = gs_plugin_dispose;
        object_class->finalize = gs_plugin_finalize;
 
        /**
@@ -1740,6 +1798,36 @@ gs_plugin_class_init (GsPluginClass *klass)
                                    GS_TYPE_PLUGIN_FLAGS, GS_PLUGIN_FLAGS_NONE,
                                    G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
 
+       /**
+        * GsPlugin:session-bus-connection: (not nullable)
+        *
+        * A connection to the D-Bus session bus.
+        *
+        * This must be set at construction time and will not be %NULL
+        * afterwards.
+        *
+        * Since: 43
+        */
+       obj_props[PROP_SESSION_BUS_CONNECTION] =
+               g_param_spec_object ("session-bus-connection", NULL, NULL,
+                                    G_TYPE_DBUS_CONNECTION,
+                                    G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY);
+
+       /**
+        * GsPlugin:system-bus-connection: (not nullable)
+        *
+        * A connection to the D-Bus system bus.
+        *
+        * This must be set at construction time and will not be %NULL
+        * afterwards.
+        *
+        * Since: 43
+        */
+       obj_props[PROP_SYSTEM_BUS_CONNECTION] =
+               g_param_spec_object ("system-bus-connection", NULL, NULL,
+                                    G_TYPE_DBUS_CONNECTION,
+                                    G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | 
G_PARAM_EXPLICIT_NOTIFY);
+
        g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
 
        signals [SIGNAL_UPDATES_CHANGED] =
@@ -1824,19 +1912,28 @@ gs_plugin_init (GsPlugin *plugin)
 
 /**
  * gs_plugin_new:
+ * @session_bus_connection: (not nullable) (transfer none): a session bus
+ *   connection to use
+ * @system_bus_connection: (not nullable) (transfer none): a system bus
+ *   connection to use
  *
  * Creates a new plugin.
  *
  * Returns: a #GsPlugin
  *
- * Since: 3.22
+ * Since: 43
  **/
 GsPlugin *
-gs_plugin_new (void)
+gs_plugin_new (GDBusConnection *session_bus_connection,
+               GDBusConnection *system_bus_connection)
 {
-       GsPlugin *plugin;
-       plugin = g_object_new (GS_TYPE_PLUGIN, NULL);
-       return plugin;
+       g_return_val_if_fail (G_IS_DBUS_CONNECTION (session_bus_connection), NULL);
+       g_return_val_if_fail (G_IS_DBUS_CONNECTION (system_bus_connection), NULL);
+
+       return g_object_new (GS_TYPE_PLUGIN,
+                            "session-bus-connection", session_bus_connection,
+                            "system-bus-connection", system_bus_connection,
+                            NULL);
 }
 
 typedef struct {
@@ -2002,3 +2099,41 @@ gs_plugin_ask_untrusted (GsPlugin *plugin,
                       &accepts);
        return accepts;
 }
+
+/**
+ * gs_plugin_get_session_bus_connection:
+ * @self: a #GsPlugin
+ *
+ * Get the D-Bus session bus connection in use by the plugin.
+ *
+ * Returns: (transfer none) (not nullable): a D-Bus connection
+ * Since: 43
+ */
+GDBusConnection *
+gs_plugin_get_session_bus_connection (GsPlugin *self)
+{
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (self);
+
+       g_return_val_if_fail (GS_IS_PLUGIN (self), NULL);
+
+       return priv->session_bus_connection;
+}
+
+/**
+ * gs_plugin_get_system_bus_connection:
+ * @self: a #GsPlugin
+ *
+ * Get the D-Bus system bus connection in use by the plugin.
+ *
+ * Returns: (transfer none) (not nullable): a D-Bus connection
+ * Since: 43
+ */
+GDBusConnection *
+gs_plugin_get_system_bus_connection (GsPlugin *self)
+{
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (self);
+
+       g_return_val_if_fail (GS_IS_PLUGIN (self), NULL);
+
+       return priv->system_bus_connection;
+}
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index 9a75d5b12..165eca1f0 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -174,6 +174,7 @@ gs_plugin_download_rewrite_func (void)
 {
        g_autofree gchar *css = NULL;
        g_autoptr(GError) error = NULL;
+       g_autoptr(GDBusConnection) bus_connection = NULL;
        g_autoptr(GsPlugin) plugin = NULL;
        const gchar *resource = "background:\n"
                                " url('file://" DATADIR "/gnome-software/featured-maps.png')\n"
@@ -187,7 +188,10 @@ gs_plugin_download_rewrite_func (void)
        }
 
        /* test rewrite */
-       plugin = gs_plugin_new ();
+       bus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+       g_assert_no_error (error);
+
+       plugin = gs_plugin_new (bus_connection, bus_connection);
        gs_plugin_set_name (plugin, "self-test");
        css = gs_plugin_download_rewrite_resource (plugin,
                                                   NULL, /* app */


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