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 <system/sound_trigger.h>
     36 #include <ServiceUtilities.h>
     37 #include "SoundTriggerHwService.h"
     38 
     39 #ifdef SOUND_TRIGGER_USE_STUB_MODULE
     40 #define HW_MODULE_PREFIX "stub"
     41 #else
     42 #define HW_MODULE_PREFIX "primary"
     43 #endif
     44 namespace android {
     45 
     46 SoundTriggerHwService::SoundTriggerHwService()
     47     : BnSoundTriggerHwService(),
     48       mNextUniqueId(1),
     49       mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
     50       mCaptureState(false)
     51 {
     52 }
     53 
     54 void SoundTriggerHwService::onFirstRef()
     55 {
     56     int rc;
     57 
     58     sp<SoundTriggerHalInterface> halInterface =
     59             SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
     60 
     61     if (halInterface == 0) {
     62         ALOGW("could not connect to HAL");
     63         return;
     64     }
     65     sound_trigger_module_descriptor descriptor;
     66     rc = halInterface->getProperties(&descriptor.properties);
     67     if (rc != 0) {
     68         ALOGE("could not read implementation properties");
     69         return;
     70     }
     71     descriptor.handle =
     72             (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
     73     ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
     74                                                  descriptor.handle);
     75 
     76     sp<Module> module = new Module(this, halInterface, descriptor);
     77     mModules.add(descriptor.handle, module);
     78     mCallbackThread = new CallbackThread(this);
     79 }
     80 
     81 SoundTriggerHwService::~SoundTriggerHwService()
     82 {
     83     if (mCallbackThread != 0) {
     84         mCallbackThread->exit();
     85     }
     86 }
     87 
     88 status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
     89                              uint32_t *numModules)
     90 {
     91     ALOGV("listModules");
     92     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
     93                                IPCThreadState::self()->getCallingUid())) {
     94         return PERMISSION_DENIED;
     95     }
     96 
     97     AutoMutex lock(mServiceLock);
     98     if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
     99         return BAD_VALUE;
    100     }
    101     size_t maxModules = *numModules;
    102     *numModules = mModules.size();
    103     for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
    104         modules[i] = mModules.valueAt(i)->descriptor();
    105     }
    106     return NO_ERROR;
    107 }
    108 
    109 status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
    110                         const sp<ISoundTriggerClient>& client,
    111                         sp<ISoundTrigger>& moduleInterface)
    112 {
    113     ALOGV("attach module %d", handle);
    114     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
    115                                IPCThreadState::self()->getCallingUid())) {
    116         return PERMISSION_DENIED;
    117     }
    118 
    119     AutoMutex lock(mServiceLock);
    120     moduleInterface.clear();
    121     if (client == 0) {
    122         return BAD_VALUE;
    123     }
    124     ssize_t index = mModules.indexOfKey(handle);
    125     if (index < 0) {
    126         return BAD_VALUE;
    127     }
    128     sp<Module> module = mModules.valueAt(index);
    129 
    130     sp<ModuleClient> moduleClient = module->addClient(client);
    131     if (moduleClient == 0) {
    132         return NO_INIT;
    133     }
    134 
    135     moduleClient->setCaptureState_l(mCaptureState);
    136     moduleInterface = moduleClient;
    137 
    138     return NO_ERROR;
    139 }
    140 
    141 status_t SoundTriggerHwService::setCaptureState(bool active)
    142 {
    143     ALOGV("setCaptureState %d", active);
    144     AutoMutex lock(mServiceLock);
    145     mCaptureState = active;
    146     for (size_t i = 0; i < mModules.size(); i++) {
    147         mModules.valueAt(i)->setCaptureState_l(active);
    148     }
    149     return NO_ERROR;
    150 }
    151 
    152 
    153 static const int kDumpLockRetries = 50;
    154 static const int kDumpLockSleep = 60000;
    155 
    156 static bool tryLock(Mutex& mutex)
    157 {
    158     bool locked = false;
    159     for (int i = 0; i < kDumpLockRetries; ++i) {
    160         if (mutex.tryLock() == NO_ERROR) {
    161             locked = true;
    162             break;
    163         }
    164         usleep(kDumpLockSleep);
    165     }
    166     return locked;
    167 }
    168 
    169 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
    170     String8 result;
    171     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
    172         result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
    173         write(fd, result.string(), result.size());
    174     } else {
    175         bool locked = tryLock(mServiceLock);
    176         // failed to lock - SoundTriggerHwService is probably deadlocked
    177         if (!locked) {
    178             result.append("SoundTriggerHwService may be deadlocked\n");
    179             write(fd, result.string(), result.size());
    180         }
    181 
    182         if (locked) mServiceLock.unlock();
    183     }
    184     return NO_ERROR;
    185 }
    186 
    187 status_t SoundTriggerHwService::onTransact(
    188     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    189     return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
    190 }
    191 
    192 
    193 // static
    194 void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
    195                                                 void *cookie)
    196 {
    197     Module *module = (Module *)cookie;
    198     if (module == NULL) {
    199         return;
    200     }
    201     sp<SoundTriggerHwService> service = module->service().promote();
    202     if (service == 0) {
    203         return;
    204     }
    205 
    206     service->sendRecognitionEvent(event, module);
    207 }
    208 
    209 sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
    210                                                     struct sound_trigger_recognition_event *event)
    211 {
    212     AutoMutex lock(mMemoryDealerLock);
    213     sp<IMemory> eventMemory;
    214 
    215     //sanitize event
    216     switch (event->type) {
    217     case SOUND_MODEL_TYPE_KEYPHRASE:
    218         ALOGW_IF(event->data_size != 0 && event->data_offset !=
    219                     sizeof(struct sound_trigger_phrase_recognition_event),
    220                     "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
    221                     event->data_offset);
    222         event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
    223         break;
    224     case SOUND_MODEL_TYPE_GENERIC:
    225         ALOGW_IF(event->data_size != 0 && event->data_offset !=
    226                     sizeof(struct sound_trigger_generic_recognition_event),
    227                     "prepareRecognitionEvent(): invalid data offset %u for generic event type",
    228                     event->data_offset);
    229         event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
    230         break;
    231     case SOUND_MODEL_TYPE_UNKNOWN:
    232         ALOGW_IF(event->data_size != 0 && event->data_offset !=
    233                     sizeof(struct sound_trigger_recognition_event),
    234                     "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
    235                     event->data_offset);
    236         event->data_offset = sizeof(struct sound_trigger_recognition_event);
    237         break;
    238     default:
    239         return eventMemory;
    240     }
    241 
    242     size_t size = event->data_offset + event->data_size;
    243     eventMemory = mMemoryDealer->allocate(size);
    244     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    245         eventMemory.clear();
    246         return eventMemory;
    247     }
    248     memcpy(eventMemory->pointer(), event, size);
    249 
    250     return eventMemory;
    251 }
    252 
    253 void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
    254                                                  Module *module)
    255 {
    256     if (module == NULL) {
    257         return;
    258     }
    259     sp<IMemory> eventMemory = prepareRecognitionEvent(event);
    260     if (eventMemory == 0) {
    261         return;
    262     }
    263 
    264     sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
    265                                                         eventMemory);
    266     callbackEvent->setModule(module);
    267     sendCallbackEvent(callbackEvent);
    268 }
    269 
    270 // static
    271 void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
    272                                                void *cookie)
    273 {
    274     Module *module = (Module *)cookie;
    275     if (module == NULL) {
    276         return;
    277     }
    278     sp<SoundTriggerHwService> service = module->service().promote();
    279     if (service == 0) {
    280         return;
    281     }
    282 
    283     service->sendSoundModelEvent(event, module);
    284 }
    285 
    286 sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
    287 {
    288     AutoMutex lock(mMemoryDealerLock);
    289     sp<IMemory> eventMemory;
    290 
    291     size_t size = event->data_offset + event->data_size;
    292     eventMemory = mMemoryDealer->allocate(size);
    293     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    294         eventMemory.clear();
    295         return eventMemory;
    296     }
    297     memcpy(eventMemory->pointer(), event, size);
    298 
    299     return eventMemory;
    300 }
    301 
    302 void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
    303                                                 Module *module)
    304 {
    305     sp<IMemory> eventMemory = prepareSoundModelEvent(event);
    306     if (eventMemory == 0) {
    307         return;
    308     }
    309     sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
    310                                                         eventMemory);
    311     callbackEvent->setModule(module);
    312     sendCallbackEvent(callbackEvent);
    313 }
    314 
    315 
    316 sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
    317 {
    318     AutoMutex lock(mMemoryDealerLock);
    319     sp<IMemory> eventMemory;
    320 
    321     size_t size = sizeof(sound_trigger_service_state_t);
    322     eventMemory = mMemoryDealer->allocate(size);
    323     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    324         eventMemory.clear();
    325         return eventMemory;
    326     }
    327     *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
    328     return eventMemory;
    329 }
    330 
    331 void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
    332                                                   Module *module)
    333 {
    334     sp<IMemory> eventMemory = prepareServiceStateEvent(state);
    335     if (eventMemory == 0) {
    336         return;
    337     }
    338     sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
    339                                                         eventMemory);
    340     callbackEvent->setModule(module);
    341     sendCallbackEvent(callbackEvent);
    342 }
    343 
    344 void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
    345                                                   ModuleClient *moduleClient)
    346 {
    347     sp<IMemory> eventMemory = prepareServiceStateEvent(state);
    348     if (eventMemory == 0) {
    349         return;
    350     }
    351     sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
    352                                                         eventMemory);
    353     callbackEvent->setModuleClient(moduleClient);
    354     sendCallbackEvent(callbackEvent);
    355 }
    356 
    357 void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
    358 {
    359     mCallbackThread->sendCallbackEvent(event);
    360 }
    361 
    362 void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
    363 {
    364     ALOGV("onCallbackEvent");
    365     sp<Module> module;
    366     sp<ModuleClient> moduleClient;
    367     {
    368         AutoMutex lock(mServiceLock);
    369         //CallbackEvent is either for Module or ModuleClient
    370         module = event->mModule.promote();
    371         if (module == 0) {
    372             moduleClient = event->mModuleClient.promote();
    373             if (moduleClient == 0) {
    374                 return;
    375             }
    376         } else {
    377             // Sanity check on this being a Module we know about.
    378             bool foundModule = false;
    379             for (size_t i = 0; i < mModules.size(); i++) {
    380                 if (mModules.valueAt(i).get() == module.get()) {
    381                     foundModule = true;
    382                     break;
    383                 }
    384             }
    385             if (!foundModule) {
    386                 ALOGE("onCallbackEvent for unknown module");
    387                 return;
    388             }
    389         }
    390     }
    391     if (module != 0) {
    392         ALOGV("onCallbackEvent for module");
    393         module->onCallbackEvent(event);
    394     } else if (moduleClient != 0) {
    395         ALOGV("onCallbackEvent for moduleClient");
    396         moduleClient->onCallbackEvent(event);
    397     }
    398     {
    399         AutoMutex lock(mServiceLock);
    400         // clear now to execute with mServiceLock locked
    401         event->mMemory.clear();
    402     }
    403 }
    404 
    405 #undef LOG_TAG
    406 #define LOG_TAG "SoundTriggerHwService::CallbackThread"
    407 
    408 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
    409     : mService(service)
    410 {
    411 }
    412 
    413 SoundTriggerHwService::CallbackThread::~CallbackThread()
    414 {
    415     while (!mEventQueue.isEmpty()) {
    416         mEventQueue[0]->mMemory.clear();
    417         mEventQueue.removeAt(0);
    418     }
    419 }
    420 
    421 void SoundTriggerHwService::CallbackThread::onFirstRef()
    422 {
    423     run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
    424 }
    425 
    426 bool SoundTriggerHwService::CallbackThread::threadLoop()
    427 {
    428     while (!exitPending()) {
    429         sp<CallbackEvent> event;
    430         sp<SoundTriggerHwService> service;
    431         {
    432             Mutex::Autolock _l(mCallbackLock);
    433             while (mEventQueue.isEmpty() && !exitPending()) {
    434                 ALOGV("CallbackThread::threadLoop() sleep");
    435                 mCallbackCond.wait(mCallbackLock);
    436                 ALOGV("CallbackThread::threadLoop() wake up");
    437             }
    438             if (exitPending()) {
    439                 break;
    440             }
    441             event = mEventQueue[0];
    442             mEventQueue.removeAt(0);
    443             service = mService.promote();
    444         }
    445         if (service != 0) {
    446             service->onCallbackEvent(event);
    447         }
    448     }
    449     return false;
    450 }
    451 
    452 void SoundTriggerHwService::CallbackThread::exit()
    453 {
    454     Mutex::Autolock _l(mCallbackLock);
    455     requestExit();
    456     mCallbackCond.broadcast();
    457 }
    458 
    459 void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
    460                         const sp<SoundTriggerHwService::CallbackEvent>& event)
    461 {
    462     AutoMutex lock(mCallbackLock);
    463     mEventQueue.add(event);
    464     mCallbackCond.signal();
    465 }
    466 
    467 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
    468     : mType(type), mMemory(memory)
    469 {
    470 }
    471 
    472 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
    473 {
    474 }
    475 
    476 
    477 #undef LOG_TAG
    478 #define LOG_TAG "SoundTriggerHwService::Module"
    479 
    480 SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
    481                                       const sp<SoundTriggerHalInterface>& halInterface,
    482                                       sound_trigger_module_descriptor descriptor)
    483  : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
    484    mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
    485 {
    486 }
    487 
    488 SoundTriggerHwService::Module::~Module() {
    489     mModuleClients.clear();
    490 }
    491 
    492 sp<SoundTriggerHwService::ModuleClient>
    493 SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
    494 {
    495     AutoMutex lock(mLock);
    496     sp<ModuleClient> moduleClient;
    497 
    498     for (size_t i = 0; i < mModuleClients.size(); i++) {
    499         if (mModuleClients[i]->client() == client) {
    500             // Client already present, reuse client
    501             return moduleClient;
    502         }
    503     }
    504     moduleClient = new ModuleClient(this, client);
    505 
    506     ALOGV("addClient() client %p", moduleClient.get());
    507     mModuleClients.add(moduleClient);
    508 
    509     return moduleClient;
    510 }
    511 
    512 void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
    513 {
    514     ALOGV("Module::detach()");
    515     Vector<audio_session_t> releasedSessions;
    516 
    517     {
    518         AutoMutex lock(mLock);
    519         ssize_t index = -1;
    520 
    521         for (size_t i = 0; i < mModuleClients.size(); i++) {
    522             if (mModuleClients[i] == moduleClient) {
    523                 index = i;
    524                 break;
    525             }
    526         }
    527         if (index == -1) {
    528             return;
    529         }
    530 
    531         ALOGV("remove client %p", moduleClient.get());
    532         mModuleClients.removeAt(index);
    533 
    534         // Iterate in reverse order as models are removed from list inside the loop.
    535         for (size_t i = mModels.size(); i > 0; i--) {
    536             sp<Model> model = mModels.valueAt(i - 1);
    537             if (moduleClient == model->mModuleClient) {
    538                 mModels.removeItemsAt(i - 1);
    539                 ALOGV("detach() unloading model %d", model->mHandle);
    540                 if (mHalInterface != 0) {
    541                     if (model->mState == Model::STATE_ACTIVE) {
    542                         mHalInterface->stopRecognition(model->mHandle);
    543                     }
    544                     mHalInterface->unloadSoundModel(model->mHandle);
    545                 }
    546                 releasedSessions.add(model->mCaptureSession);
    547             }
    548         }
    549     }
    550 
    551     for (size_t i = 0; i < releasedSessions.size(); i++) {
    552         // do not call AudioSystem methods with mLock held
    553         AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
    554     }
    555 }
    556 
    557 status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
    558                                                        sp<ModuleClient> moduleClient,
    559                                                        sound_model_handle_t *handle)
    560 {
    561     ALOGV("loadSoundModel() handle");
    562     if (mHalInterface == 0) {
    563         return NO_INIT;
    564     }
    565     if (modelMemory == 0 || modelMemory->pointer() == NULL) {
    566         ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
    567         return BAD_VALUE;
    568     }
    569     struct sound_trigger_sound_model *sound_model =
    570             (struct sound_trigger_sound_model *)modelMemory->pointer();
    571 
    572     size_t structSize;
    573     if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
    574         structSize = sizeof(struct sound_trigger_phrase_sound_model);
    575     } else {
    576         structSize = sizeof(struct sound_trigger_sound_model);
    577     }
    578 
    579     if (sound_model->data_offset < structSize ||
    580            sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
    581            modelMemory->size() < sound_model->data_offset ||
    582            sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
    583         android_errorWriteLog(0x534e4554, "30148546");
    584         ALOGE("loadSoundModel() data_size is too big");
    585         return BAD_VALUE;
    586     }
    587 
    588     audio_session_t session;
    589     audio_io_handle_t ioHandle;
    590     audio_devices_t device;
    591     // do not call AudioSystem methods with mLock held
    592     status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
    593     if (status != NO_ERROR) {
    594         return status;
    595     }
    596 
    597     {
    598         AutoMutex lock(mLock);
    599 
    600         if (mModels.size() >= mDescriptor.properties.max_sound_models) {
    601             ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
    602                   mDescriptor.properties.max_sound_models);
    603             status = INVALID_OPERATION;
    604             goto exit;
    605         }
    606 
    607         status = mHalInterface->loadSoundModel(sound_model,
    608                                                       SoundTriggerHwService::soundModelCallback,
    609                                                       this, handle);
    610         if (status != NO_ERROR) {
    611             goto exit;
    612         }
    613 
    614         sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
    615                                     moduleClient);
    616         mModels.replaceValueFor(*handle, model);
    617     }
    618 exit:
    619     if (status != NO_ERROR) {
    620         // do not call AudioSystem methods with mLock held
    621         AudioSystem::releaseSoundTriggerSession(session);
    622     }
    623     return status;
    624 }
    625 
    626 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
    627 {
    628     ALOGV("unloadSoundModel() model handle %d", handle);
    629     status_t status;
    630     audio_session_t session;
    631 
    632     {
    633         AutoMutex lock(mLock);
    634         if (mHalInterface == 0) {
    635             return NO_INIT;
    636         }
    637         ssize_t index = mModels.indexOfKey(handle);
    638         if (index < 0) {
    639             return BAD_VALUE;
    640         }
    641         sp<Model> model = mModels.valueAt(index);
    642         mModels.removeItem(handle);
    643         if (model->mState == Model::STATE_ACTIVE) {
    644             mHalInterface->stopRecognition(model->mHandle);
    645             model->mState = Model::STATE_IDLE;
    646         }
    647         status = mHalInterface->unloadSoundModel(handle);
    648         session = model->mCaptureSession;
    649     }
    650     // do not call AudioSystem methods with mLock held
    651     AudioSystem::releaseSoundTriggerSession(session);
    652     return status;
    653 }
    654 
    655 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
    656                                  const sp<IMemory>& dataMemory)
    657 {
    658     ALOGV("startRecognition() model handle %d", handle);
    659     if (mHalInterface == 0) {
    660         return NO_INIT;
    661     }
    662     if (dataMemory == 0 || dataMemory->pointer() == NULL) {
    663         ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
    664         return BAD_VALUE;
    665 
    666     }
    667 
    668     struct sound_trigger_recognition_config *config =
    669             (struct sound_trigger_recognition_config *)dataMemory->pointer();
    670 
    671     if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
    672             config->data_size > (UINT_MAX - config->data_offset) ||
    673             dataMemory->size() < config->data_offset ||
    674             config->data_size > (dataMemory->size() - config->data_offset)) {
    675         ALOGE("startRecognition() data_size is too big");
    676         return BAD_VALUE;
    677     }
    678 
    679     AutoMutex lock(mLock);
    680     if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
    681         return INVALID_OPERATION;
    682     }
    683     sp<Model> model = getModel(handle);
    684     if (model == 0) {
    685         return BAD_VALUE;
    686     }
    687 
    688     if (model->mState == Model::STATE_ACTIVE) {
    689         return INVALID_OPERATION;
    690     }
    691 
    692 
    693     //TODO: get capture handle and device from audio policy service
    694     config->capture_handle = model->mCaptureIOHandle;
    695     config->capture_device = model->mCaptureDevice;
    696     status_t status = mHalInterface->startRecognition(handle, config,
    697                                         SoundTriggerHwService::recognitionCallback,
    698                                         this);
    699 
    700     if (status == NO_ERROR) {
    701         model->mState = Model::STATE_ACTIVE;
    702         model->mConfig = *config;
    703     }
    704 
    705     return status;
    706 }
    707 
    708 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
    709 {
    710     ALOGV("stopRecognition() model handle %d", handle);
    711     if (mHalInterface == 0) {
    712         return NO_INIT;
    713     }
    714     AutoMutex lock(mLock);
    715     sp<Model> model = getModel(handle);
    716     if (model == 0) {
    717         return BAD_VALUE;
    718     }
    719 
    720     if (model->mState != Model::STATE_ACTIVE) {
    721         return INVALID_OPERATION;
    722     }
    723     mHalInterface->stopRecognition(handle);
    724     model->mState = Model::STATE_IDLE;
    725     return NO_ERROR;
    726 }
    727 
    728 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
    729 {
    730     ALOGV("onCallbackEvent type %d", event->mType);
    731 
    732     sp<IMemory> eventMemory = event->mMemory;
    733 
    734     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
    735         return;
    736     }
    737     if (mModuleClients.isEmpty()) {
    738         ALOGI("%s no clients", __func__);
    739         return;
    740     }
    741 
    742     Vector< sp<ModuleClient> > clients;
    743 
    744     switch (event->mType) {
    745     case CallbackEvent::TYPE_RECOGNITION: {
    746         struct sound_trigger_recognition_event *recognitionEvent =
    747                 (struct sound_trigger_recognition_event *)eventMemory->pointer();
    748         {
    749             AutoMutex lock(mLock);
    750             sp<Model> model = getModel(recognitionEvent->model);
    751             if (model == 0) {
    752                 ALOGW("%s model == 0", __func__);
    753                 return;
    754             }
    755             if (model->mState != Model::STATE_ACTIVE) {
    756                 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
    757                 return;
    758             }
    759 
    760             recognitionEvent->capture_session = model->mCaptureSession;
    761             model->mState = Model::STATE_IDLE;
    762             clients.add(model->mModuleClient);
    763         }
    764     } break;
    765     case CallbackEvent::TYPE_SOUNDMODEL: {
    766         struct sound_trigger_model_event *soundmodelEvent =
    767                 (struct sound_trigger_model_event *)eventMemory->pointer();
    768         {
    769             AutoMutex lock(mLock);
    770             sp<Model> model = getModel(soundmodelEvent->model);
    771             if (model == 0) {
    772                 ALOGW("%s model == 0", __func__);
    773                 return;
    774             }
    775             clients.add(model->mModuleClient);
    776         }
    777     } break;
    778     case CallbackEvent::TYPE_SERVICE_STATE: {
    779         {
    780             AutoMutex lock(mLock);
    781             for (size_t i = 0; i < mModuleClients.size(); i++) {
    782                 if (mModuleClients[i] != 0) {
    783                     clients.add(mModuleClients[i]);
    784                 }
    785             }
    786         }
    787     } break;
    788     default:
    789         LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
    790     }
    791 
    792     for (size_t i = 0; i < clients.size(); i++) {
    793         clients[i]->onCallbackEvent(event);
    794     }
    795 }
    796 
    797 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
    798         sound_model_handle_t handle)
    799 {
    800     sp<Model> model;
    801     ssize_t index = mModels.indexOfKey(handle);
    802     if (index >= 0) {
    803         model = mModels.valueAt(index);
    804     }
    805     return model;
    806 }
    807 
    808 // Called with mServiceLock held
    809 void SoundTriggerHwService::Module::setCaptureState_l(bool active)
    810 {
    811     ALOGV("Module::setCaptureState_l %d", active);
    812     sp<SoundTriggerHwService> service;
    813     sound_trigger_service_state_t state;
    814 
    815     Vector< sp<IMemory> > events;
    816     {
    817         AutoMutex lock(mLock);
    818         state = (active && !mDescriptor.properties.concurrent_capture) ?
    819                                         SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
    820 
    821         if (state == mServiceState) {
    822             return;
    823         }
    824 
    825         mServiceState = state;
    826 
    827         service = mService.promote();
    828         if (service == 0) {
    829             return;
    830         }
    831 
    832         if (state == SOUND_TRIGGER_STATE_ENABLED) {
    833             goto exit;
    834         }
    835 
    836         const bool supports_stop_all =
    837                 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
    838 
    839         for (size_t i = 0; i < mModels.size(); i++) {
    840             sp<Model> model = mModels.valueAt(i);
    841             if (model->mState == Model::STATE_ACTIVE) {
    842                 if (mHalInterface != 0 && !supports_stop_all) {
    843                     mHalInterface->stopRecognition(model->mHandle);
    844                 }
    845                 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
    846                 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
    847                     struct sound_trigger_phrase_recognition_event event;
    848                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
    849                     event.num_phrases = model->mConfig.num_phrases;
    850                     for (size_t i = 0; i < event.num_phrases; i++) {
    851                         event.phrase_extras[i] = model->mConfig.phrases[i];
    852                     }
    853                     event.common.status = RECOGNITION_STATUS_ABORT;
    854                     event.common.type = model->mType;
    855                     event.common.model = model->mHandle;
    856                     event.common.data_size = 0;
    857                     sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
    858                     if (eventMemory != 0) {
    859                         events.add(eventMemory);
    860                     }
    861                 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
    862                     struct sound_trigger_generic_recognition_event event;
    863                     memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
    864                     event.common.status = RECOGNITION_STATUS_ABORT;
    865                     event.common.type = model->mType;
    866                     event.common.model = model->mHandle;
    867                     event.common.data_size = 0;
    868                     sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
    869                     if (eventMemory != 0) {
    870                         events.add(eventMemory);
    871                     }
    872                 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
    873                     struct sound_trigger_phrase_recognition_event event;
    874                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
    875                     event.common.status = RECOGNITION_STATUS_ABORT;
    876                     event.common.type = model->mType;
    877                     event.common.model = model->mHandle;
    878                     event.common.data_size = 0;
    879                     sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
    880                     if (eventMemory != 0) {
    881                         events.add(eventMemory);
    882                     }
    883                 } else {
    884                     goto exit;
    885                 }
    886             }
    887         }
    888     }
    889 
    890     for (size_t i = 0; i < events.size(); i++) {
    891         sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
    892                                                             events[i]);
    893         callbackEvent->setModule(this);
    894         service->sendCallbackEvent(callbackEvent);
    895     }
    896 
    897 exit:
    898     service->sendServiceStateEvent(state, this);
    899 }
    900 
    901 
    902 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
    903                                     audio_io_handle_t ioHandle, audio_devices_t device,
    904                                     sound_trigger_sound_model_type_t type,
    905                                     sp<ModuleClient>& moduleClient) :
    906     mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
    907     mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
    908     mModuleClient(moduleClient)
    909 {
    910 }
    911 
    912 #undef LOG_TAG
    913 #define LOG_TAG "SoundTriggerHwService::ModuleClient"
    914 
    915 SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
    916                                                   const sp<ISoundTriggerClient>& client)
    917  : mModule(module), mClient(client)
    918 {
    919 }
    920 
    921 void SoundTriggerHwService::ModuleClient::onFirstRef()
    922 {
    923     sp<IBinder> binder = IInterface::asBinder(mClient);
    924     if (binder != 0) {
    925         binder->linkToDeath(this);
    926     }
    927 }
    928 
    929 SoundTriggerHwService::ModuleClient::~ModuleClient()
    930 {
    931 }
    932 
    933 status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
    934                                                    const Vector<String16>& args __unused) {
    935     String8 result;
    936     return NO_ERROR;
    937 }
    938 
    939 void SoundTriggerHwService::ModuleClient::detach() {
    940     ALOGV("detach()");
    941     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
    942                                IPCThreadState::self()->getCallingUid())) {
    943         return;
    944     }
    945 
    946     {
    947         AutoMutex lock(mLock);
    948         if (mClient != 0) {
    949             IInterface::asBinder(mClient)->unlinkToDeath(this);
    950             mClient.clear();
    951         }
    952     }
    953 
    954     sp<Module> module = mModule.promote();
    955     if (module == 0) {
    956         return;
    957     }
    958     module->detach(this);
    959 }
    960 
    961 status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
    962                                 sound_model_handle_t *handle)
    963 {
    964     ALOGV("loadSoundModel() handle");
    965     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
    966                                IPCThreadState::self()->getCallingUid())) {
    967         return PERMISSION_DENIED;
    968     }
    969 
    970     sp<Module> module = mModule.promote();
    971     if (module == 0) {
    972         return NO_INIT;
    973     }
    974     return module->loadSoundModel(modelMemory, this, handle);
    975 }
    976 
    977 status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
    978 {
    979     ALOGV("unloadSoundModel() model handle %d", handle);
    980     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
    981                                IPCThreadState::self()->getCallingUid())) {
    982         return PERMISSION_DENIED;
    983     }
    984 
    985     sp<Module> module = mModule.promote();
    986     if (module == 0) {
    987         return NO_INIT;
    988     }
    989     return module->unloadSoundModel(handle);
    990 }
    991 
    992 status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
    993                                  const sp<IMemory>& dataMemory)
    994 {
    995     ALOGV("startRecognition() model handle %d", handle);
    996     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
    997                                IPCThreadState::self()->getCallingUid())) {
    998         return PERMISSION_DENIED;
    999     }
   1000 
   1001     sp<Module> module = mModule.promote();
   1002     if (module == 0) {
   1003         return NO_INIT;
   1004     }
   1005     return module->startRecognition(handle, dataMemory);
   1006 }
   1007 
   1008 status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
   1009 {
   1010     ALOGV("stopRecognition() model handle %d", handle);
   1011     if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
   1012                                IPCThreadState::self()->getCallingUid())) {
   1013         return PERMISSION_DENIED;
   1014     }
   1015 
   1016     sp<Module> module = mModule.promote();
   1017     if (module == 0) {
   1018         return NO_INIT;
   1019     }
   1020     return module->stopRecognition(handle);
   1021 }
   1022 
   1023 void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
   1024 {
   1025     ALOGV("ModuleClient::setCaptureState_l %d", active);
   1026     sp<SoundTriggerHwService> service;
   1027     sound_trigger_service_state_t state;
   1028 
   1029     sp<Module> module = mModule.promote();
   1030     if (module == 0) {
   1031         return;
   1032     }
   1033     {
   1034         AutoMutex lock(mLock);
   1035         state = (active && !module->isConcurrentCaptureAllowed()) ?
   1036                                         SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
   1037 
   1038         service = module->service().promote();
   1039         if (service == 0) {
   1040             return;
   1041         }
   1042     }
   1043     service->sendServiceStateEvent(state, this);
   1044 }
   1045 
   1046 void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
   1047 {
   1048     ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
   1049 
   1050     sp<IMemory> eventMemory = event->mMemory;
   1051 
   1052     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
   1053         return;
   1054     }
   1055 
   1056     sp<ISoundTriggerClient> client;
   1057     {
   1058         AutoMutex lock(mLock);
   1059         client = mClient;
   1060     }
   1061 
   1062     if (client != 0) {
   1063         switch (event->mType) {
   1064         case CallbackEvent::TYPE_RECOGNITION: {
   1065             client->onRecognitionEvent(eventMemory);
   1066         } break;
   1067         case CallbackEvent::TYPE_SOUNDMODEL: {
   1068             client->onSoundModelEvent(eventMemory);
   1069         } break;
   1070         case CallbackEvent::TYPE_SERVICE_STATE: {
   1071             client->onServiceStateChange(eventMemory);
   1072         } break;
   1073         default:
   1074             LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
   1075         }
   1076     }
   1077 }
   1078 
   1079 void SoundTriggerHwService::ModuleClient::binderDied(
   1080     const wp<IBinder> &who __unused) {
   1081     ALOGW("client binder died for client %p", this);
   1082     detach();
   1083 }
   1084 
   1085 }; // namespace android
   1086