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