From df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Sun, 27 Jul 2014 18:39:40 -0700 Subject: 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 --- services/soundtrigger/Android.mk | 3 +- services/soundtrigger/SoundTriggerHwService.cpp | 460 +++++++++++++++++------- services/soundtrigger/SoundTriggerHwService.h | 71 ++-- 3 files changed, 385 insertions(+), 149 deletions(-) (limited to 'services/soundtrigger') 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 #include #include +#include +#include #include #include #include #include #include -#include #include #include #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) { +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) +{ 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 service = module->service().promote(); + if (service == 0) { + return; + } + + service->sendRecognitionEvent(event, module); +} + +sp SoundTriggerHwService::prepareRecognitionEvent_l( + struct sound_trigger_recognition_event *event) +{ + sp 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 eventMemory = prepareRecognitionEvent_l(event); + if (eventMemory == 0) { + return; + } + sp 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 service = module->service().promote(); + if (service == 0) { + return; + } + + service->sendSoundModelEvent(event, module); +} -void SoundTriggerHwService::sendRecognitionEvent(const sp& event) +sp SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event) { - mCallbackThread->sendRecognitionEvent(event); + sp 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& event) +void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event, + Module *module) { - ALOGV("onRecognitionEvent"); + AutoMutex lock(mServiceLock); + sp eventMemory = prepareSoundModelEvent_l(event); + if (eventMemory == 0) { + return; + } + sp 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 SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state) +{ + sp 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 eventMemory = prepareServiceStateEvent_l(state); + if (eventMemory == 0) { + return; + } + sp 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& event) +{ + mCallbackThread->sendCallbackEvent(event); +} + +void SoundTriggerHwService::onCallbackEvent(const sp& event) +{ + ALOGV("onCallbackEvent"); sp module; { AutoMutex lock(mServiceLock); @@ -220,15 +396,12 @@ void SoundTriggerHwService::onRecognitionEvent(const sp& 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 wpmMemory.clear(); + mEventQueue.removeAt(0); + } } void SoundTriggerHwService::CallbackThread::onFirstRef() @@ -252,7 +428,7 @@ void SoundTriggerHwService::CallbackThread::onFirstRef() bool SoundTriggerHwService::CallbackThread::threadLoop() { while (!exitPending()) { - sp event; + sp event; sp 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& event) +void SoundTriggerHwService::CallbackThread::sendCallbackEvent( + const sp& event) { AutoMutex lock(mCallbackLock); mEventQueue.add(event); mCallbackCond.signal(); } -SoundTriggerHwService::RecognitionEvent::RecognitionEvent( - sp eventMemory, - wp module) - : mEventMemory(eventMemory), mModule(module) +SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp memory, + wp 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& service, sound_trigger_module_descriptor descriptor, const sp& 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& 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 = 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 = 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 service; - sp eventMemory; - ALOGV("sendRecognitionEvent for model %d", event->model); - { - AutoMutex lock(mLock); - sp 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 eventMemory) +void SoundTriggerHwService::Module::onCallbackEvent(const sp& event) { - ALOGV("Module::onRecognitionEvent"); + ALOGV("onCallbackEvent type %d", event->mType); AutoMutex lock(mLock); + sp 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 = 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 = 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 = 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::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 service; + sound_trigger_service_state_t state; -} + Vector< sp > events; + { + AutoMutex lock(mLock); + state = (active && !mDescriptor.properties.concurrent_capture) ? + SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; + if (state == mServiceState) { + return; + } -sp SoundTriggerHwService::Model::allocateMemory(size_t size) -{ - sp 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 = 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 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& client, sp& 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 allocateMemory(size_t size); - void deallocateMemory(); - sound_model_handle_t mHandle; int mState; - audio_io_handle_t mInputHandle; audio_session_t mCaptureSession; - sp 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 memory, wp module); + + virtual ~CallbackEvent(); + + event_type mType; + sp mMemory; + wp mModule; }; class Module : public virtual RefBase, @@ -109,36 +127,29 @@ public: struct sound_trigger_module_descriptor descriptor() { return mDescriptor; } void setClient(sp client) { mClient = client; } void clearClient() { mClient.clear(); } - sp client() { return mClient; } + sp client() const { return mClient; } + wp service() const { return mService; } - void sendRecognitionEvent(struct sound_trigger_recognition_event *event); - void onRecognitionEvent(sp eventMemory); + void onCallbackEvent(const sp& event); sp getModel(sound_model_handle_t handle); + void setCaptureState_l(bool active); + // IBinder::DeathRecipient implementation virtual void binderDied(const wp &who); private: + Mutex mLock; wp mService; struct sound_trigger_hw_device* mHwDevice; struct sound_trigger_module_descriptor mDescriptor; sp mClient; DefaultKeyedVector< sound_model_handle_t, sp > mModels; + sound_trigger_service_state_t mServiceState; }; // class Module - class RecognitionEvent : public RefBase { - public: - - RecognitionEvent(sp eventMemory, wp module); - - virtual ~RecognitionEvent(); - - sp mEventMemory; - wp mModule; - }; - class CallbackThread : public Thread { public: @@ -153,22 +164,30 @@ public: virtual void onFirstRef(); void exit(); - void sendRecognitionEvent(const sp& event); + void sendCallbackEvent(const sp& event); private: wp mService; Condition mCallbackCond; Mutex mCallbackLock; - Vector< sp > mEventQueue; + Vector< sp > mEventQueue; }; - void detachModule(sp module); + void detachModule(sp module); static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie); - void sendRecognitionEvent(const sp& event); - void onRecognitionEvent(const sp& event); + sp 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 prepareSoundModelEvent_l(struct sound_trigger_model_event *event); + void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module); + + sp prepareServiceStateEvent_l(sound_trigger_service_state_t state); + void sendServiceStateEvent_l(sound_trigger_service_state_t state, Module *module); + + void sendCallbackEvent_l(const sp& event); + void onCallbackEvent(const sp& event); private: @@ -178,6 +197,8 @@ private: volatile int32_t mNextUniqueId; DefaultKeyedVector< sound_trigger_module_handle_t, sp > mModules; sp mCallbackThread; + sp mMemoryDealer; + bool mCaptureState; }; } // namespace android -- cgit v1.1