Preempt direct track on resource constraint
If a direct output profile has reached its max open count, attempt to
close existing tracks on the profile to service the latest request.
Test: test_steal_exclusive
Test: atest AudioTrackOffloadTest
Test: atest ^#testMultipleAudioTrackOffloadPreemption
Bug: 294525897
Change-Id: If94405b5e92ae4c2e3ee8c97a3a941b3224940cd
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2e13178..81369e2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -42,6 +42,7 @@
#include <Serializer.h>
#include <android/media/audio/common/AudioPort.h>
#include <com_android_media_audio.h>
+#include <com_android_media_audioserver.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <media/AudioParameter.h>
@@ -1509,11 +1510,30 @@
}
if (!profile->canOpenNewIo()) {
+ if (!com::android::media::audioserver::direct_track_reprioritization()) {
+ return NAME_NOT_FOUND;
+ } else if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) != 0) {
+ // MMAP gracefully handles lack of an exclusive track resource by mixing
+ // above the audio framework. For AAudio to know that the limit is reached,
+ // return an error.
+ return NAME_NOT_FOUND;
+ } else {
+ // Close outputs on this profile, if available, to free resources for this request
+ for (int i = 0; i < mOutputs.size() && !profile->canOpenNewIo(); i++) {
+ const auto desc = mOutputs.valueAt(i);
+ if (desc->mProfile == profile) {
+ closeOutput(desc->mIoHandle);
+ }
+ }
+ }
+ }
+
+ // Unable to close streams to find free resources for this request
+ if (!profile->canOpenNewIo()) {
return NAME_NOT_FOUND;
}
- sp<SwAudioOutputDescriptor> outputDesc =
- new SwAudioOutputDescriptor(profile, mpClientInterface);
+ auto outputDesc = sp<SwAudioOutputDescriptor>::make(profile, mpClientInterface);
// An MSD patch may be using the only output stream that can service this request. Release
// all MSD patches to prioritize this request over any active output on MSD.