global: update child permissions

When the permissions of a global change, update the child permissions
as well.
This commit is contained in:
Wim Taymans 2019-05-14 12:08:35 +02:00
parent d39d15b0d9
commit d7c7e9bf6f

View file

@ -42,8 +42,7 @@ struct impl {
/** \endcond */ /** \endcond */
SPA_EXPORT static inline uint32_t get_permissions(struct pw_global *global, struct pw_client *client, bool recurse)
uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client)
{ {
uint32_t perms; uint32_t perms;
@ -52,13 +51,21 @@ uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *c
perms = client->permission_func(global, client, client->permission_data); perms = client->permission_func(global, client, client->permission_data);
while (global->parent != NULL && global != global->parent) { if (recurse) {
global = global->parent; while (global->parent != NULL && global != global->parent) {
perms &= client->permission_func(global, client, client->permission_data); global = global->parent;
perms &= client->permission_func(global, client, client->permission_data);
}
} }
return perms; return perms;
} }
SPA_EXPORT
uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client)
{
return get_permissions(global, client, true);
}
/** Create a new global /** Create a new global
* *
* \param core a core object * \param core a core object
@ -302,17 +309,30 @@ int pw_global_update_permissions(struct pw_global *global, struct pw_client *cli
{ {
struct pw_core *core = global->core; struct pw_core *core = global->core;
struct pw_resource *resource, *t; struct pw_resource *resource, *t;
struct pw_global *g;
uint32_t perms;
pw_global_emit_permissions_changed(global, client, old_permissions, new_permissions); pw_global_emit_permissions_changed(global, client, old_permissions, new_permissions);
spa_list_for_each(g, &global->child_list, child_link) {
if (g == global)
continue;
perms = get_permissions(g, client, false);
pw_global_update_permissions(g, client,
perms & old_permissions,
perms & new_permissions);
}
spa_list_for_each(resource, &core->registry_resource_list, link) { spa_list_for_each(resource, &core->registry_resource_list, link) {
if (resource->client != client) if (resource->client != client)
continue; continue;
if (PW_PERM_IS_R(old_permissions) && !PW_PERM_IS_R(new_permissions)) { if (PW_PERM_IS_R(old_permissions) && !PW_PERM_IS_R(new_permissions)) {
pw_log_debug("client %p: hide global %d", client, global->id);
pw_registry_resource_global_remove(resource, global->id); pw_registry_resource_global_remove(resource, global->id);
} }
else if (!PW_PERM_IS_R(old_permissions) && PW_PERM_IS_R(new_permissions)) { else if (!PW_PERM_IS_R(old_permissions) && PW_PERM_IS_R(new_permissions)) {
pw_log_debug("client %p: show global %d", client, global->id);
pw_registry_resource_global(resource, pw_registry_resource_global(resource,
global->id, global->id,
global->parent->id, global->parent->id,