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

Commit 21270b67 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy service: fix spatializer locking scheme

The audio policy service should never call Spatializer controller
methods with its mutex held. This rule was only partly repected.
This CL fixes the remaining call sites.

Bug: 237833275
Test: repro steps in the bug.
Change-Id: I2a1828d9e4cd3e16a68c727ae84329c92666c6ab
parent 740ed10d
Loading
Loading
Loading
Loading
+12 −17
Original line number Diff line number Diff line
@@ -516,8 +516,6 @@ void AudioPolicyService::onCheckSpatializer_l()

void AudioPolicyService::doOnCheckSpatializer()
{
    Mutex::Autolock _l(mLock);

    ALOGI("%s mSpatializer %p level %d", __func__, mSpatializer.get(), (int)mSpatializer->getLevel());

    if (mSpatializer != nullptr) {
@@ -527,6 +525,8 @@ void AudioPolicyService::doOnCheckSpatializer()
            audio_io_handle_t newOutput;
            const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
            audio_config_base_t config = mSpatializer->getAudioInConfig();

            Mutex::Autolock _l(mLock);
            status_t status =
                    mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);
            ALOGV("%s currentOutput %d newOutput %d channel_mask %#x",
@@ -538,21 +538,19 @@ void AudioPolicyService::doOnCheckSpatializer()
            mLock.unlock();
            // It is OK to call detachOutput() is none is already attached.
            mSpatializer->detachOutput();
            if (status != NO_ERROR || newOutput == AUDIO_IO_HANDLE_NONE) {
                mLock.lock();
                return;
            }
            if (status == NO_ERROR && newOutput != AUDIO_IO_HANDLE_NONE) {
                status = mSpatializer->attachOutput(newOutput, numActiveTracks);
            }
            mLock.lock();
            if (status != NO_ERROR) {
                mAudioPolicyManager->releaseSpatializerOutput(newOutput);
            }
        } else if (mSpatializer->getLevel() == media::SpatializationLevel::NONE
                               && mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
            mLock.unlock();
            audio_io_handle_t output = mSpatializer->detachOutput();
            mLock.lock();

            if (output != AUDIO_IO_HANDLE_NONE) {
                Mutex::Autolock _l(mLock);
                mAudioPolicyManager->releaseSpatializerOutput(output);
            }
        }
@@ -581,19 +579,16 @@ void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {

void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
{
    sp<Spatializer> spatializer;
    size_t activeClients;
    {
        Mutex::Autolock _l(mLock);
    if (mSpatializer == nullptr) {
        return;
    }
        spatializer = mSpatializer;
        activeClients = countActiveClientsOnOutput_l(mSpatializer->getOutput());
    }
    if (spatializer != nullptr) {
        spatializer->updateActiveTracks(activeClients);
    audio_io_handle_t output = mSpatializer->getOutput();
    size_t activeClients;
    {
        Mutex::Autolock _l(mLock);
        activeClients = countActiveClientsOnOutput_l(output);
    }
    mSpatializer->updateActiveTracks(activeClients);
}

status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
+1 −0
Original line number Diff line number Diff line
@@ -1060,6 +1060,7 @@ private:

    CaptureStateNotifier mCaptureStateNotifier;

    // created in onFirstRef() and never cleared: does not need to be guarded by mLock
    sp<Spatializer> mSpatializer;

    void *mLibraryHandle = nullptr;