• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "SoundTriggerHwService"
18 //#define LOG_NDEBUG 0
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <pthread.h>
24 
25 #include <system/sound_trigger.h>
26 #include <cutils/atomic.h>
27 #include <cutils/properties.h>
28 #include <hardware/hardware.h>
29 #include <media/AudioSystem.h>
30 #include <utils/Errors.h>
31 #include <utils/Log.h>
32 #include <binder/IServiceManager.h>
33 #include <binder/MemoryBase.h>
34 #include <binder/MemoryHeapBase.h>
35 #include <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     size_t structSize;
546     if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
547         structSize = sizeof(struct sound_trigger_phrase_sound_model);
548     } else {
549         structSize = sizeof(struct sound_trigger_sound_model);
550     }
551 
552     if (sound_model->data_offset < structSize ||
553            sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
554            modelMemory->size() < sound_model->data_offset ||
555            sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
556         android_errorWriteLog(0x534e4554, "30148546");
557         ALOGE("loadSoundModel() data_size is too big");
558         return BAD_VALUE;
559     }
560 
561     AutoMutex lock(mLock);
562 
563     if (mModels.size() >= mDescriptor.properties.max_sound_models) {
564         ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
565               mDescriptor.properties.max_sound_models);
566         return INVALID_OPERATION;
567     }
568 
569     status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model,
570                                                   SoundTriggerHwService::soundModelCallback,
571                                                   this, handle);
572 
573     if (status != NO_ERROR) {
574         return status;
575     }
576     audio_session_t session;
577     audio_io_handle_t ioHandle;
578     audio_devices_t device;
579 
580     status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
581     if (status != NO_ERROR) {
582         return status;
583     }
584 
585     sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
586     mModels.replaceValueFor(*handle, model);
587 
588     return status;
589 }
590 
unloadSoundModel(sound_model_handle_t handle)591 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
592 {
593     ALOGV("unloadSoundModel() model handle %d", handle);
594     if (!captureHotwordAllowed()) {
595         return PERMISSION_DENIED;
596     }
597 
598     AutoMutex lock(mLock);
599     return unloadSoundModel_l(handle);
600 }
601 
unloadSoundModel_l(sound_model_handle_t handle)602 status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
603 {
604     ssize_t index = mModels.indexOfKey(handle);
605     if (index < 0) {
606         return BAD_VALUE;
607     }
608     sp<Model> model = mModels.valueAt(index);
609     mModels.removeItem(handle);
610     if (model->mState == Model::STATE_ACTIVE) {
611         mHwDevice->stop_recognition(mHwDevice, model->mHandle);
612         model->mState = Model::STATE_IDLE;
613     }
614     AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
615     return mHwDevice->unload_sound_model(mHwDevice, handle);
616 }
617 
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)618 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
619                                  const sp<IMemory>& dataMemory)
620 {
621     ALOGV("startRecognition() model handle %d", handle);
622     if (!captureHotwordAllowed()) {
623         return PERMISSION_DENIED;
624     }
625 
626     if (dataMemory == 0 || dataMemory->pointer() == NULL) {
627         ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
628         return BAD_VALUE;
629 
630     }
631 
632     struct sound_trigger_recognition_config *config =
633             (struct sound_trigger_recognition_config *)dataMemory->pointer();
634 
635     if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
636             config->data_size > (UINT_MAX - config->data_offset) ||
637             dataMemory->size() < config->data_offset ||
638             config->data_size > (dataMemory->size() - config->data_offset)) {
639         ALOGE("startRecognition() data_size is too big");
640         return BAD_VALUE;
641     }
642 
643     AutoMutex lock(mLock);
644     if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
645         return INVALID_OPERATION;
646     }
647     sp<Model> model = getModel(handle);
648     if (model == 0) {
649         return BAD_VALUE;
650     }
651 
652     if (model->mState == Model::STATE_ACTIVE) {
653         return INVALID_OPERATION;
654     }
655 
656 
657     //TODO: get capture handle and device from audio policy service
658     config->capture_handle = model->mCaptureIOHandle;
659     config->capture_device = model->mCaptureDevice;
660     status_t status = mHwDevice->start_recognition(mHwDevice, handle, config,
661                                         SoundTriggerHwService::recognitionCallback,
662                                         this);
663 
664     if (status == NO_ERROR) {
665         model->mState = Model::STATE_ACTIVE;
666         model->mConfig = *config;
667     }
668 
669     return status;
670 }
671 
stopRecognition(sound_model_handle_t handle)672 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
673 {
674     ALOGV("stopRecognition() model handle %d", handle);
675     if (!captureHotwordAllowed()) {
676         return PERMISSION_DENIED;
677     }
678 
679     AutoMutex lock(mLock);
680     sp<Model> model = getModel(handle);
681     if (model == 0) {
682         return BAD_VALUE;
683     }
684 
685     if (model->mState != Model::STATE_ACTIVE) {
686         return INVALID_OPERATION;
687     }
688     mHwDevice->stop_recognition(mHwDevice, handle);
689     model->mState = Model::STATE_IDLE;
690     return NO_ERROR;
691 }
692 
693 
onCallbackEvent(const sp<CallbackEvent> & event)694 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
695 {
696     ALOGV("onCallbackEvent type %d", event->mType);
697 
698     sp<IMemory> eventMemory = event->mMemory;
699 
700     if (eventMemory == 0 || eventMemory->pointer() == NULL) {
701         return;
702     }
703     if (mClient == 0) {
704         ALOGI("%s mClient == 0", __func__);
705         return;
706     }
707 
708     switch (event->mType) {
709     case CallbackEvent::TYPE_RECOGNITION: {
710         struct sound_trigger_recognition_event *recognitionEvent =
711                 (struct sound_trigger_recognition_event *)eventMemory->pointer();
712         sp<ISoundTriggerClient> client;
713         {
714             AutoMutex lock(mLock);
715             sp<Model> model = getModel(recognitionEvent->model);
716             if (model == 0) {
717                 ALOGW("%s model == 0", __func__);
718                 return;
719             }
720             if (model->mState != Model::STATE_ACTIVE) {
721                 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
722                 return;
723             }
724 
725             recognitionEvent->capture_session = model->mCaptureSession;
726             model->mState = Model::STATE_IDLE;
727             client = mClient;
728         }
729         if (client != 0) {
730             client->onRecognitionEvent(eventMemory);
731         }
732     } break;
733     case CallbackEvent::TYPE_SOUNDMODEL: {
734         struct sound_trigger_model_event *soundmodelEvent =
735                 (struct sound_trigger_model_event *)eventMemory->pointer();
736         sp<ISoundTriggerClient> client;
737         {
738             AutoMutex lock(mLock);
739             sp<Model> model = getModel(soundmodelEvent->model);
740             if (model == 0) {
741                 ALOGW("%s model == 0", __func__);
742                 return;
743             }
744             client = mClient;
745         }
746         if (client != 0) {
747             client->onSoundModelEvent(eventMemory);
748         }
749     } break;
750     case CallbackEvent::TYPE_SERVICE_STATE: {
751         sp<ISoundTriggerClient> client;
752         {
753             AutoMutex lock(mLock);
754             client = mClient;
755         }
756         if (client != 0) {
757             client->onServiceStateChange(eventMemory);
758         }
759     } break;
760     default:
761         LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
762     }
763 }
764 
getModel(sound_model_handle_t handle)765 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
766         sound_model_handle_t handle)
767 {
768     sp<Model> model;
769     ssize_t index = mModels.indexOfKey(handle);
770     if (index >= 0) {
771         model = mModels.valueAt(index);
772     }
773     return model;
774 }
775 
binderDied(const wp<IBinder> & who __unused)776 void SoundTriggerHwService::Module::binderDied(
777     const wp<IBinder> &who __unused) {
778     ALOGW("client binder died for module %d", mDescriptor.handle);
779     detach();
780 }
781 
782 // Called with mServiceLock held
setCaptureState_l(bool active)783 void SoundTriggerHwService::Module::setCaptureState_l(bool active)
784 {
785     ALOGV("Module::setCaptureState_l %d", active);
786     sp<SoundTriggerHwService> service;
787     sound_trigger_service_state_t state;
788 
789     Vector< sp<IMemory> > events;
790     {
791         AutoMutex lock(mLock);
792         state = (active && !mDescriptor.properties.concurrent_capture) ?
793                                         SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
794 
795         if (state == mServiceState) {
796             return;
797         }
798 
799         mServiceState = state;
800 
801         service = mService.promote();
802         if (service == 0) {
803             return;
804         }
805 
806         if (state == SOUND_TRIGGER_STATE_ENABLED) {
807             goto exit;
808         }
809 
810         const bool supports_stop_all =
811             (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
812              mHwDevice->stop_all_recognitions);
813 
814         if (supports_stop_all) {
815             mHwDevice->stop_all_recognitions(mHwDevice);
816         }
817 
818         for (size_t i = 0; i < mModels.size(); i++) {
819             sp<Model> model = mModels.valueAt(i);
820             if (model->mState == Model::STATE_ACTIVE) {
821                 if (!supports_stop_all) {
822                     mHwDevice->stop_recognition(mHwDevice, model->mHandle);
823                 }
824                 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
825                 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
826                     struct sound_trigger_phrase_recognition_event event;
827                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
828                     event.num_phrases = model->mConfig.num_phrases;
829                     for (size_t i = 0; i < event.num_phrases; i++) {
830                         event.phrase_extras[i] = model->mConfig.phrases[i];
831                     }
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 if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
841                     struct sound_trigger_generic_recognition_event event;
842                     memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
843                     event.common.status = RECOGNITION_STATUS_ABORT;
844                     event.common.type = model->mType;
845                     event.common.model = model->mHandle;
846                     event.common.data_size = 0;
847                     sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
848                     if (eventMemory != 0) {
849                         events.add(eventMemory);
850                     }
851                 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
852                     struct sound_trigger_phrase_recognition_event event;
853                     memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
854                     event.common.status = RECOGNITION_STATUS_ABORT;
855                     event.common.type = model->mType;
856                     event.common.model = model->mHandle;
857                     event.common.data_size = 0;
858                     sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
859                     if (eventMemory != 0) {
860                         events.add(eventMemory);
861                     }
862                 } else {
863                     goto exit;
864                 }
865             }
866         }
867     }
868 
869     for (size_t i = 0; i < events.size(); i++) {
870         service->sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, events[i],
871                                                      this));
872     }
873 
874 exit:
875     service->sendServiceStateEvent_l(state, this);
876 }
877 
878 
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)879 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
880                                     audio_io_handle_t ioHandle, audio_devices_t device,
881                                     sound_trigger_sound_model_type_t type) :
882     mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
883     mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type)
884 {
885 
886 }
887 
dump(int fd __unused,const Vector<String16> & args __unused)888 status_t SoundTriggerHwService::Module::dump(int fd __unused,
889                                              const Vector<String16>& args __unused) {
890     String8 result;
891     return NO_ERROR;
892 }
893 
894 }; // namespace android
895