mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-09 12:08:04 +02:00
modules: delete the old dbus-reservation module
This commit is contained in:
parent
ef908439c4
commit
c78373b1fc
8 changed files with 1 additions and 1243 deletions
|
|
@ -1,556 +0,0 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Generated with gdbus-codegen */
|
||||
#include "reserve-device-interface.h"
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include "dbus-device-reservation.h"
|
||||
|
||||
#define DEVICE_RESERVATION_SERVICE_PREFIX "org.freedesktop.ReserveDevice1."
|
||||
#define DEVICE_RESERVATION_OBJECT_PREFIX "/org/freedesktop/ReserveDevice1/"
|
||||
|
||||
struct _WpDbusDeviceReservation
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* Props */
|
||||
gint card_id;
|
||||
char *application_name;
|
||||
gint priority;
|
||||
char *app_dev_name;
|
||||
|
||||
char *service_name;
|
||||
char *object_path;
|
||||
GDBusConnection *connection;
|
||||
guint watcher_id;
|
||||
guint owner_id;
|
||||
guint registered_id;
|
||||
GDBusMethodInvocation *pending_release;
|
||||
|
||||
GTask *pending_task;
|
||||
char *pending_property_name;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CARD_ID,
|
||||
PROP_APPLICATION_NAME,
|
||||
PROP_PRIORITY,
|
||||
PROP_APP_DEV_NAME,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SIGNAL_RELEASE,
|
||||
SIGNAL_OWNER_APPEARED,
|
||||
SIGNAL_OWNER_VANISHED,
|
||||
SIGNAL_LAST,
|
||||
};
|
||||
|
||||
static guint device_reservation_signals[SIGNAL_LAST] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (WpDbusDeviceReservation, wp_dbus_device_reservation,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
handle_method_call (GDBusConnection *connection, const char *sender,
|
||||
const char *object_path, const char *interface_name,
|
||||
const char *method_name, GVariant *parameters,
|
||||
GDBusMethodInvocation *invocation, gpointer data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = data;
|
||||
|
||||
if (g_strcmp0 (method_name, "RequestRelease") == 0) {
|
||||
gint priority;
|
||||
g_variant_get (parameters, "(i)", &priority);
|
||||
|
||||
if (priority > self->priority) {
|
||||
if (self->pending_release)
|
||||
wp_dbus_device_reservation_complete_release (self, FALSE);
|
||||
self->pending_release = g_object_ref (invocation);
|
||||
g_signal_emit (self, device_reservation_signals[SIGNAL_RELEASE], 0, FALSE);
|
||||
} else {
|
||||
wp_dbus_device_reservation_complete_release (self, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
handle_get_property (GDBusConnection *connection, const char *sender,
|
||||
const char *object_path, const char *interface_name,
|
||||
const char *property, GError **error, gpointer data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = data;
|
||||
GVariant *ret = NULL;
|
||||
|
||||
if (g_strcmp0 (property, "ApplicationName") == 0)
|
||||
ret = g_variant_new_string (self->application_name ? self->application_name : "");
|
||||
else if (g_strcmp0 (property, "ApplicationDeviceName") == 0)
|
||||
ret = g_variant_new_string (self->app_dev_name ? self->app_dev_name : "");
|
||||
else if (g_strcmp0 (property, "Priority") == 0)
|
||||
ret = g_variant_new_int32 (self->priority);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
on_bus_acquired (GDBusConnection *connection, const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
g_autoptr (GError) error = NULL;
|
||||
static const GDBusInterfaceVTable interface_vtable = {
|
||||
handle_method_call,
|
||||
handle_get_property,
|
||||
NULL, /* Don't allow setting a property */
|
||||
};
|
||||
|
||||
wp_debug_object (self, "bus acquired");
|
||||
|
||||
self->registered_id = g_dbus_connection_register_object (connection,
|
||||
self->object_path,
|
||||
wp_org_freedesktop_reserve_device1_interface_info (),
|
||||
&interface_vtable,
|
||||
g_object_ref (self),
|
||||
g_object_unref,
|
||||
&error);
|
||||
g_return_if_fail (!error);
|
||||
g_return_if_fail (self->registered_id > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_acquired (GDBusConnection *connection, const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
wp_debug_object (self, "name acquired");
|
||||
|
||||
self->connection = connection;
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_unregister_object (WpDbusDeviceReservation *self)
|
||||
{
|
||||
if (self->connection && self->registered_id > 0) {
|
||||
g_dbus_connection_unregister_object (self->connection, self->registered_id);
|
||||
self->registered_id = 0;
|
||||
self->connection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_lost (GDBusConnection *connection, const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
wp_debug_object (self, "name lost");
|
||||
|
||||
self->connection = connection;
|
||||
|
||||
/* Unregister object */
|
||||
wp_dbus_device_reservation_unregister_object (self);
|
||||
|
||||
/* Emit release signal with forced set to TRUE */
|
||||
g_signal_emit (self, device_reservation_signals[SIGNAL_RELEASE], 0, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_appeared (GDBusConnection *connection, const gchar *name,
|
||||
const gchar *owner, gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
g_signal_emit (self, device_reservation_signals[SIGNAL_OWNER_APPEARED], 0,
|
||||
owner);
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_vanished (GDBusConnection *connection, const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
g_signal_emit (self, device_reservation_signals[SIGNAL_OWNER_VANISHED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_constructed (GObject * object)
|
||||
{
|
||||
WpDbusDeviceReservation *self = WP_DBUS_DEVICE_RESERVATION (object);
|
||||
|
||||
/* Set service name and object path */
|
||||
self->service_name = g_strdup_printf (DEVICE_RESERVATION_SERVICE_PREFIX
|
||||
"Audio%d", self->card_id);
|
||||
self->object_path = g_strdup_printf (DEVICE_RESERVATION_OBJECT_PREFIX
|
||||
"Audio%d", self->card_id);
|
||||
|
||||
/* Watch for the name */
|
||||
self->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, self->service_name,
|
||||
G_BUS_NAME_WATCHER_FLAGS_NONE, on_name_appeared, on_name_vanished, self,
|
||||
NULL);
|
||||
g_return_if_fail (self->watcher_id > 0);
|
||||
|
||||
G_OBJECT_CLASS (wp_dbus_device_reservation_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_get_property (GObject * object, guint property_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
WpDbusDeviceReservation *self = WP_DBUS_DEVICE_RESERVATION (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_CARD_ID:
|
||||
g_value_set_int (value, self->card_id);
|
||||
break;
|
||||
case PROP_APPLICATION_NAME:
|
||||
g_value_set_string (value, self->application_name);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
g_value_set_int (value, self->priority);
|
||||
break;
|
||||
case PROP_APP_DEV_NAME:
|
||||
g_value_set_string (value, self->app_dev_name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_set_property (GObject * object,
|
||||
guint property_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
WpDbusDeviceReservation *self = WP_DBUS_DEVICE_RESERVATION (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_CARD_ID:
|
||||
self->card_id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_APPLICATION_NAME:
|
||||
g_clear_pointer (&self->application_name, g_free);
|
||||
self->application_name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
self->priority = g_value_get_int(value);
|
||||
break;
|
||||
case PROP_APP_DEV_NAME:
|
||||
g_clear_pointer (&self->app_dev_name, g_free);
|
||||
self->app_dev_name = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_finalize (GObject * object)
|
||||
{
|
||||
WpDbusDeviceReservation *self = WP_DBUS_DEVICE_RESERVATION (object);
|
||||
|
||||
/* Finish pending task */
|
||||
if (self->pending_task) {
|
||||
g_autoptr (GTask) task = g_steal_pointer (&self->pending_task);
|
||||
GError *error = g_error_new (WP_DOMAIN_LIBRARY,
|
||||
WP_LIBRARY_ERROR_OPERATION_FAILED, "finishing before task is done");
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
g_clear_pointer (&self->pending_property_name, g_free);
|
||||
|
||||
/* Unwatch the name */
|
||||
if (self->watcher_id > 0)
|
||||
g_bus_unwatch_name (self->watcher_id);
|
||||
|
||||
/* Unregister and release */
|
||||
wp_dbus_device_reservation_unregister_object (self);
|
||||
wp_dbus_device_reservation_release (self);
|
||||
|
||||
g_clear_object (&self->pending_release);
|
||||
g_clear_pointer (&self->service_name, g_free);
|
||||
g_clear_pointer (&self->object_path, g_free);
|
||||
|
||||
/* Props */
|
||||
g_clear_pointer (&self->application_name, g_free);
|
||||
g_clear_pointer (&self->app_dev_name, g_free);
|
||||
|
||||
G_OBJECT_CLASS ( wp_dbus_device_reservation_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_init (WpDbusDeviceReservation * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wp_dbus_device_reservation_class_init (WpDbusDeviceReservationClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->constructed = wp_dbus_device_reservation_constructed;
|
||||
object_class->get_property = wp_dbus_device_reservation_get_property;
|
||||
object_class->set_property = wp_dbus_device_reservation_set_property;
|
||||
object_class->finalize = wp_dbus_device_reservation_finalize;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property (object_class, PROP_CARD_ID,
|
||||
g_param_spec_int ("card-id", "card-id",
|
||||
"The card Id", G_MININT, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_APPLICATION_NAME,
|
||||
g_param_spec_string ("application-name", "application-name",
|
||||
"The application name", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_PRIORITY,
|
||||
g_param_spec_int ("priority", "priority",
|
||||
"The priority", G_MININT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_APP_DEV_NAME,
|
||||
g_param_spec_string ("app-dev-name", "app-dev-name",
|
||||
"The application device name", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/* Signals */
|
||||
device_reservation_signals[SIGNAL_RELEASE] = g_signal_new (
|
||||
"release", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
|
||||
device_reservation_signals[SIGNAL_OWNER_APPEARED] = g_signal_new (
|
||||
"owner-appeared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
device_reservation_signals[SIGNAL_OWNER_VANISHED] = g_signal_new (
|
||||
"owner-vanished", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
WpDbusDeviceReservation *
|
||||
wp_dbus_device_reservation_new (gint card_id, const char *application_name,
|
||||
gint priority, const char *app_dev_name)
|
||||
{
|
||||
return g_object_new (WP_TYPE_DBUS_DEVICE_RESERVATION,
|
||||
"card-id", card_id,
|
||||
"application-name", application_name,
|
||||
"priority", priority,
|
||||
"app-dev-name", app_dev_name,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
wp_dbus_device_reservation_release (WpDbusDeviceReservation *self)
|
||||
{
|
||||
g_return_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self));
|
||||
if (self->owner_id == 0)
|
||||
return;
|
||||
|
||||
/* Release */
|
||||
g_bus_unown_name (self->owner_id);
|
||||
self->owner_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
wp_dbus_device_reservation_complete_release (WpDbusDeviceReservation *self,
|
||||
gboolean res)
|
||||
{
|
||||
g_return_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self));
|
||||
|
||||
if (!self->pending_release)
|
||||
return;
|
||||
|
||||
g_dbus_method_invocation_return_value (self->pending_release,
|
||||
g_variant_new ("(b)", res));
|
||||
g_clear_object (&self->pending_release);
|
||||
}
|
||||
|
||||
static void
|
||||
on_unowned (gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
wp_dbus_device_reservation_unregister_object (self);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wp_dbus_device_reservation_acquire (WpDbusDeviceReservation *self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self), FALSE);
|
||||
g_return_val_if_fail (!self->pending_task, FALSE);
|
||||
if (self->owner_id > 0)
|
||||
return FALSE;
|
||||
|
||||
/* Aquire */
|
||||
self->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, self->service_name,
|
||||
self->priority < INT32_MAX ?
|
||||
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT : G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||
on_bus_acquired, on_name_acquired, on_name_lost, g_object_ref (self),
|
||||
on_unowned);
|
||||
return self->owner_id > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
on_request_release_done (GObject *proxy, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = user_data;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_autoptr (GTask) task = g_steal_pointer (&self->pending_task);
|
||||
gboolean ret;
|
||||
|
||||
g_return_if_fail (task);
|
||||
|
||||
/* Finish */
|
||||
wp_org_freedesktop_reserve_device1_call_request_release_finish (
|
||||
WP_ORG_FREEDESKTOP_RESERVE_DEVICE1 (proxy),
|
||||
&ret, res, &error);
|
||||
if (error)
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
else
|
||||
g_task_return_pointer (task, GUINT_TO_POINTER (ret), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_proxy_done_request_release (GObject *obj, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = data;
|
||||
g_autoptr (WpOrgFreedesktopReserveDevice1) proxy = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_return_if_fail (self->pending_task);
|
||||
|
||||
/* Finish */
|
||||
proxy = wp_org_freedesktop_reserve_device1_proxy_new_for_bus_finish (
|
||||
res, &error);
|
||||
if (error) {
|
||||
g_autoptr (GTask) task = g_steal_pointer (&self->pending_task);
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request release */
|
||||
g_return_if_fail (proxy);
|
||||
wp_org_freedesktop_reserve_device1_call_request_release (proxy,
|
||||
self->priority, NULL, on_request_release_done, self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wp_dbus_device_reservation_request_release (WpDbusDeviceReservation *self,
|
||||
GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self), FALSE);
|
||||
g_return_val_if_fail (!self->pending_task, FALSE);
|
||||
|
||||
/* Set the new task */
|
||||
self->pending_task = g_task_new (self, cancellable, callback, user_data);
|
||||
|
||||
/* Get the proxy */
|
||||
wp_org_freedesktop_reserve_device1_proxy_new_for_bus (
|
||||
G_BUS_TYPE_SESSION, G_BUS_NAME_OWNER_FLAGS_NONE, self->service_name,
|
||||
self->object_path, NULL, on_proxy_done_request_release, self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_request_property_done (GObject *proxy, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = data;
|
||||
g_autoptr (GError) e = NULL;
|
||||
g_autoptr (GTask) task = g_steal_pointer (&self->pending_task);
|
||||
g_autoptr (GVariant) ret = NULL;
|
||||
g_autoptr (GVariant) var = NULL;
|
||||
g_return_if_fail (task);
|
||||
|
||||
/* Finish */
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, &e);
|
||||
if (e) {
|
||||
GError *error = g_error_new (WP_DOMAIN_LIBRARY,
|
||||
WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"failed to get property '%s' on proxy: %s",
|
||||
self->pending_property_name, e->message);
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the property value */
|
||||
g_variant_get (ret, "(v)", &var);
|
||||
g_return_if_fail (var);
|
||||
if (g_strcmp0 (self->pending_property_name, "ApplicationName") == 0) {
|
||||
g_task_return_pointer (task, g_variant_dup_string (var, NULL), NULL);
|
||||
}
|
||||
else if (g_strcmp0 (self->pending_property_name, "ApplicationDeviceName") == 0) {
|
||||
gchar *v = NULL;
|
||||
g_variant_get (ret, "(v)", &v);
|
||||
g_task_return_pointer (task, g_variant_dup_string (var, NULL), NULL);
|
||||
}
|
||||
else if (g_strcmp0 (self->pending_property_name, "Priority") == 0) {
|
||||
g_task_return_pointer (task, GINT_TO_POINTER (g_variant_get_int32 (var)), NULL);
|
||||
}
|
||||
else {
|
||||
GError *error = g_error_new (WP_DOMAIN_LIBRARY,
|
||||
WP_LIBRARY_ERROR_OPERATION_FAILED, "invalid property '%s' on proxy",
|
||||
self->pending_property_name);
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_proxy_done_request_property (GObject *obj, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
WpDbusDeviceReservation *self = data;
|
||||
g_autoptr (WpOrgFreedesktopReserveDevice1) proxy = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_return_if_fail (self->pending_task);
|
||||
|
||||
/* Finish */
|
||||
proxy = wp_org_freedesktop_reserve_device1_proxy_new_for_bus_finish (res,
|
||||
&error);
|
||||
if (error) {
|
||||
g_autoptr (GTask) task = g_steal_pointer (&self->pending_task);
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request the property call the Get method */
|
||||
g_return_if_fail (proxy);
|
||||
g_return_if_fail (self->pending_property_name);
|
||||
g_dbus_proxy_call (
|
||||
G_DBUS_PROXY (proxy),
|
||||
"org.freedesktop.DBus.Properties.Get",
|
||||
g_variant_new ("(ss)", "org.freedesktop.ReserveDevice1", self->pending_property_name),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
on_request_property_done,
|
||||
self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wp_dbus_device_reservation_request_property (WpDbusDeviceReservation *self,
|
||||
const char *name, GCancellable *cancellable, GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self), FALSE);
|
||||
g_return_val_if_fail (!self->pending_task, FALSE);
|
||||
|
||||
/* Set the new task and property name */
|
||||
self->pending_task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_clear_pointer (&self->pending_property_name, g_free);
|
||||
self->pending_property_name = g_strdup (name);
|
||||
|
||||
/* Get the proxy */
|
||||
wp_org_freedesktop_reserve_device1_proxy_new_for_bus (
|
||||
G_BUS_TYPE_SESSION, G_BUS_NAME_OWNER_FLAGS_NONE, self->service_name,
|
||||
self->object_path, NULL, on_proxy_done_request_property, self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gpointer
|
||||
wp_dbus_device_reservation_async_finish (WpDbusDeviceReservation *self,
|
||||
GAsyncResult * res, GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_DBUS_DEVICE_RESERVATION (self), FALSE);
|
||||
g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (res), error);
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __WIREPLUMBER_DBUS_DEVICE_RESERVATION_H__
|
||||
#define __WIREPLUMBER_DBUS_DEVICE_RESERVATION_H__
|
||||
|
||||
#include <wp/wp.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JACK_APPLICATION_NAME "Jack audio server"
|
||||
#define PULSEAUDIO_APPLICATION_NAME "PulseAudio Sound Server"
|
||||
#define PIPEWIRE_APPLICATION_NAME "PipeWire"
|
||||
|
||||
#define WP_TYPE_DBUS_DEVICE_RESERVATION (wp_dbus_device_reservation_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (WpDbusDeviceReservation, wp_dbus_device_reservation, WP,
|
||||
DBUS_DEVICE_RESERVATION, GObject)
|
||||
|
||||
WpDbusDeviceReservation * wp_dbus_device_reservation_new (
|
||||
gint card_id, const char *application_name, gint priority,
|
||||
const char *app_dev_name);
|
||||
|
||||
void wp_dbus_device_reservation_release (WpDbusDeviceReservation *self);
|
||||
|
||||
void wp_dbus_device_reservation_complete_release (WpDbusDeviceReservation *self,
|
||||
gboolean res);
|
||||
|
||||
gboolean wp_dbus_device_reservation_acquire (WpDbusDeviceReservation *self);
|
||||
|
||||
gboolean wp_dbus_device_reservation_request_release (
|
||||
WpDbusDeviceReservation *self, GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback, gpointer user_data);
|
||||
|
||||
gboolean wp_dbus_device_reservation_request_property (
|
||||
WpDbusDeviceReservation *self, const char *name, GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback, gpointer user_data);
|
||||
|
||||
gpointer wp_dbus_device_reservation_async_finish (WpDbusDeviceReservation *self,
|
||||
GAsyncResult * res, GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<node>
|
||||
<interface name="org.freedesktop.ReserveDevice1">
|
||||
<method name="RequestRelease">
|
||||
<arg name="priority" type="i" direction="in"/>
|
||||
<arg name="result" type="b" direction="out"/>
|
||||
</method>
|
||||
<property name="Priority" type="i" access="read"/>
|
||||
<property name="ApplicationName" type="s" access="read"/>
|
||||
<property name="ApplicationDeviceName" type="s" access="read"/>
|
||||
</interface>
|
||||
</node>
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "reserve-device.h"
|
||||
|
||||
#include <spa/pod/builder.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
G_DEFINE_QUARK (wp-reserve-device-jack-n-acquired, jack_n_acquired);
|
||||
|
||||
struct _WpReserveDevice
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* Props */
|
||||
GWeakRef core;
|
||||
WpDbusDeviceReservation *reservation;
|
||||
GClosure *manager_closure;
|
||||
|
||||
/* JACK */
|
||||
WpObjectManager *jack_device_om;
|
||||
|
||||
GSource *timeout_source;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CORE,
|
||||
PROP_RESERVATION,
|
||||
PROP_MANAGER_CLOSURE,
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (WpReserveDevice, wp_reserve_device, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
set_device_profile (WpPipewireObject *device, gint index)
|
||||
{
|
||||
g_return_if_fail (device);
|
||||
g_autoptr (WpSpaPod) profile = wp_spa_pod_new_object (
|
||||
"Spa:Pod:Object:Param:Profile", "Profile",
|
||||
"index", "i", index,
|
||||
NULL);
|
||||
wp_debug_object (device, "set profile %d", index);
|
||||
wp_pipewire_object_set_param (device, "Profile", 0, profile);
|
||||
}
|
||||
|
||||
static gint
|
||||
decrement_jack_n_acquired (WpPipewireObject *device)
|
||||
{
|
||||
gpointer p = g_object_get_qdata (G_OBJECT (device), jack_n_acquired_quark ());
|
||||
gint val = GPOINTER_TO_INT (p);
|
||||
if (val == 0)
|
||||
return -1;
|
||||
g_object_set_qdata (G_OBJECT (device), jack_n_acquired_quark (),
|
||||
GINT_TO_POINTER (--val));
|
||||
return val;
|
||||
}
|
||||
|
||||
static gint
|
||||
increment_jack_n_acquired (WpPipewireObject *device)
|
||||
{
|
||||
gpointer p = g_object_get_qdata (G_OBJECT (device), jack_n_acquired_quark ());
|
||||
gint val = GPOINTER_TO_INT (p);
|
||||
g_object_set_qdata (G_OBJECT (device), jack_n_acquired_quark (),
|
||||
GINT_TO_POINTER (++val));
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
enable_jack_device (WpReserveDevice *self) {
|
||||
g_autoptr (WpPipewireObject) jack_device = NULL;
|
||||
g_return_if_fail (self);
|
||||
|
||||
/* Get the JACK device and increment the jack acquisition. We only enable the
|
||||
* JACK device if this is the first acquisition */
|
||||
jack_device = wp_object_manager_lookup (self->jack_device_om, WP_TYPE_DEVICE,
|
||||
NULL);
|
||||
if (jack_device && increment_jack_n_acquired (jack_device) == 1) {
|
||||
set_device_profile (jack_device, 1);
|
||||
wp_info_object (self, "jack device enabled");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disable_jack_device (WpReserveDevice *self) {
|
||||
g_autoptr (WpPipewireObject) jack_device = NULL;
|
||||
g_return_if_fail (self);
|
||||
|
||||
/* Get the JACK device and decrement the jack acquisition. We only disable the
|
||||
* JACK device if there is no more acquisitions */
|
||||
jack_device = wp_object_manager_lookup (self->jack_device_om, WP_TYPE_DEVICE,
|
||||
NULL);
|
||||
if (jack_device && decrement_jack_n_acquired (jack_device) == 0) {
|
||||
set_device_profile (jack_device, 0);
|
||||
wp_info_object (self, "jack device disabled");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invoke_manager_closure (WpReserveDevice *self, gboolean create)
|
||||
{
|
||||
GValue values[2] = { G_VALUE_INIT, G_VALUE_INIT };
|
||||
|
||||
g_return_if_fail (self->manager_closure);
|
||||
|
||||
g_value_init (&values[0], G_TYPE_OBJECT);
|
||||
g_value_init (&values[1], G_TYPE_BOOLEAN);
|
||||
g_value_set_object (&values[0], self);
|
||||
g_value_set_boolean (&values[1], create);
|
||||
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (self->manager_closure))
|
||||
g_closure_set_marshal (self->manager_closure,
|
||||
g_cclosure_marshal_VOID__BOOLEAN);
|
||||
g_closure_invoke (self->manager_closure, NULL, 2, values, NULL);
|
||||
|
||||
g_value_unset (&values[0]);
|
||||
g_value_unset (&values[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_done (WpCore *core, GAsyncResult *res, WpReserveDevice *self)
|
||||
{
|
||||
if (self->reservation)
|
||||
wp_dbus_device_reservation_complete_release (self->reservation, TRUE);
|
||||
else
|
||||
wp_warning_object (self, "release not completed");
|
||||
}
|
||||
|
||||
static void
|
||||
on_application_name_appeared (GObject *obj, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
WpReserveDevice *self = data;
|
||||
g_autoptr (GError) e = NULL;
|
||||
g_autofree gchar *name = NULL;
|
||||
|
||||
/* Note that the ApplicationName property is optional as described in the
|
||||
* specification (http://git.0pointer.net/reserve.git/tree/reserve.txt), so
|
||||
* some audio servers can return NULL, and this is not an error */
|
||||
name = wp_dbus_device_reservation_async_finish (self->reservation, res, &e);
|
||||
if (e) {
|
||||
wp_warning_object (self, "could not get application name: %s", e->message);
|
||||
return;
|
||||
}
|
||||
|
||||
wp_info_object (self, "owner appeared: %s", name ? name : "unknown");
|
||||
|
||||
/* If the JACK server owns the audio device, we disable the audio device and
|
||||
* enable the JACK device */
|
||||
if (name && g_strcmp0 (name, JACK_APPLICATION_NAME) == 0) {
|
||||
invoke_manager_closure (self, FALSE);
|
||||
enable_jack_device (self);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we (PipeWire) own the audio device, we enable the audio device and
|
||||
* disable the JACK device */
|
||||
else if (name && g_strcmp0 (name, PIPEWIRE_APPLICATION_NAME) == 0) {
|
||||
disable_jack_device (self);
|
||||
invoke_manager_closure (self, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If another server different to JACK and PipeWire (ie PulseAudio) owns the
|
||||
* device, we disable both the audio device and the JACK device */
|
||||
else {
|
||||
disable_jack_device (self);
|
||||
invoke_manager_closure (self, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_reservation_owner_appeared (WpDbusDeviceReservation *reservation,
|
||||
const gchar *owner, WpReserveDevice *self)
|
||||
{
|
||||
/* Clear the current timeout acquire callback */
|
||||
if (self->timeout_source)
|
||||
g_source_destroy (self->timeout_source);
|
||||
g_clear_pointer (&self->timeout_source, g_source_unref);
|
||||
|
||||
/* Request the application name to know who is the new owner */
|
||||
wp_dbus_device_reservation_request_property (self->reservation,
|
||||
"ApplicationName", NULL, on_application_name_appeared, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
timeout_acquire_callback (WpReserveDevice *self)
|
||||
{
|
||||
g_return_val_if_fail (self, G_SOURCE_REMOVE);
|
||||
wp_dbus_device_reservation_acquire (self->reservation);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_reservation_owner_vanished (WpDbusDeviceReservation *reservation,
|
||||
WpReserveDevice *self)
|
||||
{
|
||||
g_autoptr (WpCore) core = g_weak_ref_get (&self->core);
|
||||
|
||||
wp_info_object (self, "owner vanished");
|
||||
|
||||
/* Always disable JACK device and destroy audio device when owner vanishes.
|
||||
* The devices will be enabled/created later when a new owner appears */
|
||||
disable_jack_device (self);
|
||||
invoke_manager_closure (self, FALSE);
|
||||
|
||||
/* Clear the current timeout acquire callback */
|
||||
if (self->timeout_source)
|
||||
g_source_destroy (self->timeout_source);
|
||||
g_clear_pointer (&self->timeout_source, g_source_unref);
|
||||
|
||||
/* Try to acquire the device if it has no owner for at least 3 seconds */
|
||||
g_return_if_fail (core);
|
||||
wp_core_timeout_add_closure (core, &self->timeout_source, 3000,
|
||||
g_cclosure_new_object (G_CALLBACK (timeout_acquire_callback),
|
||||
G_OBJECT (self)));
|
||||
}
|
||||
|
||||
static void
|
||||
on_reservation_release (WpDbusDeviceReservation *reservation, gboolean forced,
|
||||
WpReserveDevice *self)
|
||||
{
|
||||
/* Release reservation */
|
||||
wp_dbus_device_reservation_release (reservation);
|
||||
|
||||
/* Destroy the device */
|
||||
invoke_manager_closure (self, FALSE);
|
||||
|
||||
/* Only complete the release if not forced */
|
||||
if (!forced) {
|
||||
g_autoptr (WpCore) core = g_weak_ref_get (&self->core);
|
||||
g_return_if_fail (core);
|
||||
wp_core_sync (core, NULL, (GAsyncReadyCallback)on_device_done, self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_constructed (GObject * object)
|
||||
{
|
||||
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
||||
g_autoptr (WpProxy) device = NULL;
|
||||
g_autoptr (WpCore) core = g_weak_ref_get (&self->core);
|
||||
g_return_if_fail (core);
|
||||
|
||||
/* Create the JACK device object manager */
|
||||
self->jack_device_om = wp_object_manager_new ();
|
||||
wp_object_manager_add_interest (self->jack_device_om, WP_TYPE_DEVICE,
|
||||
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, PW_KEY_DEVICE_API, "=s", "jack",
|
||||
NULL);
|
||||
wp_object_manager_request_object_features (self->jack_device_om,
|
||||
WP_TYPE_DEVICE, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL);
|
||||
wp_core_install_object_manager (core, self->jack_device_om);
|
||||
|
||||
/* Handle the reservation signals */
|
||||
g_return_if_fail (self->reservation);
|
||||
g_signal_connect_object (self->reservation, "owner-appeared",
|
||||
(GCallback) on_reservation_owner_appeared, self, 0);
|
||||
g_signal_connect_object (self->reservation, "owner-vanished",
|
||||
(GCallback) on_reservation_owner_vanished, self, 0);
|
||||
g_signal_connect_object (self->reservation, "release",
|
||||
(GCallback) on_reservation_release, self, 0);
|
||||
|
||||
/* Try to acquire the device */
|
||||
wp_dbus_device_reservation_acquire (self->reservation);
|
||||
|
||||
G_OBJECT_CLASS (wp_reserve_device_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_get_property (GObject * object,
|
||||
guint property_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_CORE:
|
||||
g_value_take_object (value, g_weak_ref_get (&self->core));
|
||||
break;
|
||||
case PROP_RESERVATION:
|
||||
g_value_set_object (value, self->reservation);
|
||||
break;
|
||||
case PROP_MANAGER_CLOSURE:
|
||||
g_value_set_boxed (value, self->manager_closure);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_set_property (GObject * object,
|
||||
guint property_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_CORE:
|
||||
g_weak_ref_set (&self->core, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_RESERVATION:
|
||||
self->reservation = g_value_dup_object (value);
|
||||
break;
|
||||
case PROP_MANAGER_CLOSURE:
|
||||
self->manager_closure = g_value_dup_boxed (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_finalize (GObject * object)
|
||||
{
|
||||
WpReserveDevice *self = WP_RESERVE_DEVICE (object);
|
||||
|
||||
/* Clear the current timeout acquire callback */
|
||||
if (self->timeout_source)
|
||||
g_source_destroy (self->timeout_source);
|
||||
g_clear_pointer (&self->timeout_source, g_source_unref);
|
||||
|
||||
wp_dbus_device_reservation_release (self->reservation);
|
||||
|
||||
/* JACK */
|
||||
g_clear_object (&self->jack_device_om);
|
||||
|
||||
/* Props */
|
||||
g_weak_ref_clear (&self->core);
|
||||
g_clear_object (&self->reservation);
|
||||
g_clear_pointer (&self->manager_closure, g_closure_unref);
|
||||
|
||||
G_OBJECT_CLASS (wp_reserve_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_init (WpReserveDevice * self)
|
||||
{
|
||||
/* Props */
|
||||
g_weak_ref_init (&self->core, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_reserve_device_class_init (WpReserveDeviceClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->constructed = wp_reserve_device_constructed;
|
||||
object_class->get_property = wp_reserve_device_get_property;
|
||||
object_class->set_property = wp_reserve_device_set_property;
|
||||
object_class->finalize = wp_reserve_device_finalize;
|
||||
|
||||
/* Props */
|
||||
g_object_class_install_property (object_class, PROP_CORE,
|
||||
g_param_spec_object ("core", "core",
|
||||
"The wireplumber core", WP_TYPE_CORE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_RESERVATION,
|
||||
g_param_spec_object ("reservation", "reservation",
|
||||
"The dbus device reservation", WP_TYPE_DBUS_DEVICE_RESERVATION,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_MANAGER_CLOSURE,
|
||||
g_param_spec_boxed ("manager-closure", "manager-closure",
|
||||
"The closure that manages the device", G_TYPE_CLOSURE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
WpReserveDevice *
|
||||
wp_reserve_device_new (WpCore *core, WpDbusDeviceReservation *reservation,
|
||||
GClosure *manager_closure)
|
||||
{
|
||||
return g_object_new (WP_TYPE_RESERVE_DEVICE,
|
||||
"core", core,
|
||||
"reservation", reservation,
|
||||
"manager-closure", manager_closure,
|
||||
NULL);
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __WIREPLUMBER_RESERVE_DEVICE_H__
|
||||
#define __WIREPLUMBER_RESERVE_DEVICE_H__
|
||||
|
||||
#include <wp/wp.h>
|
||||
|
||||
#include "dbus-device-reservation.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define WP_TYPE_RESERVE_DEVICE (wp_reserve_device_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (WpReserveDevice, wp_reserve_device, WP, RESERVE_DEVICE,
|
||||
GObject)
|
||||
|
||||
WpReserveDevice * wp_reserve_device_new (WpCore *core,
|
||||
WpDbusDeviceReservation *reservation, GClosure *manager_closure);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -50,7 +50,7 @@ load-module C libwireplumber-module-si-bluez5-endpoint
|
|||
#
|
||||
|
||||
# Grants dbus reservation functionality
|
||||
#load-module C libwireplumber-module-dbus-reservation
|
||||
load-module C libwireplumber-module-reserve-device
|
||||
|
||||
# Grants functionality to store and restaure default device profiles
|
||||
load-module C libwireplumber-module-default-profile
|
||||
|
|
|
|||
|
|
@ -1,205 +0,0 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2020 Collabora Ltd.
|
||||
* @author Julian Bouzas <julian.bouzas@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <wp/wp.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include "../../modules/module-dbus-reservation/dbus-device-reservation.h"
|
||||
|
||||
typedef struct {
|
||||
GTestDBus *dbus_test;
|
||||
GMainLoop *loop;
|
||||
gboolean owner_appeared;
|
||||
gboolean released;
|
||||
gpointer property;
|
||||
} TestDbusFixture;
|
||||
|
||||
static void
|
||||
test_dbus_setup (TestDbusFixture *self, gconstpointer data)
|
||||
{
|
||||
self->dbus_test = g_test_dbus_new (G_TEST_DBUS_NONE);
|
||||
g_test_dbus_up (self->dbus_test);
|
||||
self->loop = g_main_loop_new (NULL, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dbus_teardown (TestDbusFixture *self, gconstpointer data)
|
||||
{
|
||||
g_clear_pointer (&self->loop, g_main_loop_unref);
|
||||
g_test_dbus_down (self->dbus_test);
|
||||
g_clear_object (&self->dbus_test);
|
||||
}
|
||||
|
||||
static void
|
||||
on_reservation_release (WpDbusDeviceReservation *reservation,
|
||||
gboolean forced, TestDbusFixture *self)
|
||||
{
|
||||
wp_dbus_device_reservation_release (reservation);
|
||||
if (!forced)
|
||||
wp_dbus_device_reservation_complete_release (reservation, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_reservation_owner_appeared (WpDbusDeviceReservation *reservation,
|
||||
const gchar *owner, TestDbusFixture *self)
|
||||
{
|
||||
self->owner_appeared = TRUE;
|
||||
g_main_loop_quit (self->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_request_release_done (GObject *obj, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
TestDbusFixture *self = user_data;
|
||||
WpDbusDeviceReservation *r = WP_DBUS_DEVICE_RESERVATION (obj);
|
||||
g_autoptr (GError) e = NULL;
|
||||
wp_dbus_device_reservation_async_finish (r, res, &e);
|
||||
g_assert_null (e);
|
||||
self->released = TRUE;
|
||||
g_main_loop_quit (self->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_request_property_done (GObject *obj, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
TestDbusFixture *self = user_data;
|
||||
WpDbusDeviceReservation *r = WP_DBUS_DEVICE_RESERVATION (obj);
|
||||
g_autoptr (GError) e = NULL;
|
||||
gpointer ret = wp_dbus_device_reservation_async_finish (r, res, &e);
|
||||
g_assert_null (e);
|
||||
self->property = ret;
|
||||
g_main_loop_quit (self->loop);
|
||||
}
|
||||
|
||||
static WpDbusDeviceReservation *
|
||||
create_representation (TestDbusFixture *self, gint card_id,
|
||||
const char *app_name, gint priority, const char *app_dev_name)
|
||||
{
|
||||
WpDbusDeviceReservation *r = wp_dbus_device_reservation_new (
|
||||
card_id, app_name, priority, app_dev_name);
|
||||
g_assert_nonnull (r);
|
||||
g_signal_connect (r, "release",
|
||||
(GCallback) on_reservation_release, self);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
test_dbus_basic (TestDbusFixture *self, gconstpointer data)
|
||||
{
|
||||
g_autoptr (WpDbusDeviceReservation) r1 = NULL;
|
||||
g_autoptr (WpDbusDeviceReservation) r2 = NULL;
|
||||
|
||||
/* Create 2 reservations */
|
||||
r1 = create_representation (self, 0, "Server", 10, "hw:0,0");
|
||||
r2 = create_representation (self, 0, "PipeWire", 15, "hw:0,0");
|
||||
|
||||
/* Only handle owner-appeared on r1 */
|
||||
g_signal_connect (r1, "owner-appeared",
|
||||
(GCallback) on_reservation_owner_appeared, self);
|
||||
|
||||
/* Acquire the device on r1 */
|
||||
self->owner_appeared = FALSE;
|
||||
g_assert_true (wp_dbus_device_reservation_acquire (r1));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_true (self->owner_appeared);
|
||||
|
||||
/* Request the priority property on r1 and make sure it is 10 */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r1,
|
||||
"Priority", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (self->property), ==, 10);
|
||||
|
||||
/* Request the application name property on r1 and make sure it is Server */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r1,
|
||||
"ApplicationName", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpstr (self->property, ==, "Server");
|
||||
g_free (self->property);
|
||||
|
||||
/* Request the app device name property on r1 and make sure it is hw:0,0 */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r1,
|
||||
"ApplicationDeviceName", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpstr (self->property, ==, "hw:0,0");
|
||||
g_free (self->property);
|
||||
|
||||
/* Request the priority property on r2 and make sure it is also 10 because r1
|
||||
* owns the device */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r2,
|
||||
"Priority", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (self->property), ==, 10);
|
||||
|
||||
/* Request release on r2 (higher priority) */
|
||||
self->released = FALSE;
|
||||
g_assert_true (wp_dbus_device_reservation_request_release (r2, NULL,
|
||||
on_request_release_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_true (self->released);
|
||||
|
||||
/* Acquire the device on r2 */
|
||||
self->owner_appeared = FALSE;
|
||||
g_assert_true (wp_dbus_device_reservation_acquire (r2));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_true (self->owner_appeared);
|
||||
|
||||
/* Request the priority property on r2 and make sure it is 15 */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r2,
|
||||
"Priority", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (self->property), ==, 15);
|
||||
|
||||
/* Request the application name property on r1 and make sure it is Server */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r2,
|
||||
"ApplicationName", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpstr (self->property, ==, "PipeWire");
|
||||
g_free (self->property);
|
||||
|
||||
/* Request the app device name property on r2 and make sure it is hw:0,0 */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r2,
|
||||
"ApplicationDeviceName", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpstr (self->property, ==, "hw:0,0");
|
||||
g_free (self->property);
|
||||
|
||||
/* Request the priority property on r1 and make sure it is also 15 because r2
|
||||
* owns the device now */
|
||||
self->property = NULL;
|
||||
g_assert_true (wp_dbus_device_reservation_request_property (r1,
|
||||
"Priority", NULL, on_request_property_done, self));
|
||||
g_main_loop_run (self->loop);
|
||||
g_assert_nonnull (self->property);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (self->property), ==, 15);
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
wp_init (WP_INIT_ALL);
|
||||
|
||||
g_test_add ("/wp/dbus/basic", TestDbusFixture, NULL,
|
||||
test_dbus_setup, test_dbus_basic, test_dbus_teardown);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
@ -50,19 +50,6 @@ test(
|
|||
workdir : meson.current_source_dir(),
|
||||
)
|
||||
|
||||
test(
|
||||
'test-dbus-device-reservation',
|
||||
executable('test-dbus-device-reservation',
|
||||
[
|
||||
'dbus-device-reservation.c',
|
||||
'../../modules/module-dbus-reservation/dbus-device-reservation.c',
|
||||
reserve_device_interface_src,
|
||||
],
|
||||
dependencies: common_deps + [giounix_dep], c_args: common_args),
|
||||
env: common_env,
|
||||
workdir : meson.current_source_dir(),
|
||||
)
|
||||
|
||||
test(
|
||||
'test-reserve-device',
|
||||
executable('test-reserve-device', 'reserve-device.c',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue