Merge "Soundtrigger service: fix cross deadlock with audio policy service" into lmp-dev
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 596b23d..dda1a7b 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -497,6 +497,8 @@
if (!captureHotwordAllowed()) {
return;
}
+ Vector<audio_session_t> releasedSessions;
+
{
AutoMutex lock(mLock);
for (size_t i = 0; i < mModels.size(); i++) {
@@ -506,9 +508,16 @@
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
}
mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
+ releasedSessions.add(model->mCaptureSession);
}
mModels.clear();
}
+
+ for (size_t i = 0; i < releasedSessions.size(); i++) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
+ }
+
if (mClient != 0) {
mClient->asBinder()->unlinkToDeath(this);
}
@@ -550,27 +559,35 @@
return BAD_VALUE;
}
- AutoMutex lock(mLock);
- status_t status = mHwDevice->load_sound_model(mHwDevice,
- 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);
+ // do not call AudioSystem methods with mLock held
+ status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
if (status != NO_ERROR) {
return status;
}
- sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
- mModels.replaceValueFor(*handle, model);
+ {
+ AutoMutex lock(mLock);
+ status_t status = mHwDevice->load_sound_model(mHwDevice,
+ sound_model,
+ SoundTriggerHwService::soundModelCallback,
+ this,
+ handle);
+ if (status != NO_ERROR) {
+ goto exit;
+ }
+ sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
+ mModels.replaceValueFor(*handle, model);
+ }
+
+exit:
+ if (status != NO_ERROR) {
+ // do not call AudioSystem methods with mLock held
+ AudioSystem::releaseSoundTriggerSession(session);
+ }
return status;
}
@@ -580,19 +597,25 @@
if (!captureHotwordAllowed()) {
return PERMISSION_DENIED;
}
+ status_t status;
+ audio_session_t session;
- AutoMutex lock(mLock);
- ssize_t index = mModels.indexOfKey(handle);
- if (index < 0) {
- return BAD_VALUE;
+ {
+ AutoMutex lock(mLock);
+ ssize_t index = mModels.indexOfKey(handle);
+ if (index < 0) {
+ return BAD_VALUE;
+ }
+ sp<Model> model = mModels.valueAt(index);
+ mModels.removeItem(handle);
+ if (model->mState == Model::STATE_ACTIVE) {
+ mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+ }
+ status = mHwDevice->unload_sound_model(mHwDevice, handle);
+ session = model->mCaptureSession;
}
- sp<Model> model = mModels.valueAt(index);
- mModels.removeItem(handle);
- if (model->mState == Model::STATE_ACTIVE) {
- mHwDevice->stop_recognition(mHwDevice, model->mHandle);
- }
- AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
- return mHwDevice->unload_sound_model(mHwDevice, handle);
+ AudioSystem::releaseSoundTriggerSession(session);
+ return status;
}
status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,