From add310d9eb8274739fdce9e4f439e86ebf376f6b Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Sun, 4 Jun 2023 22:22:26 +0300 Subject: [PATCH] dbus: refactor WpDBus into a plugin called dbus-connection Now that we have proper module load order, we can have this shared dbus connection in a module instead of the library. The module has to be loaded before any other modules that need it, obviously. --- lib/wp/dbus.c | 373 ------------------ lib/wp/dbus.h | 59 --- lib/wp/meson.build | 2 - lib/wp/wp.h | 1 - modules/dbus-connection-state.h | 24 ++ modules/meson.build | 15 + modules/module-dbus-connection.c | 250 ++++++++++++ modules/module-portal-permissionstore.c | 88 ++--- modules/module-reserve-device/plugin.c | 85 ++-- modules/module-reserve-device/plugin.h | 8 +- .../module-reserve-device/reserve-device.c | 11 +- modules/module-reserve-device/transitions.c | 3 +- src/config/wireplumber.conf | 7 + tests/modules/dbus-connection.c | 101 +++++ tests/modules/meson.build | 7 + tests/modules/reserve-device.c | 102 ++--- tests/wp/dbus.c | 103 ----- tests/wp/meson.build | 9 - 18 files changed, 519 insertions(+), 729 deletions(-) delete mode 100644 lib/wp/dbus.c delete mode 100644 lib/wp/dbus.h create mode 100644 modules/dbus-connection-state.h create mode 100644 modules/module-dbus-connection.c create mode 100644 tests/modules/dbus-connection.c delete mode 100644 tests/wp/dbus.c diff --git a/lib/wp/dbus.c b/lib/wp/dbus.c deleted file mode 100644 index c4ae1cda..00000000 --- a/lib/wp/dbus.c +++ /dev/null @@ -1,373 +0,0 @@ -/* WirePlumber - * - * Copyright © 2022 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#include "private/registry.h" -#include "log.h" -#include "wpenums.h" -#include "dbus.h" - -WP_DEFINE_LOCAL_LOG_TOPIC ("wp-dbus") - -enum { - STEP_DBUS_ENABLE = WP_TRANSITION_STEP_CUSTOM_START, -}; - -enum -{ - PROP_DBUS_0, - PROP_DBUS_BUS_TYPE, - PROP_DBUS_STATE, -}; - -struct _WpDbus -{ - WpObject parent; - - /* Props */ - GBusType bus_type; - WpDBusState state; - - GCancellable *cancellable; - GDBusConnection *connection; -}; - -static void on_connection_closed (GDBusConnection *connection, gboolean - remote_peer_vanished, GError *error, gpointer data); - -G_DEFINE_TYPE (WpDbus, wp_dbus, WP_TYPE_OBJECT) - -static void -wp_dbus_init (WpDbus * self) -{ -} - -static void -wp_dbus_set_state (WpDbus *self, WpDBusState new_state) -{ - if (self->state != new_state) { - self->state = new_state; - g_object_notify (G_OBJECT (self), "state"); - } -} - -static void -on_got_bus (GObject * obj, GAsyncResult * res, gpointer data) -{ - WpTransition *transition; - WpDbus *self; - g_autoptr (GError) error = NULL; - - if (WP_IS_TRANSITION (data)) { - // coming from wp_dbus_enable - transition = WP_TRANSITION (data); - self = wp_transition_get_source_object (transition); - } else { - // coming from on_sync_reconnect - transition = NULL; - self = WP_DBUS (data); - } - - self->connection = g_dbus_connection_new_for_address_finish (res, &error); - if (!self->connection) { - if (transition) { - g_prefix_error (&error, "Failed to connect to bus: "); - wp_transition_return_error (transition, g_steal_pointer (&error)); - } - return; - } - - wp_debug_object (self, "Connected to bus"); - - /* set up connection */ - g_signal_connect_object (self->connection, "closed", - G_CALLBACK (on_connection_closed), self, 0); - g_dbus_connection_set_exit_on_close (self->connection, FALSE); - - wp_dbus_set_state (self, WP_DBUS_STATE_CONNECTED); - - wp_object_update_features (WP_OBJECT (self), WP_DBUS_FEATURE_ENABLED, 0); -} - -static gboolean -do_connect (WpDbus *self, GAsyncReadyCallback callback, gpointer data, - GError **error) -{ - g_autofree gchar *address = NULL; - - address = g_dbus_address_get_for_bus_sync (self->bus_type, NULL, error); - if (!address) { - g_prefix_error (error, "Error acquiring bus address: "); - return FALSE; - } - - wp_dbus_set_state (self, WP_DBUS_STATE_CONNECTING); - - wp_debug_object (self, "Connecting to bus: %s", address); - g_dbus_connection_new_for_address (address, - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | - G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, - NULL, self->cancellable, callback, data); - return TRUE; -} - -static void -on_sync_reconnect (WpCore * core, GAsyncResult * res, WpDbus * self) -{ - g_autoptr (GError) error = NULL; - - if (!wp_core_sync_finish (core, res, &error)) { - wp_warning_object (self, "core sync error: %s", error->message); - return; - } - - if (!do_connect (self, on_got_bus, self, &error)) - wp_info_object (self, "Cannot reconnect on sync: %s", error->message); -} - -static void -on_connection_closed (GDBusConnection *connection, - gboolean remote_peer_vanished, GError *error, gpointer data) -{ - WpDbus *self = WP_DBUS (data); - g_autoptr (WpCore) core = NULL; - - wp_info_object (self, "DBus connection closed: %s", error->message); - - g_clear_object (&self->connection); - wp_dbus_set_state (self, WP_DBUS_STATE_CLOSED); - - /* try to reconnect on idle if connection was closed */ - core = wp_object_get_core (WP_OBJECT (self)); - if (core && wp_core_is_connected (core)) { - wp_info_object (self, "Trying to reconnect on sync"); - wp_core_sync_closure (core, NULL, g_cclosure_new_object ( - G_CALLBACK (on_sync_reconnect), G_OBJECT (self))); - } -} - -static void -wp_dbus_enable (WpDbus *self, WpTransition *transition) -{ - g_autoptr (GError) error = NULL; - if (!do_connect (self, on_got_bus, transition, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } -} - -static void -wp_dbus_disable (WpDbus *self) -{ - g_cancellable_cancel (self->cancellable); - - g_clear_object (&self->connection); - wp_dbus_set_state (self, WP_DBUS_STATE_CLOSED); - - g_clear_object (&self->cancellable); - self->cancellable = g_cancellable_new (); - - wp_object_update_features (WP_OBJECT (self), 0, WP_DBUS_FEATURE_ENABLED); -} - -static WpObjectFeatures -wp_dbus_get_supported_features (WpObject * self) -{ - return WP_DBUS_FEATURE_ENABLED; -} - -static guint -wp_dbus_activate_get_next_step (WpObject * object, - WpFeatureActivationTransition * t, guint step, WpObjectFeatures missing) -{ - switch (step) { - case WP_TRANSITION_STEP_NONE: - return STEP_DBUS_ENABLE; - case STEP_DBUS_ENABLE: - return WP_TRANSITION_STEP_NONE; - default: - return WP_TRANSITION_STEP_ERROR; - } -} - -static void -wp_dbus_activate_execute_step (WpObject * object, - WpFeatureActivationTransition * t, guint step, WpObjectFeatures missing) -{ - WpDbus *self = WP_DBUS (object); - WpTransition *transition = WP_TRANSITION (t); - - switch (step) { - case STEP_DBUS_ENABLE: - wp_dbus_enable (self, transition); - break; - - case WP_TRANSITION_STEP_ERROR: - break; - - default: - g_return_if_reached (); - } -} - -static void -wp_dbus_deactivate (WpObject * object, WpObjectFeatures features) -{ - WpDbus *self = WP_DBUS (object); - guint current = wp_object_get_active_features (object); - - if (features & current & WP_DBUS_FEATURE_ENABLED) - wp_dbus_disable (self); -} - -static void -wp_dbus_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpDbus *self = WP_DBUS (object); - - switch (property_id) { - case PROP_DBUS_BUS_TYPE: - g_value_set_enum (value, self->bus_type); - break; - case PROP_DBUS_STATE: - g_value_set_enum (value, self->state); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_dbus_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - WpDbus *self = WP_DBUS (object); - - switch (property_id) { - case PROP_DBUS_BUS_TYPE: - self->bus_type = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_dbus_class_init (WpDbusClass * klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpObjectClass *wpobject_class = (WpObjectClass *) klass; - - object_class->set_property = wp_dbus_set_property; - object_class->get_property = wp_dbus_get_property; - - wpobject_class->get_supported_features = wp_dbus_get_supported_features; - wpobject_class->activate_get_next_step = wp_dbus_activate_get_next_step; - wpobject_class->activate_execute_step = wp_dbus_activate_execute_step; - wpobject_class->deactivate = wp_dbus_deactivate; - - g_object_class_install_property (object_class, PROP_DBUS_BUS_TYPE, - g_param_spec_enum ("bus-type", "bus-type", "The bus type", - G_TYPE_BUS_TYPE, G_BUS_TYPE_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_DBUS_STATE, - g_param_spec_enum ("state", "state", "The dbus connection state", - WP_TYPE_DBUS_STATE, WP_DBUS_STATE_CLOSED, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -} - -static gboolean -find_dbus_func (gpointer object, gpointer p) -{ - GBusType *bus_type = p; - - if (!WP_IS_DBUS (object) || !bus_type) - return FALSE; - - return wp_dbus_get_bus_type (WP_DBUS (object)) == *bus_type; -} - -/*! - * \brief Returns the dbus instance that is associated with the given core and - * bus type. - * - * This method will also create the instance and register it with the core - * if it had not been created before. - * - * \param core the core - * \param bus_type the bus type - * \return (transfer full): the dbus instance - */ -WpDbus * -wp_dbus_get_instance (WpCore *core, GBusType bus_type) -{ - WpRegistry *registry; - WpDbus *dbus; - - g_return_val_if_fail (core, NULL); - g_return_val_if_fail ( - bus_type != G_BUS_TYPE_NONE && bus_type != G_BUS_TYPE_STARTER, NULL); - - registry = wp_core_get_registry (core); - dbus = wp_registry_find_object (registry, (GEqualFunc) find_dbus_func, - &bus_type); - if (G_UNLIKELY (!dbus)) { - dbus = g_object_new (WP_TYPE_DBUS, - "core", core, - "bus-type", bus_type, - NULL); - wp_registry_register_object (registry, g_object_ref (dbus)); - } - - return dbus; -} - -/*! - * \brief Returns the bus type of the dbus object. - * - * \param self the DBus object - * \returns the bus type - */ -GBusType -wp_dbus_get_bus_type (WpDbus *self) -{ - g_return_val_if_fail (WP_IS_DBUS (self), G_BUS_TYPE_NONE); - - return self->bus_type; -} - -/*! - * \brief Returns the dbus connection state of the dbus object. - * - * \param self the DBus object - * \returns the dbus connection state - */ -WpDBusState -wp_dbus_get_state (WpDbus *self) -{ - g_return_val_if_fail (WP_IS_DBUS (self), WP_DBUS_STATE_CLOSED); - - return self->state; -} - -/*! - * \brief Returns the DBus connection object of the dbus object. - * - * \param self the DBus object - * \return (transfer full): the DBus connection object - */ -GDBusConnection * -wp_dbus_get_connection (WpDbus *self) -{ - g_return_val_if_fail (WP_IS_DBUS (self), NULL); - - return self->connection ? g_object_ref (self->connection) : NULL; -} diff --git a/lib/wp/dbus.h b/lib/wp/dbus.h deleted file mode 100644 index b67aac32..00000000 --- a/lib/wp/dbus.h +++ /dev/null @@ -1,59 +0,0 @@ -/* WirePlumber - * - * Copyright © 2022 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_DBUS_H__ -#define __WIREPLUMBER_DBUS_H__ - -#include "object.h" - -G_BEGIN_DECLS - -/* WpDbus */ - -/*! - * \brief Flags to be used as WpObjectFeatures for WpDbus. - * \ingroup wpdbus - */ -typedef enum { /*< flags >*/ - /* main features */ - WP_DBUS_FEATURE_ENABLED = (1 << 0), -} WpDbusFeatures; - -/*! - * \brief The state of the dbus connection - * \ingroup wpdbus - */ -typedef enum { - WP_DBUS_STATE_CLOSED = 0, - WP_DBUS_STATE_CONNECTING, - WP_DBUS_STATE_CONNECTED, -} WpDBusState; - -/*! - * \brief The WpDbus GType - * \ingroup wpdbus - */ -#define WP_TYPE_DBUS (wp_dbus_get_type ()) -WP_API -G_DECLARE_FINAL_TYPE (WpDbus, wp_dbus, WP, DBUS, WpObject) - -WP_API -WpDbus *wp_dbus_get_instance (WpCore *core, GBusType bus_type); - -WP_API -GBusType wp_dbus_get_bus_type (WpDbus *self); - -WP_API -WpDBusState wp_dbus_get_state (WpDbus *self); - -WP_API -GDBusConnection *wp_dbus_get_connection (WpDbus *self); - -G_END_DECLS - -#endif diff --git a/lib/wp/meson.build b/lib/wp/meson.build index ae560e60..9347da77 100644 --- a/lib/wp/meson.build +++ b/lib/wp/meson.build @@ -3,7 +3,6 @@ wp_lib_sources = files( 'component-loader.c', 'conf.c', 'core.c', - 'dbus.c', 'device.c', 'error.c', 'event.c', @@ -47,7 +46,6 @@ wp_lib_headers = files( 'component-loader.h', 'conf.h', 'core.h', - 'dbus.h', 'defs.h', 'device.h', 'error.h', diff --git a/lib/wp/wp.h b/lib/wp/wp.h index 53707278..e7bd5574 100644 --- a/lib/wp/wp.h +++ b/lib/wp/wp.h @@ -13,7 +13,6 @@ #include "component-loader.h" #include "conf.h" #include "core.h" -#include "dbus.h" #include "device.h" #include "error.h" #include "event-dispatcher.h" diff --git a/modules/dbus-connection-state.h b/modules/dbus-connection-state.h new file mode 100644 index 00000000..0ddb5807 --- /dev/null +++ b/modules/dbus-connection-state.h @@ -0,0 +1,24 @@ +/* WirePlumber + * + * Copyright © 2023 Collabora Ltd. + * @author George Kiagiadakis + * + * SPDX-License-Identifier: MIT + */ + +#ifndef __WIREPLUMBER_DBUS_CONNECTION_STATE_H__ +#define __WIREPLUMBER_DBUS_CONNECTION_STATE_H__ + +#include + +G_BEGIN_DECLS + +typedef enum { + WP_DBUS_CONNECTION_STATE_CLOSED = 0, + WP_DBUS_CONNECTION_STATE_CONNECTING, + WP_DBUS_CONNECTION_STATE_CONNECTED, +} WpDBusConnectionState; + +G_END_DECLS + +#endif diff --git a/modules/meson.build b/modules/meson.build index 92f3399e..a1541c3b 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -14,6 +14,21 @@ shared_library( dependencies : [wp_dep, pipewire_dep], ) +dbus_connection_enums = gnome.mkenums_simple('dbus-connection-enums', + sources: [ 'dbus-connection-state.h' ], +) +shared_library( + 'wireplumber-module-dbus-connection', + [ + 'module-dbus-connection.c', + dbus_connection_enums, + ], + c_args : [common_c_args], + install : true, + install_dir : wireplumber_module_dir, + dependencies : [wp_dep], +) + shared_library( 'wireplumber-module-default-nodes-api', [ diff --git a/modules/module-dbus-connection.c b/modules/module-dbus-connection.c new file mode 100644 index 00000000..21ba95a2 --- /dev/null +++ b/modules/module-dbus-connection.c @@ -0,0 +1,250 @@ +/* WirePlumber + * + * Copyright © 2022-2023 Collabora Ltd. + * @author Julian Bouzas + * + * SPDX-License-Identifier: MIT + */ + +#include +#include "dbus-connection-state.h" +#include "dbus-connection-enums.h" + +WP_DEFINE_LOCAL_LOG_TOPIC ("m-dbus-connection") + +enum +{ + PROP_0, + PROP_BUS_TYPE, + PROP_STATE, + PROP_CONNECTION, +}; + +struct _WpDBusConnection +{ + WpPlugin parent; + + /* Props */ + GBusType bus_type; + WpDBusConnectionState state; + GDBusConnection *connection; + + GCancellable *cancellable; +}; + +static void on_connection_closed (GDBusConnection * connection, + gboolean remote_peer_vanished, GError * error, gpointer data); + +G_DECLARE_FINAL_TYPE (WpDBusConnection, wp_dbus_connection, + WP, DBUS_CONNECTION, WpPlugin) +G_DEFINE_TYPE (WpDBusConnection, wp_dbus_connection, WP_TYPE_PLUGIN) + +static void +wp_dbus_connection_init (WpDBusConnection * self) +{ +} + +static void +wp_dbus_connection_set_state (WpDBusConnection * self, WpDBusConnectionState new_state) +{ + if (self->state != new_state) { + self->state = new_state; + g_object_notify (G_OBJECT (self), "state"); + } +} + +static void +on_got_bus (GObject * obj, GAsyncResult * res, gpointer data) +{ + WpTransition *transition; + WpDBusConnection *self; + g_autoptr (GError) error = NULL; + + if (WP_IS_TRANSITION (data)) { + // coming from wp_dbus_connection_enable + transition = WP_TRANSITION (data); + self = wp_transition_get_source_object (transition); + } else { + // coming from on_sync_reconnect + transition = NULL; + self = WP_DBUS_CONNECTION (data); + } + + self->connection = g_dbus_connection_new_for_address_finish (res, &error); + if (!self->connection) { + if (transition) { + g_prefix_error (&error, "Failed to connect to bus: "); + wp_transition_return_error (transition, g_steal_pointer (&error)); + } + return; + } + + wp_debug_object (self, "Connected to bus"); + + /* set up connection */ + g_signal_connect_object (self->connection, "closed", + G_CALLBACK (on_connection_closed), self, 0); + g_dbus_connection_set_exit_on_close (self->connection, FALSE); + + wp_dbus_connection_set_state (self, WP_DBUS_CONNECTION_STATE_CONNECTED); + + if (transition) + wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); +} + +static gboolean +do_connect (WpDBusConnection * self, GAsyncReadyCallback callback, + gpointer data, GError ** error) +{ + g_autofree gchar *address = NULL; + + address = g_dbus_address_get_for_bus_sync (self->bus_type, NULL, error); + if (!address) { + g_prefix_error (error, "Error acquiring bus address: "); + return FALSE; + } + + wp_dbus_connection_set_state (self, WP_DBUS_CONNECTION_STATE_CONNECTING); + + wp_debug_object (self, "Connecting to bus: %s", address); + g_dbus_connection_new_for_address (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, self->cancellable, callback, data); + return TRUE; +} + +static void +on_sync_reconnect (WpCore * core, GAsyncResult * res, WpDBusConnection * self) +{ + g_autoptr (GError) error = NULL; + + if (!wp_core_sync_finish (core, res, &error)) { + wp_warning_object (self, "core sync error: %s", error->message); + return; + } + + if (!do_connect (self, on_got_bus, self, &error)) + wp_notice_object (self, "Cannot reconnect: %s", error->message); +} + +static void +on_connection_closed (GDBusConnection * connection, + gboolean remote_peer_vanished, GError * error, gpointer data) +{ + WpDBusConnection *self = WP_DBUS_CONNECTION (data); + g_autoptr (WpCore) core = NULL; + + wp_notice_object (self, "DBus connection closed: %s", error->message); + + g_clear_object (&self->connection); + wp_dbus_connection_set_state (self, WP_DBUS_CONNECTION_STATE_CLOSED); + + /* try to reconnect on idle if connection was closed */ + core = wp_object_get_core (WP_OBJECT (self)); + if (core && wp_core_is_connected (core)) { + wp_notice_object (self, "Trying to reconnect after core sync"); + wp_core_sync_closure (core, NULL, g_cclosure_new_object ( + G_CALLBACK (on_sync_reconnect), G_OBJECT (self))); + } +} + +static void +wp_dbus_connection_enable (WpPlugin * plugin, WpTransition * transition) +{ + WpDBusConnection *self = WP_DBUS_CONNECTION (plugin); + g_autoptr (GError) error = NULL; + if (!do_connect (self, on_got_bus, transition, &error)) { + wp_transition_return_error (transition, g_steal_pointer (&error)); + } +} + +static void +wp_dbus_connection_disable (WpPlugin * plugin) +{ + WpDBusConnection *self = WP_DBUS_CONNECTION (plugin); + + g_cancellable_cancel (self->cancellable); + + g_clear_object (&self->connection); + wp_dbus_connection_set_state (self, WP_DBUS_CONNECTION_STATE_CLOSED); + + g_clear_object (&self->cancellable); + self->cancellable = g_cancellable_new (); +} + +static void +wp_dbus_connection_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + WpDBusConnection *self = WP_DBUS_CONNECTION (object); + + switch (property_id) { + case PROP_BUS_TYPE: + g_value_set_enum (value, self->bus_type); + break; + case PROP_STATE: + g_value_set_enum (value, self->state); + break; + case PROP_CONNECTION: + g_value_set_object (value, self->connection); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +wp_dbus_connection_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + WpDBusConnection *self = WP_DBUS_CONNECTION (object); + + switch (property_id) { + case PROP_BUS_TYPE: + self->bus_type = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +wp_dbus_connection_class_init (WpDBusConnectionClass * klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + WpPluginClass *plugin_class = (WpPluginClass *) klass; + + object_class->get_property = wp_dbus_connection_get_property; + object_class->set_property = wp_dbus_connection_set_property; + + plugin_class->enable = wp_dbus_connection_enable; + plugin_class->disable = wp_dbus_connection_disable; + + g_object_class_install_property (object_class, PROP_BUS_TYPE, + g_param_spec_enum ("bus-type", "bus-type", "The bus type", + G_TYPE_BUS_TYPE, G_BUS_TYPE_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_STATE, + g_param_spec_enum ("state", "state", "The dbus connection state", + WP_TYPE_DBUS_CONNECTION_STATE, WP_DBUS_CONNECTION_STATE_CLOSED, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_CONNECTION, + g_param_spec_object ("connection", "connection", "The dbus connection", + G_TYPE_DBUS_CONNECTION, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +WP_PLUGIN_EXPORT GObject * +wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error) +{ + return G_OBJECT (g_object_new ( + wp_dbus_connection_get_type(), + "name", "dbus-connection", + "core", core, + "bus-type", G_BUS_TYPE_SESSION, + NULL)); +} diff --git a/modules/module-portal-permissionstore.c b/modules/module-portal-permissionstore.c index 7683da25..907da13e 100644 --- a/modules/module-portal-permissionstore.c +++ b/modules/module-portal-permissionstore.c @@ -7,6 +7,7 @@ */ #include +#include "dbus-connection-state.h" WP_DEFINE_LOCAL_LOG_TOPIC ("m-portal-permissionstore") @@ -28,7 +29,7 @@ struct _WpPortalPermissionStorePlugin { WpPlugin parent; - WpDbus *dbus; + WpPlugin *dbus; guint signal_id; }; @@ -53,7 +54,7 @@ wp_portal_permissionstore_plugin_lookup (WpPortalPermissionStorePlugin *self, g_autoptr (GVariant) res = NULL; GVariant *permissions = NULL, *data = NULL; - conn = wp_dbus_get_connection (self->dbus); + g_object_get (self->dbus, "connection", &conn, NULL); g_return_val_if_fail (conn, NULL); /* Lookup */ @@ -81,7 +82,7 @@ wp_portal_permissionstore_plugin_set (WpPortalPermissionStorePlugin *self, g_autoptr (GVariant) res = NULL; GVariant *data = NULL; - conn = wp_dbus_get_connection (self->dbus); + g_object_get (self->dbus, "connection", &conn, NULL); g_return_if_fail (conn); /* Set */ @@ -118,7 +119,7 @@ clear_signal (WpPortalPermissionStorePlugin *self) { g_autoptr (GDBusConnection) conn = NULL; - conn = wp_dbus_get_connection (self->dbus); + g_object_get (self->dbus, "connection", &conn, NULL); if (conn && self->signal_id > 0) { g_dbus_connection_signal_unsubscribe (conn, self->signal_id); self->signal_id = 0; @@ -126,16 +127,17 @@ clear_signal (WpPortalPermissionStorePlugin *self) } static void -on_dbus_state_changed (GObject * obj, GParamSpec * spec, +on_dbus_state_changed (GObject * dbus, GParamSpec * spec, WpPortalPermissionStorePlugin *self) { - WpDBusState state = wp_dbus_get_state (self->dbus); + WpDBusConnectionState state = -1; + g_object_get (dbus, "state", &state, NULL); switch (state) { - case WP_DBUS_STATE_CONNECTED: { + case WP_DBUS_CONNECTION_STATE_CONNECTED: { g_autoptr (GDBusConnection) conn = NULL; - conn = wp_dbus_get_connection (self->dbus); + g_object_get (dbus, "connection", &conn, NULL); g_return_if_fail (conn); self->signal_id = g_dbus_connection_signal_subscribe (conn, @@ -145,8 +147,8 @@ on_dbus_state_changed (GObject * obj, GParamSpec * spec, break; } - case WP_DBUS_STATE_CONNECTING: - case WP_DBUS_STATE_CLOSED: + case WP_DBUS_CONNECTION_STATE_CONNECTING: + case WP_DBUS_CONNECTION_STATE_CLOSED: clear_signal (self); break; @@ -160,60 +162,27 @@ wp_portal_permissionstore_plugin_init (WpPortalPermissionStorePlugin * self) { } -static void -wp_portal_permissionstore_plugin_constructed (GObject *object) -{ - WpPortalPermissionStorePlugin *self = - WP_PORTAL_PERMISSIONSTORE_PLUGIN (object); - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - - self->dbus = wp_dbus_get_instance (core, G_BUS_TYPE_SESSION); - g_signal_connect_object (self->dbus, "notify::state", - G_CALLBACK (on_dbus_state_changed), self, 0); - - G_OBJECT_CLASS (wp_portal_permissionstore_plugin_parent_class)->constructed ( - object); -} - -static void -wp_portal_permissionstore_plugin_finalize (GObject * object) -{ - WpPortalPermissionStorePlugin *self = - WP_PORTAL_PERMISSIONSTORE_PLUGIN (object); - - g_clear_object (&self->dbus); - - G_OBJECT_CLASS (wp_portal_permissionstore_plugin_parent_class)->finalize ( - object); -} - -static void -on_dbus_activated (GObject * obj, GAsyncResult * res, gpointer user_data) -{ - WpTransition * transition = WP_TRANSITION (user_data); - WpPortalPermissionStorePlugin * self = - wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (WP_OBJECT (obj), res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); -} - static void wp_portal_permissionstore_plugin_enable (WpPlugin * plugin, WpTransition * transition) { WpPortalPermissionStorePlugin *self = WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin); + g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - /* make sure dbus always activated */ - g_return_if_fail (self->dbus); - wp_object_activate (WP_OBJECT (self->dbus), WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_dbus_activated, transition); + self->dbus = wp_plugin_find (core, "dbus-connection"); + if (!self->dbus) { + wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY, + WP_LIBRARY_ERROR_INVARIANT, + "dbus-connection module must be loaded before portal-permissionstore")); + return; + } + + g_signal_connect_object (self->dbus, "notify::state", + G_CALLBACK (on_dbus_state_changed), self, 0); + on_dbus_state_changed (G_OBJECT (self->dbus), NULL, self); + + wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); } static void @@ -223,6 +192,7 @@ wp_portal_permissionstore_plugin_disable (WpPlugin * plugin) WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin); clear_signal (self); + g_clear_object (&self->dbus); wp_object_update_features (WP_OBJECT (self), 0, WP_PLUGIN_FEATURE_ENABLED); } @@ -231,12 +201,8 @@ static void wp_portal_permissionstore_plugin_class_init ( WpPortalPermissionStorePluginClass * klass) { - GObjectClass *object_class = (GObjectClass *) klass; WpPluginClass *plugin_class = (WpPluginClass *) klass; - object_class->constructed = wp_portal_permissionstore_plugin_constructed; - object_class->finalize = wp_portal_permissionstore_plugin_finalize; - plugin_class->enable = wp_portal_permissionstore_plugin_enable; plugin_class->disable = wp_portal_permissionstore_plugin_disable; diff --git a/modules/module-reserve-device/plugin.c b/modules/module-reserve-device/plugin.c index 86089536..e6789ffc 100644 --- a/modules/module-reserve-device/plugin.c +++ b/modules/module-reserve-device/plugin.c @@ -9,6 +9,7 @@ #include "plugin.h" #include "reserve-device.h" #include "reserve-device-enums.h" +#include "../dbus-connection-state.h" WP_LOG_TOPIC (log_topic_rd, "m-reserve-device") @@ -41,15 +42,17 @@ clear_reservation (WpReserveDevicePlugin *self) } static void -on_dbus_state_changed (GObject * obj, GParamSpec * spec, +on_dbus_state_changed (GObject * dbus, GParamSpec * spec, WpReserveDevicePlugin *self) { - WpDBusState state = wp_dbus_get_state (self->dbus); + WpDBusConnectionState state = -1; + g_object_get (dbus, "state", &state, NULL); + switch (state) { - case WP_DBUS_STATE_CONNECTED: { + case WP_DBUS_CONNECTION_STATE_CONNECTED: { g_autoptr (GDBusConnection) conn = NULL; - conn = wp_dbus_get_connection (self->dbus); + g_object_get (dbus, "connection", &conn, NULL); g_return_if_fail (conn); self->manager = g_dbus_object_manager_server_new ( @@ -58,35 +61,21 @@ on_dbus_state_changed (GObject * obj, GParamSpec * spec, break; } - case WP_DBUS_STATE_CONNECTING: - case WP_DBUS_STATE_CLOSED: + case WP_DBUS_CONNECTION_STATE_CONNECTING: + case WP_DBUS_CONNECTION_STATE_CLOSED: clear_reservation (self); break; default: - break; + g_assert_not_reached (); } } static void wp_reserve_device_plugin_init (WpReserveDevicePlugin * self) { -} - -static void -wp_reserve_device_plugin_constructed (GObject *object) -{ - WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (object); - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - self->reserve_devices = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, rd_unref); - - self->dbus = wp_dbus_get_instance (core, G_BUS_TYPE_SESSION); - g_signal_connect_object (self->dbus, "notify::state", - G_CALLBACK (on_dbus_state_changed), self, 0); - - G_OBJECT_CLASS (wp_reserve_device_plugin_parent_class)->constructed (object); } static void @@ -95,35 +84,29 @@ wp_reserve_device_plugin_finalize (GObject * object) WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (object); g_clear_pointer (&self->reserve_devices, g_hash_table_unref); - g_clear_object (&self->dbus); G_OBJECT_CLASS (wp_reserve_device_plugin_parent_class)->finalize (object); } -static void -on_dbus_activated (GObject * obj, GAsyncResult * res, gpointer user_data) -{ - WpTransition * transition = WP_TRANSITION (user_data); - WpReserveDevicePlugin * self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (WP_OBJECT (obj), res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); -} - static void wp_reserve_device_plugin_enable (WpPlugin * plugin, WpTransition * transition) { WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin); + g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - /* make sure dbus always activated */ - g_return_if_fail (self->dbus); - wp_object_activate (WP_OBJECT (self->dbus), WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_dbus_activated, transition); + self->dbus = wp_plugin_find (core, "dbus-connection"); + if (!self->dbus) { + wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY, + WP_LIBRARY_ERROR_INVARIANT, + "dbus-connection module must be loaded before reserve-device")); + return; + } + + g_signal_connect_object (self->dbus, "notify::state", + G_CALLBACK (on_dbus_state_changed), self, 0); + on_dbus_state_changed (G_OBJECT (self->dbus), NULL, self); + + wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); } static void @@ -132,6 +115,7 @@ wp_reserve_device_plugin_disable (WpPlugin * plugin) WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin); clear_reservation (self); + g_clear_object (&self->dbus); wp_object_update_features (WP_OBJECT (self), 0, WP_PLUGIN_FEATURE_ENABLED); } @@ -141,8 +125,10 @@ wp_reserve_device_plugin_create_reservation (WpReserveDevicePlugin *self, const gchar *name, const gchar *app_name, const gchar *app_dev_name, gint priority) { - WpDBusState state = wp_dbus_get_state (self->dbus); - if (state != WP_DBUS_STATE_CONNECTED) { + WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED; + g_object_get (self->dbus, "state", &state, NULL); + + if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) { wp_notice_object (self, "not connected to D-Bus"); return NULL; } @@ -165,8 +151,10 @@ static void wp_reserve_device_plugin_destroy_reservation (WpReserveDevicePlugin *self, const gchar *name) { - WpDBusState state = wp_dbus_get_state (self->dbus); - if (state != WP_DBUS_STATE_CONNECTED) { + WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED; + g_object_get (self->dbus, "state", &state, NULL); + + if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) { wp_notice_object (self, "not connected to D-Bus"); return; } @@ -177,8 +165,10 @@ static gpointer wp_reserve_device_plugin_get_reservation (WpReserveDevicePlugin *self, const gchar *name) { - WpDBusState state = wp_dbus_get_state (self->dbus); - if (state != WP_DBUS_STATE_CONNECTED) { + WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED; + g_object_get (self->dbus, "state", &state, NULL); + + if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) { wp_notice_object (self, "not connected to D-Bus"); return NULL; } @@ -199,7 +189,6 @@ wp_reserve_device_plugin_class_init (WpReserveDevicePluginClass * klass) GObjectClass *object_class = (GObjectClass *) klass; WpPluginClass *plugin_class = (WpPluginClass *) klass; - object_class->constructed = wp_reserve_device_plugin_constructed; object_class->finalize = wp_reserve_device_plugin_finalize; plugin_class->enable = wp_reserve_device_plugin_enable; diff --git a/modules/module-reserve-device/plugin.h b/modules/module-reserve-device/plugin.h index 75b6db0f..2461efbb 100644 --- a/modules/module-reserve-device/plugin.h +++ b/modules/module-reserve-device/plugin.h @@ -19,12 +19,6 @@ WP_LOG_TOPIC_EXTERN (log_topic_rd) #define FDO_RESERVE_DEVICE1_SERVICE "org.freedesktop.ReserveDevice1" #define FDO_RESERVE_DEVICE1_PATH "/org/freedesktop/ReserveDevice1" -typedef enum { - WP_DBUS_CONNECTION_STATE_CLOSED = 0, - WP_DBUS_CONNECTION_STATE_CONNECTING, - WP_DBUS_CONNECTION_STATE_CONNECTED, -} WpDBusConnectionState; - G_DECLARE_FINAL_TYPE (WpReserveDevicePlugin, wp_reserve_device_plugin, WP, RESERVE_DEVICE_PLUGIN, WpPlugin) @@ -32,7 +26,7 @@ struct _WpReserveDevicePlugin { WpPlugin parent; - WpDbus *dbus; + WpPlugin *dbus; GHashTable *reserve_devices; GDBusObjectManagerServer *manager; }; diff --git a/modules/module-reserve-device/reserve-device.c b/modules/module-reserve-device/reserve-device.c index 66913359..0858a452 100644 --- a/modules/module-reserve-device/reserve-device.c +++ b/modules/module-reserve-device/reserve-device.c @@ -76,7 +76,8 @@ update_owner_app_name (WpReserveDevice *self) if (self->state == WP_RESERVE_DEVICE_STATE_BUSY && !self->owner_app_name) { /* create proxy */ g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin); - g_autoptr (GDBusConnection) conn = wp_dbus_get_connection (plugin->dbus); + g_autoptr (GDBusConnection) conn = NULL; + g_object_get (plugin->dbus, "connection", &conn, NULL); wp_org_freedesktop_reserve_device1_proxy_new (conn, G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, @@ -124,7 +125,9 @@ wp_reserve_device_constructed (GObject * object) { WpReserveDevice *self = WP_RESERVE_DEVICE (object); g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin); - g_autoptr (GDBusConnection) conn = wp_dbus_get_connection (plugin->dbus); + g_autoptr (GDBusConnection) conn = NULL; + + g_object_get (plugin->dbus, "connection", &conn, NULL); self->service_name = g_strdup_printf (FDO_RESERVE_DEVICE1_SERVICE ".%s", self->name); @@ -498,7 +501,9 @@ wp_reserve_device_own_name (WpReserveDevice * self, gboolean force) g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin); if (plugin) { - g_autoptr (GDBusConnection) conn = wp_dbus_get_connection (plugin->dbus); + g_autoptr (GDBusConnection) conn = NULL; + g_object_get (plugin->dbus, "connection", &conn, NULL); + GBusNameOwnerFlags flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE; if (self->priority != G_MAXINT32) flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; diff --git a/modules/module-reserve-device/transitions.c b/modules/module-reserve-device/transitions.c index 4edf8c02..7b74d27b 100644 --- a/modules/module-reserve-device/transitions.c +++ b/modules/module-reserve-device/transitions.c @@ -174,7 +174,8 @@ wp_reserve_device_acquire_transition_execute_step ( break; case STEP_GET_PROXY: { - g_autoptr (GDBusConnection) conn = wp_dbus_get_connection (plugin->dbus); + g_autoptr (GDBusConnection) conn = NULL; + g_object_get (plugin->dbus, "connection", &conn, NULL); wp_org_freedesktop_reserve_device1_proxy_new (conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | diff --git a/src/config/wireplumber.conf b/src/config/wireplumber.conf index 5744c406..a2b9e562 100644 --- a/src/config/wireplumber.conf +++ b/src/config/wireplumber.conf @@ -137,6 +137,13 @@ wireplumber.components = [ priority = 130 } + ## The shared D-Bus connection + { + name = libwireplumber-module-dbus-connection + type = module + priority = 120 + } + ## API to access default nodes from scripts { name = libwireplumber-module-default-nodes-api, diff --git a/tests/modules/dbus-connection.c b/tests/modules/dbus-connection.c new file mode 100644 index 00000000..971c0768 --- /dev/null +++ b/tests/modules/dbus-connection.c @@ -0,0 +1,101 @@ +/* WirePlumber + * + * Copyright © 2022-2023 Collabora Ltd. + * @author Julian Bouzas + * + * SPDX-License-Identifier: MIT + */ + +#include +#include "../../modules/dbus-connection-state.h" +#include "../common/base-test-fixture.h" + +typedef struct { + WpBaseTestFixture base; + GTestDBus *test_dbus; +} TestFixture; + +static void +test_setup (TestFixture *self, gconstpointer user_data) +{ + wp_base_test_fixture_setup (&self->base, 0); + self->test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (self->test_dbus); +} + +static void +test_teardown (TestFixture *self, gconstpointer user_data) +{ + g_test_dbus_down (self->test_dbus); + g_clear_object (&self->test_dbus); + wp_base_test_fixture_teardown (&self->base); +} + +static void +on_dbus_state_changed (GObject * dbus, GParamSpec * spec, TestFixture *f) +{ + WpDBusConnectionState state = -1; + g_object_get (dbus, "state", &state, NULL); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CLOSED); + + g_object_set_data (G_OBJECT (dbus), "state-closed", GUINT_TO_POINTER (0x1)); +} + +static void +on_plugin_loaded (WpCore * core, GAsyncResult * res, TestFixture *f) +{ + gboolean loaded; + GError *error = NULL; + + loaded = wp_core_load_component_finish (core, res, &error); + g_assert_no_error (error); + g_assert_true (loaded); + + g_main_loop_quit (f->base.loop); +} + +static void +test_dbus_connection (TestFixture *f, gconstpointer user_data) +{ + g_autoptr (WpPlugin) dbus = NULL; + g_autoptr (GDBusConnection) conn = NULL; + WpDBusConnectionState state = -1; + + wp_core_load_component (f->base.core, + "libwireplumber-module-dbus-connection", "module", NULL, NULL, + (GAsyncReadyCallback) on_plugin_loaded, f); + g_main_loop_run (f->base.loop); + + dbus = wp_plugin_find (f->base.core, "dbus-connection"); + g_assert_nonnull (dbus); + + g_object_get (dbus, "state", &state, NULL); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CONNECTED); + + g_object_get (dbus, "connection", &conn, NULL); + g_assert_nonnull (conn); + g_clear_object (&conn); + + g_signal_connect (dbus, "notify::state", G_CALLBACK (on_dbus_state_changed), + f); + + wp_object_deactivate (WP_OBJECT (dbus), WP_PLUGIN_FEATURE_ENABLED); + + // set by on_dbus_state_changed + g_assert_cmphex (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dbus), "state-closed")), ==, 0x1); + + g_object_get (dbus, "connection", &conn, NULL); + g_assert_null (conn); +} + +gint +main (gint argc, gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + wp_init (WP_INIT_ALL); + + g_test_add ("/wp/dbus/connection", TestFixture, NULL, + test_setup, test_dbus_connection, test_teardown); + + return g_test_run (); +} diff --git a/tests/modules/meson.build b/tests/modules/meson.build index 1e6d082d..60dff5ec 100644 --- a/tests/modules/meson.build +++ b/tests/modules/meson.build @@ -8,6 +8,13 @@ common_args = [ ] if get_option('dbus-tests') + test( + 'test-dbus-connection', + executable('test-dbus-connection', 'dbus-connection.c', + dependencies: common_deps, c_args: common_args), + env: common_env, + ) + test( 'test-reserve-device', executable('test-reserve-device', 'reserve-device.c', diff --git a/tests/modules/reserve-device.c b/tests/modules/reserve-device.c index a1a96d2e..52165f45 100644 --- a/tests/modules/reserve-device.c +++ b/tests/modules/reserve-device.c @@ -7,16 +7,16 @@ */ #include - +#include "../../modules/dbus-connection-state.h" #include "../common/base-test-fixture.h" typedef struct { WpBaseTestFixture base; GTestDBus *test_dbus; + WpPlugin *dbus_1; + WpPlugin *dbus_2; WpPlugin *rd_plugin_1; WpPlugin *rd_plugin_2; - WpDbus *dbus_1; - WpDbus *dbus_2; gint expected_rd1_state; gint expected_rd2_state; } RdTestFixture; @@ -37,12 +37,26 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, RdTestFixture *f) static void test_rd_setup (RdTestFixture *f, gconstpointer data) { + WpDBusConnectionState state = -1; + wp_base_test_fixture_setup (&f->base, WP_BASE_TEST_FLAG_CLIENT_CORE | WP_BASE_TEST_FLAG_DONT_CONNECT); f->test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE); g_test_dbus_up (f->test_dbus); + { + wp_core_load_component (f->base.core, + "libwireplumber-module-dbus-connection", "module", NULL, NULL, + (GAsyncReadyCallback) on_plugin_loaded, f); + g_main_loop_run (f->base.loop); + } + { + wp_core_load_component (f->base.client_core, + "libwireplumber-module-dbus-connection", "module", NULL, NULL, + (GAsyncReadyCallback) on_plugin_loaded, f); + g_main_loop_run (f->base.loop); + } { wp_core_load_component (f->base.core, "libwireplumber-module-reserve-device", "module", NULL, NULL, @@ -56,17 +70,23 @@ test_rd_setup (RdTestFixture *f, gconstpointer data) g_main_loop_run (f->base.loop); } + f->dbus_1 = wp_plugin_find (f->base.core, "dbus-connection"); + g_assert_nonnull (f->dbus_1); + + f->dbus_2 = wp_plugin_find (f->base.client_core, "dbus-connection"); + g_assert_nonnull (f->dbus_2); + f->rd_plugin_1 = wp_plugin_find (f->base.core, "reserve-device"); g_assert_nonnull (f->rd_plugin_1); f->rd_plugin_2 = wp_plugin_find (f->base.client_core, "reserve-device"); g_assert_nonnull (f->rd_plugin_2); - g_signal_emit_by_name (f->rd_plugin_1, "get-dbus", &f->dbus_1); - g_assert_nonnull (f->dbus_1); + g_object_get (f->dbus_1, "state", &state, NULL); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CONNECTED); - g_signal_emit_by_name (f->rd_plugin_2, "get-dbus", &f->dbus_2); - g_assert_nonnull (f->dbus_2); + g_object_get (f->dbus_2, "state", &state, NULL); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CONNECTED); } static void @@ -84,10 +104,13 @@ test_rd_teardown (RdTestFixture *f, gconstpointer data) static void ensure_plugins_stable_state (GObject * obj, GParamSpec * spec, RdTestFixture *f) { - gint state1 = 0, state2 = 0; + WpDBusConnectionState state1 = -1, state2 = -1; g_object_get (f->dbus_1, "state", &state1, NULL); g_object_get (f->dbus_2, "state", &state2, NULL); - if (state1 != 1 && state2 != 1 && state1 == state2) + + if (state1 != WP_DBUS_CONNECTION_STATE_CONNECTING && + state2 != WP_DBUS_CONNECTION_STATE_CONNECTING && + state1 == state2) g_main_loop_quit (f->base.loop); } @@ -95,19 +118,9 @@ static void test_rd_plugin (RdTestFixture *f, gconstpointer data) { GObject *rd1 = NULL, *rd2 = NULL, *rd_video = NULL, *tmp = NULL; - gint state = 0; + gint priority = 0; gchar *str; - g_signal_connect (f->dbus_1, "notify::state", - G_CALLBACK (ensure_plugins_stable_state), f); - g_signal_connect (f->dbus_2, "notify::state", - G_CALLBACK (ensure_plugins_stable_state), f); - - g_object_get (f->dbus_1, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_object_get (f->dbus_2, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_signal_emit_by_name (f->rd_plugin_1, "create-reservation", "Audio0", "WirePlumber", "hw:0,0", 10, &rd1); g_assert_nonnull (rd1); @@ -143,10 +156,10 @@ test_rd_plugin (RdTestFixture *f, gconstpointer data) g_object_get (rd1, "application-device-name", &str, NULL); g_assert_cmpstr (str, ==, "hw:0,0"); g_free (str); - g_object_get (rd1, "priority", &state, NULL); - g_assert_cmpint (state, ==, 10); - g_object_get (rd2, "priority", &state, NULL); - g_assert_cmpint (state, ==, 15); + g_object_get (rd1, "priority", &priority, NULL); + g_assert_cmpint (priority, ==, 10); + g_object_get (rd2, "priority", &priority, NULL); + g_assert_cmpint (priority, ==, 15); g_signal_emit_by_name (f->rd_plugin_1, "destroy-reservation", "Audio0"); g_signal_emit_by_name (f->rd_plugin_1, "get-reservation", "Audio0", &tmp); @@ -158,35 +171,19 @@ test_rd_plugin (RdTestFixture *f, gconstpointer data) g_clear_object (&rd2); g_clear_object (&rd1); g_clear_object (&rd_video); - - wp_object_deactivate (WP_OBJECT (f->rd_plugin_1), WP_PLUGIN_FEATURE_ENABLED); - wp_object_deactivate (WP_OBJECT (f->rd_plugin_2), WP_PLUGIN_FEATURE_ENABLED); - - wp_object_deactivate (WP_OBJECT (f->dbus_1), WP_DBUS_FEATURE_ENABLED); - wp_object_deactivate (WP_OBJECT (f->dbus_2), WP_DBUS_FEATURE_ENABLED); - - g_object_get (f->dbus_1, "state", &state, NULL); - g_assert_cmpint (state, ==, 0); - g_object_get (f->dbus_2, "state", &state, NULL); - g_assert_cmpint (state, ==, 0); } static void test_rd_conn_closed (RdTestFixture *f, gconstpointer data) { GObject *rd1 = NULL; - gint state = 0; + WpDBusConnectionState state = -1; g_signal_connect (f->dbus_1, "notify::state", G_CALLBACK (ensure_plugins_stable_state), f); g_signal_connect (f->dbus_2, "notify::state", G_CALLBACK (ensure_plugins_stable_state), f); - g_object_get (f->dbus_1, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_object_get (f->dbus_2, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_signal_emit_by_name (f->rd_plugin_1, "create-reservation", "Audio0", "WirePlumber", "hw:0,0", 10, &rd1); g_assert_nonnull (rd1); @@ -198,15 +195,12 @@ test_rd_conn_closed (RdTestFixture *f, gconstpointer data) g_main_loop_run (f->base.loop); g_object_get (f->dbus_1, "state", &state, NULL); - g_assert_cmpint (state, ==, 0); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CLOSED); g_object_get (f->dbus_2, "state", &state, NULL); - g_assert_cmpint (state, ==, 0); + g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CLOSED); g_signal_emit_by_name (f->rd_plugin_1, "get-reservation", "Audio0", &rd1); g_assert_null (rd1); - - wp_object_deactivate (WP_OBJECT (f->dbus_1), WP_DBUS_FEATURE_ENABLED); - wp_object_deactivate (WP_OBJECT (f->dbus_2), WP_DBUS_FEATURE_ENABLED); } static void @@ -244,16 +238,6 @@ test_rd_acquire_release (RdTestFixture *f, gconstpointer data) gint state = 0; gchar *str = NULL; - g_signal_connect (f->dbus_1, "notify::state", - G_CALLBACK (ensure_plugins_stable_state), f); - g_signal_connect (f->dbus_2, "notify::state", - G_CALLBACK (ensure_plugins_stable_state), f); - - g_object_get (f->dbus_1, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_object_get (f->dbus_2, "state", &state, NULL); - g_assert_cmpint (state, ==, 2); - g_signal_emit_by_name (f->rd_plugin_1, "create-reservation", "Audio0", "WirePlumber", "hw:0,0", 10, &rd1); g_assert_nonnull (rd1); @@ -336,12 +320,6 @@ test_rd_acquire_release (RdTestFixture *f, gconstpointer data) g_clear_object (&rd1); g_clear_object (&rd2); - - wp_object_deactivate (WP_OBJECT (f->rd_plugin_1), WP_PLUGIN_FEATURE_ENABLED); - wp_object_deactivate (WP_OBJECT (f->rd_plugin_2), WP_PLUGIN_FEATURE_ENABLED); - - wp_object_deactivate (WP_OBJECT (f->dbus_1), WP_DBUS_FEATURE_ENABLED); - wp_object_deactivate (WP_OBJECT (f->dbus_2), WP_DBUS_FEATURE_ENABLED); } gint diff --git a/tests/wp/dbus.c b/tests/wp/dbus.c deleted file mode 100644 index d90f504a..00000000 --- a/tests/wp/dbus.c +++ /dev/null @@ -1,103 +0,0 @@ -/* WirePlumber - * - * Copyright © 2022 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#include - -#include "../common/base-test-fixture.h" - -typedef struct { - WpBaseTestFixture base; - GTestDBus *test_dbus; -} TestFixture; - -static void -test_dbus_setup (TestFixture *self, gconstpointer user_data) -{ - wp_base_test_fixture_setup (&self->base, 0); - self->test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE); - g_test_dbus_up (self->test_dbus); -} - -static void -test_dbus_teardown (TestFixture *self, gconstpointer user_data) -{ - g_test_dbus_down (self->test_dbus); - g_clear_object (&self->test_dbus); - wp_base_test_fixture_teardown (&self->base); -} - -static void -test_dbus_basic (TestFixture *f, gconstpointer user_data) -{ - g_autoptr (WpDbus) dbus = wp_dbus_get_instance (f->base.core, - G_BUS_TYPE_SESSION); - g_assert_nonnull (dbus); - g_autoptr (WpDbus) dbus2 = wp_dbus_get_instance (f->base.core, - G_BUS_TYPE_SESSION); - g_assert_nonnull (dbus2); - - GBusType bus_type = wp_dbus_get_bus_type (dbus); - g_assert_true (bus_type == G_BUS_TYPE_SESSION); - GBusType bus_type2 = wp_dbus_get_bus_type (dbus); - g_assert_true (bus_type2 == G_BUS_TYPE_SESSION); - g_assert_true (dbus == dbus2); -} - -static void -on_dbus_activated (WpObject * dbus, GAsyncResult * res, TestFixture * f) -{ - g_autoptr (GError) error = NULL; - if (!wp_object_activate_finish (dbus, res, &error)) { - wp_critical_object (dbus, "%s", error->message); - g_main_loop_quit (f->base.loop); - } -} - -static void -on_dbus_state_changed (GObject * obj, GParamSpec * spec, TestFixture *f) -{ - WpDBusState state = wp_dbus_get_state (WP_DBUS (obj)); - if (state == WP_DBUS_STATE_CONNECTED) - g_main_loop_quit (f->base.loop); -} - -static void -test_dbus_activation (TestFixture *f, gconstpointer user_data) -{ - g_autoptr (WpDbus) dbus = wp_dbus_get_instance ( - f->base.core, G_BUS_TYPE_SESSION); - g_assert_nonnull (dbus); - - wp_object_activate (WP_OBJECT (dbus), WP_DBUS_FEATURE_ENABLED, - NULL, (GAsyncReadyCallback) on_dbus_activated, f); - - g_signal_connect (dbus, "notify::state", G_CALLBACK (on_dbus_state_changed), - f); - - g_main_loop_run (f->base.loop); - g_assert_cmpint (wp_dbus_get_state (WP_DBUS (dbus)), ==, - WP_DBUS_STATE_CONNECTED); - - wp_object_deactivate (WP_OBJECT (dbus), WP_DBUS_FEATURE_ENABLED); - g_assert_cmpint (wp_dbus_get_state (WP_DBUS (dbus)), ==, - WP_DBUS_STATE_CLOSED); -} - -gint -main (gint argc, gchar *argv[]) -{ - g_test_init (&argc, &argv, NULL); - wp_init (WP_INIT_ALL); - - g_test_add ("/wp/dbus/basic", TestFixture, NULL, - test_dbus_setup, test_dbus_basic, test_dbus_teardown); - g_test_add ("/wp/dbus/activation", TestFixture, NULL, - test_dbus_setup, test_dbus_activation, test_dbus_teardown); - - return g_test_run (); -} diff --git a/tests/wp/meson.build b/tests/wp/meson.build index d43afd7e..5aa9882f 100644 --- a/tests/wp/meson.build +++ b/tests/wp/meson.build @@ -91,15 +91,6 @@ test( env: common_env, ) -if get_option('dbus-tests') - test( - 'test-dbus', - executable('test-dbus', 'dbus.c', - dependencies: common_deps, c_args: common_args), - env: common_env, - ) -endif - test( 'test-settings', executable('test-settings', 'settings.c',