mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
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.
This commit is contained in:
parent
83bc033837
commit
98da5a2e9e
4 changed files with 38 additions and 3 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue