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
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3730c34..c5c13e9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5770,15 +5770,6 @@
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 @@
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