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