diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-05-13 17:04:43 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-05-13 17:04:43 +0200 |
commit | 98da5a2e9e5524751aaa96e2043d475135a2bb9b (patch) | |
tree | 231bee25af176d63b99eacc93a9075bb9098fc0d | |
parent | 83bc033837f7525d898f1de91119f669f9bf97f5 (diff) |
global: emit permissions_changed event
Add a permissions_changed event when the permissions change for a
global for a client.
Recheck if a link is still allowed when node permissions changed
and destroy the link if not.
-rw-r--r-- | src/pipewire/client.c | 9 | ||||
-rw-r--r-- | src/pipewire/global.h | 8 | ||||
-rw-r--r-- | src/pipewire/link.c | 22 | ||||
-rw-r--r-- | src/pipewire/private.h | 2 |
4 files changed, 38 insertions, 3 deletions
diff --git a/src/pipewire/client.c b/src/pipewire/client.c index a09e3da8..4c647fe2 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -395,6 +395,7 @@ static int do_permissions(void *data, struct pw_global *global) struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this); struct permission *p; size_t len, i; + uint32_t old; len = pw_array_get_len(&impl->permissions, struct permission); if (len <= global->id) { @@ -410,12 +411,16 @@ static int do_permissions(void *data, struct pw_global *global) p = pw_array_get_unchecked(&impl->permissions, global->id, struct permission); if (p->permissions == -1) - p->permissions = impl->permissions_default; + old = p->permissions = impl->permissions_default; else if (update->only_new) return 0; + old = p->permissions; p->permissions &= update->permissions; - pw_log_debug("client %p: set global %d permissions to %08x", client, global->id, p->permissions); + pw_log_debug("client %p: change global %d permissions %08x -> %08x", + client, global->id, old, p->permissions); + + pw_global_events_permissions_changed(global, client, old, p->permissions); return 0; } diff --git a/src/pipewire/global.h b/src/pipewire/global.h index 813409f9..2c5f07ff 100644 --- a/src/pipewire/global.h +++ b/src/pipewire/global.h @@ -57,7 +57,7 @@ struct pw_global; /** Global events, use \ref pw_global_add_listener */ struct pw_global_events { -#define PW_VERSION_GLOBAL_EVENTS 0 +#define PW_VERSION_GLOBAL_EVENTS 1 uint32_t version; /** The global is destroyed */ @@ -72,6 +72,12 @@ struct pw_global_events { uint32_t permissions, /**< permissions for the bind */ uint32_t version, /**< client interface version */ uint32_t id /**< client proxy id */); + + /* permissions for the global changed, Since version 1 */ + void (*permissions_changed) (void *data, + struct pw_client *client, + uint32_t old_permissions, + uint32_t new_permissions); }; /** Create a new global object */ diff --git a/src/pipewire/link.c b/src/pipewire/link.c index f4529be9..9b33c160 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -51,8 +51,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 resource_data { @@ -868,6 +870,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); pw_loop_invoke(port->node->data_loop, do_remove_input, 1, NULL, 0, true, this); @@ -897,6 +900,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); pw_loop_invoke(port->node->data_loop, do_remove_output, 1, NULL, 0, true, this); @@ -1105,9 +1109,25 @@ check_permission(struct pw_core *core, if ((client = input_node->global->owner) != NULL && !PW_PERM_IS_R(pw_global_get_permissions(output_node->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; + + 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, @@ -1166,8 +1186,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; if (output_node->clock) diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 9e51d21a..1bb314e7 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -124,6 +124,8 @@ struct pw_client { #define pw_global_events_destroy(g) pw_global_events_emit(g, destroy, 0) #define pw_global_events_free(g) pw_global_events_emit(g, free, 0) #define pw_global_events_bind(g,...) pw_global_events_emit(g, bind, 0, __VA_ARGS__) +#define pw_global_events_permissions_changed(g,...) \ + pw_global_events_emit(g, permissions_changed, 1, __VA_ARGS__) struct pw_global { struct pw_core *core; /**< the core */ |