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 impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||||
struct permission *p;
|
struct permission *p;
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
uint32_t old;
|
||||||
|
|
||||||
len = pw_array_get_len(&impl->permissions, struct permission);
|
len = pw_array_get_len(&impl->permissions, struct permission);
|
||||||
if (len <= global->id) {
|
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);
|
p = pw_array_get_unchecked(&impl->permissions, global->id, struct permission);
|
||||||
if (p->permissions == -1)
|
if (p->permissions == -1)
|
||||||
p->permissions = impl->permissions_default;
|
old = p->permissions = impl->permissions_default;
|
||||||
else if (update->only_new)
|
else if (update->only_new)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
old = p->permissions;
|
||||||
p->permissions &= update->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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ struct pw_global;
|
||||||
|
|
||||||
/** Global events, use \ref pw_global_add_listener */
|
/** Global events, use \ref pw_global_add_listener */
|
||||||
struct pw_global_events {
|
struct pw_global_events {
|
||||||
#define PW_VERSION_GLOBAL_EVENTS 0
|
#define PW_VERSION_GLOBAL_EVENTS 1
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
/** The global is destroyed */
|
/** The global is destroyed */
|
||||||
|
|
@ -72,6 +72,12 @@ struct pw_global_events {
|
||||||
uint32_t permissions, /**< permissions for the bind */
|
uint32_t permissions, /**< permissions for the bind */
|
||||||
uint32_t version, /**< client interface version */
|
uint32_t version, /**< client interface version */
|
||||||
uint32_t id /**< client proxy id */);
|
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 */
|
/** Create a new global object */
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,10 @@ struct impl {
|
||||||
|
|
||||||
struct spa_hook input_port_listener;
|
struct spa_hook input_port_listener;
|
||||||
struct spa_hook input_node_listener;
|
struct spa_hook input_node_listener;
|
||||||
|
struct spa_hook input_global_listener;
|
||||||
struct spa_hook output_port_listener;
|
struct spa_hook output_port_listener;
|
||||||
struct spa_hook output_node_listener;
|
struct spa_hook output_node_listener;
|
||||||
|
struct spa_hook output_global_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct resource_data {
|
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);
|
pw_log_debug("link %p: remove input port %p", this, port);
|
||||||
spa_hook_remove(&impl->input_port_listener);
|
spa_hook_remove(&impl->input_port_listener);
|
||||||
spa_hook_remove(&impl->input_node_listener);
|
spa_hook_remove(&impl->input_node_listener);
|
||||||
|
spa_hook_remove(&impl->input_global_listener);
|
||||||
|
|
||||||
pw_loop_invoke(port->node->data_loop,
|
pw_loop_invoke(port->node->data_loop,
|
||||||
do_remove_input, 1, NULL, 0, true, this);
|
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);
|
pw_log_debug("link %p: remove output port %p", this, port);
|
||||||
spa_hook_remove(&impl->output_port_listener);
|
spa_hook_remove(&impl->output_port_listener);
|
||||||
spa_hook_remove(&impl->output_node_listener);
|
spa_hook_remove(&impl->output_node_listener);
|
||||||
|
spa_hook_remove(&impl->output_global_listener);
|
||||||
|
|
||||||
pw_loop_invoke(port->node->data_loop,
|
pw_loop_invoke(port->node->data_loop,
|
||||||
do_remove_output, 1, NULL, 0, true, this);
|
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 &&
|
if ((client = input_node->global->owner) != NULL &&
|
||||||
!PW_PERM_IS_R(pw_global_get_permissions(output_node->global, client)))
|
!PW_PERM_IS_R(pw_global_get_permissions(output_node->global, client)))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
return 0;
|
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
|
SPA_EXPORT
|
||||||
struct pw_link *pw_link_new(struct pw_core *core,
|
struct pw_link *pw_link_new(struct pw_core *core,
|
||||||
struct pw_port *output,
|
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_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_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_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_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;
|
input_node->live = output_node->live;
|
||||||
if (output_node->clock)
|
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_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_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_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_global {
|
||||||
struct pw_core *core; /**< the core */
|
struct pw_core *core; /**< the core */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue