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.
This commit is contained in:
373
lib/wp/dbus.c
373
lib/wp/dbus.c
@@ -1,373 +0,0 @@
|
|||||||
/* WirePlumber
|
|
||||||
*
|
|
||||||
* Copyright © 2022 Collabora Ltd.
|
|
||||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
@@ -1,59 +0,0 @@
|
|||||||
/* WirePlumber
|
|
||||||
*
|
|
||||||
* Copyright © 2022 Collabora Ltd.
|
|
||||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
|
||||||
*
|
|
||||||
* 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
|
|
@@ -3,7 +3,6 @@ wp_lib_sources = files(
|
|||||||
'component-loader.c',
|
'component-loader.c',
|
||||||
'conf.c',
|
'conf.c',
|
||||||
'core.c',
|
'core.c',
|
||||||
'dbus.c',
|
|
||||||
'device.c',
|
'device.c',
|
||||||
'error.c',
|
'error.c',
|
||||||
'event.c',
|
'event.c',
|
||||||
@@ -47,7 +46,6 @@ wp_lib_headers = files(
|
|||||||
'component-loader.h',
|
'component-loader.h',
|
||||||
'conf.h',
|
'conf.h',
|
||||||
'core.h',
|
'core.h',
|
||||||
'dbus.h',
|
|
||||||
'defs.h',
|
'defs.h',
|
||||||
'device.h',
|
'device.h',
|
||||||
'error.h',
|
'error.h',
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#include "component-loader.h"
|
#include "component-loader.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "dbus.h"
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "event-dispatcher.h"
|
#include "event-dispatcher.h"
|
||||||
|
24
modules/dbus-connection-state.h
Normal file
24
modules/dbus-connection-state.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* WirePlumber
|
||||||
|
*
|
||||||
|
* Copyright © 2023 Collabora Ltd.
|
||||||
|
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WIREPLUMBER_DBUS_CONNECTION_STATE_H__
|
||||||
|
#define __WIREPLUMBER_DBUS_CONNECTION_STATE_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
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
|
@@ -14,6 +14,21 @@ shared_library(
|
|||||||
dependencies : [wp_dep, pipewire_dep],
|
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(
|
shared_library(
|
||||||
'wireplumber-module-default-nodes-api',
|
'wireplumber-module-default-nodes-api',
|
||||||
[
|
[
|
||||||
|
250
modules/module-dbus-connection.c
Normal file
250
modules/module-dbus-connection.c
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/* WirePlumber
|
||||||
|
*
|
||||||
|
* Copyright © 2022-2023 Collabora Ltd.
|
||||||
|
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wp/wp.h>
|
||||||
|
#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));
|
||||||
|
}
|
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <wp/wp.h>
|
#include <wp/wp.h>
|
||||||
|
#include "dbus-connection-state.h"
|
||||||
|
|
||||||
WP_DEFINE_LOCAL_LOG_TOPIC ("m-portal-permissionstore")
|
WP_DEFINE_LOCAL_LOG_TOPIC ("m-portal-permissionstore")
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ struct _WpPortalPermissionStorePlugin
|
|||||||
{
|
{
|
||||||
WpPlugin parent;
|
WpPlugin parent;
|
||||||
|
|
||||||
WpDbus *dbus;
|
WpPlugin *dbus;
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ wp_portal_permissionstore_plugin_lookup (WpPortalPermissionStorePlugin *self,
|
|||||||
g_autoptr (GVariant) res = NULL;
|
g_autoptr (GVariant) res = NULL;
|
||||||
GVariant *permissions = NULL, *data = 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);
|
g_return_val_if_fail (conn, NULL);
|
||||||
|
|
||||||
/* Lookup */
|
/* Lookup */
|
||||||
@@ -81,7 +82,7 @@ wp_portal_permissionstore_plugin_set (WpPortalPermissionStorePlugin *self,
|
|||||||
g_autoptr (GVariant) res = NULL;
|
g_autoptr (GVariant) res = NULL;
|
||||||
GVariant *data = NULL;
|
GVariant *data = NULL;
|
||||||
|
|
||||||
conn = wp_dbus_get_connection (self->dbus);
|
g_object_get (self->dbus, "connection", &conn, NULL);
|
||||||
g_return_if_fail (conn);
|
g_return_if_fail (conn);
|
||||||
|
|
||||||
/* Set */
|
/* Set */
|
||||||
@@ -118,7 +119,7 @@ clear_signal (WpPortalPermissionStorePlugin *self)
|
|||||||
{
|
{
|
||||||
g_autoptr (GDBusConnection) conn = NULL;
|
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) {
|
if (conn && self->signal_id > 0) {
|
||||||
g_dbus_connection_signal_unsubscribe (conn, self->signal_id);
|
g_dbus_connection_signal_unsubscribe (conn, self->signal_id);
|
||||||
self->signal_id = 0;
|
self->signal_id = 0;
|
||||||
@@ -126,16 +127,17 @@ clear_signal (WpPortalPermissionStorePlugin *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_dbus_state_changed (GObject * obj, GParamSpec * spec,
|
on_dbus_state_changed (GObject * dbus, GParamSpec * spec,
|
||||||
WpPortalPermissionStorePlugin *self)
|
WpPortalPermissionStorePlugin *self)
|
||||||
{
|
{
|
||||||
WpDBusState state = wp_dbus_get_state (self->dbus);
|
WpDBusConnectionState state = -1;
|
||||||
|
g_object_get (dbus, "state", &state, NULL);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case WP_DBUS_STATE_CONNECTED: {
|
case WP_DBUS_CONNECTION_STATE_CONNECTED: {
|
||||||
g_autoptr (GDBusConnection) conn = NULL;
|
g_autoptr (GDBusConnection) conn = NULL;
|
||||||
|
|
||||||
conn = wp_dbus_get_connection (self->dbus);
|
g_object_get (dbus, "connection", &conn, NULL);
|
||||||
g_return_if_fail (conn);
|
g_return_if_fail (conn);
|
||||||
|
|
||||||
self->signal_id = g_dbus_connection_signal_subscribe (conn,
|
self->signal_id = g_dbus_connection_signal_subscribe (conn,
|
||||||
@@ -145,8 +147,8 @@ on_dbus_state_changed (GObject * obj, GParamSpec * spec,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WP_DBUS_STATE_CONNECTING:
|
case WP_DBUS_CONNECTION_STATE_CONNECTING:
|
||||||
case WP_DBUS_STATE_CLOSED:
|
case WP_DBUS_CONNECTION_STATE_CLOSED:
|
||||||
clear_signal (self);
|
clear_signal (self);
|
||||||
break;
|
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
|
static void
|
||||||
wp_portal_permissionstore_plugin_enable (WpPlugin * plugin,
|
wp_portal_permissionstore_plugin_enable (WpPlugin * plugin,
|
||||||
WpTransition * transition)
|
WpTransition * transition)
|
||||||
{
|
{
|
||||||
WpPortalPermissionStorePlugin *self =
|
WpPortalPermissionStorePlugin *self =
|
||||||
WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin);
|
WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin);
|
||||||
|
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self));
|
||||||
|
|
||||||
/* make sure dbus always activated */
|
self->dbus = wp_plugin_find (core, "dbus-connection");
|
||||||
g_return_if_fail (self->dbus);
|
if (!self->dbus) {
|
||||||
wp_object_activate (WP_OBJECT (self->dbus), WP_OBJECT_FEATURES_ALL, NULL,
|
wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY,
|
||||||
(GAsyncReadyCallback) on_dbus_activated, transition);
|
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
|
static void
|
||||||
@@ -223,6 +192,7 @@ wp_portal_permissionstore_plugin_disable (WpPlugin * plugin)
|
|||||||
WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin);
|
WP_PORTAL_PERMISSIONSTORE_PLUGIN (plugin);
|
||||||
|
|
||||||
clear_signal (self);
|
clear_signal (self);
|
||||||
|
g_clear_object (&self->dbus);
|
||||||
|
|
||||||
wp_object_update_features (WP_OBJECT (self), 0, WP_PLUGIN_FEATURE_ENABLED);
|
wp_object_update_features (WP_OBJECT (self), 0, WP_PLUGIN_FEATURE_ENABLED);
|
||||||
}
|
}
|
||||||
@@ -231,12 +201,8 @@ static void
|
|||||||
wp_portal_permissionstore_plugin_class_init (
|
wp_portal_permissionstore_plugin_class_init (
|
||||||
WpPortalPermissionStorePluginClass * klass)
|
WpPortalPermissionStorePluginClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = (GObjectClass *) klass;
|
|
||||||
WpPluginClass *plugin_class = (WpPluginClass *) 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->enable = wp_portal_permissionstore_plugin_enable;
|
||||||
plugin_class->disable = wp_portal_permissionstore_plugin_disable;
|
plugin_class->disable = wp_portal_permissionstore_plugin_disable;
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "reserve-device.h"
|
#include "reserve-device.h"
|
||||||
#include "reserve-device-enums.h"
|
#include "reserve-device-enums.h"
|
||||||
|
#include "../dbus-connection-state.h"
|
||||||
|
|
||||||
WP_LOG_TOPIC (log_topic_rd, "m-reserve-device")
|
WP_LOG_TOPIC (log_topic_rd, "m-reserve-device")
|
||||||
|
|
||||||
@@ -41,15 +42,17 @@ clear_reservation (WpReserveDevicePlugin *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_dbus_state_changed (GObject * obj, GParamSpec * spec,
|
on_dbus_state_changed (GObject * dbus, GParamSpec * spec,
|
||||||
WpReserveDevicePlugin *self)
|
WpReserveDevicePlugin *self)
|
||||||
{
|
{
|
||||||
WpDBusState state = wp_dbus_get_state (self->dbus);
|
WpDBusConnectionState state = -1;
|
||||||
|
g_object_get (dbus, "state", &state, NULL);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case WP_DBUS_STATE_CONNECTED: {
|
case WP_DBUS_CONNECTION_STATE_CONNECTED: {
|
||||||
g_autoptr (GDBusConnection) conn = NULL;
|
g_autoptr (GDBusConnection) conn = NULL;
|
||||||
|
|
||||||
conn = wp_dbus_get_connection (self->dbus);
|
g_object_get (dbus, "connection", &conn, NULL);
|
||||||
g_return_if_fail (conn);
|
g_return_if_fail (conn);
|
||||||
|
|
||||||
self->manager = g_dbus_object_manager_server_new (
|
self->manager = g_dbus_object_manager_server_new (
|
||||||
@@ -58,35 +61,21 @@ on_dbus_state_changed (GObject * obj, GParamSpec * spec,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WP_DBUS_STATE_CONNECTING:
|
case WP_DBUS_CONNECTION_STATE_CONNECTING:
|
||||||
case WP_DBUS_STATE_CLOSED:
|
case WP_DBUS_CONNECTION_STATE_CLOSED:
|
||||||
clear_reservation (self);
|
clear_reservation (self);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wp_reserve_device_plugin_init (WpReserveDevicePlugin * self)
|
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,
|
self->reserve_devices = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL, rd_unref);
|
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
|
static void
|
||||||
@@ -95,35 +84,29 @@ wp_reserve_device_plugin_finalize (GObject * object)
|
|||||||
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (object);
|
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (object);
|
||||||
|
|
||||||
g_clear_pointer (&self->reserve_devices, g_hash_table_unref);
|
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);
|
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
|
static void
|
||||||
wp_reserve_device_plugin_enable (WpPlugin * plugin, WpTransition * transition)
|
wp_reserve_device_plugin_enable (WpPlugin * plugin, WpTransition * transition)
|
||||||
{
|
{
|
||||||
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin);
|
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin);
|
||||||
|
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self));
|
||||||
|
|
||||||
/* make sure dbus always activated */
|
self->dbus = wp_plugin_find (core, "dbus-connection");
|
||||||
g_return_if_fail (self->dbus);
|
if (!self->dbus) {
|
||||||
wp_object_activate (WP_OBJECT (self->dbus), WP_OBJECT_FEATURES_ALL, NULL,
|
wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY,
|
||||||
(GAsyncReadyCallback) on_dbus_activated, transition);
|
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
|
static void
|
||||||
@@ -132,6 +115,7 @@ wp_reserve_device_plugin_disable (WpPlugin * plugin)
|
|||||||
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin);
|
WpReserveDevicePlugin *self = WP_RESERVE_DEVICE_PLUGIN (plugin);
|
||||||
|
|
||||||
clear_reservation (self);
|
clear_reservation (self);
|
||||||
|
g_clear_object (&self->dbus);
|
||||||
|
|
||||||
wp_object_update_features (WP_OBJECT (self), 0, WP_PLUGIN_FEATURE_ENABLED);
|
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,
|
const gchar *name, const gchar *app_name, const gchar *app_dev_name,
|
||||||
gint priority)
|
gint priority)
|
||||||
{
|
{
|
||||||
WpDBusState state = wp_dbus_get_state (self->dbus);
|
WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED;
|
||||||
if (state != WP_DBUS_STATE_CONNECTED) {
|
g_object_get (self->dbus, "state", &state, NULL);
|
||||||
|
|
||||||
|
if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) {
|
||||||
wp_notice_object (self, "not connected to D-Bus");
|
wp_notice_object (self, "not connected to D-Bus");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -165,8 +151,10 @@ static void
|
|||||||
wp_reserve_device_plugin_destroy_reservation (WpReserveDevicePlugin *self,
|
wp_reserve_device_plugin_destroy_reservation (WpReserveDevicePlugin *self,
|
||||||
const gchar *name)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
WpDBusState state = wp_dbus_get_state (self->dbus);
|
WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED;
|
||||||
if (state != WP_DBUS_STATE_CONNECTED) {
|
g_object_get (self->dbus, "state", &state, NULL);
|
||||||
|
|
||||||
|
if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) {
|
||||||
wp_notice_object (self, "not connected to D-Bus");
|
wp_notice_object (self, "not connected to D-Bus");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,8 +165,10 @@ static gpointer
|
|||||||
wp_reserve_device_plugin_get_reservation (WpReserveDevicePlugin *self,
|
wp_reserve_device_plugin_get_reservation (WpReserveDevicePlugin *self,
|
||||||
const gchar *name)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
WpDBusState state = wp_dbus_get_state (self->dbus);
|
WpDBusConnectionState state = WP_DBUS_CONNECTION_STATE_CLOSED;
|
||||||
if (state != WP_DBUS_STATE_CONNECTED) {
|
g_object_get (self->dbus, "state", &state, NULL);
|
||||||
|
|
||||||
|
if (state != WP_DBUS_CONNECTION_STATE_CONNECTED) {
|
||||||
wp_notice_object (self, "not connected to D-Bus");
|
wp_notice_object (self, "not connected to D-Bus");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -199,7 +189,6 @@ wp_reserve_device_plugin_class_init (WpReserveDevicePluginClass * klass)
|
|||||||
GObjectClass *object_class = (GObjectClass *) klass;
|
GObjectClass *object_class = (GObjectClass *) klass;
|
||||||
WpPluginClass *plugin_class = (WpPluginClass *) klass;
|
WpPluginClass *plugin_class = (WpPluginClass *) klass;
|
||||||
|
|
||||||
object_class->constructed = wp_reserve_device_plugin_constructed;
|
|
||||||
object_class->finalize = wp_reserve_device_plugin_finalize;
|
object_class->finalize = wp_reserve_device_plugin_finalize;
|
||||||
|
|
||||||
plugin_class->enable = wp_reserve_device_plugin_enable;
|
plugin_class->enable = wp_reserve_device_plugin_enable;
|
||||||
|
@@ -19,12 +19,6 @@ WP_LOG_TOPIC_EXTERN (log_topic_rd)
|
|||||||
#define FDO_RESERVE_DEVICE1_SERVICE "org.freedesktop.ReserveDevice1"
|
#define FDO_RESERVE_DEVICE1_SERVICE "org.freedesktop.ReserveDevice1"
|
||||||
#define FDO_RESERVE_DEVICE1_PATH "/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,
|
G_DECLARE_FINAL_TYPE (WpReserveDevicePlugin, wp_reserve_device_plugin,
|
||||||
WP, RESERVE_DEVICE_PLUGIN, WpPlugin)
|
WP, RESERVE_DEVICE_PLUGIN, WpPlugin)
|
||||||
|
|
||||||
@@ -32,7 +26,7 @@ struct _WpReserveDevicePlugin
|
|||||||
{
|
{
|
||||||
WpPlugin parent;
|
WpPlugin parent;
|
||||||
|
|
||||||
WpDbus *dbus;
|
WpPlugin *dbus;
|
||||||
GHashTable *reserve_devices;
|
GHashTable *reserve_devices;
|
||||||
GDBusObjectManagerServer *manager;
|
GDBusObjectManagerServer *manager;
|
||||||
};
|
};
|
||||||
|
@@ -76,7 +76,8 @@ update_owner_app_name (WpReserveDevice *self)
|
|||||||
if (self->state == WP_RESERVE_DEVICE_STATE_BUSY && !self->owner_app_name) {
|
if (self->state == WP_RESERVE_DEVICE_STATE_BUSY && !self->owner_app_name) {
|
||||||
/* create proxy */
|
/* create proxy */
|
||||||
g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin);
|
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,
|
wp_org_freedesktop_reserve_device1_proxy_new (conn,
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||||
@@ -124,7 +125,9 @@ wp_reserve_device_constructed (GObject * object)
|
|||||||
{
|
{
|
||||||
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
||||||
g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin);
|
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 =
|
self->service_name =
|
||||||
g_strdup_printf (FDO_RESERVE_DEVICE1_SERVICE ".%s", self->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);
|
g_autoptr (WpReserveDevicePlugin) plugin = g_weak_ref_get (&self->plugin);
|
||||||
if (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;
|
GBusNameOwnerFlags flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE;
|
||||||
if (self->priority != G_MAXINT32)
|
if (self->priority != G_MAXINT32)
|
||||||
flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
|
flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
|
||||||
|
@@ -174,7 +174,8 @@ wp_reserve_device_acquire_transition_execute_step (
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STEP_GET_PROXY: {
|
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,
|
wp_org_freedesktop_reserve_device1_proxy_new (conn,
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||||
|
@@ -137,6 +137,13 @@ wireplumber.components = [
|
|||||||
priority = 130
|
priority = 130
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## The shared D-Bus connection
|
||||||
|
{
|
||||||
|
name = libwireplumber-module-dbus-connection
|
||||||
|
type = module
|
||||||
|
priority = 120
|
||||||
|
}
|
||||||
|
|
||||||
## API to access default nodes from scripts
|
## API to access default nodes from scripts
|
||||||
{
|
{
|
||||||
name = libwireplumber-module-default-nodes-api,
|
name = libwireplumber-module-default-nodes-api,
|
||||||
|
101
tests/modules/dbus-connection.c
Normal file
101
tests/modules/dbus-connection.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/* WirePlumber
|
||||||
|
*
|
||||||
|
* Copyright © 2022-2023 Collabora Ltd.
|
||||||
|
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wp/wp.h>
|
||||||
|
#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 ();
|
||||||
|
}
|
@@ -8,6 +8,13 @@ common_args = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
if get_option('dbus-tests')
|
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(
|
||||||
'test-reserve-device',
|
'test-reserve-device',
|
||||||
executable('test-reserve-device', 'reserve-device.c',
|
executable('test-reserve-device', 'reserve-device.c',
|
||||||
|
@@ -7,16 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <wp/wp.h>
|
#include <wp/wp.h>
|
||||||
|
#include "../../modules/dbus-connection-state.h"
|
||||||
#include "../common/base-test-fixture.h"
|
#include "../common/base-test-fixture.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
WpBaseTestFixture base;
|
WpBaseTestFixture base;
|
||||||
GTestDBus *test_dbus;
|
GTestDBus *test_dbus;
|
||||||
|
WpPlugin *dbus_1;
|
||||||
|
WpPlugin *dbus_2;
|
||||||
WpPlugin *rd_plugin_1;
|
WpPlugin *rd_plugin_1;
|
||||||
WpPlugin *rd_plugin_2;
|
WpPlugin *rd_plugin_2;
|
||||||
WpDbus *dbus_1;
|
|
||||||
WpDbus *dbus_2;
|
|
||||||
gint expected_rd1_state;
|
gint expected_rd1_state;
|
||||||
gint expected_rd2_state;
|
gint expected_rd2_state;
|
||||||
} RdTestFixture;
|
} RdTestFixture;
|
||||||
@@ -37,12 +37,26 @@ on_plugin_loaded (WpCore * core, GAsyncResult * res, RdTestFixture *f)
|
|||||||
static void
|
static void
|
||||||
test_rd_setup (RdTestFixture *f, gconstpointer data)
|
test_rd_setup (RdTestFixture *f, gconstpointer data)
|
||||||
{
|
{
|
||||||
|
WpDBusConnectionState state = -1;
|
||||||
|
|
||||||
wp_base_test_fixture_setup (&f->base,
|
wp_base_test_fixture_setup (&f->base,
|
||||||
WP_BASE_TEST_FLAG_CLIENT_CORE | WP_BASE_TEST_FLAG_DONT_CONNECT);
|
WP_BASE_TEST_FLAG_CLIENT_CORE | WP_BASE_TEST_FLAG_DONT_CONNECT);
|
||||||
|
|
||||||
f->test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
|
f->test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
|
||||||
g_test_dbus_up (f->test_dbus);
|
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,
|
wp_core_load_component (f->base.core,
|
||||||
"libwireplumber-module-reserve-device", "module", NULL, NULL,
|
"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);
|
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");
|
f->rd_plugin_1 = wp_plugin_find (f->base.core, "reserve-device");
|
||||||
g_assert_nonnull (f->rd_plugin_1);
|
g_assert_nonnull (f->rd_plugin_1);
|
||||||
|
|
||||||
f->rd_plugin_2 = wp_plugin_find (f->base.client_core, "reserve-device");
|
f->rd_plugin_2 = wp_plugin_find (f->base.client_core, "reserve-device");
|
||||||
g_assert_nonnull (f->rd_plugin_2);
|
g_assert_nonnull (f->rd_plugin_2);
|
||||||
|
|
||||||
g_signal_emit_by_name (f->rd_plugin_1, "get-dbus", &f->dbus_1);
|
g_object_get (f->dbus_1, "state", &state, NULL);
|
||||||
g_assert_nonnull (f->dbus_1);
|
g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CONNECTED);
|
||||||
|
|
||||||
g_signal_emit_by_name (f->rd_plugin_2, "get-dbus", &f->dbus_2);
|
g_object_get (f->dbus_2, "state", &state, NULL);
|
||||||
g_assert_nonnull (f->dbus_2);
|
g_assert_cmpint (state, ==, WP_DBUS_CONNECTION_STATE_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -84,10 +104,13 @@ test_rd_teardown (RdTestFixture *f, gconstpointer data)
|
|||||||
static void
|
static void
|
||||||
ensure_plugins_stable_state (GObject * obj, GParamSpec * spec, RdTestFixture *f)
|
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_1, "state", &state1, NULL);
|
||||||
g_object_get (f->dbus_2, "state", &state2, 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);
|
g_main_loop_quit (f->base.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,19 +118,9 @@ static void
|
|||||||
test_rd_plugin (RdTestFixture *f, gconstpointer data)
|
test_rd_plugin (RdTestFixture *f, gconstpointer data)
|
||||||
{
|
{
|
||||||
GObject *rd1 = NULL, *rd2 = NULL, *rd_video = NULL, *tmp = NULL;
|
GObject *rd1 = NULL, *rd2 = NULL, *rd_video = NULL, *tmp = NULL;
|
||||||
gint state = 0;
|
gint priority = 0;
|
||||||
gchar *str;
|
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",
|
g_signal_emit_by_name (f->rd_plugin_1, "create-reservation",
|
||||||
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
||||||
g_assert_nonnull (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_object_get (rd1, "application-device-name", &str, NULL);
|
||||||
g_assert_cmpstr (str, ==, "hw:0,0");
|
g_assert_cmpstr (str, ==, "hw:0,0");
|
||||||
g_free (str);
|
g_free (str);
|
||||||
g_object_get (rd1, "priority", &state, NULL);
|
g_object_get (rd1, "priority", &priority, NULL);
|
||||||
g_assert_cmpint (state, ==, 10);
|
g_assert_cmpint (priority, ==, 10);
|
||||||
g_object_get (rd2, "priority", &state, NULL);
|
g_object_get (rd2, "priority", &priority, NULL);
|
||||||
g_assert_cmpint (state, ==, 15);
|
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, "destroy-reservation", "Audio0");
|
||||||
g_signal_emit_by_name (f->rd_plugin_1, "get-reservation", "Audio0", &tmp);
|
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 (&rd2);
|
||||||
g_clear_object (&rd1);
|
g_clear_object (&rd1);
|
||||||
g_clear_object (&rd_video);
|
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
|
static void
|
||||||
test_rd_conn_closed (RdTestFixture *f, gconstpointer data)
|
test_rd_conn_closed (RdTestFixture *f, gconstpointer data)
|
||||||
{
|
{
|
||||||
GObject *rd1 = NULL;
|
GObject *rd1 = NULL;
|
||||||
gint state = 0;
|
WpDBusConnectionState state = -1;
|
||||||
|
|
||||||
g_signal_connect (f->dbus_1, "notify::state",
|
g_signal_connect (f->dbus_1, "notify::state",
|
||||||
G_CALLBACK (ensure_plugins_stable_state), f);
|
G_CALLBACK (ensure_plugins_stable_state), f);
|
||||||
g_signal_connect (f->dbus_2, "notify::state",
|
g_signal_connect (f->dbus_2, "notify::state",
|
||||||
G_CALLBACK (ensure_plugins_stable_state), f);
|
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",
|
g_signal_emit_by_name (f->rd_plugin_1, "create-reservation",
|
||||||
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
||||||
g_assert_nonnull (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_main_loop_run (f->base.loop);
|
||||||
|
|
||||||
g_object_get (f->dbus_1, "state", &state, NULL);
|
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_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_signal_emit_by_name (f->rd_plugin_1, "get-reservation", "Audio0", &rd1);
|
||||||
g_assert_null (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
|
static void
|
||||||
@@ -244,16 +238,6 @@ test_rd_acquire_release (RdTestFixture *f, gconstpointer data)
|
|||||||
gint state = 0;
|
gint state = 0;
|
||||||
gchar *str = NULL;
|
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",
|
g_signal_emit_by_name (f->rd_plugin_1, "create-reservation",
|
||||||
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
"Audio0", "WirePlumber", "hw:0,0", 10, &rd1);
|
||||||
g_assert_nonnull (rd1);
|
g_assert_nonnull (rd1);
|
||||||
@@ -336,12 +320,6 @@ test_rd_acquire_release (RdTestFixture *f, gconstpointer data)
|
|||||||
|
|
||||||
g_clear_object (&rd1);
|
g_clear_object (&rd1);
|
||||||
g_clear_object (&rd2);
|
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
|
gint
|
||||||
|
103
tests/wp/dbus.c
103
tests/wp/dbus.c
@@ -1,103 +0,0 @@
|
|||||||
/* WirePlumber
|
|
||||||
*
|
|
||||||
* Copyright © 2022 Collabora Ltd.
|
|
||||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <wp/wp.h>
|
|
||||||
|
|
||||||
#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 ();
|
|
||||||
}
|
|
@@ -91,15 +91,6 @@ test(
|
|||||||
env: common_env,
|
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(
|
||||||
'test-settings',
|
'test-settings',
|
||||||
executable('test-settings', 'settings.c',
|
executable('test-settings', 'settings.c',
|
||||||
|
Reference in New Issue
Block a user