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