Commit 0b558eca authored by George Kiagiadakis's avatar George Kiagiadakis Committed by Julian Bouzas
Browse files

proxy: add a "bind" watch, to watch for proxy errors while binding/exporting

Add a unit test for this. Create a link with invalid nodes and expect
the activation transition to error out.
parent 7cf67a82
......@@ -438,6 +438,7 @@ wp_spa_device_activate_execute_step (WpObject * object,
struct pw_core *pw_core = wp_core_get_pw_core (core);
g_return_if_fail (pw_core);
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self),
pw_core_export (pw_core, SPA_TYPE_INTERFACE_Device,
wp_properties_peek_dict (self->properties),
......
......@@ -530,6 +530,7 @@ wp_impl_endpoint_link_activate_execute_step (WpObject * object,
}
/* bind */
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core,
PW_TYPE_INTERFACE_EndpointLink,
wp_properties_peek_dict (self->immutable_props),
......
......@@ -703,6 +703,7 @@ wp_impl_endpoint_activate_execute_step (WpObject * object,
}
/* bind */
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core,
PW_TYPE_INTERFACE_Endpoint,
wp_properties_peek_dict (self->immutable_props),
......
......@@ -138,6 +138,7 @@ wp_global_proxy_activate_execute_step (WpObject * object,
switch (step) {
case STEP_BIND:
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
if (wp_proxy_get_pw_proxy (WP_PROXY (self)) == NULL) {
if (!wp_global_proxy_bind (self)) {
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
......
......@@ -634,6 +634,7 @@ wp_impl_metadata_activate_execute_step (WpObject * object,
return;
}
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core,
PW_TYPE_INTERFACE_Metadata,
NULL, priv->iface, 0));
......
......@@ -657,6 +657,7 @@ wp_impl_node_activate_execute_step (WpObject * object,
struct pw_core *pw_core = wp_core_get_pw_core (core);
g_return_if_fail (pw_core);
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self),
pw_core_export (pw_core, PW_TYPE_INTERFACE_Node, NULL,
self->pw_impl_node, 0));
......
......@@ -15,6 +15,7 @@
#include "proxy.h"
#include "log.h"
#include "error.h"
#include <pipewire/pipewire.h>
#include <spa/utils/hook.h>
......@@ -267,3 +268,30 @@ wp_proxy_set_pw_proxy (WpProxy * self, struct pw_proxy * proxy)
/* inform subclasses and listeners */
g_signal_emit (self, signals[SIGNAL_PW_PROXY_CREATED], 0, priv->pw_proxy);
}
static void
bind_error (WpProxy * proxy, int seq, int res, const gchar *msg,
WpTransition * transition)
{
wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED, "%s", msg));
}
static void
bind_success (WpProxy * proxy, uint32_t global_id, WpTransition * transition)
{
g_signal_handlers_disconnect_by_func (proxy, bind_error, transition);
g_signal_handlers_disconnect_by_func (proxy, bind_success, transition);
}
void
wp_proxy_watch_bind_error (WpProxy * proxy, WpTransition * transition)
{
g_return_if_fail (WP_IS_PROXY (proxy));
g_return_if_fail (WP_IS_TRANSITION (transition));
g_signal_connect_object (proxy, "error", G_CALLBACK (bind_error),
transition, 0);
g_signal_connect_object (proxy, "bound", G_CALLBACK (bind_success),
transition, 0);
}
......@@ -103,6 +103,9 @@ struct pw_proxy * wp_proxy_get_pw_proxy (WpProxy * self);
WP_API
void wp_proxy_set_pw_proxy (WpProxy * self, struct pw_proxy * proxy);
WP_API
void wp_proxy_watch_bind_error (WpProxy * proxy, WpTransition * transition);
G_END_DECLS
#endif
......@@ -690,6 +690,7 @@ wp_impl_session_activate_execute_step (WpObject * object,
wp_properties_set (d->properties, PW_KEY_CLIENT_ID, NULL);
wp_properties_set (d->properties, PW_KEY_FACTORY_ID, NULL);
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core,
PW_TYPE_INTERFACE_Session,
wp_properties_peek_dict (d->properties),
......
......@@ -192,6 +192,44 @@ test_node (TestFixture *f, gconstpointer data)
g_main_loop_run (f->base.loop);
}
static void
activate_error_cb (WpObject * object, GAsyncResult * res,
WpBaseTestFixture * f)
{
g_autoptr (GError) error = NULL;
gboolean augment_ret = wp_object_activate_finish (object, res, &error);
g_assert_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED);
g_assert_false (augment_ret);
g_main_loop_quit (f->loop);
}
static void
test_link_error (TestFixture *f, gconstpointer data)
{
g_autoptr (WpPipewireObject) proxy = NULL;
/* load audiotestsrc on the server side */
{
g_autoptr (WpTestServerLocker) lock =
wp_test_server_locker_new (&f->base.server);
g_assert_nonnull (pw_context_load_module (f->base.server.context,
"libpipewire-module-link-factory", NULL, NULL));
}
proxy = WP_PIPEWIRE_OBJECT (wp_link_new_from_factory (f->base.core,
"link-factory",
wp_properties_new (
"link.output.node", "invalid",
"link.input.node", "invalid",
NULL)));
g_assert_nonnull (proxy);
wp_object_activate (WP_OBJECT (proxy), WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL,
NULL, (GAsyncReadyCallback) activate_error_cb, f);
g_main_loop_run (f->base.loop);
}
gint
main (gint argc, gchar *argv[])
{
......@@ -202,6 +240,8 @@ main (gint argc, gchar *argv[])
test_proxy_setup, test_proxy_basic, test_proxy_teardown);
g_test_add ("/wp/proxy/node", TestFixture, NULL,
test_proxy_setup, test_node, test_proxy_teardown);
g_test_add ("/wp/proxy/link_error", TestFixture, NULL,
test_proxy_setup, test_link_error, test_proxy_teardown);
return g_test_run ();
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment