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 <hardware/sound_trigger.h>
36 #include <ServiceUtilities.h>
37 #include "SoundTriggerHwService.h"
38 
39 namespace android {
40 
41 #ifdef SOUND_TRIGGER_USE_STUB_MODULE
42 #define HW_MODULE_PREFIX "stub"
43 #else
44 #define HW_MODULE_PREFIX "primary"
45 #endif
46 
SoundTriggerHwService()47 SoundTriggerHwService::SoundTriggerHwService()
48     : BnSoundTriggerHwService(),
49       mNextUniqueId(1),
50       mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
51       mCaptureState(false)
52 {
53 }
54 
onFirstRef()55 void SoundTriggerHwService::onFirstRef()
56 {
57     const hw_module_t *mod;
58     int rc;
59     sound_trigger_hw_device *dev;
60 
61     rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod);
62     if (rc != 0) {
63         ALOGE("couldn't load sound trigger module %s.%s (%s)",
64               SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc));
65         return;
66     }
67     rc = sound_trigger_hw_device_open(mod, &dev);
68     if (rc != 0) {
69         ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
70               SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc));
71         return;
72     }
73     if (dev->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
74         dev->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
75         ALOGE("wrong sound trigger hw device version %04x", dev->common.version);
76         return;
77     }
78 
79     sound_trigger_module_descriptor descriptor;
80     rc = dev->get_properties(dev, &descriptor.properties);
81     if (rc != 0) {
82         ALOGE("could not read implementation properties");
83         return;
84     }
85     descriptor.handle =
86             (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
87     ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
88                                                  descriptor.handle);
89 
90     sp<ISoundTriggerClient> client;
91     sp<Module> module = new Module(this, dev, descriptor, client);
92     mModules.add(descriptor.handle, module);
93     mCallbackThread = new CallbackThread(this);
94 }
95 
~SoundTriggerHwService()96 SoundTriggerHwService::~SoundTriggerHwService()
97 {
98     if (mCallbackThread != 0) {
99         mCallbackThread->exit();
100     }
101     for (size_t i = 0; i < mModules.size(); i++) {
102         sound_trigger_hw_device_close(mModules.valueAt(i)->hwDevice());
103     }
104 }
105 
listModules(struct sound_trigger_module_descriptor * modules,uint32_t * numModules)106 status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
107                              uint32_t *numModules)
108 {
109     ALOGV("listModules");
110     if (!captureHotwordAllowed()) {
111         return PERMISSION_DENIED;
112     }
113 
114     AutoMutex lock(mServiceLock);
115     if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
116         return BAD_VALUE;
117     }
118     size_t maxModules = *numModules;
119     *numModules = mModules.size();
120     for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
121         modules[i] = mModules.valueAt(i)->descriptor();
122     }
123     return NO_ERROR;
124 }
125 
attach(const sound_trigger_module_handle_t handle,const sp<ISoundTriggerClient> & client,sp<ISoundTrigger> & moduleInterface)126 status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
127                         const sp<ISoundTriggerClient>& client,
128                         sp<ISoundTrigger>& moduleInterface)
129 {
130     ALOGV("attach module %d", handle);
131     if (!captureHotwordAllowed()) {
132         return PERMISSION_DENIED;
133     }
134 
135     AutoMutex lock(mServiceLock);
136     moduleInterface.clear();
137     if (client == 0) {
138         return BAD_VALUE;
139     }
140     ssize_t index = mModules.indexOfKey(handle);
141     if (index < 0) {
142         return BAD_VALUE;
143     }
144     sp<Module> module = mModules.valueAt(index);
145 
146     module->setClient(client);
147     IInterface::asBinder(client)->linkToDeath(module);
148     moduleInterface = module;
149 
150     module->setCaptureState_l(mCaptureState);
151 
152     return NO_ERROR;
153 }
154 
setCaptureState(bool active)155 status_t SoundTriggerHwService::setCaptureState(bool active)
156 {
157     ALOGV("setCaptureState %d", active);
158     AutoMutex lock(mServiceLock);
159     mCaptureState = active;
160     for (size_t i = 0; i < mModules.size(); i++) {
161         mModules.valueAt(i)->setCaptureState_l(active);
162     }
163     return NO_ERROR;
164 }
165 
166 
detachModule(sp<Module> module)167 void SoundTriggerHwService::detachModule(sp<Module> module)
168 {
169     ALOGV("detachModule");
170     AutoMutex lock(mServiceLock);
171     module->clearClient();
172 }
173 
174 
175 static const int kDumpLockRetries = 50;
176 static const int kDumpLockSleep = 60000;
177 
tryLock(Mutex & mutex)178 static bool tryLock(Mutex& mutex)
179 {
180     bool locked = false;
181     for (int i = 0; i < kDumpLockRetries; ++i) {
182         if (mutex.tryLock() == NO_ERROR) {
183             locked = true;
184             break;
185         }
186         usleep(kDumpLockSleep);
187     }
188     return locked;
189 }
190 
dump(int fd,const Vector<String16> & args __unused)191 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
192     String8 result;
193     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
194         result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
195         write(fd, result.string(), result.size());
196     } else {
197         bool locked = tryLock(mServiceLock);
198         // failed to lock - SoundTriggerHwService is probably deadlocked
199         if (!locked) {
200             result.append("SoundTriggerHwService may be deadlocked\n");
201             write(fd, result.string(), result.size());
202         }
203 
204         if (locked) mServiceLock.unlock();
205     }
206     return NO_ERROR;
207 }
208 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)209 status_t SoundTriggerHwService::onTransact(
210     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
211     return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
212 }
213 
214 
215 // static
recognitionCallback(struct sound_trigger_recognition_event * event,void * cookie)216 void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
217                                                 void *cookie)
218 {
219     Module *module = (Module *)cookie;
220     if (module == NULL) {
221         return;
222     }
223     sp<SoundTriggerHwService> service = module->service().promote();
224     if (service == 0) {
225         return;
226     }
227 
228     service->sendRecognitionEvent(event, module);
229 }
230 
prepareRecognitionEvent_l(struct sound_trigger_recognition_event * event)231 sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
232                                                     struct sound_trigger_recognition_event *event)
233 {
234     sp<IMemory> eventMemory;
235 
236     //sanitize event
237     switch (event->type) {
238     case SOUND_MODEL_TYPE_KEYPHRASE:
239         ALOGW_IF(event->data_size != 0 && event->data_offset !=
240                     sizeof(struct sound_trigger_phrase_recognition_event),
241                     "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
242                     event->data_offset);
243         event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
244         break;
245     case SOUND_MODEL_TYPE_GENERIC:
246         ALOGW_IF(event->data_size != 0 && event->data_offset !=
247                     sizeof(struct sound_trigger_generic_recognition_event),
248                     "prepareRecognitionEvent_l(): invalid data offset %u for generic event type",
249                     event->data_offset);
250         event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
251         break;
252     case SOUND_MODEL_TYPE_UNKNOWN:
253         ALOGW_IF(event->data_size != 0 && event->data_offset !=
254                     sizeof(struct sound_trigger_recognition_event),
255                     "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
256                     event->data_offset);
257         event->data_offset = sizeof(struct sound_trigger_recognition_event);
258         break;
259     default:
260         return eventMemory;
261     }
262 
263     size_t size = event->data_offset + event->data_size;
264     eventMemory = mMemoryDealer->allocate(size);
265     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
266         eventMemory.clear();
267         return eventMemory;
268     }
269     memcpy(eventMemory->pointer(), event, size);
270 
271     return eventMemory;
272 }
273 
sendRecognitionEvent(struct sound_trigger_recognition_event * event,Module * module)274 void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
275                                                  Module *module)
276  {
277      AutoMutex lock(mServiceLock);
278      if (module == NULL) {
279          return;
280      }
281      sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
282      if (eventMemory == 0) {
283          return;
284      }
285      sp<Module> strongModule;
286      for (size_t i = 0; i < mModules.size(); i++) {
287          if (mModules.valueAt(i).get() == module) {
288              strongModule = mModules.valueAt(i);
289              break;
290          }
291      }
292      if (strongModule == 0) {
293          return;
294      }
295 
296      sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
297                                                   eventMemory, strongModule));
298 }
299 
300 // static
soundModelCallback(struct sound_trigger_model_event * event,void * cookie)301 void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
302                                                void *cookie)
303 {
304     Module *module = (Module *)cookie;
305     if (module == NULL) {
306         return;
307     }
308     sp<SoundTriggerHwService> service = module->service().promote();
309     if (service == 0) {
310         return;
311     }
312 
313     service->sendSoundModelEvent(event, module);
314 }
315 
prepareSoundModelEvent_l(struct sound_trigger_model_event * event)316 sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
317 {
318     sp<IMemory> eventMemory;
319 
320     size_t size = event->data_offset + event->data_size;
321     eventMemory = mMemoryDealer->allocate(size);
322     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
323         eventMemory.clear();
324         return eventMemory;
325     }
326     memcpy(eventMemory->pointer(), event, size);
327 
328     return eventMemory;
329 }
330 
sendSoundModelEvent(struct sound_trigger_model_event * event,Module * module)331 void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
332                                                 Module *module)
333 {
334     AutoMutex lock(mServiceLock);
335     sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
336     if (eventMemory == 0) {
337         return;
338     }
339     sp<Module> strongModule;
340     for (size_t i = 0; i < mModules.size(); i++) {
341         if (mModules.valueAt(i).get() == module) {
342             strongModule = mModules.valueAt(i);
343             break;
344         }
345     }
346     if (strongModule == 0) {
347         return;
348     }
349     sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
350                                                  eventMemory, strongModule));
351 }
352 
353 
prepareServiceStateEvent_l(sound_trigger_service_state_t state)354 sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
355 {
356     sp<IMemory> eventMemory;
357 
358     size_t size = sizeof(sound_trigger_service_state_t);
359     eventMemory = mMemoryDealer->allocate(size);
360     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
361         eventMemory.clear();
362         return eventMemory;
363     }
364     *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
365     return eventMemory;
366 }
367 
368 // call with mServiceLock held
sendServiceStateEvent_l(sound_trigger_service_state_t state,Module * module)369 void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
370                                                   Module *module)
371 {
372     sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
373     if (eventMemory == 0) {
374         return;
375     }
376     sp<Module> strongModule;
377     for (size_t i = 0; i < mModules.size(); i++) {
378         if (mModules.valueAt(i).get() == module) {
379             strongModule = mModules.valueAt(i);
380             break;
381         }
382     }
383     if (strongModule == 0) {
384         return;
385     }
386     sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
387                                                  eventMemory, strongModule));
388 }
389 
390 // call with mServiceLock held
sendCallbackEvent_l(const sp<CallbackEvent> & event)391 void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
392 {
393     mCallbackThread->sendCallbackEvent(event);
394 }
395 
onCallbackEvent(const sp<CallbackEvent> & event)396 void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
397 {
398     ALOGV("onCallbackEvent");
399     sp<Module> module;
400     {
401         AutoMutex lock(mServiceLock);
402         module = event->mModule.promote();
403         if (module == 0) {
404             return;
405         }
406     }
407     module->onCallbackEvent(event);
408     {
409         AutoMutex lock(mServiceLock);
410         // clear now to execute with mServiceLock locked
411         event->mMemory.clear();
412     }
413 }
414 
415 #undef LOG_TAG
416 #define LOG_TAG "SoundTriggerHwService::CallbackThread"
417 
CallbackThread(const wp<SoundTriggerHwService> & service)418 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
419     : mService(service)
420 {
421 }
422 
~CallbackThread()423 SoundTriggerHwService::CallbackThread::~CallbackThread()
424 {
425     while (!mEventQueue.isEmpty()) {
426         mEventQueue[0]->mMemory.clear();
427         mEventQueue.removeAt(0);
428     }
429 }
430 
onFirstRef()431 void SoundTriggerHwService::CallbackThread::onFirstRef()
432 {
433     run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
434 }
435 
threadLoop()436 bool SoundTriggerHwService::CallbackThread::threadLoop()
437 {
438     while (!exitPending()) {
439         sp<CallbackEvent> event;
440         sp<SoundTriggerHwService> service;
441         {
442             Mutex::Autolock _l(mCallbackLock);
443             while (mEventQueue.isEmpty() && !exitPending()) {
444                 ALOGV("CallbackThread::threadLoop() sleep");
445                 mCallbackCond.wait(mCallbackLock);
446                 ALOGV("CallbackThread::threadLoop() wake up");
447             }
448             if (exitPending()) {
449                 break;
450             }
451             event = mEventQueue[0];
452             mEventQueue.removeAt(0);
453             service = mService.promote();
454         }
455         if (service != 0) {
456             service->onCallbackEvent(event);
457         }
458     }
459     return false;
460 }
461 
exit()462 void SoundTriggerHwService::CallbackThread::exit()
463 {
464     Mutex::Autolock _l(mCallbackLock);
465     requestExit();
466     mCallbackCond.broadcast();
467 }
468 
sendCallbackEvent(const sp<SoundTriggerHwService::CallbackEvent> & event)469 void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
470                         const sp<SoundTriggerHwService::CallbackEvent>& event)
471 {
472     AutoMutex lock(mCallbackLock);
473     mEventQueue.add(event);
474     mCallbackCond.signal();
475 }
476 
CallbackEvent(event_type type,sp<IMemory> memory,wp<Module> module)477 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory,
478                                                     wp<Module> module)
479     : mType(type), mMemory(memory), mModule(module)
480 {
481 }
482 
~CallbackEvent()483 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
484 {
485 }
486 
487 
488 #undef LOG_TAG
489 #define LOG_TAG "SoundTriggerHwService::Module"
490 
Module(const sp<SoundTriggerHwService> & service,sound_trigger_hw_device * hwDevice,sound_trigger_module_descriptor descriptor,const sp<ISoundTriggerClient> & client)491 SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
492                                       sound_trigger_hw_device* hwDevice,
493                                       sound_trigger_module_descriptor descriptor,
494                                       const sp<ISoundTriggerClient>& client)
495  : mService(service), mHwDevice(hwDevice), mDescriptor(descriptor),
496    mClient(client), mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
497 {
498 }
499 
~Module()500 SoundTriggerHwService::Module::~Module() {
501 }
502 
detach()503 void SoundTriggerHwService::Module::detach() {
504     ALOGV("detach()");
505     if (!captureHotwordAllowed()) {
506         return;
507     }
508     {
509         AutoMutex lock(mLock);
510         for (size_t i = 0; i < mModels.size(); i++) {
511             sp<Model> model = mModels.valueAt(i);
512             ALOGV("detach() unloading model %d", model->mHandle);
513             if (model->mState == Model::STATE_ACTIVE) {
514                 mHwDevice->stop_recognition(mHwDevice, model->mHandle);
515             }
516             mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
517         }
518         mModels.clear();
519     }
520     if (mClient != 0) {
521         IInterface::asBinder(mClient)->unlinkToDeath(this);
522     }
523     sp<SoundTriggerHwService> service = mService.promote();
524     if (service == 0) {
525         return;
526     }
527     service->detachModule(this);
528 }
529 
loadSoundModel(const sp<IMemory> & modelMemory,sound_model_handle_t * handle)530 status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
531                                 sound_model_handle_t *handle)
532 {
533     ALOGV("loadSoundModel() handle");
534     if (!captureHotwordAllowed()) {
535         return PERMISSION_DENIED;
536     }
537 
538     if (modelMemory == 0 || modelMemory->pointer() == NULL) {
539         ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
540         return BAD_VALUE;
541     }
542     struct sound_trigger_sound_model *sound_model =
543             (struct sound_trigger_sound_model *)modelMemory->pointer();
544 
545     AutoMutex lock(mLock);
546 
547     if (mModels.size() >= mDescriptor.properties.max_sound_models) {
548         ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
549               mDescriptor.properties.max_sound_models);
550         return INVALID_OPERATION;
551     }
552 
553     status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model,
554                                                   SoundTriggerHwService::soundModelCallback,
555                                                   this, handle);
556 
557     if (status != NO_ERROR) {
558         return status;
559     }
560     audio_session_t session;
561     audio_io_handle_t ioHandle;
562     audio_devices_t device;
563 
564     status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
565     if (status != NO_ERROR) {
566         return status;
567     }
568 
569     sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
570     mModels.replaceValueFor(*handle, model);
571 
572     return status;
573 }
574 
unloadSoundModel(sound_model_handle_t handle)575 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
576 {
577     ALOGV("unloadSoundModel() model handle %d", handle);
578     if (!captureHotwordAllowed()) {
579         return PERMISSION_DENIED;
580     }
581 
582     AutoMutex lock(mLock);
583     return unloadSoundModel_l(handle);
584 }
585 
unloadSoundModel_l(sound_model_handle_t handle)586 status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
587 {
588     ssize_t index = mModels.indexOfKey(handle);
589     if (index < 0) {
590         return BAD_VALUE;
591     }
592     sp<Model> model = mModels.valueAt(index);
593     mModels.removeItem(handle);
594     if (model->mState == Model::STATE_ACTIVE) {
595         mHwDevice->stop_recognition(mHwDevice, model->mHandle);
596         model->mState = Model::STATE_IDLE;
597     }
598     AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
599     return mHwDevice->unload_sound_model(mHwDevice, handle);
600 }
601 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)602 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
603                                  const sp<IMemory>& dataMemory)
604 {
605     ALOGV("startRecognition() model handle %d", handle);
606     if (!captureHotwordAllowed()) {
607         return PERMISSION_DENIED;
608     }
609 
610     if (dataMemory != 0 && dataMemory->pointer() == NULL) {
611         ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
612         return BAD_VALUE;
613 
614     }
615     AutoMutex lock(mLock);
616     if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
617         return INVALID_OPERATION;
618     }
619     sp<Model> model = getModel(handle);
620     if (model == 0) {
621         return BAD_VALUE;
622     }
623     if ((dataMemory == 0) ||
624             (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
625         return BAD_VALUE;
626     }
627 
628     if (model->mState == Model::STATE_ACTIVE) {
629         return INVALID_OPERATION;
630     }
631 
632     struct sound_trigger_recognition_config *config =
633             (struct sound_trigger_recognition_config *)dataMemory->pointer();
634 
635     //TODO: get capture handle and device from audio policy service
636     config->capture_handle = model->mCaptureIOHandle;
637     config->capture_device = model->mCaptureDevice;
638     status_t status = mHwDevice->start_recognition(mHwDevice, handle, config,
639                                         SoundTriggerHwService::recognitionCallback,
640                                         this);
641 
642     if (status == NO_ERROR) {
643         model->mState = Model::STATE_ACTIVE;
644         model->mConfig = *config;
645     }
646 
647     return status;
648 }
649 
stopRecognition(sound_model_handle_t handle)650 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
651 {
652     ALOGV("stopRecognition() model handle %d", handle);
653     if (!captureHotwordAllowed()) {
654         return PERMISSION_DENIED;
655     }
656 
657     AutoMutex lock(mLock);
658     sp<Model> model = getModel(handle);
659     if (model == 0) {
660         return BAD_VALUE;
661     }
662 
663     if (model->mState != Model::STATE_ACTIVE) {
664         return INVALID_OPERATION;
665     }
666     mHwDevice->stop_recognition(mHwDevice, handle);
667     model->mState = Model::STATE_IDLE;
668     return NO_ERROR;
669 }
670 
671 
onCallbackEvent(const sp<CallbackEvent> & event)672 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
673 {
674     ALOGV("onCallbackEvent type %d", event->mType);
675 
676     sp<IMemory> eventMemory = event->mMemory;
677 
678     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
679         return;
680     }
681     if (mClient == 0) {
682         ALOGI("%s mClient == 0", __func__);
683         return;
684     }
685 
686     switch (event->mType) {
687     case CallbackEvent::TYPE_RECOGNITION: {
688         struct sound_trigger_recognition_event *recognitionEvent =
689                 (struct sound_trigger_recognition_event *)eventMemory->pointer();
690         sp<ISoundTriggerClient> client;
691         {
692             AutoMutex lock(mLock);
693             sp<Model> model = getModel(recognitionEvent->model);
694             if (model == 0) {
695                 ALOGW("%s model == 0", __func__);
696                 return;
697             }
698             if (model->mState != Model::STATE_ACTIVE) {
699                 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
700                 return;
701             }
702 
703             recognitionEvent->capture_session = model->mCaptureSession;
704             model->mState = Model::STATE_IDLE;
705             client = mClient;
706         }
707         if (client != 0) {
708             client->onRecognitionEvent(eventMemory);
709         }
710     } break;
711     case CallbackEvent::TYPE_SOUNDMODEL: {
712         struct sound_trigger_model_event *soundmodelEvent =
713                 (struct sound_trigger_model_event *)eventMemory->pointer();
714         sp<ISoundTriggerClient> client;
715         {
716             AutoMutex lock(mLock);
717             sp<Model> model = getModel(soundmodelEvent->model);
718             if (model == 0) {
719                 ALOGW("%s model == 0", __func__);
720                 return;
721             }
722             client = mClient;
723         }
724         if (client != 0) {
725             client->onSoundModelEvent(eventMemory);
726         }
727     } break;
728     case CallbackEvent::TYPE_SERVICE_STATE: {
729         sp<ISoundTriggerClient> client;
730         {
731             AutoMutex lock(mLock);
732             client = mClient;
733         }
734         if (client != 0) {
735             client->onServiceStateChange(eventMemory);
736         }
737     } break;
738     default:
739         LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
740     }
741 }
742 
getModel(sound_model_handle_t handle)743 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
744         sound_model_handle_t handle)
745 {
746     sp<Model> model;
747     ssize_t index = mModels.indexOfKey(handle);
748     if (index >= 0) {
749         model = mModels.valueAt(index);
750     }
751     return model;
752 }
753 
binderDied(const wp<IBinder> & who __unused)754 void SoundTriggerHwService::Module::binderDied(
755     const wp<IBinder> &who __unused) {
756     ALOGW("client binder died for module %d", mDescriptor.handle);
757     detach();
758 }
759 
760 // Called with mServiceLock held
setCaptureState_l(bool active)761 void SoundTriggerHwService::Module::setCaptureState_l(bool active)
762 {
763     ALOGV("Module::setCaptureState_l %d", active);
764     sp<SoundTriggerHwService> service;
765     sound_trigger_service_state_t state;
766 
767     Vector< sp<IMemory> > events;
768     {
769         AutoMutex lock(mLock);
770         state = (active && !mDescriptor.properties.concurrent_capture) ?
771                                         SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
772 
773         if (state == mServiceState) {
774             return;
775         }
776 
777         mServiceState = state;
778 
779         service = mService.promote();
780         if (service == 0) {
781             return;
782         }
783 
784         if (state == SOUND_TRIGGER_STATE_ENABLED) {
785             goto exit;
786         }
787 
788         const bool supports_stop_all =
789             (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
790              mHwDevice->stop_all_recognitions);
791 
792         if (supports_stop_all) {
793             mHwDevice->stop_all_recognitions(mHwDevice);
794         }
795 
796         for (size_t i = 0; i < mModels.size(); i++) {
797             sp<Model> model = mModels.valueAt(i);
798             if (model->mState == Model::STATE_ACTIVE) {
799                 if (!supports_stop_all) {
800                     mHwDevice->stop_recognition(mHwDevice, model->mHandle);
801                 }
802                 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
803                 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
804                     struct sound_trigger_phrase_recognition_event event;
805                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
806                     event.num_phrases = model->mConfig.num_phrases;
807                     for (size_t i = 0; i < event.num_phrases; i++) {
808                         event.phrase_extras[i] = model->mConfig.phrases[i];
809                     }
810                     event.common.status = RECOGNITION_STATUS_ABORT;
811                     event.common.type = model->mType;
812                     event.common.model = model->mHandle;
813                     event.common.data_size = 0;
814                     sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
815                     if (eventMemory != 0) {
816                         events.add(eventMemory);
817                     }
818                 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
819                     struct sound_trigger_generic_recognition_event event;
820                     memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
821                     event.common.status = RECOGNITION_STATUS_ABORT;
822                     event.common.type = model->mType;
823                     event.common.model = model->mHandle;
824                     event.common.data_size = 0;
825                     sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
826                     if (eventMemory != 0) {
827                         events.add(eventMemory);
828                     }
829                 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
830                     struct sound_trigger_phrase_recognition_event event;
831                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
832                     event.common.status = RECOGNITION_STATUS_ABORT;
833                     event.common.type = model->mType;
834                     event.common.model = model->mHandle;
835                     event.common.data_size = 0;
836                     sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
837                     if (eventMemory != 0) {
838                         events.add(eventMemory);
839                     }
840                 } else {
841                     goto exit;
842                 }
843             }
844         }
845     }
846 
847     for (size_t i = 0; i < events.size(); i++) {
848         service->sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, events[i],
849                                                      this));
850     }
851 
852 exit:
853     service->sendServiceStateEvent_l(state, this);
854 }
855 
856 
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)857 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
858                                     audio_io_handle_t ioHandle, audio_devices_t device,
859                                     sound_trigger_sound_model_type_t type) :
860     mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
861     mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type)
862 {
863 
864 }
865 
dump(int fd __unused,const Vector<String16> & args __unused)866 status_t SoundTriggerHwService::Module::dump(int fd __unused,
867                                              const Vector<String16>& args __unused) {
868     String8 result;
869     return NO_ERROR;
870 }
871 
872 }; // namespace android
873