• 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 <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 
SoundTriggerHwService()43 SoundTriggerHwService::SoundTriggerHwService()
44     : BnSoundTriggerHwService(),
45       mNextUniqueId(1),
46       mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
47       mCaptureState(false)
48 {
49 }
50 
onFirstRef()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 
~SoundTriggerHwService()78 SoundTriggerHwService::~SoundTriggerHwService()
79 {
80     if (mCallbackThread != 0) {
81         mCallbackThread->exit();
82     }
83 }
84 
listModules(const String16 & opPackageName,struct sound_trigger_module_descriptor * modules,uint32_t * numModules)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 
attach(const String16 & opPackageName,const sound_trigger_module_handle_t handle,const sp<ISoundTriggerClient> & client,sp<ISoundTrigger> & moduleInterface)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 
setCaptureState(bool active)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 
dumpTryLock(Mutex & mutex)156 static bool dumpTryLock(Mutex& mutex)
157 {
158     status_t err = mutex.timedLock(kDumpLockTimeoutNs);
159     return err == NO_ERROR;
160 }
161 
dump(int fd,const Vector<String16> & args __unused)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 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)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
recognitionCallback(struct sound_trigger_recognition_event * event,void * cookie)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 
prepareRecognitionEvent(struct sound_trigger_recognition_event * event)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 
sendRecognitionEvent(struct sound_trigger_recognition_event * event,Module * module)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
soundModelCallback(struct sound_trigger_model_event * event,void * cookie)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 
prepareSoundModelEvent(struct sound_trigger_model_event * event)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 
sendSoundModelEvent(struct sound_trigger_model_event * event,Module * module)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 
prepareServiceStateEvent(sound_trigger_service_state_t state)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 
sendServiceStateEvent(sound_trigger_service_state_t state,Module * module)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 
sendServiceStateEvent(sound_trigger_service_state_t state,ModuleClient * moduleClient)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 
sendCallbackEvent(const sp<CallbackEvent> & event)350 void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
351 {
352     mCallbackThread->sendCallbackEvent(event);
353 }
354 
onCallbackEvent(const sp<CallbackEvent> & event)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 
CallbackThread(const wp<SoundTriggerHwService> & service)401 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
402     : mService(service)
403 {
404 }
405 
~CallbackThread()406 SoundTriggerHwService::CallbackThread::~CallbackThread()
407 {
408     while (!mEventQueue.isEmpty()) {
409         mEventQueue[0]->mMemory.clear();
410         mEventQueue.removeAt(0);
411     }
412 }
413 
onFirstRef()414 void SoundTriggerHwService::CallbackThread::onFirstRef()
415 {
416     run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
417 }
418 
threadLoop()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 
exit()445 void SoundTriggerHwService::CallbackThread::exit()
446 {
447     Mutex::Autolock _l(mCallbackLock);
448     requestExit();
449     mCallbackCond.broadcast();
450 }
451 
sendCallbackEvent(const sp<SoundTriggerHwService::CallbackEvent> & event)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 
CallbackEvent(event_type type,sp<IMemory> memory)460 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
461     : mType(type), mMemory(memory)
462 {
463 }
464 
~CallbackEvent()465 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
466 {
467 }
468 
469 
470 #undef LOG_TAG
471 #define LOG_TAG "SoundTriggerHwService::Module"
472 
Module(const sp<SoundTriggerHwService> & service,const sp<SoundTriggerHalInterface> & halInterface,sound_trigger_module_descriptor descriptor)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 
~Module()481 SoundTriggerHwService::Module::~Module() {
482     mModuleClients.clear();
483 }
484 
485 sp<SoundTriggerHwService::ModuleClient>
addClient(const sp<ISoundTriggerClient> & client,const String16 & opPackageName)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 
detach(const sp<ModuleClient> & moduleClient)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 
loadSoundModel(const sp<IMemory> & modelMemory,sp<ModuleClient> moduleClient,sound_model_handle_t * handle)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 
unloadSoundModel(sound_model_handle_t handle)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 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)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 
stopRecognition(sound_model_handle_t handle)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 
getModelState(sound_model_handle_t handle)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 
onCallbackEvent(const sp<CallbackEvent> & event)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 
getModel(sound_model_handle_t handle)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
setCaptureState_l(bool active)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 
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)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 
ModuleClient(const sp<Module> & module,const sp<ISoundTriggerClient> & client,const String16 & opPackageName)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 
onFirstRef()927 void SoundTriggerHwService::ModuleClient::onFirstRef()
928 {
929     sp<IBinder> binder = IInterface::asBinder(mClient);
930     if (binder != 0) {
931         binder->linkToDeath(this);
932     }
933 }
934 
~ModuleClient()935 SoundTriggerHwService::ModuleClient::~ModuleClient()
936 {
937 }
938 
dump(int fd __unused,const Vector<String16> & args __unused)939 status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
940                                                    const Vector<String16>& args __unused) {
941     String8 result;
942     return NO_ERROR;
943 }
944 
detach()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 
loadSoundModel(const sp<IMemory> & modelMemory,sound_model_handle_t * handle)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 
unloadSoundModel(sound_model_handle_t handle)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 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)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 
stopRecognition(sound_model_handle_t handle)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 
getModelState(sound_model_handle_t handle)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 
setCaptureState_l(bool active)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 
onCallbackEvent(const sp<CallbackEvent> & event)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 
binderDied(const wp<IBinder> & who __unused)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