mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
client: register client global after update properties
This way we only expose the client after we have all the properties. Also add a new CLIENT_ACCESS property that contains the desired client access mode.
This commit is contained in:
parent
8b70a83c96
commit
12e6dd89e2
3 changed files with 35 additions and 9 deletions
|
|
@ -157,7 +157,7 @@ handle_client(struct impl *impl, struct sm_object *object)
|
||||||
struct client *client;
|
struct client *client;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: client", impl);
|
pw_log_debug(NAME" %p: client %u", impl, object->id);
|
||||||
|
|
||||||
client = sm_object_add_data(object, SESSION_KEY, sizeof(struct client));
|
client = sm_object_add_data(object, SESSION_KEY, sizeof(struct client));
|
||||||
client->obj = (struct sm_client*)object;
|
client->obj = (struct sm_client*)object;
|
||||||
|
|
@ -168,7 +168,8 @@ handle_client(struct impl *impl, struct sm_object *object)
|
||||||
client->obj->obj.mask |= SM_CLIENT_CHANGE_MASK_INFO;
|
client->obj->obj.mask |= SM_CLIENT_CHANGE_MASK_INFO;
|
||||||
sm_object_add_listener(&client->obj->obj, &client->listener, &object_events, client);
|
sm_object_add_listener(&client->obj->obj, &client->listener, &object_events, client);
|
||||||
|
|
||||||
if ((str = pw_properties_get(client->obj->obj.props, PW_KEY_ACCESS)) != NULL &&
|
if (((str = pw_properties_get(client->obj->obj.props, PW_KEY_ACCESS)) != NULL ||
|
||||||
|
(str = pw_properties_get(client->obj->obj.props, PW_KEY_CLIENT_ACCESS)) != NULL) &&
|
||||||
strcmp(str, "portal") == 0) {
|
strcmp(str, "portal") == 0) {
|
||||||
client->portal_managed = true;
|
client->portal_managed = true;
|
||||||
pw_log_info(NAME " %p: portal managed client %d added",
|
pw_log_info(NAME " %p: portal managed client %d added",
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ struct impl {
|
||||||
struct spa_hook context_listener;
|
struct spa_hook context_listener;
|
||||||
struct pw_array permissions;
|
struct pw_array permissions;
|
||||||
struct spa_hook pool_listener;
|
struct spa_hook pool_listener;
|
||||||
|
unsigned int registered:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define pw_client_resource(r,m,v,...) pw_resource_call(r,struct pw_client_events,m,v,__VA_ARGS__)
|
#define pw_client_resource(r,m,v,...) pw_resource_call(r,struct pw_client_events,m,v,__VA_ARGS__)
|
||||||
|
|
@ -137,12 +138,15 @@ static int update_properties(struct pw_impl_client *client, const struct spa_dic
|
||||||
struct pw_resource *resource;
|
struct pw_resource *resource;
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
const char *old;
|
||||||
|
|
||||||
for (i = 0; i < dict->n_items; i++) {
|
for (i = 0; i < dict->n_items; i++) {
|
||||||
if (filter && strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
|
if (filter && strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
|
||||||
pw_properties_get(client->properties, dict->items[i].key) != NULL) {
|
(old = pw_properties_get(client->properties, dict->items[i].key)) != NULL &&
|
||||||
pw_log_warn(NAME" %p: refuse property update '%s' to '%s'",
|
(dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) {
|
||||||
client, dict->items[i].key, dict->items[i].value);
|
pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'",
|
||||||
|
client, dict->items[i].key, old,
|
||||||
|
dict->items[i].value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value);
|
changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value);
|
||||||
|
|
@ -167,12 +171,32 @@ static int update_properties(struct pw_impl_client *client, const struct spa_dic
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int finish_register(struct pw_impl_client *client)
|
||||||
|
{
|
||||||
|
struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this);
|
||||||
|
const char *keys[] = {
|
||||||
|
PW_KEY_CLIENT_ACCESS,
|
||||||
|
PW_KEY_APP_NAME,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
if (impl->registered)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pw_global_update_keys(client->global, client->info.props, keys);
|
||||||
|
pw_global_register(client->global);
|
||||||
|
impl->registered = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int client_update_properties(void *object, const struct spa_dict *props)
|
static int client_update_properties(void *object, const struct spa_dict *props)
|
||||||
{
|
{
|
||||||
struct pw_resource *resource = object;
|
struct pw_resource *resource = object;
|
||||||
struct resource_data *data = pw_resource_get_user_data(resource);
|
struct resource_data *data = pw_resource_get_user_data(resource);
|
||||||
struct pw_impl_client *client = data->client;
|
struct pw_impl_client *client = data->client;
|
||||||
return update_properties(client, props, true);
|
int res = update_properties(client, props, true);
|
||||||
|
finish_register(client);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_get_permissions(void *object, uint32_t index, uint32_t num)
|
static int client_get_permissions(void *object, uint32_t index, uint32_t num)
|
||||||
|
|
@ -429,6 +453,7 @@ int pw_impl_client_register(struct pw_impl_client *client,
|
||||||
PW_KEY_SEC_GID,
|
PW_KEY_SEC_GID,
|
||||||
PW_KEY_SEC_LABEL,
|
PW_KEY_SEC_LABEL,
|
||||||
PW_KEY_ACCESS,
|
PW_KEY_ACCESS,
|
||||||
|
PW_KEY_CLIENT_ACCESS,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -452,14 +477,12 @@ int pw_impl_client_register(struct pw_impl_client *client,
|
||||||
client->info.id = client->global->id;
|
client->info.id = client->global->id;
|
||||||
pw_properties_setf(client->properties, PW_KEY_OBJECT_ID, "%d", client->info.id);
|
pw_properties_setf(client->properties, PW_KEY_OBJECT_ID, "%d", client->info.id);
|
||||||
client->info.props = &client->properties->dict;
|
client->info.props = &client->properties->dict;
|
||||||
|
pw_global_add_listener(client->global, &client->global_listener, &global_events, client);
|
||||||
|
|
||||||
pw_global_update_keys(client->global, client->info.props, keys);
|
pw_global_update_keys(client->global, client->info.props, keys);
|
||||||
|
|
||||||
pw_impl_client_emit_initialized(client);
|
pw_impl_client_emit_initialized(client);
|
||||||
|
|
||||||
pw_global_add_listener(client->global, &client->global_listener, &global_events, client);
|
|
||||||
pw_global_register(client->global);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_existed:
|
error_existed:
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define PW_KEY_PROTOCOL "pipewire.protocol" /**< protocol used for connection */
|
#define PW_KEY_PROTOCOL "pipewire.protocol" /**< protocol used for connection */
|
||||||
#define PW_KEY_ACCESS "pipewire.access" /**< how the client access is controlled */
|
#define PW_KEY_ACCESS "pipewire.access" /**< how the client access is controlled */
|
||||||
|
#define PW_KEY_CLIENT_ACCESS "pipewire.client.access"/**< how the client wants to be access
|
||||||
|
* controlled */
|
||||||
|
|
||||||
/** Various keys related to the identity of a client process and its security.
|
/** Various keys related to the identity of a client process and its security.
|
||||||
* Must be obtained from trusted sources by the protocol and placed as
|
* Must be obtained from trusted sources by the protocol and placed as
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue