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

Commit 09576218 authored by Eric Laurent's avatar Eric Laurent
Browse files

Soundtrigger service: fix cross deadlock with audio policy service

Do not hold Module mutex when calling into audio policy manager to
avoid cross deadlock with audio poicy service mutex: Audio policy manager
can call into sound trigger service with its mutex held in methods like
stopInput().

Regression introduced by fix for b/64340921 commit f759b8c4

Bug: 64340921
Bug: 67310830
Test: repro steps in b/67310830

Merged-In: Ie50b2e7c55fe9828a3fd8de6b31eb4a492791583

Change-Id: Ie50b2e7c55fe9828a3fd8de6b31eb4a492791583
parent 969f2c97
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ status_t SoundTriggerSessionCollection::releaseSession(audio_session_t session)
{
    ssize_t index = indexOfKey(session);
    if (index < 0) {
        ALOGW("acquireSoundTriggerSession() session %d not registered", session);
        ALOGW("releaseSession() session %d not registered", session);
        return BAD_VALUE;
    }

+82 −64
Original line number Diff line number Diff line
@@ -528,6 +528,9 @@ SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
{
    ALOGV("Module::detach()");
    Vector<audio_session_t> releasedSessions;

    {
        AutoMutex lock(mLock);
        ssize_t index = -1;

@@ -556,9 +559,14 @@ void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
                    }
                    mHalInterface->unloadSoundModel(model->mHandle);
                }
            AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
            mHalInterface->unloadSoundModel(model->mHandle);
                releasedSessions.add(model->mCaptureSession);
            }
        }
    }

    for (size_t i = 0; i < releasedSessions.size(); i++) {
        // do not call AudioSystem methods with mLock held
        AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
    }
}

@@ -593,46 +601,52 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM
        return BAD_VALUE;
    }

    audio_session_t session;
    audio_io_handle_t ioHandle;
    audio_devices_t device;
    // do not call AudioSystem methods with mLock held
    status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
    if (status != NO_ERROR) {
        return status;
    }

    {
        AutoMutex lock(mLock);

        if (mModels.size() >= mDescriptor.properties.max_sound_models) {
            ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
                  mDescriptor.properties.max_sound_models);
        return INVALID_OPERATION;
            status = INVALID_OPERATION;
            goto exit;
        }

    status_t status = mHalInterface->loadSoundModel(sound_model,
        status = mHalInterface->loadSoundModel(sound_model,
                                                      SoundTriggerHwService::soundModelCallback,
                                                      this, handle);

        if (status != NO_ERROR) {
        return status;
    }
    audio_session_t session;
    audio_io_handle_t ioHandle;
    audio_devices_t device;

    status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
    if (status != NO_ERROR) {
        return status;
            goto exit;
        }

        sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
                                    moduleClient);
        mModels.replaceValueFor(*handle, model);

    }
exit:
    if (status != NO_ERROR) {
        // do not call AudioSystem methods with mLock held
        AudioSystem::releaseSoundTriggerSession(session);
    }
    return status;
}

status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
{
    ALOGV("unloadSoundModel() model handle %d", handle);
    AutoMutex lock(mLock);
    return unloadSoundModel_l(handle);
}
    status_t status;
    audio_session_t session;

status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
    {
        AutoMutex lock(mLock);
        if (mHalInterface == 0) {
            return NO_INIT;
        }
@@ -646,8 +660,12 @@ status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t
            mHalInterface->stopRecognition(model->mHandle);
            model->mState = Model::STATE_IDLE;
        }
    AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
    return mHalInterface->unloadSoundModel(handle);
        status = mHalInterface->unloadSoundModel(handle);
        session = model->mCaptureSession;
    }
    // do not call AudioSystem methods with mLock held
    AudioSystem::releaseSoundTriggerSession(session);
    return status;
}

status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
+0 −2
Original line number Diff line number Diff line
@@ -140,8 +140,6 @@ public:

    private:

        status_t unloadSoundModel_l(sound_model_handle_t handle);

        Mutex                                  mLock;
        wp<SoundTriggerHwService>              mService;
        sp<SoundTriggerHalInterface>           mHalInterface;