summaryrefslogtreecommitdiffstats
path: root/services/soundtrigger
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-07-27 18:39:40 -0700
committerEric Laurent <elaurent@google.com>2014-08-05 12:10:27 -0700
commitdf3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871 (patch)
treee54724362f700e3e72fc72604a3b5f568d8cee7b /services/soundtrigger
parentd0fded31e473e909c018f534d3019fb5168bdcd6 (diff)
downloadframeworks_av-df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871.zip
frameworks_av-df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871.tar.gz
frameworks_av-df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871.tar.bz2
Add sound trigger control by audio policy
Audio policy: - Added active capture indication to sound trigger service: recognition stops if concurrent capture is not supported. - Added generation of reserved I/O handle and session ID for utterance capture. Sound trigger service - Added sound model update callback handling. - Added service state callback - Simplified callback shared memory allocation. Bug: 12378680. Change-Id: Ib0292c2733e6df90fdae480633dd9953d0016ef1
Diffstat (limited to 'services/soundtrigger')
-rw-r--r--services/soundtrigger/Android.mk3
-rw-r--r--services/soundtrigger/SoundTriggerHwService.cpp460
-rw-r--r--services/soundtrigger/SoundTriggerHwService.h71
3 files changed, 385 insertions, 149 deletions
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index 51eb845..572ae56 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -31,7 +31,8 @@ LOCAL_SHARED_LIBRARIES:= \
libbinder \
libcutils \
libhardware \
- libsoundtrigger
+ libsoundtrigger \
+ libmedia
LOCAL_STATIC_LIBRARIES := \
libserviceutility
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 3654136..2502e0d 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -25,12 +25,13 @@
#include <system/sound_trigger.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>
+#include <hardware/hardware.h>
+#include <media/AudioSystem.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
-#include <hardware/hardware.h>
#include <hardware/sound_trigger.h>
#include <ServiceUtilities.h>
#include "SoundTriggerHwService.h"
@@ -45,7 +46,9 @@ namespace android {
SoundTriggerHwService::SoundTriggerHwService()
: BnSoundTriggerHwService(),
- mNextUniqueId(1)
+ mNextUniqueId(1),
+ mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
+ mCaptureState(false)
{
}
@@ -143,15 +146,31 @@ status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handl
client->asBinder()->linkToDeath(module);
moduleInterface = module;
+ module->setCaptureState_l(mCaptureState);
+
return NO_ERROR;
}
-void SoundTriggerHwService::detachModule(sp<Module> module) {
+status_t SoundTriggerHwService::setCaptureState(bool active)
+{
+ ALOGV("setCaptureState %d", active);
+ AutoMutex lock(mServiceLock);
+ mCaptureState = active;
+ for (size_t i = 0; i < mModules.size(); i++) {
+ mModules.valueAt(i)->setCaptureState_l(active);
+ }
+ return NO_ERROR;
+}
+
+
+void SoundTriggerHwService::detachModule(sp<Module> module)
+{
ALOGV("detachModule");
AutoMutex lock(mServiceLock);
module->clearClient();
}
+
static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 60000;
@@ -200,18 +219,175 @@ void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition
if (module == NULL) {
return;
}
- module->sendRecognitionEvent(event);
+ sp<SoundTriggerHwService> service = module->service().promote();
+ if (service == 0) {
+ return;
+ }
+
+ service->sendRecognitionEvent(event, module);
+}
+
+sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
+ struct sound_trigger_recognition_event *event)
+{
+ sp<IMemory> eventMemory;
+
+ //sanitize event
+ switch (event->type) {
+ case SOUND_MODEL_TYPE_KEYPHRASE:
+ ALOGW_IF(event->data_size != 0 && event->data_offset !=
+ sizeof(struct sound_trigger_phrase_recognition_event),
+ "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
+ event->data_offset);
+ event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
+ break;
+ case SOUND_MODEL_TYPE_UNKNOWN:
+ ALOGW_IF(event->data_size != 0 && event->data_offset !=
+ sizeof(struct sound_trigger_recognition_event),
+ "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
+ event->data_offset);
+ event->data_offset = sizeof(struct sound_trigger_recognition_event);
+ break;
+ default:
+ return eventMemory;
+ }
+
+ size_t size = event->data_offset + event->data_size;
+ eventMemory = mMemoryDealer->allocate(size);
+ if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+ eventMemory.clear();
+ return eventMemory;
+ }
+ memcpy(eventMemory->pointer(), event, size);
+
+ return eventMemory;
+}
+
+void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
+ Module *module)
+ {
+ AutoMutex lock(mServiceLock);
+ if (module == NULL) {
+ return;
+ }
+ sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
+ if (eventMemory == 0) {
+ return;
+ }
+ sp<Module> strongModule;
+ for (size_t i = 0; i < mModules.size(); i++) {
+ if (mModules.valueAt(i).get() == module) {
+ strongModule = mModules.valueAt(i);
+ break;
+ }
+ }
+ if (strongModule == 0) {
+ return;
+ }
+
+ sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
+ eventMemory, strongModule));
}
+// static
+void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
+ void *cookie)
+{
+ Module *module = (Module *)cookie;
+ if (module == NULL) {
+ return;
+ }
+ sp<SoundTriggerHwService> service = module->service().promote();
+ if (service == 0) {
+ return;
+ }
+
+ service->sendSoundModelEvent(event, module);
+}
-void SoundTriggerHwService::sendRecognitionEvent(const sp<RecognitionEvent>& event)
+sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
{
- mCallbackThread->sendRecognitionEvent(event);
+ sp<IMemory> eventMemory;
+
+ size_t size = event->data_offset + event->data_size;
+ eventMemory = mMemoryDealer->allocate(size);
+ if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+ eventMemory.clear();
+ return eventMemory;
+ }
+ memcpy(eventMemory->pointer(), event, size);
+
+ return eventMemory;
}
-void SoundTriggerHwService::onRecognitionEvent(const sp<RecognitionEvent>& event)
+void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
+ Module *module)
{
- ALOGV("onRecognitionEvent");
+ AutoMutex lock(mServiceLock);
+ sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
+ if (eventMemory == 0) {
+ return;
+ }
+ sp<Module> strongModule;
+ for (size_t i = 0; i < mModules.size(); i++) {
+ if (mModules.valueAt(i).get() == module) {
+ strongModule = mModules.valueAt(i);
+ break;
+ }
+ }
+ if (strongModule == 0) {
+ return;
+ }
+ sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
+ eventMemory, strongModule));
+}
+
+
+sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
+{
+ sp<IMemory> eventMemory;
+
+ size_t size = sizeof(sound_trigger_service_state_t);
+ eventMemory = mMemoryDealer->allocate(size);
+ if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+ eventMemory.clear();
+ return eventMemory;
+ }
+ *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
+ return eventMemory;
+}
+
+// call with mServiceLock held
+void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
+ Module *module)
+{
+ sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
+ if (eventMemory == 0) {
+ return;
+ }
+ sp<Module> strongModule;
+ for (size_t i = 0; i < mModules.size(); i++) {
+ if (mModules.valueAt(i).get() == module) {
+ strongModule = mModules.valueAt(i);
+ break;
+ }
+ }
+ if (strongModule == 0) {
+ return;
+ }
+ sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
+ eventMemory, strongModule));
+}
+
+// call with mServiceLock held
+void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
+{
+ mCallbackThread->sendCallbackEvent(event);
+}
+
+void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
+{
+ ALOGV("onCallbackEvent");
sp<Module> module;
{
AutoMutex lock(mServiceLock);
@@ -220,15 +396,12 @@ void SoundTriggerHwService::onRecognitionEvent(const sp<RecognitionEvent>& event
return;
}
}
- module->onRecognitionEvent(event->mEventMemory);
-}
-
-// static
-void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event __unused,
- void *cookie)
-{
- Module *module = (Module *)cookie;
-
+ module->onCallbackEvent(event);
+ {
+ AutoMutex lock(mServiceLock);
+ // clear now to execute with mServiceLock locked
+ event->mMemory.clear();
+ }
}
#undef LOG_TAG
@@ -241,7 +414,10 @@ SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwSer
SoundTriggerHwService::CallbackThread::~CallbackThread()
{
- mEventQueue.clear();
+ while (!mEventQueue.isEmpty()) {
+ mEventQueue[0]->mMemory.clear();
+ mEventQueue.removeAt(0);
+ }
}
void SoundTriggerHwService::CallbackThread::onFirstRef()
@@ -252,7 +428,7 @@ void SoundTriggerHwService::CallbackThread::onFirstRef()
bool SoundTriggerHwService::CallbackThread::threadLoop()
{
while (!exitPending()) {
- sp<RecognitionEvent> event;
+ sp<CallbackEvent> event;
sp<SoundTriggerHwService> service;
{
Mutex::Autolock _l(mCallbackLock);
@@ -269,7 +445,7 @@ bool SoundTriggerHwService::CallbackThread::threadLoop()
service = mService.promote();
}
if (service != 0) {
- service->onRecognitionEvent(event);
+ service->onCallbackEvent(event);
}
}
return false;
@@ -282,25 +458,25 @@ void SoundTriggerHwService::CallbackThread::exit()
mCallbackCond.broadcast();
}
-void SoundTriggerHwService::CallbackThread::sendRecognitionEvent(
- const sp<SoundTriggerHwService::RecognitionEvent>& event)
+void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
+ const sp<SoundTriggerHwService::CallbackEvent>& event)
{
AutoMutex lock(mCallbackLock);
mEventQueue.add(event);
mCallbackCond.signal();
}
-SoundTriggerHwService::RecognitionEvent::RecognitionEvent(
- sp<IMemory> eventMemory,
- wp<Module> module)
- : mEventMemory(eventMemory), mModule(module)
+SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory,
+ wp<Module> module)
+ : mType(type), mMemory(memory), mModule(module)
{
}
-SoundTriggerHwService::RecognitionEvent::~RecognitionEvent()
+SoundTriggerHwService::CallbackEvent::~CallbackEvent()
{
}
+
#undef LOG_TAG
#define LOG_TAG "SoundTriggerHwService::Module"
@@ -309,7 +485,7 @@ SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
sound_trigger_module_descriptor descriptor,
const sp<ISoundTriggerClient>& client)
: mService(service), mHwDevice(hwDevice), mDescriptor(descriptor),
- mClient(client)
+ mClient(client), mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
{
}
@@ -328,7 +504,6 @@ void SoundTriggerHwService::Module::detach() {
ALOGV("detach() unloading model %d", model->mHandle);
if (model->mState == Model::STATE_ACTIVE) {
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
- model->deallocateMemory();
}
mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
}
@@ -365,10 +540,21 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM
SoundTriggerHwService::soundModelCallback,
this,
handle);
- if (status == NO_ERROR) {
- mModels.replaceValueFor(*handle, new Model(*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;
}
+ sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
+ mModels.replaceValueFor(*handle, model);
+
return status;
}
@@ -388,8 +574,8 @@ status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t ha
mModels.removeItem(handle);
if (model->mState == Model::STATE_ACTIVE) {
mHwDevice->stop_recognition(mHwDevice, model->mHandle);
- model->deallocateMemory();
}
+ AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
return mHwDevice->unload_sound_model(mHwDevice, handle);
}
@@ -407,6 +593,9 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha
}
AutoMutex lock(mLock);
+ if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
+ return INVALID_OPERATION;
+ }
sp<Model> model = getModel(handle);
if (model == 0) {
return BAD_VALUE;
@@ -419,17 +608,23 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha
if (model->mState == Model::STATE_ACTIVE) {
return INVALID_OPERATION;
}
- model->mState = Model::STATE_ACTIVE;
struct sound_trigger_recognition_config *config =
(struct sound_trigger_recognition_config *)dataMemory->pointer();
//TODO: get capture handle and device from audio policy service
- config->capture_handle = AUDIO_IO_HANDLE_NONE;
- config->capture_device = AUDIO_DEVICE_NONE;
- return mHwDevice->start_recognition(mHwDevice, handle, config,
+ config->capture_handle = model->mCaptureIOHandle;
+ config->capture_device = model->mCaptureDevice;
+ status_t status = mHwDevice->start_recognition(mHwDevice, handle, config,
SoundTriggerHwService::recognitionCallback,
this);
+
+ if (status == NO_ERROR) {
+ model->mState = Model::STATE_ACTIVE;
+ model->mConfig = *config;
+ }
+
+ return status;
}
status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
@@ -449,93 +644,62 @@ status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t han
return INVALID_OPERATION;
}
mHwDevice->stop_recognition(mHwDevice, handle);
- model->deallocateMemory();
model->mState = Model::STATE_IDLE;
return NO_ERROR;
}
-void SoundTriggerHwService::Module::sendRecognitionEvent(
- struct sound_trigger_recognition_event *event)
-{
- sp<SoundTriggerHwService> service;
- sp<IMemory> eventMemory;
- ALOGV("sendRecognitionEvent for model %d", event->model);
- {
- AutoMutex lock(mLock);
- sp<Model> model = getModel(event->model);
- if (model == 0) {
- return;
- }
- if (model->mState != Model::STATE_ACTIVE) {
- ALOGV("sendRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
- return;
- }
- if (mClient == 0) {
- return;
- }
- service = mService.promote();
- if (service == 0) {
- return;
- }
-
- //sanitize event
- switch (event->type) {
- case SOUND_MODEL_TYPE_KEYPHRASE:
- ALOGW_IF(event->data_offset !=
- sizeof(struct sound_trigger_phrase_recognition_event),
- "sendRecognitionEvent(): invalid data offset %u for keyphrase event type",
- event->data_offset);
- event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
- break;
- case SOUND_MODEL_TYPE_UNKNOWN:
- ALOGW_IF(event->data_offset !=
- sizeof(struct sound_trigger_recognition_event),
- "sendRecognitionEvent(): invalid data offset %u for unknown event type",
- event->data_offset);
- event->data_offset = sizeof(struct sound_trigger_recognition_event);
- break;
- default:
- return;
- }
-
- size_t size = event->data_offset + event->data_size;
- eventMemory = model->allocateMemory(size);
- if (eventMemory == 0 || eventMemory->pointer() == NULL) {
- return;
- }
- memcpy(eventMemory->pointer(), event, size);
- }
- service->sendRecognitionEvent(new RecognitionEvent(eventMemory, this));
-}
-void SoundTriggerHwService::Module::onRecognitionEvent(sp<IMemory> eventMemory)
+void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
{
- ALOGV("Module::onRecognitionEvent");
+ ALOGV("onCallbackEvent type %d", event->mType);
AutoMutex lock(mLock);
+ sp<IMemory> eventMemory = event->mMemory;
if (eventMemory == 0 || eventMemory->pointer() == NULL) {
return;
}
- struct sound_trigger_recognition_event *event =
- (struct sound_trigger_recognition_event *)eventMemory->pointer();
-
- sp<Model> model = getModel(event->model);
- if (model == 0) {
- ALOGI("%s model == 0", __func__);
- return;
- }
- if (model->mState != Model::STATE_ACTIVE) {
- ALOGV("onRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
- return;
- }
if (mClient == 0) {
ALOGI("%s mClient == 0", __func__);
return;
}
- mClient->onRecognitionEvent(eventMemory);
- model->mState = Model::STATE_IDLE;
- model->deallocateMemory();
+
+ switch (event->mType) {
+ case CallbackEvent::TYPE_RECOGNITION: {
+ struct sound_trigger_recognition_event *recognitionEvent =
+ (struct sound_trigger_recognition_event *)eventMemory->pointer();
+
+ sp<Model> model = getModel(recognitionEvent->model);
+ if (model == 0) {
+ ALOGW("%s model == 0", __func__);
+ return;
+ }
+ if (model->mState != Model::STATE_ACTIVE) {
+ ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
+ return;
+ }
+
+ recognitionEvent->capture_session = model->mCaptureSession;
+ mClient->onRecognitionEvent(eventMemory);
+ model->mState = Model::STATE_IDLE;
+ } break;
+ case CallbackEvent::TYPE_SOUNDMODEL: {
+ struct sound_trigger_model_event *soundmodelEvent =
+ (struct sound_trigger_model_event *)eventMemory->pointer();
+
+ sp<Model> model = getModel(soundmodelEvent->model);
+ if (model == 0) {
+ ALOGW("%s model == 0", __func__);
+ return;
+ }
+ mClient->onSoundModelEvent(eventMemory);
+ } break;
+ case CallbackEvent::TYPE_SERVICE_STATE: {
+ mClient->onServiceStateChange(eventMemory);
+ } break;
+ default:
+ LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
+ }
}
sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
@@ -555,30 +719,80 @@ void SoundTriggerHwService::Module::binderDied(
detach();
}
-
-SoundTriggerHwService::Model::Model(sound_model_handle_t handle) :
- mHandle(handle), mState(STATE_IDLE), mInputHandle(AUDIO_IO_HANDLE_NONE),
- mCaptureSession(AUDIO_SESSION_ALLOCATE),
- mMemoryDealer(new MemoryDealer(sizeof(struct sound_trigger_recognition_event),
- "SoundTriggerHwService::Event"))
+// Called with mServiceLock held
+void SoundTriggerHwService::Module::setCaptureState_l(bool active)
{
+ ALOGV("Module::setCaptureState_l %d", active);
+ sp<SoundTriggerHwService> service;
+ sound_trigger_service_state_t state;
-}
+ Vector< sp<IMemory> > events;
+ {
+ AutoMutex lock(mLock);
+ state = (active && !mDescriptor.properties.concurrent_capture) ?
+ SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
+ if (state == mServiceState) {
+ return;
+ }
-sp<IMemory> SoundTriggerHwService::Model::allocateMemory(size_t size)
-{
- sp<IMemory> memory;
- if (mMemoryDealer->getMemoryHeap()->getSize() < size) {
- mMemoryDealer = new MemoryDealer(size, "SoundTriggerHwService::Event");
+ mServiceState = state;
+
+ service = mService.promote();
+ if (service == 0) {
+ return;
+ }
+
+ if (state == SOUND_TRIGGER_STATE_ENABLED) {
+ goto exit;
+ }
+
+ for (size_t i = 0; i < mModels.size(); i++) {
+ sp<Model> model = mModels.valueAt(i);
+ if (model->mState == Model::STATE_ACTIVE) {
+ mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+ // keep model in ACTIVE state so that event is processed by onCallbackEvent()
+ struct sound_trigger_phrase_recognition_event phraseEvent;
+ switch (model->mType) {
+ case SOUND_MODEL_TYPE_KEYPHRASE:
+ phraseEvent.num_phrases = model->mConfig.num_phrases;
+ for (size_t i = 0; i < phraseEvent.num_phrases; i++) {
+ phraseEvent.phrase_extras[i] = model->mConfig.phrases[i];
+ }
+ break;
+ case SOUND_MODEL_TYPE_UNKNOWN:
+ default:
+ break;
+ }
+ phraseEvent.common.status = RECOGNITION_STATUS_ABORT;
+ phraseEvent.common.type = model->mType;
+ phraseEvent.common.model = model->mHandle;
+ phraseEvent.common.data_size = 0;
+ sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&phraseEvent.common);
+ if (eventMemory != 0) {
+ events.add(eventMemory);
+ }
+ }
+ }
}
- memory = mMemoryDealer->allocate(size);
- return memory;
+
+ for (size_t i = 0; i < events.size(); i++) {
+ service->sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, events[i],
+ this));
+ }
+
+exit:
+ service->sendServiceStateEvent_l(state, this);
}
-void SoundTriggerHwService::Model::deallocateMemory()
+
+SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
+ audio_io_handle_t ioHandle, audio_devices_t device,
+ sound_trigger_sound_model_type_t type) :
+ mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
+ mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type)
{
- mMemoryDealer->deallocate(0);
+
}
status_t SoundTriggerHwService::Module::dump(int fd __unused,
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index 377f2a1..d05dacd 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -53,6 +53,8 @@ public:
const sp<ISoundTriggerClient>& client,
sp<ISoundTrigger>& module);
+ virtual status_t setCaptureState(bool active);
+
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
@@ -66,17 +68,33 @@ public:
STATE_ACTIVE
};
- Model(sound_model_handle_t handle);
+ Model(sound_model_handle_t handle, audio_session_t session, audio_io_handle_t ioHandle,
+ audio_devices_t device, sound_trigger_sound_model_type_t type);
~Model() {}
- sp<IMemory> allocateMemory(size_t size);
- void deallocateMemory();
-
sound_model_handle_t mHandle;
int mState;
- audio_io_handle_t mInputHandle;
audio_session_t mCaptureSession;
- sp<MemoryDealer> mMemoryDealer;
+ audio_io_handle_t mCaptureIOHandle;
+ audio_devices_t mCaptureDevice;
+ sound_trigger_sound_model_type_t mType;
+ struct sound_trigger_recognition_config mConfig;
+ };
+
+ class CallbackEvent : public RefBase {
+ public:
+ typedef enum {
+ TYPE_RECOGNITION,
+ TYPE_SOUNDMODEL,
+ TYPE_SERVICE_STATE,
+ } event_type;
+ CallbackEvent(event_type type, sp<IMemory> memory, wp<Module> module);
+
+ virtual ~CallbackEvent();
+
+ event_type mType;
+ sp<IMemory> mMemory;
+ wp<Module> mModule;
};
class Module : public virtual RefBase,
@@ -109,36 +127,29 @@ public:
struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
void setClient(sp<ISoundTriggerClient> client) { mClient = client; }
void clearClient() { mClient.clear(); }
- sp<ISoundTriggerClient> client() { return mClient; }
+ sp<ISoundTriggerClient> client() const { return mClient; }
+ wp<SoundTriggerHwService> service() const { return mService; }
- void sendRecognitionEvent(struct sound_trigger_recognition_event *event);
- void onRecognitionEvent(sp<IMemory> eventMemory);
+ void onCallbackEvent(const sp<CallbackEvent>& event);
sp<Model> getModel(sound_model_handle_t handle);
+ void setCaptureState_l(bool active);
+
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
+
Mutex mLock;
wp<SoundTriggerHwService> mService;
struct sound_trigger_hw_device* mHwDevice;
struct sound_trigger_module_descriptor mDescriptor;
sp<ISoundTriggerClient> mClient;
DefaultKeyedVector< sound_model_handle_t, sp<Model> > mModels;
+ sound_trigger_service_state_t mServiceState;
}; // class Module
- class RecognitionEvent : public RefBase {
- public:
-
- RecognitionEvent(sp<IMemory> eventMemory, wp<Module> module);
-
- virtual ~RecognitionEvent();
-
- sp<IMemory> mEventMemory;
- wp<Module> mModule;
- };
-
class CallbackThread : public Thread {
public:
@@ -153,22 +164,30 @@ public:
virtual void onFirstRef();
void exit();
- void sendRecognitionEvent(const sp<RecognitionEvent>& event);
+ void sendCallbackEvent(const sp<CallbackEvent>& event);
private:
wp<SoundTriggerHwService> mService;
Condition mCallbackCond;
Mutex mCallbackLock;
- Vector< sp<RecognitionEvent> > mEventQueue;
+ Vector< sp<CallbackEvent> > mEventQueue;
};
- void detachModule(sp<Module> module);
+ void detachModule(sp<Module> module);
static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
- void sendRecognitionEvent(const sp<RecognitionEvent>& event);
- void onRecognitionEvent(const sp<RecognitionEvent>& event);
+ sp<IMemory> prepareRecognitionEvent_l(struct sound_trigger_recognition_event *event);
+ void sendRecognitionEvent(struct sound_trigger_recognition_event *event, Module *module);
static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
+ sp<IMemory> prepareSoundModelEvent_l(struct sound_trigger_model_event *event);
+ void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);
+
+ sp<IMemory> prepareServiceStateEvent_l(sound_trigger_service_state_t state);
+ void sendServiceStateEvent_l(sound_trigger_service_state_t state, Module *module);
+
+ void sendCallbackEvent_l(const sp<CallbackEvent>& event);
+ void onCallbackEvent(const sp<CallbackEvent>& event);
private:
@@ -178,6 +197,8 @@ private:
volatile int32_t mNextUniqueId;
DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> > mModules;
sp<CallbackThread> mCallbackThread;
+ sp<MemoryDealer> mMemoryDealer;
+ bool mCaptureState;
};
} // namespace android