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