diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 39cdcf0e13761..fca0cc7327caf 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -161,6 +161,11 @@ public class AudioMix { return mDeviceAddress; } + /** @hide */ + public boolean isAffectingUsage(int usage) { + return mRule.isAffectingUsage(usage); + } + /** @hide */ @Override public boolean equals(Object o) { diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index 866b574f61415..749a45e3d7bd3 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -135,6 +135,17 @@ public class AudioMixingRule { } } + boolean isAffectingUsage(int usage) { + for (AudioMixMatchCriterion criterion : mCriteria) { + if ((criterion.mRule & RULE_MATCH_ATTRIBUTE_USAGE) != 0 + && criterion.mAttr != null + && criterion.mAttr.getUsage() == usage) { + return true; + } + } + return false; + } + private static boolean areCriteriaEquivalent(ArrayList cr1, ArrayList cr2) { if (cr1 == null || cr2 == null) return false; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 3b5cad660d2cb..94a64eb55052e 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -144,6 +144,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -5683,7 +5684,9 @@ public class AudioService extends IAudioService.Stub } // ignore condition on device being actually used for music when in communication // because music routing is altered in this case. - if (((device == musicDevice) || isInCommunication()) && (device == devices)) { + // also checks whether media routing if affected by a dynamic policy + if (((device == musicDevice) || isInCommunication()) && (device == devices) + && !hasMediaDynamicPolicy()) { mAudioHandler.removeMessages(MSG_BROADCAST_AUDIO_BECOMING_NOISY); sendMsg(mAudioHandler, MSG_BROADCAST_AUDIO_BECOMING_NOISY, @@ -5709,6 +5712,24 @@ public class AudioService extends IAudioService.Stub return delay; } + /** + * @return true if there is currently a registered dynamic mixing policy that affects media + */ + private boolean hasMediaDynamicPolicy() { + synchronized (mAudioPolicies) { + if (mAudioPolicies.isEmpty()) { + return false; + } + final Collection appColl = mAudioPolicies.values(); + for (AudioPolicyProxy app : appColl) { + if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA)) { + return true; + } + } + return false; + } + } + private void updateAudioRoutes(int device, int state) { int connType = 0; @@ -7407,6 +7428,15 @@ public class AudioService extends IAudioService.Stub Binder.restoreCallingIdentity(identity); } + boolean hasMixAffectingUsage(int usage) { + for (AudioMix mix : mMixes) { + if (mix.isAffectingUsage(usage)) { + return true; + } + } + return false; + } + void addMixes(@NonNull ArrayList mixes) { // TODO optimize to not have to unregister the mixes already in place synchronized (mMixes) {