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

Commit 441b487e authored by Eric Laurent's avatar Eric Laurent Committed by Andy Hung
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.
Merged-In: I2a1828d9e4cd3e16a68c727ae84329c92666c6ab
Change-Id: I2a1828d9e4cd3e16a68c727ae84329c92666c6ab
parent b22c6b25
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;