policy_hal: Avoid invalidation of music stream if not required.
-APM tries to open output for all profiles supported on headphone
device During insertion of headphone and invalidate music stream
if number of output doesn't matches with outputs on previous device.
Since DSD profile is supported on headphone device only, APM opens
DSD output on headphone insertion and invalidate music stream.
-Check if any of the new output is for DSD profile if number of output
doesn't match on new device and prev device. Avoid invalidation if
difference in outputs is because of DSD output.
Change-Id: I97092f620851b22a66a6f9cbfc9337db3828c5d6
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 022a3c0..d06929c 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -435,6 +435,48 @@
return BAD_VALUE;
}
+bool AudioPolicyManagerCustom::isInvalidationOfMusicStreamNeeded(routing_strategy strategy)
+{
+ if (strategy == STRATEGY_MEDIA) {
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> newOutputDesc = mOutputs.valueAt(i);
+ if (newOutputDesc->mFormat == AUDIO_FORMAT_DSD)
+ return false;
+ }
+ }
+ return true;
+}
+
+void AudioPolicyManagerCustom::checkOutputForStrategy(routing_strategy strategy)
+{
+ audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
+ audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
+ SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mOutputs);
+ SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
+
+ // also take into account external policy-related changes: add all outputs which are
+ // associated with policies in the "before" and "after" output vectors
+ ALOGV("checkOutputForStrategy(): policy related outputs");
+ for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
+ const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
+ if (desc != 0 && desc->mPolicyMix != NULL) {
+ srcOutputs.add(desc->mIoHandle);
+ ALOGV(" previous outputs: adding %d", desc->mIoHandle);
+ }
+ }
+ for (size_t i = 0 ; i < mOutputs.size() ; i++) {
+ const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (desc != 0 && desc->mPolicyMix != NULL) {
+ dstOutputs.add(desc->mIoHandle);
+ ALOGV(" new outputs: adding %d", desc->mIoHandle);
+ }
+ }
+
+ if (!vectorsEqual(srcOutputs,dstOutputs) && isInvalidationOfMusicStreamNeeded(strategy)) {
+ AudioPolicyManager::checkOutputForStrategy(strategy);
+ }
+}
+
// This function checks for the parameters which can be offloaded.
// This can be enhanced depending on the capability of the DSP and policy
// of the system.
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index deef57d..00da599 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -96,6 +96,14 @@
// see getDeviceForStrategy() for the use of fromCache parameter
audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
bool fromCache);
+
+ // avoid invalidation for active music stream on previous outputs
+ // which is supported on the new device.
+ bool isInvalidationOfMusicStreamNeeded(routing_strategy strategy);
+
+ // Must be called before updateDevicesAndOutputs()
+ void checkOutputForStrategy(routing_strategy strategy);
+
// returns true if given output is direct output
bool isDirectOutput(audio_io_handle_t output);