diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-05-13 18:03:27 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-05-13 18:03:27 +0200 |
commit | b474666e2e841a2cd37cfb49558ca60b37d8501f (patch) | |
tree | c7d79523b1f47ddcc2ece46fe80042bd3fd647d6 | |
parent | a224234acd1fe1f4a4302bbaa1df2d1a4c7c8476 (diff) |
link: listen for permission changes
Destroy the link when the ports or nodes are no longer visible
to the other side of the link.
-rw-r--r-- | src/pipewire/link.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/pipewire/link.c b/src/pipewire/link.c index 1e39da58..86c639d9 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -62,8 +62,10 @@ struct impl { struct spa_hook input_port_listener; struct spa_hook input_node_listener; + struct spa_hook input_global_listener; struct spa_hook output_port_listener; struct spa_hook output_node_listener; + struct spa_hook output_global_listener; struct spa_io_buffers io; @@ -872,6 +874,7 @@ static void input_remove(struct pw_link *this, struct pw_port *port) pw_log_debug("link %p: remove input port %p", this, port); spa_hook_remove(&impl->input_port_listener); spa_hook_remove(&impl->input_node_listener); + spa_hook_remove(&impl->input_global_listener); spa_list_remove(&this->input_link); pw_port_emit_link_removed(this->input, this); @@ -891,6 +894,7 @@ static void output_remove(struct pw_link *this, struct pw_port *port) pw_log_debug("link %p: remove output port %p", this, port); spa_hook_remove(&impl->output_port_listener); spa_hook_remove(&impl->output_node_listener); + spa_hook_remove(&impl->output_global_listener); spa_list_remove(&this->output_link); pw_port_emit_link_removed(this->output, this); @@ -1177,22 +1181,34 @@ check_permission(struct pw_core *core, struct pw_port *input, struct pw_properties *properties) { - struct pw_node *input_node, *output_node; struct pw_client *client; - input_node = input->node; - output_node = output->node; - - if ((client = output_node->global->owner) != NULL && - !PW_PERM_IS_R(pw_global_get_permissions(input_node->global, client))) + if ((client = output->global->owner) != NULL && + !PW_PERM_IS_R(pw_global_get_permissions(input->global, client))) return -EPERM; - if ((client = input_node->global->owner) != NULL && - !PW_PERM_IS_R(pw_global_get_permissions(output_node->global, client))) + if ((client = input->global->owner) != NULL && + !PW_PERM_IS_R(pw_global_get_permissions(output->global, client))) return -EPERM; + return 0; } +static void global_permissions_changed(void *data, + struct pw_client *client, uint32_t old, uint32_t new) +{ + struct pw_link *this = data; + + pw_log_debug("link %p: permissions changed", this); + if (check_permission(this->core, this->output, this->input, this->properties) < 0) + pw_link_destroy(this); +} + +static const struct pw_global_events global_node_events = { + PW_VERSION_GLOBAL_EVENTS, + .permissions_changed = global_permissions_changed, +}; + SPA_EXPORT struct pw_link *pw_link_new(struct pw_core *core, struct pw_port *output, @@ -1254,8 +1270,10 @@ struct pw_link *pw_link_new(struct pw_core *core, pw_port_add_listener(input, &impl->input_port_listener, &input_port_events, impl); pw_node_add_listener(input_node, &impl->input_node_listener, &input_node_events, impl); + pw_global_add_listener(input_node->global, &impl->input_global_listener, &global_node_events, impl); pw_port_add_listener(output, &impl->output_port_listener, &output_port_events, impl); pw_node_add_listener(output_node, &impl->output_node_listener, &output_node_events, impl); + pw_global_add_listener(output_node->global, &impl->output_global_listener, &global_node_events, impl); input_node->live = output_node->live; |