sink/source: Initialize port before fixate hook (fixes volume/mute not saved)

In case a port has not yet been saved, which is e g often the case
if a sink/source has only one port, reading volume/mute will be done
without port, whereas writing volume/mute will be done with port.

Work around this by setting a default port before the fixate hook,
so module-device-restore can read volume/mute for the correct port.

BugLink: https://bugs.launchpad.net/bugs/1289515
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
David Henningsson 2014-03-21 10:19:19 +01:00
parent 633bc529e2
commit e0e6bf6875
4 changed files with 49 additions and 35 deletions

View file

@ -176,3 +176,30 @@ void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p); pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p);
} }
pa_device_port *pa_device_port_find_best(pa_hashmap *ports)
{
void *state;
pa_device_port *p, *best = NULL;
if (!ports)
return NULL;
/* First run: skip unavailable ports */
PA_HASHMAP_FOREACH(p, ports, state) {
if (p->available == PA_AVAILABLE_NO)
continue;
if (!best || p->priority > best->priority)
best = p;
}
/* Second run: if only unavailable ports exist, still suggest a port */
if (!best) {
PA_HASHMAP_FOREACH(p, ports, state)
if (!best || p->priority > best->priority)
best = p;
}
return best;
}

View file

@ -83,4 +83,6 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset); void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
pa_device_port *pa_device_port_find_best(pa_hashmap *ports);
#endif #endif

View file

@ -235,6 +235,12 @@ pa_sink* pa_sink_new(
pa_device_init_icon(data->proplist, true); pa_device_init_icon(data->proplist, true);
pa_device_init_intended_roles(data->proplist); pa_device_init_intended_roles(data->proplist);
if (!data->active_port) {
pa_device_port *p = pa_device_port_find_best(data->ports);
if (p)
pa_sink_new_data_set_port(data, p->name);
}
if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) { if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
pa_xfree(s); pa_xfree(s);
pa_namereg_unregister(core, name); pa_namereg_unregister(core, name);
@ -300,23 +306,10 @@ pa_sink* pa_sink_new(
if ((s->active_port = pa_hashmap_get(s->ports, data->active_port))) if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
s->save_port = data->save_port; s->save_port = data->save_port;
if (!s->active_port) { /* Hopefully the active port has already been assigned in the previous call
void *state; to pa_device_port_find_best, but better safe than sorry */
pa_device_port *p; if (!s->active_port)
s->active_port = pa_device_port_find_best(s->ports);
PA_HASHMAP_FOREACH(p, s->ports, state) {
if (p->available == PA_AVAILABLE_NO)
continue;
if (!s->active_port || p->priority > s->active_port->priority)
s->active_port = p;
}
if (!s->active_port) {
PA_HASHMAP_FOREACH(p, s->ports, state)
if (!s->active_port || p->priority > s->active_port->priority)
s->active_port = p;
}
}
if (s->active_port) if (s->active_port)
s->latency_offset = s->active_port->latency_offset; s->latency_offset = s->active_port->latency_offset;

View file

@ -222,6 +222,12 @@ pa_source* pa_source_new(
pa_device_init_icon(data->proplist, false); pa_device_init_icon(data->proplist, false);
pa_device_init_intended_roles(data->proplist); pa_device_init_intended_roles(data->proplist);
if (!data->active_port) {
pa_device_port *p = pa_device_port_find_best(data->ports);
if (p)
pa_source_new_data_set_port(data, p->name);
}
if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) { if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
pa_xfree(s); pa_xfree(s);
pa_namereg_unregister(core, name); pa_namereg_unregister(core, name);
@ -288,24 +294,10 @@ pa_source* pa_source_new(
if ((s->active_port = pa_hashmap_get(s->ports, data->active_port))) if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
s->save_port = data->save_port; s->save_port = data->save_port;
if (!s->active_port) { /* Hopefully the active port has already been assigned in the previous call
void *state; to pa_device_port_find_best, but better safe than sorry */
pa_device_port *p; if (!s->active_port)
s->active_port = pa_device_port_find_best(s->ports);
PA_HASHMAP_FOREACH(p, s->ports, state) {
if (p->available == PA_AVAILABLE_NO)
continue;
if (!s->active_port || p->priority > s->active_port->priority)
s->active_port = p;
}
if (!s->active_port) {
PA_HASHMAP_FOREACH(p, s->ports, state)
if (!s->active_port || p->priority > s->active_port->priority)
s->active_port = p;
}
}
if (s->active_port) if (s->active_port)
s->latency_offset = s->active_port->latency_offset; s->latency_offset = s->active_port->latency_offset;