From 9004362cda6ba9b8bdd77b8e09c9c6e17ef8fbe5 Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Fri, 9 Dec 2022 13:01:13 -0500 Subject: [PATCH] lib: remove WpEndpoint and WpSiEndpoint APIs --- docs/rst/c_api.rst | 1 - docs/rst/c_api/endpoint_api.rst | 24 - docs/rst/c_api/meson.build | 1 - docs/rst/c_api/si_interfaces_api.rst | 5 - lib/wp/endpoint.c | 698 ---------------------- lib/wp/endpoint.h | 59 -- lib/wp/meson.build | 2 - lib/wp/object-manager.c | 2 +- lib/wp/private/pipewire-object-mixin.h | 2 +- lib/wp/session-item.c | 7 +- lib/wp/si-interfaces.c | 82 +-- lib/wp/si-interfaces.h | 26 - lib/wp/wp.c | 1 - lib/wp/wp.h | 1 - modules/module-lua-scripting/api/api.c | 8 - modules/module-si-audio-endpoint.c | 81 +-- modules/module-standard-event-source.c | 6 - src/tools/wpctl.c | 74 +-- tests/modules/si-audio-endpoint.c | 15 +- tests/wp/endpoint.c | 780 ------------------------- tests/wp/meson.build | 7 - 21 files changed, 11 insertions(+), 1871 deletions(-) delete mode 100644 docs/rst/c_api/endpoint_api.rst delete mode 100644 lib/wp/endpoint.c delete mode 100644 lib/wp/endpoint.h delete mode 100644 tests/wp/endpoint.c diff --git a/docs/rst/c_api.rst b/docs/rst/c_api.rst index f1b7631d..665a85bb 100644 --- a/docs/rst/c_api.rst +++ b/docs/rst/c_api.rst @@ -24,7 +24,6 @@ C API Documentation c_api/device_api.rst c_api/client_api.rst c_api/metadata_api.rst - c_api/endpoint_api.rst c_api/spa_device_api.rst c_api/impl_node_api.rst c_api/impl_module_api.rst diff --git a/docs/rst/c_api/endpoint_api.rst b/docs/rst/c_api/endpoint_api.rst deleted file mode 100644 index 51a75360..00000000 --- a/docs/rst/c_api/endpoint_api.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. _endpoint_api: - -PipeWire Endpoint -================= -.. graphviz:: - :align: center - - digraph inheritance { - rankdir=LR; - GObject -> WpObject; - WpObject -> WpProxy; - WpProxy -> WpGlobalProxy; - WpGlobalProxy -> WpEndpoint; - GInterface -> WpPipewireObject; - WpPipewireObject -> WpEndpoint; - WpEndpoint -> WpImplEndpoint; - } - -.. doxygenstruct:: WpEndpoint - -.. doxygenstruct:: WpImplEndpoint - -.. doxygengroup:: wpendpoint - :content-only: diff --git a/docs/rst/c_api/meson.build b/docs/rst/c_api/meson.build index 8b4f634f..e8f0fec2 100644 --- a/docs/rst/c_api/meson.build +++ b/docs/rst/c_api/meson.build @@ -4,7 +4,6 @@ sphinx_files += files( 'component_loader_api.rst', 'core_api.rst', 'device_api.rst', - 'endpoint_api.rst', 'global_proxy_api.rst', 'impl_module_api.rst', 'impl_node_api.rst', diff --git a/docs/rst/c_api/si_interfaces_api.rst b/docs/rst/c_api/si_interfaces_api.rst index 237a0b7d..df03a536 100644 --- a/docs/rst/c_api/si_interfaces_api.rst +++ b/docs/rst/c_api/si_interfaces_api.rst @@ -7,17 +7,12 @@ Session Items Interfaces digraph inheritance { rankdir=LR; - GInterface -> WpSiEndpoint; GInterface -> WpSiAdapter; GInterface -> WpSiLinkable; GInterface -> WpSiLink; GInterface -> WpSiAcquisition; } -.. doxygenstruct:: WpSiEndpoint - -.. doxygenstruct:: _WpSiEndpointInterface - .. doxygenstruct:: WpSiAdapter .. doxygenstruct:: _WpSiAdapterInterface diff --git a/lib/wp/endpoint.c b/lib/wp/endpoint.c deleted file mode 100644 index 07ab47c6..00000000 --- a/lib/wp/endpoint.c +++ /dev/null @@ -1,698 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#define G_LOG_DOMAIN "wp-endpoint" - -#include "endpoint.h" -#include "node.h" -#include "object-manager.h" -#include "error.h" -#include "log.h" -#include "wpenums.h" -#include "spa-type.h" -#include "si-factory.h" -#include "private/pipewire-object-mixin.h" - -#include -#include -#include - -/*! \defgroup wpendpoint WpEndpoint */ -/*! - * \struct WpEndpoint - * - * The WpEndpoint class allows accessing the properties and methods of a - * PipeWire endpoint object (`struct pw_endpoint` from the session-manager extension). - * - * A WpEndpoint is constructed internally when a new endpoint appears on the - * PipeWire registry and it is made available through the WpObjectManager API. - * - * \gproperties - * - * \gproperty{name, gchar *, G_PARAM_READABLE, The name of the endpoint} - * - * \gproperty{media-class, gchar *, G_PARAM_READABLE, - * The media class of the endpoint (ex. "Audio/Sink")} - * - * \gproperty{direction, WpDirection, G_PARAM_READABLE, - * The direction of the endpoint} - */ - -enum { - PROP_NAME = WP_PW_OBJECT_MIXIN_PROP_CUSTOM_START, - PROP_MEDIA_CLASS, - PROP_DIRECTION, -}; - -typedef struct _WpEndpointPrivate WpEndpointPrivate; -struct _WpEndpointPrivate -{ - gint place_holder; -}; - -static void wp_endpoint_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface); - -G_DEFINE_TYPE_WITH_CODE (WpEndpoint, wp_endpoint, WP_TYPE_GLOBAL_PROXY, - G_ADD_PRIVATE (WpEndpoint) - G_IMPLEMENT_INTERFACE (WP_TYPE_PIPEWIRE_OBJECT, - wp_pw_object_mixin_object_interface_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_PW_OBJECT_MIXIN_PRIV, - wp_endpoint_pw_object_mixin_priv_interface_init)) - -static void -wp_endpoint_init (WpEndpoint * self) -{ -} - -static void -wp_endpoint_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object); - - switch (property_id) { - case PROP_NAME: - g_value_set_string (value, d->info ? - ((struct pw_endpoint_info *) d->info)->name : NULL); - break; - case PROP_MEDIA_CLASS: - g_value_set_string (value, d->info ? - ((struct pw_endpoint_info *) d->info)->media_class : NULL); - break; - case PROP_DIRECTION: - g_value_set_enum (value, d->info ? - ((struct pw_endpoint_info *) d->info)->direction : 0); - break; - default: - wp_pw_object_mixin_get_property (object, property_id, value, pspec); - break; - } -} - -static WpObjectFeatures -wp_endpoint_get_supported_features (WpObject * object) -{ - return wp_pw_object_mixin_get_supported_features(object); -} - -static void -wp_endpoint_activate_execute_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - switch (step) { - case WP_PW_OBJECT_MIXIN_STEP_BIND: - case WP_TRANSITION_STEP_ERROR: - /* base class can handle BIND and ERROR */ - WP_OBJECT_CLASS (wp_endpoint_parent_class)-> - activate_execute_step (object, transition, step, missing); - break; - case WP_PW_OBJECT_MIXIN_STEP_WAIT_INFO: - /* just wait, info will be emitted anyway after binding */ - break; - case WP_PW_OBJECT_MIXIN_STEP_CACHE_PARAMS: - wp_pw_object_mixin_cache_params (object, missing); - break; - default: - g_assert_not_reached (); - } -} - -static void -wp_endpoint_deactivate (WpObject * object, WpObjectFeatures features) -{ - wp_pw_object_mixin_deactivate (object, features); - WP_OBJECT_CLASS (wp_endpoint_parent_class)->deactivate (object, features); -} - -static const struct pw_endpoint_events endpoint_events = { - PW_VERSION_ENDPOINT_EVENTS, - .info = (HandleEventInfoFunc(endpoint)) wp_pw_object_mixin_handle_event_info, - .param = wp_pw_object_mixin_handle_event_param, -}; - -static void -wp_endpoint_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) -{ - wp_pw_object_mixin_handle_pw_proxy_created (proxy, pw_proxy, - endpoint, &endpoint_events); -} - -static void -wp_endpoint_pw_proxy_destroyed (WpProxy * proxy) -{ - wp_pw_object_mixin_handle_pw_proxy_destroyed (proxy); - - WP_PROXY_CLASS (wp_endpoint_parent_class)->pw_proxy_destroyed (proxy); -} - -static void -wp_endpoint_class_init (WpEndpointClass * klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpObjectClass *wpobject_class = (WpObjectClass *) klass; - WpProxyClass *proxy_class = (WpProxyClass *) klass; - - object_class->get_property = wp_endpoint_get_property; - - wpobject_class->get_supported_features = wp_endpoint_get_supported_features; - wpobject_class->activate_get_next_step = - wp_pw_object_mixin_activate_get_next_step; - wpobject_class->activate_execute_step = wp_endpoint_activate_execute_step; - wpobject_class->deactivate = wp_endpoint_deactivate; - - proxy_class->pw_iface_type = PW_TYPE_INTERFACE_Endpoint; - proxy_class->pw_iface_version = PW_VERSION_ENDPOINT; - proxy_class->pw_proxy_created = wp_endpoint_pw_proxy_created; - proxy_class->pw_proxy_destroyed = wp_endpoint_pw_proxy_destroyed; - - wp_pw_object_mixin_class_override_properties (object_class); - - g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string ("name", "name", "name", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_MEDIA_CLASS, - g_param_spec_string ("media-class", "media-class", "media-class", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_DIRECTION, - g_param_spec_enum ("direction", "direction", "direction", - WP_TYPE_DIRECTION, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -} - -static gint -wp_endpoint_enum_params (gpointer instance, guint32 id, - guint32 start, guint32 num, WpSpaPod *filter) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance); - return pw_endpoint_enum_params (d->iface, 0, id, start, num, - filter ? wp_spa_pod_get_spa_pod (filter) : NULL); -} - -static gint -wp_endpoint_set_param (gpointer instance, guint32 id, guint32 flags, - WpSpaPod * param) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance); - g_autoptr (WpSpaPod) p = param; - return pw_endpoint_set_param (d->iface, id, flags, - wp_spa_pod_get_spa_pod (p)); -} - -static void -wp_endpoint_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface) -{ - wp_pw_object_mixin_priv_interface_info_init (iface, endpoint, ENDPOINT); - iface->enum_params = wp_endpoint_enum_params; - iface->set_param = wp_endpoint_set_param; -} - -/*! - * \brief Gets the name of the endpoint - * \remarks Requires WP_PIPEWIRE_OBJECT_FEATURE_INFO - * \ingroup wpendpoint - * \param self the endpoint - * \returns the name of the endpoint - */ -const gchar * -wp_endpoint_get_name (WpEndpoint * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_PIPEWIRE_OBJECT_FEATURE_INFO, NULL); - - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - return ((struct pw_endpoint_info *) d->info)->name; -} - -/*! - * \brief Gets the media class of the endpoint (ex. "Audio/Sink") - * \remarks Requires WP_PIPEWIRE_OBJECT_FEATURE_INFO - * \ingroup wpendpoint - * \param self the endpoint - * \returns the media class of the endpoint - */ -const gchar * -wp_endpoint_get_media_class (WpEndpoint * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_PIPEWIRE_OBJECT_FEATURE_INFO, NULL); - - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - return ((struct pw_endpoint_info *) d->info)->media_class; -} - -/*! - * \brief Gets the direction of the endpoint - * \remarks Requires WP_PIPEWIRE_OBJECT_FEATURE_INFO - * \ingroup wpendpoint - * \param self the endpoint - * \returns the direction of this endpoint - */ -WpDirection -wp_endpoint_get_direction (WpEndpoint * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), 0); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_PIPEWIRE_OBJECT_FEATURE_INFO, 0); - - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - return (WpDirection) ((struct pw_endpoint_info *) d->info)->direction; -} - -/* WpImplEndpoint */ - -enum { - IMPL_PROP_0, - IMPL_PROP_ITEM, -}; - -struct _WpImplEndpoint -{ - WpEndpoint parent; - - struct spa_interface iface; - struct pw_endpoint_info info; - WpProperties *immutable_props; - - WpSiEndpoint *item; -}; - -static void wp_endpoint_impl_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface); - -G_DEFINE_TYPE_WITH_CODE (WpImplEndpoint, wp_impl_endpoint, WP_TYPE_ENDPOINT, - G_IMPLEMENT_INTERFACE (WP_TYPE_PW_OBJECT_MIXIN_PRIV, - wp_endpoint_impl_pw_object_mixin_priv_interface_init)) - -static struct spa_param_info impl_param_info[] = { - SPA_PARAM_INFO (SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE), - SPA_PARAM_INFO (SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ) -}; - -static int -impl_create_link (void *object, const struct spa_dict *props) -{ - /* not implemented */ - return -EINVAL; -} - -static const struct pw_endpoint_methods impl_endpoint = { - PW_VERSION_ENDPOINT_METHODS, - .add_listener = - (ImplAddListenerFunc(endpoint)) wp_pw_object_mixin_impl_add_listener, - .subscribe_params = wp_pw_object_mixin_impl_subscribe_params, - .enum_params = wp_pw_object_mixin_impl_enum_params, - .set_param = wp_pw_object_mixin_impl_set_param, - .create_link = impl_create_link, -}; - -static void -wp_impl_endpoint_init (WpImplEndpoint * self) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - - self->iface = SPA_INTERFACE_INIT ( - PW_TYPE_INTERFACE_Endpoint, - PW_VERSION_ENDPOINT, - &impl_endpoint, self); - - d->info = &self->info; - d->iface = &self->iface; -} - -static void -populate_properties (WpImplEndpoint * self) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - - g_clear_pointer (&d->properties, wp_properties_unref); - d->properties = wp_si_endpoint_get_properties (self->item); - if (!d->properties) - d->properties = wp_properties_new_empty (); - d->properties = wp_properties_ensure_unique_owner (d->properties); - wp_properties_update (d->properties, self->immutable_props); - - self->info.props = (struct spa_dict *) wp_properties_peek_dict (d->properties); -} - -static void -on_si_endpoint_properties_changed (WpSiEndpoint * item, WpImplEndpoint * self) -{ - populate_properties (self); - wp_pw_object_mixin_notify_info (self, PW_ENDPOINT_CHANGE_MASK_PROPS); -} - -static void -on_node_params_changed (WpNode * node, const gchar *param_name, - WpImplEndpoint * self) -{ - if (!g_strcmp0 (param_name, "PropInfo") || !g_strcmp0 (param_name, "Props")) { - guint32 param_id = wp_spa_id_value_number ( - wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", param_name)); - wp_pw_object_mixin_notify_params_changed (self, param_id); - } -} - -static void -wp_impl_endpoint_constructed (GObject * object) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - g_autoptr (GVariant) info = NULL; - g_autoptr (GVariantIter) immutable_props = NULL; - g_autoptr (WpObject) node = NULL; - const gchar *key, *value; - guchar direction; - - self->info.version = PW_VERSION_ENDPOINT_INFO; - - info = wp_si_endpoint_get_registration_info (self->item); - g_variant_get (info, "(ssya{ss})", &self->info.name, - &self->info.media_class, &direction, &immutable_props); - - self->info.direction = (enum pw_direction) direction; - - /* associate with the session (no session anymore, use -1) */ - self->info.session_id = SPA_ID_INVALID; - - /* construct export properties (these will come back through - the registry and appear in wp_proxy_get_global_properties) */ - self->immutable_props = wp_properties_new ( - PW_KEY_ENDPOINT_NAME, self->info.name, - PW_KEY_MEDIA_CLASS, self->info.media_class, - NULL); - wp_properties_setf (self->immutable_props, PW_KEY_SESSION_ID, - "%d", self->info.session_id); - - /* populate immutable (global) properties */ - while (g_variant_iter_next (immutable_props, "{&s&s}", &key, &value)) - wp_properties_set (self->immutable_props, key, value); - - /* populate standard properties */ - populate_properties (self); - - /* subscribe to changes */ - g_signal_connect_object (self->item, "endpoint-properties-changed", - G_CALLBACK (on_si_endpoint_properties_changed), self, 0); - - /* if the item has a node, proxy its ParamProps */ - node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - if (node && (wp_object_get_active_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS)) { - self->info.params = impl_param_info; - self->info.n_params = G_N_ELEMENTS (impl_param_info); - - g_signal_connect_object (node, "params-changed", - G_CALLBACK (on_node_params_changed), self, 0); - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, 0); - } else { - self->info.params = NULL; - self->info.n_params = 0; - } - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_INFO, 0); - - G_OBJECT_CLASS (wp_impl_endpoint_parent_class)->constructed (object); -} - -static void -wp_impl_endpoint_dispose (GObject * object) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - - g_clear_pointer (&self->immutable_props, wp_properties_unref); - g_clear_pointer (&self->info.name, g_free); - g_clear_pointer (&self->info.media_class, g_free); - - wp_object_update_features (WP_OBJECT (self), 0, - WP_PIPEWIRE_OBJECT_FEATURE_INFO | - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS); - - G_OBJECT_CLASS (wp_impl_endpoint_parent_class)->dispose (object); -} - -static void -wp_impl_endpoint_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - - switch (property_id) { - case IMPL_PROP_ITEM: - self->item = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_impl_endpoint_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - - switch (property_id) { - case IMPL_PROP_ITEM: - g_value_set_object (value, self->item); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -enum { - STEP_ACTIVATE_NODE = WP_PW_OBJECT_MIXIN_STEP_CUSTOM_START + 1, -}; - -static guint -wp_impl_endpoint_activate_get_next_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - - /* before anything else, if the item has a node, - cache its props so that enum_params works */ - if (missing & WP_PIPEWIRE_OBJECT_FEATURES_ALL) { - g_autoptr (WpObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (node && (wp_object_get_supported_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS) && - !(wp_object_get_active_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS)) - return STEP_ACTIVATE_NODE; - } - - return WP_OBJECT_CLASS (wp_impl_endpoint_parent_class)-> - activate_get_next_step (object, transition, step, missing); -} - -static void -wp_impl_endpoint_node_activated (WpObject * node, - GAsyncResult * res, WpTransition * transition) -{ - WpImplEndpoint *self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (node, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - self->info.params = impl_param_info; - self->info.n_params = G_N_ELEMENTS (impl_param_info); - - g_signal_connect_object (node, "params-changed", - G_CALLBACK (on_node_params_changed), self, 0); - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, 0); - wp_pw_object_mixin_notify_info (self, PW_ENDPOINT_CHANGE_MASK_PARAMS); -} - -static void -wp_impl_endpoint_activate_execute_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - - switch (step) { - case STEP_ACTIVATE_NODE: { - g_autoptr (WpObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - wp_object_activate (node, - WP_PROXY_FEATURE_BOUND | WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, - NULL, (GAsyncReadyCallback) wp_impl_endpoint_node_activated, - transition); - break; - } - case WP_PW_OBJECT_MIXIN_STEP_BIND: { - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - struct pw_core *pw_core = wp_core_get_pw_core (core); - - /* no pw_core -> we are not connected */ - if (!pw_core) { - wp_transition_return_error (WP_TRANSITION (transition), g_error_new ( - WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, - "The WirePlumber core is not connected; " - "object cannot be exported to PipeWire")); - return; - } - - /* bind */ - wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core, - PW_TYPE_INTERFACE_Endpoint, - wp_properties_peek_dict (self->immutable_props), - &self->iface, 0)); - break; - } - default: - WP_OBJECT_CLASS (wp_impl_endpoint_parent_class)-> - activate_execute_step (object, transition, step, missing); - break; - } -} - -/*! - * \struct WpImplEndpoint - * - * \gproperties - * - * \gproperty{item, WpSiEndpoint *, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY, - * The session item that implements this endpoint} - */ -static void -wp_impl_endpoint_class_init (WpImplEndpointClass * klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpObjectClass *wpobject_class = (WpObjectClass *) klass; - WpProxyClass *proxy_class = (WpProxyClass *) klass; - - object_class->constructed = wp_impl_endpoint_constructed; - object_class->dispose = wp_impl_endpoint_dispose; - object_class->set_property = wp_impl_endpoint_set_property; - object_class->get_property = wp_impl_endpoint_get_property; - - wpobject_class->activate_get_next_step = - wp_impl_endpoint_activate_get_next_step; - wpobject_class->activate_execute_step = - wp_impl_endpoint_activate_execute_step; - - proxy_class->pw_proxy_created = NULL; - proxy_class->pw_proxy_destroyed = NULL; - - g_object_class_install_property (object_class, IMPL_PROP_ITEM, - g_param_spec_object ("item", "item", "item", WP_TYPE_SI_ENDPOINT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); -} - -static GPtrArray * -wp_impl_endpoint_enum_params_sync (gpointer instance, guint32 id, - guint32 start, guint32 num, WpSpaPod *filter) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (instance); - g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (!node) { - wp_warning_object (self, "associated node is no longer available"); - return NULL; - } - - /* bypass a few things, knowing that the node - caches params in the mixin param store */ - WpPwObjectMixinData *data = wp_pw_object_mixin_get_data (node); - GPtrArray *params = wp_pw_object_mixin_get_stored_params (data, id); - /* TODO filter */ - - return params; -} - -static gint -wp_impl_endpoint_set_param (gpointer instance, guint32 id, guint32 flags, - WpSpaPod * param) -{ - WpImplEndpoint *self = WP_IMPL_ENDPOINT (instance); - g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (!node) { - wp_warning_object (self, "associated node is no longer available"); - return -EPIPE; - } - - WpSpaIdValue idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", id); - if (!idval) { - wp_critical_object (self, "invalid param id: %u", id); - return -EINVAL; - } - - return wp_pipewire_object_set_param (node, wp_spa_id_value_short_name (idval), - flags, param) ? 0 : -EIO; -} - -#define pw_endpoint_emit(hooks,method,version,...) \ - spa_hook_list_call_simple(hooks, struct pw_endpoint_events, \ - method, version, ##__VA_ARGS__) - -static void -wp_impl_endpoint_emit_info (struct spa_hook_list * hooks, gconstpointer info) -{ - pw_endpoint_emit (hooks, info, 0, info); -} - -static void -wp_impl_endpoint_emit_param (struct spa_hook_list * hooks, int seq, - guint32 id, guint32 index, guint32 next, const struct spa_pod *param) -{ - pw_endpoint_emit (hooks, param, 0, seq, id, index, next, param); -} - -static void -wp_endpoint_impl_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface) -{ - iface->flags |= WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE; - iface->enum_params_sync = wp_impl_endpoint_enum_params_sync; - iface->set_param = wp_impl_endpoint_set_param; - iface->emit_info = wp_impl_endpoint_emit_info; - iface->emit_param = wp_impl_endpoint_emit_param; -} - -/*! - * \brief Creates a new endpoint implementation - * - * \ingroup wpendpoint - * \param core the core - * \param item the session item that implements the endpoint - * \returns (transfer full): a new WpImplEndpoint - */ -WpImplEndpoint * -wp_impl_endpoint_new (WpCore * core, WpSiEndpoint * item) -{ - g_return_val_if_fail (WP_IS_CORE (core), NULL); - - return g_object_new (WP_TYPE_IMPL_ENDPOINT, - "core", core, - "item", item, - NULL); -} diff --git a/lib/wp/endpoint.h b/lib/wp/endpoint.h deleted file mode 100644 index 05bb94dc..00000000 --- a/lib/wp/endpoint.h +++ /dev/null @@ -1,59 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_ENDPOINT_H__ -#define __WIREPLUMBER_ENDPOINT_H__ - -#include "global-proxy.h" -#include "port.h" -#include "iterator.h" -#include "object-interest.h" -#include "si-interfaces.h" - -G_BEGIN_DECLS - -/*! - * \brief The WpEndpoint GType - * \ingroup wpendpoint - */ -#define WP_TYPE_ENDPOINT (wp_endpoint_get_type ()) -WP_API -G_DECLARE_DERIVABLE_TYPE (WpEndpoint, wp_endpoint, WP, ENDPOINT, WpGlobalProxy) - -struct _WpEndpointClass -{ - WpGlobalProxyClass parent_class; - - /*< private >*/ - WP_PADDING(4) -}; - -WP_API -const gchar * wp_endpoint_get_name (WpEndpoint * self); - -WP_API -const gchar * wp_endpoint_get_media_class (WpEndpoint * self); - -WP_API -WpDirection wp_endpoint_get_direction (WpEndpoint * self); - -/*! - * \brief The WpImplEndpoint GType - * \ingroup wpendpoint - */ -#define WP_TYPE_IMPL_ENDPOINT (wp_impl_endpoint_get_type ()) -WP_API -G_DECLARE_FINAL_TYPE (WpImplEndpoint, wp_impl_endpoint, - WP, IMPL_ENDPOINT, WpEndpoint) - -WP_API -WpImplEndpoint * wp_impl_endpoint_new (WpCore * core, WpSiEndpoint * item); - -G_END_DECLS - -#endif diff --git a/lib/wp/meson.build b/lib/wp/meson.build index 1aa6e5ba..4c77f73c 100644 --- a/lib/wp/meson.build +++ b/lib/wp/meson.build @@ -5,7 +5,6 @@ wp_lib_sources = files( 'core.c', 'dbus.c', 'device.c', - 'endpoint.c', 'error.c', 'event.c', 'event-dispatcher.c', @@ -50,7 +49,6 @@ wp_lib_headers = files( 'dbus.h', 'defs.h', 'device.h', - 'endpoint.h', 'error.h', 'event.h', 'event-dispatcher.h', diff --git a/lib/wp/object-manager.c b/lib/wp/object-manager.c index 6f58653b..c8b49c70 100644 --- a/lib/wp/object-manager.c +++ b/lib/wp/object-manager.c @@ -33,7 +33,7 @@ * instance that created them appears in the WpObjectManager (as soon as * its WP_PROXY_FEATURE_BOUND is enabled) * * local PipeWire objects that are being exported to PipeWire - * (WpImplMetadata, WpImplEndpoint, etc); these appear in the + * (WpImplMetadata, WpImplNode, etc); these appear in the * WpObjectManager as soon as they are exported (so, when their * WP_PROXY_FEATURE_BOUND is enabled) * * WirePlumber-specific objects, such as plugins, factories and session items diff --git a/lib/wp/private/pipewire-object-mixin.h b/lib/wp/private/pipewire-object-mixin.h index c1761242..00cb40fe 100644 --- a/lib/wp/private/pipewire-object-mixin.h +++ b/lib/wp/private/pipewire-object-mixin.h @@ -122,7 +122,7 @@ typedef struct _WpPwObjectMixinData WpPwObjectMixinData; struct _WpPwObjectMixinData { gpointer info; /* pointer to the info struct */ - gpointer iface; /* pointer to the interface (ex. pw_endpoint) */ + gpointer iface; /* pointer to the interface (ex. pw_node) */ struct spa_hook listener; struct spa_hook_list hooks; WpProperties *properties; diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index 8bd5dd75..2eff1c82 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -256,12 +256,7 @@ wp_session_item_is_configured (WpSessionItem * self) /*! * \brief An associated proxy is a WpProxy subclass instance that - * is somehow related to this item. For example: - * - An exported WpSiEndpoint should have at least: - * - an associated WpSiEndpoint - * - an associated WpSession - * - In cases where the item wraps a single PipeWire node, it should also - * have an associated WpNode + * is somehow related to this item. * * \ingroup wpsessionitem * \param self the session item diff --git a/lib/wp/si-interfaces.c b/lib/wp/si-interfaces.c index 0ca2b5fb..51ea8566 100644 --- a/lib/wp/si-interfaces.c +++ b/lib/wp/si-interfaces.c @@ -13,82 +13,6 @@ /*! \defgroup wpsiinterfaces Session Item Interfaces */ -/*! - * \struct WpSiEndpoint - * - * An interface for session items that implement a PipeWire endpoint. - * - * \gsignals - * - * \par endpoint-properties-changed - * \parblock - * \code - * void - * endpoint_properties_changed_callback (WpSiEndpoint * self, - * gpointer user_data) - * \endcode - * Emitted when the endpoint properties change - * - * Flags: G_SIGNAL_RUN_LAST - * \endparblock - */ -G_DEFINE_INTERFACE (WpSiEndpoint, wp_si_endpoint, WP_TYPE_SESSION_ITEM) - -static WpProperties * -wp_si_endpoint_default_get_properties (WpSiEndpoint * self) -{ - return NULL; -} - -static void -wp_si_endpoint_default_init (WpSiEndpointInterface * iface) -{ - iface->get_properties = wp_si_endpoint_default_get_properties; - - g_signal_new ("endpoint-properties-changed", G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); -} - -/*! - * \brief This should return information that is used for registering the - * endpoint. - * - * The return value should be a GVariant tuple of type (ssya{ss}) that contains, - * in order: - * - s: the endpoint's name - * - s: the media class - * - y: the direction - * - a{ss}: additional properties to be added to the list of global properties - * - * \ingroup wpsiinterfaces - * \param self the session item - * \returns (transfer full): registration info for the endpoint - */ -GVariant * -wp_si_endpoint_get_registration_info (WpSiEndpoint * self) -{ - g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), NULL); - g_return_val_if_fail (WP_SI_ENDPOINT_GET_IFACE (self)->get_registration_info, NULL); - - return WP_SI_ENDPOINT_GET_IFACE (self)->get_registration_info (self); -} - -/*! - * \brief Gets the properties of the endpoint - * - * \ingroup wpsiinterfaces - * \param self the session item - * \returns (transfer full) (nullable): the properties of the endpoint - */ -WpProperties * -wp_si_endpoint_get_properties (WpSiEndpoint * self) -{ - g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), NULL); - g_return_val_if_fail (WP_SI_ENDPOINT_GET_IFACE (self)->get_properties, NULL); - - return WP_SI_ENDPOINT_GET_IFACE (self)->get_properties (self); -} - /*! * \struct WpSiAdapter * An interface for port adapters @@ -210,10 +134,6 @@ wp_si_adapter_set_ports_format_finish (WpSiAdapter * self, GAsyncResult * res, * * An interface for retrieving PipeWire port information from a session item. * This information is used to create links in the nodes graph. - * - * This is normally implemented by the same session items that implement - * WpSiEndpoint. The standard link implementation expects to be able to cast - * a WpSiEndpoint into a WpSiLinkable. */ G_DEFINE_INTERFACE (WpSiLinkable, wp_si_linkable, WP_TYPE_SESSION_ITEM) @@ -303,7 +223,7 @@ wp_si_linkable_get_acquisition (WpSiLinkable * self) /*! * \struct WpSiLink * - * An interface for session items that provide a PipeWire endpoint link. + * An interface for session items that provide a PipeWire link. * * \gsignals * diff --git a/lib/wp/si-interfaces.h b/lib/wp/si-interfaces.h index 4f1e16eb..290b7f4d 100644 --- a/lib/wp/si-interfaces.h +++ b/lib/wp/si-interfaces.h @@ -17,32 +17,6 @@ G_BEGIN_DECLS typedef struct _WpSiAcquisition WpSiAcquisition; -/*! - * \brief The WpSiEndpoint GType - * \ingroup wpsiinterfaces - */ -#define WP_TYPE_SI_ENDPOINT (wp_si_endpoint_get_type ()) -WP_API -G_DECLARE_INTERFACE (WpSiEndpoint, wp_si_endpoint, - WP, SI_ENDPOINT, WpSessionItem) - -struct _WpSiEndpointInterface -{ - GTypeInterface interface; - - GVariant * (*get_registration_info) (WpSiEndpoint * self); - WpProperties * (*get_properties) (WpSiEndpoint * self); - - /*< private >*/ - WP_PADDING(6) -}; - -WP_API -GVariant * wp_si_endpoint_get_registration_info (WpSiEndpoint * self); - -WP_API -WpProperties * wp_si_endpoint_get_properties (WpSiEndpoint * self); - /*! * \brief The WpSiAdapter GType * \ingroup wpsiinterfaces diff --git a/lib/wp/wp.c b/lib/wp/wp.c index 07f61bf6..14fdcbc8 100644 --- a/lib/wp/wp.c +++ b/lib/wp/wp.c @@ -59,7 +59,6 @@ wp_init (WpInitFlags flags) to autodetect the GType of proxies created through wp_proxy_new_global() */ g_type_ensure (WP_TYPE_CLIENT); g_type_ensure (WP_TYPE_DEVICE); - g_type_ensure (WP_TYPE_ENDPOINT); g_type_ensure (WP_TYPE_LINK); g_type_ensure (WP_TYPE_METADATA); g_type_ensure (WP_TYPE_NODE); diff --git a/lib/wp/wp.h b/lib/wp/wp.h index f57d03b9..1fe33a1d 100644 --- a/lib/wp/wp.h +++ b/lib/wp/wp.h @@ -15,7 +15,6 @@ #include "core.h" #include "dbus.h" #include "device.h" -#include "endpoint.h" #include "error.h" #include "event-dispatcher.h" #include "event-hook.h" diff --git a/modules/module-lua-scripting/api/api.c b/modules/module-lua-scripting/api/api.c index f78ef7c1..439f279d 100644 --- a/modules/module-lua-scripting/api/api.c +++ b/modules/module-lua-scripting/api/api.c @@ -875,12 +875,6 @@ impl_metadata_new (lua_State *L) return m ? 1 : 0; } -/* WpEndpoint */ - -static const luaL_Reg endpoint_methods[] = { - { NULL, NULL } -}; - /* Device */ static int @@ -2340,8 +2334,6 @@ wp_lua_scripting_api_init (lua_State *L) NULL, metadata_methods); wplua_register_type_methods (L, WP_TYPE_IMPL_METADATA, impl_metadata_new, NULL); - wplua_register_type_methods (L, WP_TYPE_ENDPOINT, - NULL, endpoint_methods); wplua_register_type_methods (L, WP_TYPE_DEVICE, device_new, NULL); wplua_register_type_methods (L, WP_TYPE_SPA_DEVICE, diff --git a/modules/module-si-audio-endpoint.c b/modules/module-si-audio-endpoint.c index 9847fe75..c9193c2b 100644 --- a/modules/module-si-audio-endpoint.c +++ b/modules/module-si-audio-endpoint.c @@ -29,12 +29,8 @@ struct _WpSiAudioEndpoint /* activation */ WpNode *node; WpSiAdapter *adapter; - - /* export */ - WpImplEndpoint *impl_endpoint; }; -static void si_audio_endpoint_endpoint_init (WpSiEndpointInterface * iface); static void si_audio_endpoint_linkable_init (WpSiLinkableInterface * iface); static void si_audio_endpoint_adapter_init (WpSiAdapterInterface * iface); @@ -42,7 +38,6 @@ G_DECLARE_FINAL_TYPE(WpSiAudioEndpoint, si_audio_endpoint, WP, SI_AUDIO_ENDPOINT, WpSessionItem) G_DEFINE_TYPE_WITH_CODE (WpSiAudioEndpoint, si_audio_endpoint, WP_TYPE_SESSION_ITEM, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_audio_endpoint_endpoint_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_LINKABLE, si_audio_endpoint_linkable_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ADAPTER, si_audio_endpoint_adapter_init)) @@ -125,9 +120,6 @@ si_audio_endpoint_get_associated_proxy (WpSessionItem * item, GType proxy_type) { WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (item); - if (proxy_type == WP_TYPE_ENDPOINT) - return self->impl_endpoint ? g_object_ref (self->impl_endpoint) : NULL; - return wp_session_item_get_associated_proxy ( WP_SESSION_ITEM (self->adapter), proxy_type); } @@ -148,7 +140,6 @@ si_audio_endpoint_disable_exported (WpSessionItem *si) { WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (si); - g_clear_object (&self->impl_endpoint); wp_object_update_features (WP_OBJECT (self), 0, WP_SESSION_ITEM_FEATURE_EXPORTED); } @@ -268,36 +259,13 @@ si_audio_endpoint_enable_active (WpSessionItem *si, WpTransition *transition) (GAsyncReadyCallback) on_node_activate_done, transition); } -static void -on_impl_endpoint_activated (WpObject * object, GAsyncResult * res, - WpTransition * transition) -{ - WpSiAudioEndpoint *self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (object, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_object_update_features (WP_OBJECT (self), - WP_SESSION_ITEM_FEATURE_EXPORTED, 0); -} - static void si_audio_endpoint_enable_exported (WpSessionItem *si, WpTransition *transition) { WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (si); - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - self->impl_endpoint = wp_impl_endpoint_new (core, WP_SI_ENDPOINT (self)); - - g_signal_connect_object (self->impl_endpoint, "pw-proxy-destroyed", - G_CALLBACK (wp_session_item_handle_proxy_destroyed), self, 0); - - wp_object_activate (WP_OBJECT (self->impl_endpoint), - WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_impl_endpoint_activated, transition); + wp_object_update_features (WP_OBJECT (self), + WP_SESSION_ITEM_FEATURE_EXPORTED, 0); } static void @@ -314,51 +282,6 @@ si_audio_endpoint_class_init (WpSiAudioEndpointClass * klass) si_class->enable_exported = si_audio_endpoint_enable_exported; } -static GVariant * -si_audio_endpoint_get_registration_info (WpSiEndpoint * item) -{ - WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (item); - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(ssya{ss})")); - g_variant_builder_add (&b, "s", self->name); - g_variant_builder_add (&b, "s", self->media_class); - g_variant_builder_add (&b, "y", self->direction); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -si_audio_endpoint_get_properties (WpSiEndpoint * item) -{ - WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (item); - g_autoptr (WpNode) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->adapter), WP_TYPE_NODE); - WpProperties *result = wp_properties_new_empty (); - - wp_properties_set (result, "endpoint.name", self->name); - wp_properties_setf (result, "endpoint.priority", "%u", self->priority); - wp_properties_setf (result, "endpoint.description", "%s: %s", - (self->direction == WP_DIRECTION_OUTPUT) ? "Capture" : "Playback", - self->role); - wp_properties_set (result, "media.role", self->role); - - /* associate with the node */ - g_return_val_if_fail (node, NULL); - wp_properties_setf (result, PW_KEY_NODE_ID, "%d", - wp_proxy_get_bound_id (WP_PROXY (node))); - - return result; -} - -static void -si_audio_endpoint_endpoint_init (WpSiEndpointInterface * iface) -{ - iface->get_registration_info = si_audio_endpoint_get_registration_info; - iface->get_properties = si_audio_endpoint_get_properties; -} - static GVariant * si_audio_endpoint_get_ports (WpSiLinkable * item, const gchar * context) { diff --git a/modules/module-standard-event-source.c b/modules/module-standard-event-source.c index 3c04e121..df2c61f1 100644 --- a/modules/module-standard-event-source.c +++ b/modules/module-standard-event-source.c @@ -26,7 +26,6 @@ typedef enum { OBJECT_TYPE_LINK, OBJECT_TYPE_NODE, OBJECT_TYPE_SESSION_ITEM, - OBJECT_TYPE_ENDPOINT, OBJECT_TYPE_CLIENT, OBJECT_TYPE_DEVICE, OBJECT_TYPE_METADATA, @@ -87,7 +86,6 @@ object_type_to_gtype (ObjectType type) case OBJECT_TYPE_LINK: return WP_TYPE_LINK; case OBJECT_TYPE_NODE: return WP_TYPE_NODE; case OBJECT_TYPE_SESSION_ITEM: return WP_TYPE_SESSION_ITEM; - case OBJECT_TYPE_ENDPOINT: return WP_TYPE_ENDPOINT; case OBJECT_TYPE_CLIENT: return WP_TYPE_CLIENT; case OBJECT_TYPE_DEVICE: return WP_TYPE_DEVICE; case OBJECT_TYPE_METADATA: return WP_TYPE_METADATA; @@ -107,8 +105,6 @@ type_str_to_object_type (const gchar * type_str) return OBJECT_TYPE_NODE; else if (!g_strcmp0 (type_str, "session-item")) return OBJECT_TYPE_SESSION_ITEM; - else if (!g_strcmp0 (type_str, "endpoint")) - return OBJECT_TYPE_ENDPOINT; else if (!g_strcmp0 (type_str, "client")) return OBJECT_TYPE_CLIENT; else if (!g_strcmp0 (type_str, "device")) @@ -142,8 +138,6 @@ get_object_type (gpointer obj, WpProperties **properties) } return "session-item"; } - else if (WP_IS_ENDPOINT (obj)) - return "endpoint"; else if (WP_IS_CLIENT (obj)) return "client"; else if (WP_IS_DEVICE (obj)) diff --git a/src/tools/wpctl.c b/src/tools/wpctl.c index a1834943..b64874ec 100644 --- a/src/tools/wpctl.c +++ b/src/tools/wpctl.c @@ -189,7 +189,6 @@ status_prepare (WpCtl * self, GError ** error) { wp_object_manager_add_interest (self->om, WP_TYPE_CLIENT, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_DEVICE, NULL); - wp_object_manager_add_interest (self->om, WP_TYPE_ENDPOINT, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_NODE, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_PORT, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_LINK, NULL); @@ -259,27 +258,6 @@ print_dev_node (const GValue *item, gpointer data) print_controls (id, context); } -static void -print_endpoint (const GValue *item, gpointer data) -{ - WpPipewireObject *obj = g_value_get_object (item); - struct print_context *context = data; - guint32 id = wp_proxy_get_bound_id (WP_PROXY (obj)); - guint32 node_id = -1; - gboolean is_default = (context->default_node == id); - const gchar *str, *name; - - if ((str = wp_pipewire_object_get_property (obj, "node.id"))) - node_id = atoi (str); - - name = wp_pipewire_object_get_property (obj, "endpoint.description"); - if (!name) - name = wp_pipewire_object_get_property (obj, "endpoint.name"); - - printf (TREE_INDENT_LINE "%c %4u. %-35s", is_default ? '*' : ' ', id, name); - print_controls (node_id, context); -} - static void print_stream_node (const GValue *item, gpointer data) { @@ -410,17 +388,6 @@ status_run (WpCtl * self) printf (TREE_INDENT_LINE "\n"); - printf (TREE_INDENT_NODE "Sink endpoints:\n"); - child_it = wp_object_manager_new_filtered_iterator (self->om, - WP_TYPE_ENDPOINT, - WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_MEDIA_CLASS, "#s", "*/Sink*", - WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_MEDIA_CLASS, "#s", media_type_glob, - NULL); - wp_iterator_foreach (child_it, print_endpoint, (gpointer) &context); - g_clear_pointer (&child_it, wp_iterator_unref); - - printf (TREE_INDENT_LINE "\n"); - printf (TREE_INDENT_NODE "Sources:\n"); g_snprintf (media_class, sizeof(media_class), "%s/Source", media_type); context.default_node = -1; @@ -437,17 +404,6 @@ status_run (WpCtl * self) printf (TREE_INDENT_LINE "\n"); - printf (TREE_INDENT_NODE "Source endpoints:\n"); - child_it = wp_object_manager_new_filtered_iterator (self->om, - WP_TYPE_ENDPOINT, - WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_MEDIA_CLASS, "#s", "*/Source*", - WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_MEDIA_CLASS, "#s", media_type_glob, - NULL); - wp_iterator_foreach (child_it, print_endpoint, (gpointer) &context); - g_clear_pointer (&child_it, wp_iterator_unref); - - printf (TREE_INDENT_LINE "\n"); - printf (TREE_INDENT_END "Streams:\n"); child_it = wp_object_manager_new_filtered_iterator (self->om, WP_TYPE_NODE, @@ -590,14 +546,6 @@ struct { } assoc_keys[] = { { PW_KEY_CLIENT_ID, "Client" }, { PW_KEY_DEVICE_ID, "Device" }, - { PW_KEY_ENDPOINT_CLIENT_ID, NULL }, - { "endpoint-link.id", "EndpointLink" }, - { PW_KEY_ENDPOINT_STREAM_ID, "EndpointStream" }, - { PW_KEY_ENDPOINT_LINK_OUTPUT_ENDPOINT, NULL }, - { PW_KEY_ENDPOINT_LINK_OUTPUT_STREAM, NULL }, - { PW_KEY_ENDPOINT_LINK_INPUT_ENDPOINT, NULL }, - { PW_KEY_ENDPOINT_LINK_INPUT_STREAM, NULL }, - { PW_KEY_ENDPOINT_ID, "Endpoint" }, { PW_KEY_LINK_INPUT_NODE, NULL }, { PW_KEY_LINK_INPUT_PORT, NULL }, { PW_KEY_LINK_OUTPUT_NODE, NULL }, @@ -894,7 +842,6 @@ set_volume_parse_positional (gint argc, gchar ** argv, GError **error) static gboolean set_volume_prepare (WpCtl * self, GError ** error) { - wp_object_manager_add_interest (self->om, WP_TYPE_ENDPOINT, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_NODE, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_CLIENT, NULL); wp_object_manager_request_object_features (self->om, WP_TYPE_GLOBAL_PROXY, @@ -912,15 +859,6 @@ do_set_volume (WpCtl * self, WpPipewireObject *proxy) gdouble curr_volume = 1.0; guint32 id = wp_proxy_get_bound_id (WP_PROXY (proxy)); - if (WP_IS_ENDPOINT (proxy)) { - const gchar *str = wp_pipewire_object_get_property (proxy, "node.id"); - if (!str) { - fprintf (stderr, "Endpoint '%d' does not have an associated node\n", id); - return FALSE; - } - id = atoi (str); - } - if (cmdline.set_volume.type == 's') { g_signal_emit_by_name (mixer_api, "get-volume", id, &variant); if (!variant) { @@ -1030,7 +968,6 @@ set_mute_parse_positional (gint argc, gchar ** argv, GError **error) static gboolean set_mute_prepare (WpCtl * self, GError ** error) { - wp_object_manager_add_interest (self->om, WP_TYPE_ENDPOINT, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_NODE, NULL); wp_object_manager_add_interest (self->om, WP_TYPE_CLIENT, NULL); wp_object_manager_request_object_features (self->om, WP_TYPE_GLOBAL_PROXY, @@ -1048,15 +985,6 @@ do_set_mute (WpCtl * self, WpPipewireObject *proxy) gboolean mute = FALSE; guint32 id = wp_proxy_get_bound_id (WP_PROXY (proxy)); - if (WP_IS_ENDPOINT (proxy)) { - const gchar *str = wp_pipewire_object_get_property (proxy, "node.id"); - if (!str) { - fprintf (stderr, "Endpoint '%d' does not have an associated node\n", id); - return FALSE; - } - id = atoi (str); - } - g_signal_emit_by_name (mixer_api, "get-volume", id, &variant); if (!variant) { fprintf (stderr, "Node %d does not support mute\n", id); @@ -1309,7 +1237,7 @@ static const struct subcommand { { .name = "set-default", .positional_args = "ID", - .summary = "Sets ID to be the default endpoint of its kind " + .summary = "Sets ID to be the default object of its kind " "(capture/playback) in its session", .description = NULL, .entries = { { NULL } }, diff --git a/tests/modules/si-audio-endpoint.c b/tests/modules/si-audio-endpoint.c index 9ace12b8..bd0e0733 100644 --- a/tests/modules/si-audio-endpoint.c +++ b/tests/modules/si-audio-endpoint.c @@ -63,7 +63,6 @@ test_si_audio_endpoint_configure_activate (TestFixture * f, endpoint = wp_session_item_make (f->base.core, "si-audio-endpoint"); g_assert_nonnull (endpoint); - g_assert_true (WP_IS_SI_ENDPOINT (endpoint)); /* configure endpoint */ @@ -155,20 +154,14 @@ test_si_audio_endpoint_export (TestFixture * f, gconstpointer user_data) } { - g_autoptr (WpEndpoint) ep = NULL; + g_autoptr (WpNode) n = NULL; g_autoptr (WpProperties) props = NULL; - ep = wp_session_item_get_associated_proxy (endpoint, WP_TYPE_ENDPOINT); - g_assert_nonnull (ep); - props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (ep)); + n = wp_session_item_get_associated_proxy (endpoint, WP_TYPE_NODE); + g_assert_nonnull (n); + props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (n)); g_assert_nonnull (props); - g_assert_cmpstr (wp_endpoint_get_name (ep), ==, "endpoint"); - g_assert_cmpstr (wp_endpoint_get_media_class (ep), ==, - "Audio/Source"); - g_assert_cmpint (wp_endpoint_get_direction (ep), ==, WP_DIRECTION_OUTPUT); - g_assert_cmpstr (wp_properties_get (props, "endpoint.name"), ==, - "endpoint"); g_assert_cmpstr (wp_properties_get (props, "media.class"), ==, "Audio/Source"); } diff --git a/tests/wp/endpoint.c b/tests/wp/endpoint.c deleted file mode 100644 index c08f2d2d..00000000 --- a/tests/wp/endpoint.c +++ /dev/null @@ -1,780 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019-2020 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#include "../common/base-test-fixture.h" -#include - -struct _TestSiEndpoint -{ - WpSessionItem parent; - const gchar *name; - const gchar *media_class; - WpNode *node; - WpDirection direction; - gboolean changed_properties; - WpProxy *impl_endpoint; -}; - -G_DECLARE_FINAL_TYPE (TestSiEndpoint, test_si_endpoint, - TEST, SI_ENDPOINT, WpSessionItem) - -static GVariant * -test_si_endpoint_get_registration_info (WpSiEndpoint * item) -{ - TestSiEndpoint *self = TEST_SI_ENDPOINT (item); - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(ssya{ss})")); - g_variant_builder_add (&b, "s", self->name); - g_variant_builder_add (&b, "s", self->media_class); - g_variant_builder_add (&b, "y", (guchar) self->direction); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -test_si_endpoint_get_properties (WpSiEndpoint * item) -{ - TestSiEndpoint *self = TEST_SI_ENDPOINT (item); - if (self->changed_properties) - return wp_properties_new ("test.property", "changed-value", NULL); - else - return wp_properties_new ("test.property", "test-value", NULL); -} - -static void -test_si_endpoint_endpoint_init (WpSiEndpointInterface * iface) -{ - iface->get_registration_info = test_si_endpoint_get_registration_info; - iface->get_properties = test_si_endpoint_get_properties; -} - -G_DEFINE_TYPE_WITH_CODE (TestSiEndpoint, test_si_endpoint, WP_TYPE_SESSION_ITEM, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, test_si_endpoint_endpoint_init)) - -static void -test_si_endpoint_init (TestSiEndpoint * self) -{ -} - -static gpointer -si_endpoint_get_associated_proxy (WpSessionItem * item, GType proxy_type) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (item); - - if (proxy_type == WP_TYPE_NODE) - return self->node ? g_object_ref (self->node) : NULL; - - return NULL; -} - -static void -si_endpoint_reset (WpSessionItem * item) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (item); - - wp_object_deactivate (WP_OBJECT (self), - WP_SESSION_ITEM_FEATURE_ACTIVE | WP_SESSION_ITEM_FEATURE_EXPORTED); - - g_clear_object (&self->node); - - WP_SESSION_ITEM_CLASS (test_si_endpoint_parent_class)->reset (item); -} - -static void -si_endpoint_disable_active (WpSessionItem *si) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (si); - - wp_object_update_features (WP_OBJECT (self), 0, - WP_SESSION_ITEM_FEATURE_ACTIVE); -} - -static void -si_endpoint_disable_exported (WpSessionItem *si) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (si); - - g_clear_object (&self->impl_endpoint); - wp_object_update_features (WP_OBJECT (self), 0, - WP_SESSION_ITEM_FEATURE_EXPORTED); -} - -static void -si_endpoint_enable_active (WpSessionItem *si, WpTransition *transition) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (si); - - wp_object_update_features (WP_OBJECT (self), - WP_SESSION_ITEM_FEATURE_ACTIVE, 0); -} - -static void -on_impl_endpoint_activated (WpObject * object, GAsyncResult * res, - WpTransition * transition) -{ - TestSiEndpoint *self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (object, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_object_update_features (WP_OBJECT (self), - WP_SESSION_ITEM_FEATURE_EXPORTED, 0); -} - -static void -si_endpoint_enable_exported (WpSessionItem *si, WpTransition *transition) -{ - TestSiEndpoint * self = TEST_SI_ENDPOINT (si); - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - - self->impl_endpoint = WP_PROXY (wp_impl_endpoint_new (core, - WP_SI_ENDPOINT (self))); - g_signal_connect_object (self->impl_endpoint, "pw-proxy-destroyed", - G_CALLBACK (wp_session_item_handle_proxy_destroyed), self, 0); - - wp_object_activate (WP_OBJECT (self->impl_endpoint), - WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_impl_endpoint_activated, transition); -} - -static void -test_si_endpoint_class_init (TestSiEndpointClass * klass) -{ - WpSessionItemClass *item_class = (WpSessionItemClass *) klass; - - item_class->reset = si_endpoint_reset; - item_class->get_associated_proxy = si_endpoint_get_associated_proxy; - item_class->disable_active = si_endpoint_disable_active; - item_class->disable_exported = si_endpoint_disable_exported; - item_class->enable_active = si_endpoint_enable_active; - item_class->enable_exported = si_endpoint_enable_exported; -} - -/*******************/ - -typedef struct { - WpBaseTestFixture base; - - WpObjectManager *export_om; - WpObjectManager *proxy_om; - - WpProxy *impl_endpoint; - WpProxy *proxy_endpoint; - - gint n_events; - -} TestEndpointFixture; - -static void -test_endpoint_setup (TestEndpointFixture *self, gconstpointer user_data) -{ - wp_base_test_fixture_setup (&self->base, WP_BASE_TEST_FLAG_CLIENT_CORE); - self->export_om = wp_object_manager_new (); - self->proxy_om = wp_object_manager_new (); -} - -static void -test_endpoint_teardown (TestEndpointFixture *self, gconstpointer user_data) -{ - g_clear_object (&self->proxy_om); - g_clear_object (&self->export_om); - wp_base_test_fixture_teardown (&self->base); -} - -static void -test_endpoint_impl_object_added (WpObjectManager *om, - WpEndpoint *endpoint, TestEndpointFixture *fixture) -{ - g_debug ("impl object added"); - - g_assert_true (WP_IS_ENDPOINT (endpoint)); - g_assert_cmpstr (G_OBJECT_TYPE_NAME (endpoint), ==, "WpImplEndpoint"); - - g_assert_null (fixture->impl_endpoint); - fixture->impl_endpoint = WP_PROXY (endpoint); - - if (++fixture->n_events == 3) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_impl_object_removed (WpObjectManager *om, - WpEndpoint *endpoint, TestEndpointFixture *fixture) -{ - g_debug ("impl object removed"); - - g_assert_true (WP_IS_ENDPOINT (endpoint)); - g_assert_cmpstr (G_OBJECT_TYPE_NAME (endpoint), ==, "WpImplEndpoint"); - - g_assert_nonnull (fixture->impl_endpoint); - fixture->impl_endpoint = NULL; - - if (++fixture->n_events == 2) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_proxy_object_added (WpObjectManager *om, - WpEndpoint *endpoint, TestEndpointFixture *fixture) -{ - g_debug ("proxy object added"); - - g_assert_true (WP_IS_ENDPOINT (endpoint)); - g_assert_cmpstr (G_OBJECT_TYPE_NAME (endpoint), ==, "WpEndpoint"); - - g_assert_null (fixture->proxy_endpoint); - fixture->proxy_endpoint = WP_PROXY (endpoint); - - if (++fixture->n_events == 3) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_proxy_object_removed (WpObjectManager *om, - WpEndpoint *endpoint, TestEndpointFixture *fixture) -{ - g_debug ("proxy object removed"); - - g_assert_true (WP_IS_ENDPOINT (endpoint)); - g_assert_cmpstr (G_OBJECT_TYPE_NAME (endpoint), ==, "WpEndpoint"); - - g_assert_nonnull (fixture->proxy_endpoint); - fixture->proxy_endpoint = NULL; - - if (++fixture->n_events == 2) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_activate_done (WpObject * object, GAsyncResult * res, - TestEndpointFixture *fixture) -{ - g_autoptr (GError) error = NULL; - - g_debug ("activate done"); - - g_assert_true (wp_object_activate_finish (object, res, &error)); - g_assert_no_error (error); - - if (++fixture->n_events == 3) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_params_changed (WpPipewireObject * proxy, - const gchar * param_name, TestEndpointFixture *fixture) -{ - wp_debug_object (proxy, "params changed: %s", param_name); - - /* only count changes of id 2 (Props); PipeWire 0.3.22+git changed - behaviour and emits changes to PropInfo as well then the Props change */ - if (!g_strcmp0 (param_name, "Props") && ++fixture->n_events == 3) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_notify_properties (WpEndpoint * endpoint, GParamSpec * param, - TestEndpointFixture *fixture) -{ - g_debug ("properties changed: %s", G_OBJECT_TYPE_NAME (endpoint)); - - g_assert_true (WP_IS_ENDPOINT (endpoint)); - - if (++fixture->n_events == 2) - g_main_loop_quit (fixture->base.loop); -} - -static void -test_endpoint_no_props (TestEndpointFixture *fixture, gconstpointer data) -{ - g_autoptr (TestSiEndpoint) endpoint = NULL; - - /* set up the export side */ - g_signal_connect (fixture->export_om, "object-added", - (GCallback) test_endpoint_impl_object_added, fixture); - g_signal_connect (fixture->export_om, "object-removed", - (GCallback) test_endpoint_impl_object_removed, fixture); - wp_object_manager_add_interest (fixture->export_om, WP_TYPE_ENDPOINT, NULL); - wp_object_manager_request_object_features (fixture->export_om, - WP_TYPE_ENDPOINT, WP_OBJECT_FEATURES_ALL); - wp_core_install_object_manager (fixture->base.core, fixture->export_om); - - /* set up the proxy side */ - g_signal_connect (fixture->proxy_om, "object-added", - (GCallback) test_endpoint_proxy_object_added, fixture); - g_signal_connect (fixture->proxy_om, "object-removed", - (GCallback) test_endpoint_proxy_object_removed, fixture); - wp_object_manager_add_interest (fixture->proxy_om, WP_TYPE_ENDPOINT, NULL); - wp_object_manager_request_object_features (fixture->proxy_om, - WP_TYPE_ENDPOINT, WP_OBJECT_FEATURES_ALL); - wp_core_install_object_manager (fixture->base.client_core, fixture->proxy_om); - - /* create endpoint */ - endpoint = g_object_new (test_si_endpoint_get_type (), - "core", fixture->base.core, NULL); - endpoint->name = "test-endpoint"; - endpoint->media_class = "Audio/Source"; - endpoint->direction = WP_DIRECTION_OUTPUT; - wp_object_activate (WP_OBJECT (endpoint), - WP_SESSION_ITEM_FEATURE_ACTIVE | WP_SESSION_ITEM_FEATURE_EXPORTED, - NULL, (GAsyncReadyCallback) test_endpoint_activate_done, fixture); - - /* run until objects are created and features are cached */ - fixture->n_events = 0; - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (wp_object_get_active_features (WP_OBJECT (endpoint)), ==, - WP_SESSION_ITEM_FEATURE_ACTIVE | WP_SESSION_ITEM_FEATURE_EXPORTED); - g_assert_cmpint (fixture->n_events, ==, 3); - g_assert_nonnull (fixture->impl_endpoint); - g_assert_nonnull (fixture->proxy_endpoint); - - /* verify the values on the proxy */ - - g_assert_cmphex ( - wp_object_get_active_features (WP_OBJECT (fixture->proxy_endpoint)), ==, - wp_object_get_supported_features (WP_OBJECT (fixture->proxy_endpoint))); - g_assert_cmpuint (wp_proxy_get_bound_id (fixture->proxy_endpoint), ==, - wp_proxy_get_bound_id (fixture->impl_endpoint)); - - g_assert_cmpstr (wp_pipewire_object_get_property ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), "test.property"), - ==, "test-value"); - - { - g_autoptr (WpProperties) props = wp_global_proxy_get_global_properties ( - WP_GLOBAL_PROXY (fixture->proxy_endpoint)); - - g_assert_cmpstr (wp_properties_get (props, PW_KEY_ENDPOINT_NAME), ==, - "test-endpoint"); - g_assert_cmpstr (wp_properties_get (props, PW_KEY_MEDIA_CLASS), ==, - "Audio/Source"); - } - - g_assert_cmpstr ("test-endpoint", ==, - wp_endpoint_get_name (WP_ENDPOINT (fixture->proxy_endpoint))); - g_assert_cmpstr ("Audio/Source", ==, - wp_endpoint_get_media_class (WP_ENDPOINT (fixture->proxy_endpoint))); - g_assert_cmpint (WP_DIRECTION_OUTPUT, ==, - wp_endpoint_get_direction (WP_ENDPOINT (fixture->proxy_endpoint))); - - /* test property changes */ - g_signal_connect (fixture->proxy_endpoint, "notify::properties", - (GCallback) test_endpoint_notify_properties, fixture); - g_signal_connect (fixture->impl_endpoint, "notify::properties", - (GCallback) test_endpoint_notify_properties, fixture); - - /* change a property on the impl */ - fixture->n_events = 0; - endpoint->changed_properties = TRUE; - g_signal_emit_by_name (endpoint, "endpoint-properties-changed"); - - /* run until the change is on both sides */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 2); - - /* verify the property change on both sides */ - { - g_autoptr (WpProperties) props = wp_pipewire_object_get_properties ( - WP_PIPEWIRE_OBJECT (fixture->impl_endpoint)); - g_assert_cmpstr (wp_properties_get (props, "test.property"), ==, - "changed-value"); - } - { - g_autoptr (WpProperties) props = wp_pipewire_object_get_properties ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint)); - g_assert_cmpstr (wp_properties_get (props, "test.property"), ==, - "changed-value"); - } - - /* destroy impl endpoint */ - fixture->n_events = 0; - g_clear_object (&endpoint); - - /* run until objects are destroyed */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 2); - g_assert_null (fixture->impl_endpoint); - g_assert_null (fixture->proxy_endpoint); -} - -static void -test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data) -{ - g_autoptr (TestSiEndpoint) endpoint = NULL; - - /* load modules */ - { - g_autoptr (WpTestServerLocker) lock = - wp_test_server_locker_new (&fixture->base.server); - - g_assert_cmpint (pw_context_add_spa_lib (fixture->base.server.context, - "audiotestsrc", "audiotestsrc/libspa-audiotestsrc"), ==, 0); - if (!test_is_spa_lib_installed (&fixture->base, "audiotestsrc")) { - g_test_skip ("The pipewire audiotestsrc factory was not found"); - return; - } - - g_assert_nonnull (pw_context_load_module (fixture->base.server.context, - "libpipewire-module-adapter", NULL, NULL)); - } - - /* set up the export side */ - g_signal_connect (fixture->export_om, "object-added", - (GCallback) test_endpoint_impl_object_added, fixture); - g_signal_connect (fixture->export_om, "object-removed", - (GCallback) test_endpoint_impl_object_removed, fixture); - wp_object_manager_add_interest (fixture->export_om, WP_TYPE_ENDPOINT, NULL); - wp_object_manager_request_object_features (fixture->export_om, - WP_TYPE_ENDPOINT, WP_OBJECT_FEATURES_ALL); - wp_core_install_object_manager (fixture->base.core, fixture->export_om); - - /* set up the proxy side */ - g_signal_connect (fixture->proxy_om, "object-added", - (GCallback) test_endpoint_proxy_object_added, fixture); - g_signal_connect (fixture->proxy_om, "object-removed", - (GCallback) test_endpoint_proxy_object_removed, fixture); - wp_object_manager_add_interest (fixture->proxy_om, WP_TYPE_ENDPOINT, NULL); - wp_object_manager_request_object_features (fixture->proxy_om, - WP_TYPE_ENDPOINT, WP_OBJECT_FEATURES_ALL); - wp_core_install_object_manager (fixture->base.client_core, fixture->proxy_om); - - /* create endpoint */ - endpoint = g_object_new (test_si_endpoint_get_type (), - "core", fixture->base.core, NULL); - endpoint->name = "test-endpoint"; - endpoint->media_class = "Audio/Source"; - endpoint->direction = WP_DIRECTION_OUTPUT; - - /* associate a node that has props */ - endpoint->node = wp_node_new_from_factory (fixture->base.core, - "adapter", - wp_properties_new ( - "factory.name", "audiotestsrc", - "node.name", "audiotestsrc.adapter", - NULL)); - g_assert_nonnull (endpoint->node); - wp_object_activate (WP_OBJECT (endpoint->node), - WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL, NULL, - (GAsyncReadyCallback) test_object_activate_finish_cb, fixture); - g_main_loop_run (fixture->base.loop); - - g_assert_cmpint (wp_object_get_active_features (WP_OBJECT (endpoint->node)), - ==, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL); - - /* activate & export the endpoint */ - wp_object_activate (WP_OBJECT (endpoint), - WP_SESSION_ITEM_FEATURE_ACTIVE | WP_SESSION_ITEM_FEATURE_EXPORTED, - NULL, (GAsyncReadyCallback) test_endpoint_activate_done, fixture); - - /* run until objects are created and features are cached */ - fixture->n_events = 0; - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (wp_object_get_active_features (WP_OBJECT (endpoint)), ==, - WP_SESSION_ITEM_FEATURE_ACTIVE | WP_SESSION_ITEM_FEATURE_EXPORTED); - g_assert_cmpint (fixture->n_events, ==, 3); - g_assert_nonnull (fixture->impl_endpoint); - g_assert_nonnull (fixture->proxy_endpoint); - - /* verify features; the endpoint must have also augmented the node */ - g_assert_cmpint ( - wp_object_get_active_features (WP_OBJECT (endpoint->node)), &, - WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL | WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS); - g_assert_cmphex ( - wp_object_get_active_features (WP_OBJECT (fixture->proxy_endpoint)), &, - WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL | WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS); - - /* verify props */ - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 1.0f, 0.001); - g_assert_cmpint (boolean_value, ==, FALSE); - } - - /* setup change signals */ - g_signal_connect (fixture->proxy_endpoint, "params-changed", - (GCallback) test_endpoint_params_changed, fixture); - g_signal_connect (fixture->impl_endpoint, "params-changed", - (GCallback) test_endpoint_params_changed, fixture); - g_signal_connect (endpoint->node, "params-changed", - (GCallback) test_endpoint_params_changed, fixture); - - /* change control on the proxy */ - fixture->n_events = 0; - wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), - "Props", 0, - wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props", - "volume", "f", 0.7f, NULL)); - - /* run until the change is on all sides */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 3); - - /* verify the value change on all sides */ - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - pod = g_value_dup_boxed (&item); - g_assert_nonnull (pod); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, FALSE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->impl_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, FALSE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (endpoint->node), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, FALSE); - } - - /* change control on the impl */ - fixture->n_events = 0; - wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (fixture->impl_endpoint), - "Props", 0, - wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props", - "mute", "b", TRUE, NULL)); - - /* run until the change is on all sides */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 3); - - /* verify the value change on all sides */ - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - pod = g_value_dup_boxed (&item); - g_assert_nonnull (pod); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->impl_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (endpoint->node), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.7f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - - /* change control on the node */ - fixture->n_events = 0; - wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (endpoint->node), - "Props", 0, - wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props", - "volume", "f", 0.2f, NULL)); - - /* run until the change is on all sides */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 3); - - /* verify the value change on all sides */ - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.2f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (fixture->impl_endpoint), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.2f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - { - g_autoptr (WpIterator) iterator = NULL; - g_auto (GValue) item = G_VALUE_INIT; - g_autoptr (WpSpaPod) pod = NULL; - gfloat float_value = 0.0f; - gboolean boolean_value = TRUE; - - iterator = wp_pipewire_object_enum_params_sync ( - WP_PIPEWIRE_OBJECT (endpoint->node), "Props", NULL); - g_assert_nonnull (iterator); - - g_assert_true (wp_iterator_next (iterator, &item)); - g_assert_nonnull ((pod = g_value_dup_boxed (&item))); - - g_assert_true (wp_spa_pod_get_object (pod, NULL, - "volume", "f", &float_value, - "mute", "b", &boolean_value, - NULL)); - g_assert_cmpfloat_with_epsilon (float_value, 0.2f, 0.001); - g_assert_cmpint (boolean_value, ==, TRUE); - } - - /* destroy impl endpoint */ - fixture->n_events = 0; - g_clear_object (&endpoint); - - /* run until objects are destroyed */ - g_main_loop_run (fixture->base.loop); - g_assert_cmpint (fixture->n_events, ==, 2); - g_assert_null (fixture->impl_endpoint); - g_assert_null (fixture->proxy_endpoint); -} - -gint -main (gint argc, gchar *argv[]) -{ - g_test_init (&argc, &argv, NULL); - wp_init (WP_INIT_ALL); - - g_test_add ("/wp/endpoint/no-props", TestEndpointFixture, NULL, - test_endpoint_setup, test_endpoint_no_props, test_endpoint_teardown); - g_test_add ("/wp/endpoint/with-props", TestEndpointFixture, NULL, - test_endpoint_setup, test_endpoint_with_props, test_endpoint_teardown); - - return g_test_run (); -} diff --git a/tests/wp/meson.build b/tests/wp/meson.build index ed7108cb..d43afd7e 100644 --- a/tests/wp/meson.build +++ b/tests/wp/meson.build @@ -14,13 +14,6 @@ test( env: common_env, ) -test( - 'test-endpoint', - executable('test-endpoint', 'endpoint.c', - dependencies: common_deps, c_args: common_args), - env: common_env, -) - test( 'test-events', executable('test-events', 'events.c',