Home | History | Annotate | Download | only in soundtrigger
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "SoundTriggerHwService"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <stdio.h>
     21 #include <string.h>
     22 #include <sys/types.h>
     23 #include <pthread.h>
     24 
     25 #include <system/sound_trigger.h>
     26 #include <cutils/atomic.h>
     27 #include <cutils/properties.h>
     28 #include <hardware/hardware.h>
     29 #include <media/AudioSystem.h>
     30 #include <utils/Errors.h>
     31 #include <utils/Log.h>
     32 #include <binder/IServiceManager.h>
     33 #include <binder/MemoryBase.h>
     34 #include <binder/MemoryHeapBase.h>
     35 #include <hardware/sound_trigger.h>
     36 #include <ServiceUtilities.h>
     37 #include "SoundTriggerHwService.h"
     38 
     39 namespace android {
     40 
     41 #ifdef SOUND_TRIGGER_USE_STUB_MODULE
     42 #define HW_MODULE_PREFIX "stub"
     43 #else
     44 #define HW_MODULE_PREFIX "primary"
     45 #endif
     46 
     47 SoundTriggerHwService::SoundTriggerHwService()
     48     : BnSoundTriggerHwService(),
     49       mNextUniqueId(1),
     50       mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
     51       mCaptureState(false)
     52 {
     53 }
     54 
     55 void SoundTriggerHwService::onFirstRef()
     56 {
     57     const hw_module_t *mod;
     58     int rc;
     59     sound_trigger_hw_device *dev;
     60 
     61     rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod);
     62     if (rc != 0) {
     63         ALOGE("couldn't load sound trigger module %s.%s (%s)",
     64               SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
     65         return;
     66     }
     67     rc = sound_trigger_hw_device_open(mod, &dev);
     68     if (rc != 0) {
     69         ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
     70               SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
     71         return;
     72     }
     73     if (dev->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
     74         ALOGE("wrong sound trigger hw device version %04x", dev->common.version);
     75         return;
     76     }
     77 
     78     sound_trigger_module_descriptor descriptor;
     79     rc = dev->get_properties(dev, &descriptor.properties);
     80     if (rc != 0) {
     81         ALOGE("could not read implementation properties");
     82         return;
     83     }
     84     descriptor.handle =
     85             (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
     86     ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
     87                                                  descriptor.handle);
     88 
     89     sp<ISoundTriggerClient> client;
     90     sp<Module> module = new Module(this, dev, descriptor, client);
     91     mModules.add(descriptor.handle, module);
     92     mCallbackThread = new CallbackThread(this);
     93 }
     94 
     95 SoundTriggerHwService::~SoundTriggerHwService()
     96 {
     97     if (mCallbackThread != 0) {
     98         mCallbackThread->exit();
     99     }
    100     for (size_t i = 0; i < mModules.size(); i++) {
    101         sound_trigger_hw_device_close(mModules.valueAt(i)->hwDevice());
    102     }
    103 }
    104 
    105 status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
    106                              uint32_t *numModules)
    107 {
    108     ALOGV("listModules");
    109     if (!captureHotwordAllowed()) {
    110         return PERMISSION_DENIED;
    111     }
    112 
    113     AutoMutex lock(mServiceLock);
    114     if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
    115         return BAD_VALUE;
    116     }
    117     size_t maxModules = *numModules;
    118     *numModules = mModules.size();
    119     for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
    120         modules[i] = mModules.valueAt(i)->descriptor();
    121     }
    122     return NO_ERROR;
    123 }
    124 
    125 status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
    126                         const sp<ISoundTriggerClient>& client,
    127                         sp<ISoundTrigger>& moduleInterface)
    128 {
    129     ALOGV("attach module %d", handle);
    130     if (!captureHotwordAllowed()) {
    131         return PERMISSION_DENIED;
    132     }
    133 
    134     AutoMutex lock(mServiceLock);
    135     moduleInterface.clear();
    136     if (client == 0) {
    137         return BAD_VALUE;
    138     }
    139     ssize_t index = mModules.indexOfKey(handle);
    140     if (index < 0) {
    141         return BAD_VALUE;
    142     }
    143     sp<Module> module = mModules.valueAt(index);
    144 
    145     module->setClient(client);
    146     client->asBinder()->linkToDeath(module);
    147     moduleInterface = module;
    148 
    149     module->setCaptureState_l(mCaptureState);
    150 
    151     return NO_ERROR;
    152 }
    153 
    154 status_t SoundTriggerHwService::setCaptureState(bool active)
    155 {
    156     ALOGV("setCaptureState %d", active);
    157     AutoMutex lock(mServiceLock);
    158     mCaptureState = active;
    159     for (size_t i = 0; i < mModules.size(); i++) {
    160         mModules.valueAt(i)->setCaptureState_l(active);
    161     }
    162     return NO_ERROR;
    163 }
    164 
    165 
    166 void SoundTriggerHwService::detachModule(sp<Module> module)
    167 {
    168     ALOGV("detachModule");
    169     AutoMutex lock(mServiceLock);
    170     module->clearClient();
    171 }
    172 
    173 
    174 static const int kDumpLockRetries = 50;
    175 static const int kDumpLockSleep = 60000;
    176 
    177 static bool tryLock(Mutex& mutex)
    178 {
    179     bool locked = false;
    180     for (int i = 0; i < kDumpLockRetries; ++i) {
    181         if (mutex.tryLock() == NO_ERROR) {
    182             locked = true;
    183             break;
    184         }
    185         usleep(kDumpLockSleep);
    186     }
    187     return locked;
    188 }
    189 
    190 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
    191     String8 result;
    192     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
    193         result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
    194         write(fd, result.string(), result.size());
    195     } else {
    196         bool locked = tryLock(mServiceLock);
    197         // failed to lock - SoundTriggerHwService is probably deadlocked
    198         if (!locked) {
    199             result.append("SoundTriggerHwService may be deadlocked\n");
    200             write(fd, result.string(), result.size());
    201         }
    202 
    203         if (locked) mServiceLock.unlock();
    204     }
    205     return NO_ERROR;
    206 }
    207 
    208 status_t SoundTriggerHwService::onTransact(
    209     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    210     return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
    211 }
    212 
    213 
    214 // static
    215 void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
    216                                                 void *cookie)
    217 {
    218     Module *module = (Module *)cookie;
    219     if (module == NULL) {
    220         return;
    221     }
    222     sp<SoundTriggerHwService> service = module->service().promote();
    223     if (service == 0) {
    224         return;
    225     }
    226 
    227     service->sendRecognitionEvent(event, module);
    228 }
    229 
    230 sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
    231                                                     struct sound_trigger_recognition_event *event)
    232 {
    233     sp<IMemory> eventMemory;
    234 
    235     //sanitize event
    236     switch (event->type) {
    237     case SOUND_MODEL_TYPE_KEYPHRASE:
    238         ALOGW_IF(event->data_size != 0 && event->data_offset !=
    239                     sizeof(struct sound_trigger_phrase_recognition_event),
    240                     "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
    241                     event->data_offset);
    242         event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
    243         break;
    244     case SOUND_MODEL_TYPE_UNKNOWN:
    245         ALOGW_IF(event->data_size != 0 && event->data_offset !=
    246                     sizeof(struct sound_trigger_recognition_event),
    247                     "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
    248                     event->data_offset);
    249         event->data_offset = sizeof(struct sound_trigger_recognition_event);
    250         break;
    251     default:
    252         return eventMemory;
    253     }
    254 
    255     size_t size = event->data_offset + event->data_size;
    256     eventMemory = mMemoryDealer->allocate(size);
    257     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    258         eventMemory.clear();
    259         return eventMemory;
    260     }
    261     memcpy(eventMemory->pointer(), event, size);
    262 
    263     return eventMemory;
    264 }
    265 
    266 void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
    267                                                  Module *module)
    268  {
    269      AutoMutex lock(mServiceLock);
    270      if (module == NULL) {
    271          return;
    272      }
    273      sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
    274      if (eventMemory == 0) {
    275          return;
    276      }
    277      sp<Module> strongModule;
    278      for (size_t i = 0; i < mModules.size(); i++) {
    279          if (mModules.valueAt(i).get() == module) {
    280              strongModule = mModules.valueAt(i);
    281              break;
    282          }
    283      }
    284      if (strongModule == 0) {
    285          return;
    286      }
    287 
    288      sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
    289                                                   eventMemory, strongModule));
    290 }
    291 
    292 // static
    293 void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
    294                                                void *cookie)
    295 {
    296     Module *module = (Module *)cookie;
    297     if (module == NULL) {
    298         return;
    299     }
    300     sp<SoundTriggerHwService> service = module->service().promote();
    301     if (service == 0) {
    302         return;
    303     }
    304 
    305     service->sendSoundModelEvent(event, module);
    306 }
    307 
    308 sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
    309 {
    310     sp<IMemory> eventMemory;
    311 
    312     size_t size = event->data_offset + event->data_size;
    313     eventMemory = mMemoryDealer->allocate(size);
    314     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    315         eventMemory.clear();
    316         return eventMemory;
    317     }
    318     memcpy(eventMemory->pointer(), event, size);
    319 
    320     return eventMemory;
    321 }
    322 
    323 void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
    324                                                 Module *module)
    325 {
    326     AutoMutex lock(mServiceLock);
    327     sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
    328     if (eventMemory == 0) {
    329         return;
    330     }
    331     sp<Module> strongModule;
    332     for (size_t i = 0; i < mModules.size(); i++) {
    333         if (mModules.valueAt(i).get() == module) {
    334             strongModule = mModules.valueAt(i);
    335             break;
    336         }
    337     }
    338     if (strongModule == 0) {
    339         return;
    340     }
    341     sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
    342                                                  eventMemory, strongModule));
    343 }
    344 
    345 
    346 sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
    347 {
    348     sp<IMemory> eventMemory;
    349 
    350     size_t size = sizeof(sound_trigger_service_state_t);
    351     eventMemory = mMemoryDealer->allocate(size);
    352     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    353         eventMemory.clear();
    354         return eventMemory;
    355     }
    356     *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
    357     return eventMemory;
    358 }
    359 
    360 // call with mServiceLock held
    361 void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
    362                                                   Module *module)
    363 {
    364     sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
    365     if (eventMemory == 0) {
    366         return;
    367     }
    368     sp<Module> strongModule;
    369     for (size_t i = 0; i < mModules.size(); i++) {
    370         if (mModules.valueAt(i).get() == module) {
    371             strongModule = mModules.valueAt(i);
    372             break;
    373         }
    374     }
    375     if (strongModule == 0) {
    376         return;
    377     }
    378     sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
    379                                                  eventMemory, strongModule));
    380 }
    381 
    382 // call with mServiceLock held
    383 void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
    384 {
    385     mCallbackThread->sendCallbackEvent(event);
    386 }
    387 
    388 void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
    389 {
    390     ALOGV("onCallbackEvent");
    391     sp<Module> module;
    392     {
    393         AutoMutex lock(mServiceLock);
    394         module = event->mModule.promote();
    395         if (module == 0) {
    396             return;
    397         }
    398     }
    399     module->onCallbackEvent(event);
    400     {
    401         AutoMutex lock(mServiceLock);
    402         // clear now to execute with mServiceLock locked
    403         event->mMemory.clear();
    404     }
    405 }
    406 
    407 #undef LOG_TAG
    408 #define LOG_TAG "SoundTriggerHwService::CallbackThread"
    409 
    410 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
    411     : mService(service)
    412 {
    413 }
    414 
    415 SoundTriggerHwService::CallbackThread::~CallbackThread()
    416 {
    417     while (!mEventQueue.isEmpty()) {
    418         mEventQueue[0]->mMemory.clear();
    419         mEventQueue.removeAt(0);
    420     }
    421 }
    422 
    423 void SoundTriggerHwService::CallbackThread::onFirstRef()
    424 {
    425     run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
    426 }
    427 
    428 bool SoundTriggerHwService::CallbackThread::threadLoop()
    429 {
    430     while (!exitPending()) {
    431         sp<CallbackEvent> event;
    432         sp<SoundTriggerHwService> service;
    433         {
    434             Mutex::Autolock _l(mCallbackLock);
    435             while (mEventQueue.isEmpty() && !exitPending()) {
    436                 ALOGV("CallbackThread::threadLoop() sleep");
    437                 mCallbackCond.wait(mCallbackLock);
    438                 ALOGV("CallbackThread::threadLoop() wake up");
    439             }
    440             if (exitPending()) {
    441                 break;
    442             }
    443             event = mEventQueue[0];
    444             mEventQueue.removeAt(0);
    445             service = mService.promote();
    446         }
    447         if (service != 0) {
    448             service->onCallbackEvent(event);
    449         }
    450     }
    451     return false;
    452 }
    453 
    454 void SoundTriggerHwService::CallbackThread::exit()
    455 {
    456     Mutex::Autolock _l(mCallbackLock);
    457     requestExit();
    458     mCallbackCond.broadcast();
    459 }
    460 
    461 void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
    462                         const sp<SoundTriggerHwService::CallbackEvent>& event)
    463 {
    464     AutoMutex lock(mCallbackLock);
    465     mEventQueue.add(event);
    466     mCallbackCond.signal();
    467 }
    468 
    469 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory,
    470                                                     wp<Module> module)
    471     : mType(type), mMemory(memory), mModule(module)
    472 {
    473 }
    474 
    475 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
    476 {
    477 }
    478 
    479 
    480 #undef LOG_TAG
    481 #define LOG_TAG "SoundTriggerHwService::Module"
    482 
    483 SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
    484                                       sound_trigger_hw_device* hwDevice,
    485                                       sound_trigger_module_descriptor descriptor,
    486                                       const sp<ISoundTriggerClient>& client)
    487  : mService(service), mHwDevice(hwDevice), mDescriptor(descriptor),
    488    mClient(client), mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
    489 {
    490 }
    491 
    492 SoundTriggerHwService::Module::~Module() {
    493 }
    494 
    495 void SoundTriggerHwService::Module::detach() {
    496     ALOGV("detach()");
    497     if (!captureHotwordAllowed()) {
    498         return;
    499     }
    500     {
    501         AutoMutex lock(mLock);
    502         for (size_t i = 0; i < mModels.size(); i++) {
    503             sp<Model> model = mModels.valueAt(i);
    504             ALOGV("detach() unloading model %d", model->mHandle);
    505             if (model->mState == Model::STATE_ACTIVE) {
    506                 mHwDevice->stop_recognition(mHwDevice, model->mHandle);
    507             }
    508             mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
    509         }
    510         mModels.clear();
    511     }
    512     if (mClient != 0) {
    513         mClient->asBinder()->unlinkToDeath(this);
    514     }
    515     sp<SoundTriggerHwService> service = mService.promote();
    516     if (service == 0) {
    517         return;
    518     }
    519     service->detachModule(this);
    520 }
    521 
    522 status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
    523                                 sound_model_handle_t *handle)
    524 {
    525     ALOGV("loadSoundModel() handle");
    526     if (!captureHotwordAllowed()) {
    527         return PERMISSION_DENIED;
    528     }
    529 
    530     if (modelMemory == 0 || modelMemory->pointer() == NULL) {
    531         ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
    532         return BAD_VALUE;
    533     }
    534     struct sound_trigger_sound_model *sound_model =
    535             (struct sound_trigger_sound_model *)modelMemory->pointer();
    536 
    537     AutoMutex lock(mLock);
    538 
    539     if (mModels.size() >= mDescriptor.properties.max_sound_models) {
    540         if (mModels.size() == 0) {
    541             return INVALID_OPERATION;
    542         }
    543         ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
    544               mDescriptor.properties.max_sound_models);
    545         unloadSoundModel_l(mModels.valueAt(0)->mHandle);
    546     }
    547 
    548     status_t status = mHwDevice->load_sound_model(mHwDevice,
    549                                                   sound_model,
    550                                                   SoundTriggerHwService::soundModelCallback,
    551                                                   this,
    552                                                   handle);
    553     if (status != NO_ERROR) {
    554         return status;
    555     }
    556     audio_session_t session;
    557     audio_io_handle_t ioHandle;
    558     audio_devices_t device;
    559 
    560     status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
    561     if (status != NO_ERROR) {
    562         return status;
    563     }
    564 
    565     sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
    566     mModels.replaceValueFor(*handle, model);
    567 
    568     return status;
    569 }
    570 
    571 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
    572 {
    573     ALOGV("unloadSoundModel() model handle %d", handle);
    574     if (!captureHotwordAllowed()) {
    575         return PERMISSION_DENIED;
    576     }
    577 
    578     AutoMutex lock(mLock);
    579     return unloadSoundModel_l(handle);
    580 }
    581 
    582 status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
    583 {
    584     ssize_t index = mModels.indexOfKey(handle);
    585     if (index < 0) {
    586         return BAD_VALUE;
    587     }
    588     sp<Model> model = mModels.valueAt(index);
    589     mModels.removeItem(handle);
    590     if (model->mState == Model::STATE_ACTIVE) {
    591         mHwDevice->stop_recognition(mHwDevice, model->mHandle);
    592         model->mState = Model::STATE_IDLE;
    593     }
    594     AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
    595     return mHwDevice->unload_sound_model(mHwDevice, handle);
    596 }
    597 
    598 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
    599                                  const sp<IMemory>& dataMemory)
    600 {
    601     ALOGV("startRecognition() model handle %d", handle);
    602     if (!captureHotwordAllowed()) {
    603         return PERMISSION_DENIED;
    604     }
    605 
    606     if (dataMemory != 0 && dataMemory->pointer() == NULL) {
    607         ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
    608         return BAD_VALUE;
    609 
    610     }
    611     AutoMutex lock(mLock);
    612     if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
    613         return INVALID_OPERATION;
    614     }
    615     sp<Model> model = getModel(handle);
    616     if (model == 0) {
    617         return BAD_VALUE;
    618     }
    619     if ((dataMemory == 0) ||
    620             (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
    621         return BAD_VALUE;
    622     }
    623 
    624     if (model->mState == Model::STATE_ACTIVE) {
    625         return INVALID_OPERATION;
    626     }
    627 
    628     struct sound_trigger_recognition_config *config =
    629             (struct sound_trigger_recognition_config *)dataMemory->pointer();
    630 
    631     //TODO: get capture handle and device from audio policy service
    632     config->capture_handle = model->mCaptureIOHandle;
    633     config->capture_device = model->mCaptureDevice;
    634     status_t status = mHwDevice->start_recognition(mHwDevice, handle, config,
    635                                         SoundTriggerHwService::recognitionCallback,
    636                                         this);
    637 
    638     if (status == NO_ERROR) {
    639         model->mState = Model::STATE_ACTIVE;
    640         model->mConfig = *config;
    641     }
    642 
    643     return status;
    644 }
    645 
    646 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
    647 {
    648     ALOGV("stopRecognition() model handle %d", handle);
    649     if (!captureHotwordAllowed()) {
    650         return PERMISSION_DENIED;
    651     }
    652 
    653     AutoMutex lock(mLock);
    654     sp<Model> model = getModel(handle);
    655     if (model == 0) {
    656         return BAD_VALUE;
    657     }
    658 
    659     if (model->mState != Model::STATE_ACTIVE) {
    660         return INVALID_OPERATION;
    661     }
    662     mHwDevice->stop_recognition(mHwDevice, handle);
    663     model->mState = Model::STATE_IDLE;
    664     return NO_ERROR;
    665 }
    666 
    667 
    668 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
    669 {
    670     ALOGV("onCallbackEvent type %d", event->mType);
    671 
    672     sp<IMemory> eventMemory = event->mMemory;
    673 
    674     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    675         return;
    676     }
    677     if (mClient == 0) {
    678         ALOGI("%s mClient == 0", __func__);
    679         return;
    680     }
    681 
    682     switch (event->mType) {
    683     case CallbackEvent::TYPE_RECOGNITION: {
    684         struct sound_trigger_recognition_event *recognitionEvent =
    685                 (struct sound_trigger_recognition_event *)eventMemory->pointer();
    686         sp<ISoundTriggerClient> client;
    687         {
    688             AutoMutex lock(mLock);
    689             sp<Model> model = getModel(recognitionEvent->model);
    690             if (model == 0) {
    691                 ALOGW("%s model == 0", __func__);
    692                 return;
    693             }
    694             if (model->mState != Model::STATE_ACTIVE) {
    695                 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
    696                 return;
    697             }
    698 
    699             recognitionEvent->capture_session = model->mCaptureSession;
    700             model->mState = Model::STATE_IDLE;
    701             client = mClient;
    702         }
    703         if (client != 0) {
    704             client->onRecognitionEvent(eventMemory);
    705         }
    706     } break;
    707     case CallbackEvent::TYPE_SOUNDMODEL: {
    708         struct sound_trigger_model_event *soundmodelEvent =
    709                 (struct sound_trigger_model_event *)eventMemory->pointer();
    710         sp<ISoundTriggerClient> client;
    711         {
    712             AutoMutex lock(mLock);
    713             sp<Model> model = getModel(soundmodelEvent->model);
    714             if (model == 0) {
    715                 ALOGW("%s model == 0", __func__);
    716                 return;
    717             }
    718             client = mClient;
    719         }
    720         if (client != 0) {
    721             client->onSoundModelEvent(eventMemory);
    722         }
    723     } break;
    724     case CallbackEvent::TYPE_SERVICE_STATE: {
    725         sp<ISoundTriggerClient> client;
    726         {
    727             AutoMutex lock(mLock);
    728             client = mClient;
    729         }
    730         if (client != 0) {
    731             client->onServiceStateChange(eventMemory);
    732         }
    733     } break;
    734     default:
    735         LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
    736     }
    737 }
    738 
    739 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
    740         sound_model_handle_t handle)
    741 {
    742     sp<Model> model;
    743     ssize_t index = mModels.indexOfKey(handle);
    744     if (index >= 0) {
    745         model = mModels.valueAt(index);
    746     }
    747     return model;
    748 }
    749 
    750 void SoundTriggerHwService::Module::binderDied(
    751     const wp<IBinder> &who __unused) {
    752     ALOGW("client binder died for module %d", mDescriptor.handle);
    753     detach();
    754 }
    755 
    756 // Called with mServiceLock held
    757 void SoundTriggerHwService::Module::setCaptureState_l(bool active)
    758 {
    759     ALOGV("Module::setCaptureState_l %d", active);
    760     sp<SoundTriggerHwService> service;
    761     sound_trigger_service_state_t state;
    762 
    763     Vector< sp<IMemory> > events;
    764     {
    765         AutoMutex lock(mLock);
    766         state = (active && !mDescriptor.properties.concurrent_capture) ?
    767                                         SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
    768 
    769         if (state == mServiceState) {
    770             return;
    771         }
    772 
    773         mServiceState = state;
    774 
    775         service = mService.promote();
    776         if (service == 0) {
    777             return;
    778         }
    779 
    780         if (state == SOUND_TRIGGER_STATE_ENABLED) {
    781             goto exit;
    782         }
    783 
    784         for (size_t i = 0; i < mModels.size(); i++) {
    785             sp<Model> model = mModels.valueAt(i);
    786             if (model->mState == Model::STATE_ACTIVE) {
    787                 mHwDevice->stop_recognition(mHwDevice, model->mHandle);
    788                 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
    789                 struct sound_trigger_phrase_recognition_event phraseEvent;
    790                 switch (model->mType) {
    791                 case SOUND_MODEL_TYPE_KEYPHRASE:
    792                     phraseEvent.num_phrases = model->mConfig.num_phrases;
    793                     for (size_t i = 0; i < phraseEvent.num_phrases; i++) {
    794                         phraseEvent.phrase_extras[i] = model->mConfig.phrases[i];
    795                     }
    796                     break;
    797                 case SOUND_MODEL_TYPE_UNKNOWN:
    798                 default:
    799                     break;
    800                 }
    801                 phraseEvent.common.status = RECOGNITION_STATUS_ABORT;
    802                 phraseEvent.common.type = model->mType;
    803                 phraseEvent.common.model = model->mHandle;
    804                 phraseEvent.common.data_size = 0;
    805                 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&phraseEvent.common);
    806                 if (eventMemory != 0) {
    807                     events.add(eventMemory);
    808                 }
    809             }
    810         }
    811     }
    812 
    813     for (size_t i = 0; i < events.size(); i++) {
    814         service->sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, events[i],
    815                                                      this));
    816     }
    817 
    818 exit:
    819     service->sendServiceStateEvent_l(state, this);
    820 }
    821 
    822 
    823 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
    824                                     audio_io_handle_t ioHandle, audio_devices_t device,
    825                                     sound_trigger_sound_model_type_t type) :
    826     mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
    827     mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type)
    828 {
    829 
    830 }
    831 
    832 status_t SoundTriggerHwService::Module::dump(int fd __unused,
    833                                              const Vector<String16>& args __unused) {
    834     String8 result;
    835     return NO_ERROR;
    836 }
    837 
    838 }; // namespace android
    839