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

Commit 8d1b94af authored by Ytai Ben-tsvi's avatar Ytai Ben-tsvi Committed by Android (Google) Code Review
Browse files

Merge "Avoid risk of deadlock between APM and sound trigger"

parents 0c352748 406619f4
Loading
Loading
Loading
Loading
+68 −40
Original line number Diff line number Diff line
@@ -248,6 +248,13 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
        @Override
        public int loadModel(@NonNull SoundModel model) {
            Log.d(TAG, String.format("loadModel(model=%s)", model));

            // We must do this outside the lock, to avoid possible deadlocks with the remote process
            // that provides the audio sessions, which may also be calling into us.
            SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession =
                    mAudioSessionProvider.acquireSession();

            try {
                synchronized (SoundTriggerModule.this) {
                    checkValid();
                    if (mNumLoadedModels == mProperties.maxSoundModels) {
@@ -255,15 +262,28 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
                                "Maximum number of models loaded.");
                    }
                    Model loadedModel = new Model();
                int result = loadedModel.load(model);
                    int result = loadedModel.load(model, audioSession);
                    ++mNumLoadedModels;
                    return result;
                }
            } catch (Exception e) {
                // We must do this outside the lock, to avoid possible deadlocks with the remote
                // process that provides the audio sessions, which may also be calling into us.
                mAudioSessionProvider.releaseSession(audioSession.mSessionHandle);
                throw e;
            }
        }

        @Override
        public int loadPhraseModel(@NonNull PhraseSoundModel model) {
            Log.d(TAG, String.format("loadPhraseModel(model=%s)", model));

            // We must do this outside the lock, to avoid possible deadlocks with the remote process
            // that provides the audio sessions, which may also be calling into us.
            SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession =
                    mAudioSessionProvider.acquireSession();

            try {
                synchronized (SoundTriggerModule.this) {
                    checkValid();
                    if (mNumLoadedModels == mProperties.maxSoundModels) {
@@ -271,21 +291,34 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
                                "Maximum number of models loaded.");
                    }
                    Model loadedModel = new Model();
                int result = loadedModel.load(model);
                    int result = loadedModel.load(model, audioSession);
                    ++mNumLoadedModels;
                    Log.d(TAG, String.format("loadPhraseModel()->%d", result));
                    return result;
                }
            } catch (Exception e) {
                // We must do this outside the lock, to avoid possible deadlocks with the remote
                // process that provides the audio sessions, which may also be calling into us.
                mAudioSessionProvider.releaseSession(audioSession.mSessionHandle);
                throw e;
            }
        }

        @Override
        public void unloadModel(int modelHandle) {
            Log.d(TAG, String.format("unloadModel(handle=%d)", modelHandle));

            int sessionId;

            synchronized (SoundTriggerModule.this) {
                checkValid();
                mLoadedModels.get(modelHandle).unload();
                sessionId = mLoadedModels.get(modelHandle).unload();
                --mNumLoadedModels;
            }

            // We must do this outside the lock, to avoid possible deadlocks with the remote process
            // that provides the audio sessions, which may also be calling into us.
            mAudioSessionProvider.releaseSession(sessionId);
        }

        @Override
@@ -413,45 +446,40 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
                SoundTriggerModule.this.notifyAll();
            }

            private int load(@NonNull SoundModel model) {
            private int load(@NonNull SoundModel model,
                    SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                mModelType = model.type;
                mSession = audioSession;
                ISoundTriggerHw.SoundModel hidlModel = ConversionUtil.aidl2hidlSoundModel(model);

                mSession = mAudioSessionProvider.acquireSession();
                try {
                mHandle = mHalService.loadSoundModel(hidlModel, this, 0);
                } catch (Exception e) {
                    mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
                    throw e;
                }

                setState(ModelState.LOADED);
                mLoadedModels.put(mHandle, this);
                return mHandle;
            }

            private int load(@NonNull PhraseSoundModel model) {
            private int load(@NonNull PhraseSoundModel model,
                    SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                mModelType = model.common.type;
                mSession = audioSession;
                ISoundTriggerHw.PhraseSoundModel hidlModel =
                        ConversionUtil.aidl2hidlPhraseSoundModel(model);

                mSession = mAudioSessionProvider.acquireSession();
                try {
                mHandle = mHalService.loadPhraseSoundModel(hidlModel, this, 0);
                } catch (Exception e) {
                    mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
                    throw e;
                }

                setState(ModelState.LOADED);
                mLoadedModels.put(mHandle, this);
                return mHandle;
            }

            private void unload() {
                mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
            /**
             * Unloads the model.
             * @return The audio session handle.
             */
            private int unload() {
                mHalService.unloadSoundModel(mHandle);
                mLoadedModels.remove(mHandle);
                return mSession.mSessionHandle;
            }

            private void startRecognition(@NonNull RecognitionConfig config) {