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

Commit b16666a2 authored by Atneya Nair's avatar Atneya Nair
Browse files

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
parent 44a866a5
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2855,7 +2855,9 @@ status_t AudioTrack::restoreTrack_l(const char *from)

    if (isOffloadedOrDirect_l() || mDoNotReconnect) {
        // FIXME re-creation of offloaded and direct tracks is not yet implemented;
        // reconsider enabling for linear PCM encodings when position can be preserved.
        // Disabled since (1) timestamp correction is not implemented for non-PCM and
        // (2) We pre-empt existing direct tracks on resource constraint, so these tracks
        // shouldn't reconnect.
        result = DEAD_OBJECT;
        return result;
    }
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ cc_library_shared {
        "framework-permission-aidl-cpp",
        "libaudioclient_aidl_conversion",
        "audioclient-types-aidl-cpp",
        // Flag support
        "com.android.media.audioserver-aconfig-cc"
    ],

    header_libs: [
+22 −2
Original line number Diff line number Diff line
@@ -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>
@@ -1508,12 +1509,31 @@ status_t AudioPolicyManager::openDirectOutput(audio_stream_type_t stream,
        }
    }

    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.