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(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 
attach(const sound_trigger_module_handle_t handle,const sp<ISoundTriggerClient> & client,sp<ISoundTrigger> & moduleInterface)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 
setCaptureState(bool active)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 
tryLock(Mutex & mutex)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 
dump(int fd,const Vector<String16> & args __unused)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 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)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
recognitionCallback(struct sound_trigger_recognition_event * event,void * cookie)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 
prepareRecognitionEvent(struct sound_trigger_recognition_event * event)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 
sendRecognitionEvent(struct sound_trigger_recognition_event * event,Module * module)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
soundModelCallback(struct sound_trigger_model_event * event,void * cookie)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 
prepareSoundModelEvent(struct sound_trigger_model_event * event)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 
sendSoundModelEvent(struct sound_trigger_model_event * event,Module * module)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 
prepareServiceStateEvent(sound_trigger_service_state_t state)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 
sendServiceStateEvent(sound_trigger_service_state_t state,Module * module)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 
sendServiceStateEvent(sound_trigger_service_state_t state,ModuleClient * moduleClient)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 
sendCallbackEvent(const sp<CallbackEvent> & event)357 void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
358 {
359     mCallbackThread->sendCallbackEvent(event);
360 }
361 
onCallbackEvent(const sp<CallbackEvent> & event)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 
CallbackThread(const wp<SoundTriggerHwService> & service)408 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
409     : mService(service)
410 {
411 }
412 
~CallbackThread()413 SoundTriggerHwService::CallbackThread::~CallbackThread()
414 {
415     while (!mEventQueue.isEmpty()) {
416         mEventQueue[0]->mMemory.clear();
417         mEventQueue.removeAt(0);
418     }
419 }
420 
onFirstRef()421 void SoundTriggerHwService::CallbackThread::onFirstRef()
422 {
423     run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
424 }
425 
threadLoop()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 
exit()452 void SoundTriggerHwService::CallbackThread::exit()
453 {
454     Mutex::Autolock _l(mCallbackLock);
455     requestExit();
456     mCallbackCond.broadcast();
457 }
458 
sendCallbackEvent(const sp<SoundTriggerHwService::CallbackEvent> & event)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 
CallbackEvent(event_type type,sp<IMemory> memory)467 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
468     : mType(type), mMemory(memory)
469 {
470 }
471 
~CallbackEvent()472 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
473 {
474 }
475 
476 
477 #undef LOG_TAG
478 #define LOG_TAG "SoundTriggerHwService::Module"
479 
Module(const sp<SoundTriggerHwService> & service,const sp<SoundTriggerHalInterface> & halInterface,sound_trigger_module_descriptor descriptor)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 
~Module()488 SoundTriggerHwService::Module::~Module() {
489     mModuleClients.clear();
490 }
491 
492 sp<SoundTriggerHwService::ModuleClient>
addClient(const sp<ISoundTriggerClient> & client)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 
detach(const sp<ModuleClient> & moduleClient)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 
loadSoundModel(const sp<IMemory> & modelMemory,sp<ModuleClient> moduleClient,sound_model_handle_t * handle)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 
unloadSoundModel(sound_model_handle_t handle)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 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)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 
stopRecognition(sound_model_handle_t handle)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 
onCallbackEvent(const sp<CallbackEvent> & event)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 
getModel(sound_model_handle_t handle)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
setCaptureState_l(bool active)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 
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)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 
ModuleClient(const sp<Module> & module,const sp<ISoundTriggerClient> & client)915 SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
916                                                   const sp<ISoundTriggerClient>& client)
917  : mModule(module), mClient(client)
918 {
919 }
920 
onFirstRef()921 void SoundTriggerHwService::ModuleClient::onFirstRef()
922 {
923     sp<IBinder> binder = IInterface::asBinder(mClient);
924     if (binder != 0) {
925         binder->linkToDeath(this);
926     }
927 }
928 
~ModuleClient()929 SoundTriggerHwService::ModuleClient::~ModuleClient()
930 {
931 }
932 
dump(int fd __unused,const Vector<String16> & args __unused)933 status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
934                                                    const Vector<String16>& args __unused) {
935     String8 result;
936     return NO_ERROR;
937 }
938 
detach()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 
loadSoundModel(const sp<IMemory> & modelMemory,sound_model_handle_t * handle)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 
unloadSoundModel(sound_model_handle_t handle)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 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)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 
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(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 
setCaptureState_l(bool active)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 
onCallbackEvent(const sp<CallbackEvent> & event)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 
binderDied(const wp<IBinder> & who __unused)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