Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79ea958e authored by Eric Laurent's avatar Eric Laurent
Browse files

Audio policy: fix failure to unmute strategy.

When setOutputDevices() is called with a device not supported by the
output profile, checkDeviceMuteStrategies() was not called.
If a strategy was muted by this output because of a previous
device combination, it will never be unmuted.
A typical repro scenario is:
1) music plays over A2DP via offload path
2) incoming call: ringtone plays over speaker + A2DP
   => music is paused by audio focus
3) music manually resumed
   => media strategy is muted because it cannot play over
a2dp + speaker
4) call answered and routed to earpiece
   a) offload output is routed to earpiece which is not
supported by offload output profile
   => we fail to unmute media
   b) music stream is invalidated because earpiece is
   not supported by offload output
   => offload output is closed and we will never unmute media strategy

Fixed by calling checkDeviceMuteStrategies() before exiting in
case of unsupported device.

Bug: 157344812
Test: repro steps in bug
Test: audio regression tests
Change-Id: I0c1c189c038803a584dc222aee50c3a99c572263
parent 3244d0db
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -5770,15 +5770,6 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
    DeviceVector filteredDevices = outputDesc->filterSupportedDevices(devices);
    DeviceVector prevDevices = outputDesc->devices();

    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
    // output profile or if new device is not supported AND previous device(s) is(are) still
    // available (otherwise reset device must be done on the output)
    if (!devices.isEmpty() && filteredDevices.isEmpty() &&
            !mAvailableOutputDevices.filter(prevDevices).empty()) {
        ALOGV("%s: unsupported device %s for output", __func__, devices.toString().c_str());
        return 0;
    }

    ALOGV("setOutputDevices() prevDevice %s", prevDevices.toString().c_str());

    if (!filteredDevices.isEmpty()) {
@@ -5793,6 +5784,17 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
        muteWaitMs = 0;
    }

    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
    // output profile or if new device is not supported AND previous device(s) is(are) still
    // available (otherwise reset device must be done on the output)
    if (!devices.isEmpty() && filteredDevices.isEmpty() &&
            !mAvailableOutputDevices.filter(prevDevices).empty()) {
        ALOGV("%s: unsupported device %s for output", __func__, devices.toString().c_str());
        // restore previous device after evaluating strategy mute state
        outputDesc->setDevices(prevDevices);
        return muteWaitMs;
    }

    // Do not change the routing if:
    //      the requested device is AUDIO_DEVICE_NONE
    //      OR the requested device is the same as current device