switch-on-port-available: Fix switching away from unplugged headphones

Commits 323195e305 ("switch-on-port-available: Switch to headphones on
unknown availability") and d83ad6990e ("module-alsa-card: Drop
availability groups with only one port") broke switching from headphones
to speakers when headphones are unplugged. switch_from_port() selects
speakers, whose availability is unknown and availability group is unset,
and then calls switch_to_port(). The new logic in switch_on_port()
unintentionally blocked that switch.

This patch moves the problematic logic from switch_to_port() to
port_available_hook_callback() where it doesn't interfere with
switch_from_port().

Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/1043
This commit is contained in:
Tanu Kaskinen 2020-11-21 16:52:23 +02:00 committed by Arun Raghavan
parent 6ad2d207c5
commit eaa6d5d6c1

View file

@ -234,32 +234,6 @@ static void switch_to_port(pa_device_port *port) {
if (pp.is_port_active)
return; /* Already selected */
/* If a port availability became unknown, let's see if it's part of some
* availability group. If it is, it is likely to be a headphone jack that
* does not have impedance sensing to detect whether what was plugged in
* was a headphone, headset or microphone. In desktop environments that
* support it, this will trigger a user choice to select what kind of
* device was plugged in. However, let's switch to the headphone port at
* least, so that we have don't break functionality for setups that can't
* trigger this kind of interaction.
*
* We should make this configurable so that users can optionally override
* the default to a headset or mic.
*/
if (port->available == PA_AVAILABLE_UNKNOWN) {
/* Not part of a group of ports, so likely not a combination port */
if (!port->availability_group) {
pa_log_debug("Not switching to port %s, its availability is unknown and it's not in any availability group.", port->name);
return;
}
/* For no we only switch the headphone port */
if (port->direction != PA_DIRECTION_OUTPUT) {
pa_log_debug("Not switching to input port %s, its availability is unknown.", port->name);
return;
}
}
pa_log_debug("Trying to switch to port %s", port->name);
if (!pp.is_preferred_profile_active) {
if (try_to_switch_profile(port) < 0) {
@ -330,6 +304,34 @@ static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port
switch (port->available) {
case PA_AVAILABLE_UNKNOWN:
/* If a port availability became unknown, let's see if it's part of
* some availability group. If it is, it is likely to be a headphone
* jack that does not have impedance sensing to detect whether what was
* plugged in was a headphone, headset or microphone. In desktop
* environments that support it, this will trigger a user choice to
* select what kind of device was plugged in. However, let's switch to
* the headphone port at least, so that we have don't break
* functionality for setups that can't trigger this kind of
* interaction.
*
* We should make this configurable so that users can optionally
* override the default to a headset or mic. */
/* Not part of a group of ports, so likely not a combination port */
if (!port->availability_group) {
pa_log_debug("Not switching to port %s, its availability is unknown and it's not in any availability group.", port->name);
break;
}
/* For no we only switch the headphone port */
if (port->direction != PA_DIRECTION_OUTPUT) {
pa_log_debug("Not switching to input port %s, its availability is unknown.", port->name);
break;
}
switch_to_port(port);
break;
case PA_AVAILABLE_YES:
switch_to_port(port);
break;