mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-03-24 19:40:37 +01:00
object-manager: support declaring interest on all properties of globals
Until now, object manager could only match pw global properties on pw global objects, because this is the only available properties set at the time the registry creates the global. With this change, the object manager will now bind the proxy if the type and the pw global properties have matched and will wait until the proxy is available with all of its properties and tries the check again.
This commit is contained in:
parent
997bdb65cd
commit
1ca67abc66
4 changed files with 152 additions and 34 deletions
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "object-manager.h"
|
||||
#include "log.h"
|
||||
#include "proxy-interfaces.h"
|
||||
#include "private/registry.h"
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
|
@ -620,11 +621,27 @@ wp_object_manager_is_interested_in_global (WpObjectManager * self,
|
|||
|
||||
for (i = 0; i < self->interests->len; i++) {
|
||||
interest = g_ptr_array_index (self->interests, i);
|
||||
if (wp_object_interest_matches_full (interest, 0, global->type,
|
||||
global->proxy, NULL, global->properties) == WP_INTEREST_MATCH_ALL) {
|
||||
|
||||
/* check all constraints */
|
||||
WpInterestMatch match = wp_object_interest_matches_full (interest,
|
||||
WP_INTEREST_MATCH_FLAGS_CHECK_ALL, global->type, global->proxy,
|
||||
NULL, global->properties);
|
||||
|
||||
/* and consider the manager interested if the type and the globals match...
|
||||
if pw_properties / g_properties fail, that's ok because they are not
|
||||
known yet (the proxy is likely NULL and properties not yet retrieved) */
|
||||
if (match & (WP_INTEREST_MATCH_GTYPE |
|
||||
WP_INTEREST_MATCH_PW_GLOBAL_PROPERTIES)) {
|
||||
gpointer ft = g_hash_table_lookup (self->features,
|
||||
GSIZE_TO_POINTER (global->type));
|
||||
*wanted_features = (WpObjectFeatures) GPOINTER_TO_UINT (ft);
|
||||
|
||||
/* force INFO to be present so that we can check PW_PROPERTIES constraints */
|
||||
if (!(match & WP_INTEREST_MATCH_PW_PROPERTIES) &&
|
||||
!(*wanted_features & WP_PIPEWIRE_OBJECT_FEATURE_INFO) &&
|
||||
g_type_is_a (global->type, WP_TYPE_PIPEWIRE_OBJECT))
|
||||
*wanted_features |= WP_PIPEWIRE_OBJECT_FEATURE_INFO;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -698,6 +715,30 @@ wp_object_manager_maybe_objects_changed (WpObjectManager * self)
|
|||
}
|
||||
}
|
||||
|
||||
/* caller must also call wp_object_manager_maybe_objects_changed() after */
|
||||
static void
|
||||
wp_object_manager_add_object (WpObjectManager * self, gpointer object)
|
||||
{
|
||||
if (wp_object_manager_is_interested_in_object (self, object)) {
|
||||
wp_trace_object (self, "added: " WP_OBJECT_FORMAT, WP_OBJECT_ARGS (object));
|
||||
g_ptr_array_add (self->objects, object);
|
||||
g_signal_emit (self, signals[SIGNAL_OBJECT_ADDED], 0, object);
|
||||
self->changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* caller must also call wp_object_manager_maybe_objects_changed() after */
|
||||
static void
|
||||
wp_object_manager_rm_object (WpObjectManager * self, gpointer object)
|
||||
{
|
||||
guint index;
|
||||
if (g_ptr_array_find (self->objects, object, &index)) {
|
||||
g_ptr_array_remove_index_fast (self->objects, index);
|
||||
g_signal_emit (self, signals[SIGNAL_OBJECT_REMOVED], 0, object);
|
||||
self->changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_proxy_ready (GObject * proxy, GAsyncResult * res, gpointer data)
|
||||
{
|
||||
|
|
@ -709,10 +750,7 @@ on_proxy_ready (GObject * proxy, GAsyncResult * res, gpointer data)
|
|||
if (!wp_object_activate_finish (WP_OBJECT (proxy), res, &error)) {
|
||||
wp_message_object (self, "proxy activation failed: %s", error->message);
|
||||
} else {
|
||||
wp_trace_object (self, "added: " WP_OBJECT_FORMAT, WP_OBJECT_ARGS (proxy));
|
||||
g_ptr_array_add (self->objects, proxy);
|
||||
g_signal_emit (self, signals[SIGNAL_OBJECT_ADDED], 0, proxy);
|
||||
self->changed = TRUE;
|
||||
wp_object_manager_add_object (self, proxy);
|
||||
}
|
||||
|
||||
wp_object_manager_maybe_objects_changed (self);
|
||||
|
|
@ -748,30 +786,6 @@ wp_object_manager_add_global (WpObjectManager * self, WpGlobal * global)
|
|||
}
|
||||
}
|
||||
|
||||
/* caller must also call wp_object_manager_maybe_objects_changed() after */
|
||||
static void
|
||||
wp_object_manager_add_object (WpObjectManager * self, gpointer object)
|
||||
{
|
||||
if (wp_object_manager_is_interested_in_object (self, object)) {
|
||||
wp_trace_object (self, "added: " WP_OBJECT_FORMAT, WP_OBJECT_ARGS (object));
|
||||
g_ptr_array_add (self->objects, object);
|
||||
g_signal_emit (self, signals[SIGNAL_OBJECT_ADDED], 0, object);
|
||||
self->changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* caller must also call wp_object_manager_maybe_objects_changed() after */
|
||||
static void
|
||||
wp_object_manager_rm_object (WpObjectManager * self, gpointer object)
|
||||
{
|
||||
guint index;
|
||||
if (g_ptr_array_find (self->objects, object, &index)) {
|
||||
g_ptr_array_remove_index_fast (self->objects, index);
|
||||
g_signal_emit (self, signals[SIGNAL_OBJECT_REMOVED], 0, object);
|
||||
self->changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* WpRegistry:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ wp_base_test_fixture_setup (WpBaseTestFixture * self, WpBaseTestFlags flags)
|
|||
}
|
||||
|
||||
static void
|
||||
done_callback (WpCore *core, GAsyncResult *res, WpBaseTestFixture *self)
|
||||
test_core_done_cb (WpCore *core, GAsyncResult *res, WpBaseTestFixture *self)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_assert_true (wp_core_sync_finish (core, res, &error));
|
||||
|
|
@ -106,14 +106,15 @@ wp_base_test_fixture_teardown (WpBaseTestFixture * self)
|
|||
{
|
||||
/* wait for all client core pending tasks to be done */
|
||||
if (self->client_core && wp_core_is_connected (self->client_core)) {
|
||||
wp_core_sync (self->client_core, NULL, (GAsyncReadyCallback) done_callback,
|
||||
self);
|
||||
wp_core_sync (self->client_core, NULL,
|
||||
(GAsyncReadyCallback) test_core_done_cb, self);
|
||||
g_main_loop_run (self->loop);
|
||||
}
|
||||
|
||||
/* wait for all core pending tasks to be done */
|
||||
if (self->core && wp_core_is_connected (self->core)) {
|
||||
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) done_callback, self);
|
||||
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) test_core_done_cb,
|
||||
self);
|
||||
g_main_loop_run (self->loop);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ test(
|
|||
dependencies: common_deps, c_args: common_args),
|
||||
env: common_env,
|
||||
)
|
||||
|
||||
test(
|
||||
'test-object-interest',
|
||||
executable('test-object-interest', 'object-interest.c',
|
||||
|
|
@ -37,6 +38,13 @@ test(
|
|||
env: common_env,
|
||||
)
|
||||
|
||||
test(
|
||||
'test-object-manager',
|
||||
executable('test-object-manager', 'object-manager.c',
|
||||
dependencies: common_deps, c_args: common_args),
|
||||
env: common_env,
|
||||
)
|
||||
|
||||
test(
|
||||
'test-properties',
|
||||
executable('test-properties', 'properties.c',
|
||||
|
|
|
|||
95
tests/wp/object-manager.c
Normal file
95
tests/wp/object-manager.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2021 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "../common/base-test-fixture.h"
|
||||
|
||||
typedef struct {
|
||||
WpBaseTestFixture base;
|
||||
WpObjectManager *om;
|
||||
} TestFixture;
|
||||
|
||||
static void
|
||||
test_om_setup (TestFixture *self, gconstpointer user_data)
|
||||
{
|
||||
wp_base_test_fixture_setup (&self->base, WP_BASE_TEST_FLAG_CLIENT_CORE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_om_teardown (TestFixture *self, gconstpointer user_data)
|
||||
{
|
||||
wp_base_test_fixture_teardown (&self->base);
|
||||
}
|
||||
|
||||
static void
|
||||
test_om_interest_on_pw_props (TestFixture *f, gconstpointer user_data)
|
||||
{
|
||||
g_autoptr (WpNode) node = NULL;
|
||||
g_autoptr (WpObjectManager) om = NULL;
|
||||
|
||||
/* load audiotestsrc on the server side */
|
||||
{
|
||||
g_autoptr (WpTestServerLocker) lock =
|
||||
wp_test_server_locker_new (&f->base.server);
|
||||
|
||||
g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context,
|
||||
"fake*", "test/libspa-test"), ==, 0);
|
||||
g_assert_nonnull (pw_context_load_module (f->base.server.context,
|
||||
"libpipewire-module-spa-node-factory", NULL, NULL));
|
||||
}
|
||||
|
||||
/* export node on the client core */
|
||||
node = wp_node_new_from_factory (f->base.client_core,
|
||||
"spa-node-factory",
|
||||
wp_properties_new (
|
||||
"factory.name", "fakesink",
|
||||
"node.name", "Fakesink",
|
||||
"test.answer", "42",
|
||||
NULL));
|
||||
g_assert_nonnull (node);
|
||||
|
||||
wp_object_activate (WP_OBJECT (node), WP_OBJECT_FEATURES_ALL,
|
||||
NULL, (GAsyncReadyCallback) test_object_activate_finish_cb, f);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
/* ensure the base core is in sync */
|
||||
wp_core_sync (f->base.core, NULL, (GAsyncReadyCallback) test_core_done_cb, f);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
/* request that node from the base core */
|
||||
om = wp_object_manager_new ();
|
||||
wp_object_manager_add_interest (om, WP_TYPE_NODE,
|
||||
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "node.name", "=s", "Fakesink",
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "test.answer", "=s", "42",
|
||||
NULL);
|
||||
test_ensure_object_manager_is_installed (om, f->base.core, f->base.loop);
|
||||
|
||||
g_assert_cmpuint (wp_object_manager_get_n_objects (om), ==, 1);
|
||||
g_clear_object (&om);
|
||||
|
||||
/* request "test.answer" to be absent... this will not match */
|
||||
om = wp_object_manager_new ();
|
||||
wp_object_manager_add_interest (om, WP_TYPE_NODE,
|
||||
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "node.name", "=s", "Fakesink",
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "test.answer", "-",
|
||||
NULL);
|
||||
test_ensure_object_manager_is_installed (om, f->base.core, f->base.loop);
|
||||
|
||||
g_assert_cmpuint (wp_object_manager_get_n_objects (om), ==, 0);
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
wp_init (WP_INIT_ALL);
|
||||
|
||||
g_test_add ("/wp/om/interest-on-pw-props", TestFixture, NULL,
|
||||
test_om_setup, test_om_interest_on_pw_props, test_om_teardown);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue