pulse-server: behave like PA when moving streams to default

Pulseaudio unsets the preferred sink/source when stream is moved to a
default target. Emulate this behavior by setting + unsetting
target.node, which informs policy-node to move it accordingly.
This commit is contained in:
Pauli Virtanen 2021-01-18 13:23:23 +02:00
parent d1a0121b7c
commit d46c58e958
2 changed files with 30 additions and 5 deletions

View file

@ -675,6 +675,7 @@ int pw_manager_set_metadata(struct pw_manager *manager,
struct object *s;
va_list args;
char buf[1024];
char *value;
if ((s = find_object(m, subject)) == NULL)
return -ENOENT;
@ -686,12 +687,18 @@ int pw_manager_set_metadata(struct pw_manager *manager,
if (!SPA_FLAG_IS_SET(metadata->permissions, PW_PERM_W|PW_PERM_X))
return -EACCES;
if (type != NULL) {
va_start(args, format);
vsnprintf(buf, sizeof(buf)-1, format, args);
va_end(args);
value = buf;
} else {
spa_assert(format == NULL);
value = NULL;
}
pw_metadata_set_property(metadata->proxy,
subject, key, type, buf);
subject, key, type, value);
return 0;
}

View file

@ -4340,7 +4340,7 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag,
{
struct impl *impl = client->impl;
struct pw_manager *manager = client->manager;
struct pw_manager_object *o, *dev;
struct pw_manager_object *o, *dev, *dev_default;
uint32_t id, id_device;
const char *name_device;
struct selector sel;
@ -4378,6 +4378,24 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag,
SPA_TYPE_INFO_BASE"Id", "%d", dev->id)) < 0)
return res;
dev_default = find_device(client, SPA_ID_INVALID, NULL, sink);
if (dev == dev_default) {
/*
* When moving streams to a node that is equal to the default,
* Pulseaudio understands this to mean '... and unset preferred sink/source',
* forgetting target.node. Follow that behavior here.
*
* XXX: We set target.node key above regardless, to make policy-node
* XXX: to always see the unset event. The metadata is currently not
* XXX: always set when the node has explicit target.
*/
if ((res = pw_manager_set_metadata(manager, client->metadata_default,
o->id,
METADATA_TARGET_NODE,
NULL, NULL)) < 0)
return res;
}
return reply_simple_ack(client, tag);
}