1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "SoundTriggerHwService"
18 //#define LOG_NDEBUG 0
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <pthread.h>
24
25 #include <audio_utils/clock.h>
26 #include <system/sound_trigger.h>
27 #include <cutils/atomic.h>
28 #include <cutils/properties.h>
29 #include <hardware/hardware.h>
30 #include <media/AudioSystem.h>
31 #include <mediautils/ServiceUtilities.h>
32 #include <utils/Errors.h>
33 #include <utils/Log.h>
34 #include <binder/IServiceManager.h>
35 #include <binder/MemoryBase.h>
36 #include <binder/MemoryHeapBase.h>
37 #include <system/sound_trigger.h>
38 #include "SoundTriggerHwService.h"
39
40 #define HW_MODULE_PREFIX "primary"
41 namespace android {
42
SoundTriggerHwService()43 SoundTriggerHwService::SoundTriggerHwService()
44 : BnSoundTriggerHwService(),
45 mNextUniqueId(1),
46 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
47 mCaptureState(false)
48 {
49 }
50
onFirstRef()51 void SoundTriggerHwService::onFirstRef()
52 {
53 int rc;
54
55 sp<SoundTriggerHalInterface> halInterface =
56 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
57
58 if (halInterface == 0) {
59 ALOGW("could not connect to HAL");
60 return;
61 }
62 sound_trigger_module_descriptor descriptor;
63 rc = halInterface->getProperties(&descriptor.properties);
64 if (rc != 0) {
65 ALOGE("could not read implementation properties");
66 return;
67 }
68 descriptor.handle =
69 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
70 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
71 descriptor.handle);
72
73 sp<Module> module = new Module(this, halInterface, descriptor);
74 mModules.add(descriptor.handle, module);
75 mCallbackThread = new CallbackThread(this);
76 }
77
~SoundTriggerHwService()78 SoundTriggerHwService::~SoundTriggerHwService()
79 {
80 if (mCallbackThread != 0) {
81 mCallbackThread->exit();
82 }
83 }
84
listModules(const String16 & opPackageName,struct sound_trigger_module_descriptor * modules,uint32_t * numModules)85 status_t SoundTriggerHwService::listModules(const String16& opPackageName,
86 struct sound_trigger_module_descriptor *modules,
87 uint32_t *numModules)
88 {
89 ALOGV("listModules");
90 if (!captureHotwordAllowed(opPackageName,
91 IPCThreadState::self()->getCallingPid(),
92 IPCThreadState::self()->getCallingUid())) {
93 return PERMISSION_DENIED;
94 }
95
96 AutoMutex lock(mServiceLock);
97 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
98 return BAD_VALUE;
99 }
100 size_t maxModules = *numModules;
101 *numModules = mModules.size();
102 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
103 modules[i] = mModules.valueAt(i)->descriptor();
104 }
105 return NO_ERROR;
106 }
107
attach(const String16 & opPackageName,const sound_trigger_module_handle_t handle,const sp<ISoundTriggerClient> & client,sp<ISoundTrigger> & moduleInterface)108 status_t SoundTriggerHwService::attach(const String16& opPackageName,
109 const sound_trigger_module_handle_t handle,
110 const sp<ISoundTriggerClient>& client,
111 sp<ISoundTrigger>& moduleInterface)
112 {
113 ALOGV("attach module %d", handle);
114 if (!captureHotwordAllowed(opPackageName,
115 IPCThreadState::self()->getCallingPid(),
116 IPCThreadState::self()->getCallingUid())) {
117 return PERMISSION_DENIED;
118 }
119
120 AutoMutex lock(mServiceLock);
121 moduleInterface.clear();
122 if (client == 0) {
123 return BAD_VALUE;
124 }
125 ssize_t index = mModules.indexOfKey(handle);
126 if (index < 0) {
127 return BAD_VALUE;
128 }
129 sp<Module> module = mModules.valueAt(index);
130
131 sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
132 if (moduleClient == 0) {
133 return NO_INIT;
134 }
135
136 moduleClient->setCaptureState_l(mCaptureState);
137 moduleInterface = moduleClient;
138
139 return NO_ERROR;
140 }
141
setCaptureState(bool active)142 status_t SoundTriggerHwService::setCaptureState(bool active)
143 {
144 ALOGV("setCaptureState %d", active);
145 AutoMutex lock(mServiceLock);
146 mCaptureState = active;
147 for (size_t i = 0; i < mModules.size(); i++) {
148 mModules.valueAt(i)->setCaptureState_l(active);
149 }
150 return NO_ERROR;
151 }
152
153
154 static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
155
dumpTryLock(Mutex & mutex)156 static bool dumpTryLock(Mutex& mutex)
157 {
158 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
159 return err == NO_ERROR;
160 }
161
dump(int fd,const Vector<String16> & args __unused)162 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
163 String8 result;
164 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
165 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
166 write(fd, result.string(), result.size());
167 } else {
168 bool locked = dumpTryLock(mServiceLock);
169 // failed to lock - SoundTriggerHwService is probably deadlocked
170 if (!locked) {
171 result.append("SoundTriggerHwService may be deadlocked\n");
172 write(fd, result.string(), result.size());
173 }
174
175 if (locked) mServiceLock.unlock();
176 }
177 return NO_ERROR;
178 }
179
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)180 status_t SoundTriggerHwService::onTransact(
181 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
182 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
183 }
184
185
186 // static
recognitionCallback(struct sound_trigger_recognition_event * event,void * cookie)187 void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
188 void *cookie)
189 {
190 Module *module = (Module *)cookie;
191 if (module == NULL) {
192 return;
193 }
194 sp<SoundTriggerHwService> service = module->service().promote();
195 if (service == 0) {
196 return;
197 }
198
199 service->sendRecognitionEvent(event, module);
200 }
201
prepareRecognitionEvent(struct sound_trigger_recognition_event * event)202 sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
203 struct sound_trigger_recognition_event *event)
204 {
205 AutoMutex lock(mMemoryDealerLock);
206 sp<IMemory> eventMemory;
207
208 //sanitize event
209 switch (event->type) {
210 case SOUND_MODEL_TYPE_KEYPHRASE:
211 ALOGW_IF(event->data_size != 0 && event->data_offset !=
212 sizeof(struct sound_trigger_phrase_recognition_event),
213 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
214 event->data_offset);
215 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
216 break;
217 case SOUND_MODEL_TYPE_GENERIC:
218 ALOGW_IF(event->data_size != 0 && event->data_offset !=
219 sizeof(struct sound_trigger_generic_recognition_event),
220 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
221 event->data_offset);
222 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
223 break;
224 case SOUND_MODEL_TYPE_UNKNOWN:
225 ALOGW_IF(event->data_size != 0 && event->data_offset !=
226 sizeof(struct sound_trigger_recognition_event),
227 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
228 event->data_offset);
229 event->data_offset = sizeof(struct sound_trigger_recognition_event);
230 break;
231 default:
232 return eventMemory;
233 }
234
235 size_t size = event->data_offset + event->data_size;
236 eventMemory = mMemoryDealer->allocate(size);
237 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
238 eventMemory.clear();
239 return eventMemory;
240 }
241 memcpy(eventMemory->pointer(), event, size);
242
243 return eventMemory;
244 }
245
sendRecognitionEvent(struct sound_trigger_recognition_event * event,Module * module)246 void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
247 Module *module)
248 {
249 if (module == NULL) {
250 return;
251 }
252 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
253 if (eventMemory == 0) {
254 return;
255 }
256
257 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
258 eventMemory);
259 callbackEvent->setModule(module);
260 sendCallbackEvent(callbackEvent);
261 }
262
263 // static
soundModelCallback(struct sound_trigger_model_event * event,void * cookie)264 void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
265 void *cookie)
266 {
267 Module *module = (Module *)cookie;
268 if (module == NULL) {
269 return;
270 }
271 sp<SoundTriggerHwService> service = module->service().promote();
272 if (service == 0) {
273 return;
274 }
275
276 service->sendSoundModelEvent(event, module);
277 }
278
prepareSoundModelEvent(struct sound_trigger_model_event * event)279 sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
280 {
281 AutoMutex lock(mMemoryDealerLock);
282 sp<IMemory> eventMemory;
283
284 size_t size = event->data_offset + event->data_size;
285 eventMemory = mMemoryDealer->allocate(size);
286 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
287 eventMemory.clear();
288 return eventMemory;
289 }
290 memcpy(eventMemory->pointer(), event, size);
291
292 return eventMemory;
293 }
294
sendSoundModelEvent(struct sound_trigger_model_event * event,Module * module)295 void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
296 Module *module)
297 {
298 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
299 if (eventMemory == 0) {
300 return;
301 }
302 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
303 eventMemory);
304 callbackEvent->setModule(module);
305 sendCallbackEvent(callbackEvent);
306 }
307
308
prepareServiceStateEvent(sound_trigger_service_state_t state)309 sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
310 {
311 AutoMutex lock(mMemoryDealerLock);
312 sp<IMemory> eventMemory;
313
314 size_t size = sizeof(sound_trigger_service_state_t);
315 eventMemory = mMemoryDealer->allocate(size);
316 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
317 eventMemory.clear();
318 return eventMemory;
319 }
320 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
321 return eventMemory;
322 }
323
sendServiceStateEvent(sound_trigger_service_state_t state,Module * module)324 void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
325 Module *module)
326 {
327 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
328 if (eventMemory == 0) {
329 return;
330 }
331 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
332 eventMemory);
333 callbackEvent->setModule(module);
334 sendCallbackEvent(callbackEvent);
335 }
336
sendServiceStateEvent(sound_trigger_service_state_t state,ModuleClient * moduleClient)337 void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
338 ModuleClient *moduleClient)
339 {
340 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
341 if (eventMemory == 0) {
342 return;
343 }
344 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
345 eventMemory);
346 callbackEvent->setModuleClient(moduleClient);
347 sendCallbackEvent(callbackEvent);
348 }
349
sendCallbackEvent(const sp<CallbackEvent> & event)350 void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
351 {
352 mCallbackThread->sendCallbackEvent(event);
353 }
354
onCallbackEvent(const sp<CallbackEvent> & event)355 void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
356 {
357 ALOGV("onCallbackEvent");
358 sp<Module> module;
359 sp<ModuleClient> moduleClient;
360 {
361 AutoMutex lock(mServiceLock);
362 //CallbackEvent is either for Module or ModuleClient
363 module = event->mModule.promote();
364 if (module == 0) {
365 moduleClient = event->mModuleClient.promote();
366 if (moduleClient == 0) {
367 return;
368 }
369 } else {
370 // Sanity check on this being a Module we know about.
371 bool foundModule = false;
372 for (size_t i = 0; i < mModules.size(); i++) {
373 if (mModules.valueAt(i).get() == module.get()) {
374 foundModule = true;
375 break;
376 }
377 }
378 if (!foundModule) {
379 ALOGE("onCallbackEvent for unknown module");
380 return;
381 }
382 }
383 }
384 if (module != 0) {
385 ALOGV("onCallbackEvent for module");
386 module->onCallbackEvent(event);
387 } else if (moduleClient != 0) {
388 ALOGV("onCallbackEvent for moduleClient");
389 moduleClient->onCallbackEvent(event);
390 }
391 {
392 AutoMutex lock(mServiceLock);
393 // clear now to execute with mServiceLock locked
394 event->mMemory.clear();
395 }
396 }
397
398 #undef LOG_TAG
399 #define LOG_TAG "SoundTriggerHwService::CallbackThread"
400
CallbackThread(const wp<SoundTriggerHwService> & service)401 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
402 : mService(service)
403 {
404 }
405
~CallbackThread()406 SoundTriggerHwService::CallbackThread::~CallbackThread()
407 {
408 while (!mEventQueue.isEmpty()) {
409 mEventQueue[0]->mMemory.clear();
410 mEventQueue.removeAt(0);
411 }
412 }
413
onFirstRef()414 void SoundTriggerHwService::CallbackThread::onFirstRef()
415 {
416 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
417 }
418
threadLoop()419 bool SoundTriggerHwService::CallbackThread::threadLoop()
420 {
421 while (!exitPending()) {
422 sp<CallbackEvent> event;
423 sp<SoundTriggerHwService> service;
424 {
425 Mutex::Autolock _l(mCallbackLock);
426 while (mEventQueue.isEmpty() && !exitPending()) {
427 ALOGV("CallbackThread::threadLoop() sleep");
428 mCallbackCond.wait(mCallbackLock);
429 ALOGV("CallbackThread::threadLoop() wake up");
430 }
431 if (exitPending()) {
432 break;
433 }
434 event = mEventQueue[0];
435 mEventQueue.removeAt(0);
436 service = mService.promote();
437 }
438 if (service != 0) {
439 service->onCallbackEvent(event);
440 }
441 }
442 return false;
443 }
444
exit()445 void SoundTriggerHwService::CallbackThread::exit()
446 {
447 Mutex::Autolock _l(mCallbackLock);
448 requestExit();
449 mCallbackCond.broadcast();
450 }
451
sendCallbackEvent(const sp<SoundTriggerHwService::CallbackEvent> & event)452 void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
453 const sp<SoundTriggerHwService::CallbackEvent>& event)
454 {
455 AutoMutex lock(mCallbackLock);
456 mEventQueue.add(event);
457 mCallbackCond.signal();
458 }
459
CallbackEvent(event_type type,sp<IMemory> memory)460 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
461 : mType(type), mMemory(memory)
462 {
463 }
464
~CallbackEvent()465 SoundTriggerHwService::CallbackEvent::~CallbackEvent()
466 {
467 }
468
469
470 #undef LOG_TAG
471 #define LOG_TAG "SoundTriggerHwService::Module"
472
Module(const sp<SoundTriggerHwService> & service,const sp<SoundTriggerHalInterface> & halInterface,sound_trigger_module_descriptor descriptor)473 SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
474 const sp<SoundTriggerHalInterface>& halInterface,
475 sound_trigger_module_descriptor descriptor)
476 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
477 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
478 {
479 }
480
~Module()481 SoundTriggerHwService::Module::~Module() {
482 mModuleClients.clear();
483 }
484
485 sp<SoundTriggerHwService::ModuleClient>
addClient(const sp<ISoundTriggerClient> & client,const String16 & opPackageName)486 SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
487 const String16& opPackageName)
488 {
489 AutoMutex lock(mLock);
490 sp<ModuleClient> moduleClient;
491
492 for (size_t i = 0; i < mModuleClients.size(); i++) {
493 if (mModuleClients[i]->client() == client) {
494 // Client already present, reuse client
495 return moduleClient;
496 }
497 }
498 moduleClient = new ModuleClient(this, client, opPackageName);
499
500 ALOGV("addClient() client %p", moduleClient.get());
501 mModuleClients.add(moduleClient);
502
503 return moduleClient;
504 }
505
detach(const sp<ModuleClient> & moduleClient)506 void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
507 {
508 ALOGV("Module::detach()");
509 Vector<audio_session_t> releasedSessions;
510
511 {
512 AutoMutex lock(mLock);
513 ssize_t index = -1;
514
515 for (size_t i = 0; i < mModuleClients.size(); i++) {
516 if (mModuleClients[i] == moduleClient) {
517 index = i;
518 break;
519 }
520 }
521 if (index == -1) {
522 return;
523 }
524
525 ALOGV("remove client %p", moduleClient.get());
526 mModuleClients.removeAt(index);
527
528 // Iterate in reverse order as models are removed from list inside the loop.
529 for (size_t i = mModels.size(); i > 0; i--) {
530 sp<Model> model = mModels.valueAt(i - 1);
531 if (moduleClient == model->mModuleClient) {
532 mModels.removeItemsAt(i - 1);
533 ALOGV("detach() unloading model %d", model->mHandle);
534 if (mHalInterface != 0) {
535 if (model->mState == Model::STATE_ACTIVE) {
536 mHalInterface->stopRecognition(model->mHandle);
537 }
538 mHalInterface->unloadSoundModel(model->mHandle);
539 }
540 releasedSessions.add(model->mCaptureSession);
541 }
542 }
543 }
544
545 for (size_t i = 0; i < releasedSessions.size(); i++) {
546 // do not call AudioSystem methods with mLock held
547 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
548 }
549 }
550
loadSoundModel(const sp<IMemory> & modelMemory,sp<ModuleClient> moduleClient,sound_model_handle_t * handle)551 status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
552 sp<ModuleClient> moduleClient,
553 sound_model_handle_t *handle)
554 {
555 ALOGV("loadSoundModel() handle");
556 if (mHalInterface == 0) {
557 return NO_INIT;
558 }
559
560 struct sound_trigger_sound_model *sound_model =
561 (struct sound_trigger_sound_model *)modelMemory->pointer();
562
563 size_t structSize;
564 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
565 structSize = sizeof(struct sound_trigger_phrase_sound_model);
566 } else {
567 structSize = sizeof(struct sound_trigger_sound_model);
568 }
569
570 if (sound_model->data_offset < structSize ||
571 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
572 modelMemory->size() < sound_model->data_offset ||
573 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
574 android_errorWriteLog(0x534e4554, "30148546");
575 ALOGE("loadSoundModel() data_size is too big");
576 return BAD_VALUE;
577 }
578
579 audio_session_t session;
580 audio_io_handle_t ioHandle;
581 audio_devices_t device;
582 // do not call AudioSystem methods with mLock held
583 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
584 if (status != NO_ERROR) {
585 return status;
586 }
587
588 {
589 AutoMutex lock(mLock);
590
591 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
592 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
593 mDescriptor.properties.max_sound_models);
594 status = INVALID_OPERATION;
595 goto exit;
596 }
597
598 status = mHalInterface->loadSoundModel(sound_model,
599 SoundTriggerHwService::soundModelCallback,
600 this, handle);
601 if (status != NO_ERROR) {
602 goto exit;
603 }
604
605 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
606 moduleClient);
607 mModels.replaceValueFor(*handle, model);
608 }
609 exit:
610 if (status != NO_ERROR) {
611 // do not call AudioSystem methods with mLock held
612 AudioSystem::releaseSoundTriggerSession(session);
613 }
614 return status;
615 }
616
unloadSoundModel(sound_model_handle_t handle)617 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
618 {
619 ALOGV("unloadSoundModel() model handle %d", handle);
620 status_t status;
621 audio_session_t session;
622
623 {
624 AutoMutex lock(mLock);
625 if (mHalInterface == 0) {
626 return NO_INIT;
627 }
628 ssize_t index = mModels.indexOfKey(handle);
629 if (index < 0) {
630 return BAD_VALUE;
631 }
632 sp<Model> model = mModels.valueAt(index);
633 mModels.removeItem(handle);
634 if (model->mState == Model::STATE_ACTIVE) {
635 mHalInterface->stopRecognition(model->mHandle);
636 model->mState = Model::STATE_IDLE;
637 }
638 status = mHalInterface->unloadSoundModel(handle);
639 session = model->mCaptureSession;
640 }
641 // do not call AudioSystem methods with mLock held
642 AudioSystem::releaseSoundTriggerSession(session);
643 return status;
644 }
645
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)646 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
647 const sp<IMemory>& dataMemory)
648 {
649 ALOGV("startRecognition() model handle %d", handle);
650 if (mHalInterface == 0) {
651 return NO_INIT;
652 }
653
654 struct sound_trigger_recognition_config *config =
655 (struct sound_trigger_recognition_config *)dataMemory->pointer();
656
657 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
658 config->data_size > (UINT_MAX - config->data_offset) ||
659 dataMemory->size() < config->data_offset ||
660 config->data_size > (dataMemory->size() - config->data_offset)) {
661 ALOGE("startRecognition() data_size is too big");
662 return BAD_VALUE;
663 }
664
665 AutoMutex lock(mLock);
666 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
667 return INVALID_OPERATION;
668 }
669 sp<Model> model = getModel(handle);
670 if (model == 0) {
671 return BAD_VALUE;
672 }
673
674 if (model->mState == Model::STATE_ACTIVE) {
675 return INVALID_OPERATION;
676 }
677
678
679 //TODO: get capture handle and device from audio policy service
680 config->capture_handle = model->mCaptureIOHandle;
681 config->capture_device = model->mCaptureDevice;
682 status_t status = mHalInterface->startRecognition(handle, config,
683 SoundTriggerHwService::recognitionCallback,
684 this);
685
686 if (status == NO_ERROR) {
687 model->mState = Model::STATE_ACTIVE;
688 model->mConfig = *config;
689 }
690
691 return status;
692 }
693
stopRecognition(sound_model_handle_t handle)694 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
695 {
696 ALOGV("stopRecognition() model handle %d", handle);
697 if (mHalInterface == 0) {
698 return NO_INIT;
699 }
700 AutoMutex lock(mLock);
701 sp<Model> model = getModel(handle);
702 if (model == 0) {
703 return BAD_VALUE;
704 }
705
706 if (model->mState != Model::STATE_ACTIVE) {
707 return INVALID_OPERATION;
708 }
709 mHalInterface->stopRecognition(handle);
710 model->mState = Model::STATE_IDLE;
711 return NO_ERROR;
712 }
713
getModelState(sound_model_handle_t handle)714 status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
715 {
716 ALOGV("getModelState() model handle %d", handle);
717 if (mHalInterface == 0) {
718 return NO_INIT;
719 }
720 AutoMutex lock(mLock);
721 sp<Model> model = getModel(handle);
722 if (model == 0) {
723 return BAD_VALUE;
724 }
725
726 if (model->mState != Model::STATE_ACTIVE) {
727 return INVALID_OPERATION;
728 }
729
730 return mHalInterface->getModelState(handle);
731 }
732
onCallbackEvent(const sp<CallbackEvent> & event)733 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
734 {
735 ALOGV("onCallbackEvent type %d", event->mType);
736
737 sp<IMemory> eventMemory = event->mMemory;
738
739 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
740 return;
741 }
742 if (mModuleClients.isEmpty()) {
743 ALOGI("%s no clients", __func__);
744 return;
745 }
746
747 Vector< sp<ModuleClient> > clients;
748
749 switch (event->mType) {
750 case CallbackEvent::TYPE_RECOGNITION: {
751 struct sound_trigger_recognition_event *recognitionEvent =
752 (struct sound_trigger_recognition_event *)eventMemory->pointer();
753 {
754 AutoMutex lock(mLock);
755 sp<Model> model = getModel(recognitionEvent->model);
756 if (model == 0) {
757 ALOGW("%s model == 0", __func__);
758 return;
759 }
760 if (model->mState != Model::STATE_ACTIVE) {
761 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
762 return;
763 }
764
765 recognitionEvent->capture_session = model->mCaptureSession;
766 model->mState = Model::STATE_IDLE;
767 clients.add(model->mModuleClient);
768 }
769 } break;
770 case CallbackEvent::TYPE_SOUNDMODEL: {
771 struct sound_trigger_model_event *soundmodelEvent =
772 (struct sound_trigger_model_event *)eventMemory->pointer();
773 {
774 AutoMutex lock(mLock);
775 sp<Model> model = getModel(soundmodelEvent->model);
776 if (model == 0) {
777 ALOGW("%s model == 0", __func__);
778 return;
779 }
780 clients.add(model->mModuleClient);
781 }
782 } break;
783 case CallbackEvent::TYPE_SERVICE_STATE: {
784 {
785 AutoMutex lock(mLock);
786 for (size_t i = 0; i < mModuleClients.size(); i++) {
787 if (mModuleClients[i] != 0) {
788 clients.add(mModuleClients[i]);
789 }
790 }
791 }
792 } break;
793 default:
794 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
795 }
796
797 for (size_t i = 0; i < clients.size(); i++) {
798 clients[i]->onCallbackEvent(event);
799 }
800 }
801
getModel(sound_model_handle_t handle)802 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
803 sound_model_handle_t handle)
804 {
805 sp<Model> model;
806 ssize_t index = mModels.indexOfKey(handle);
807 if (index >= 0) {
808 model = mModels.valueAt(index);
809 }
810 return model;
811 }
812
813 // Called with mServiceLock held
setCaptureState_l(bool active)814 void SoundTriggerHwService::Module::setCaptureState_l(bool active)
815 {
816 ALOGV("Module::setCaptureState_l %d", active);
817 sp<SoundTriggerHwService> service;
818 sound_trigger_service_state_t state;
819
820 Vector< sp<IMemory> > events;
821 {
822 AutoMutex lock(mLock);
823 state = (active && !mDescriptor.properties.concurrent_capture) ?
824 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
825
826 if (state == mServiceState) {
827 return;
828 }
829
830 mServiceState = state;
831
832 service = mService.promote();
833 if (service == 0) {
834 return;
835 }
836
837 if (state == SOUND_TRIGGER_STATE_ENABLED) {
838 goto exit;
839 }
840
841 const bool supports_stop_all =
842 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
843
844 for (size_t i = 0; i < mModels.size(); i++) {
845 sp<Model> model = mModels.valueAt(i);
846 if (model->mState == Model::STATE_ACTIVE) {
847 if (mHalInterface != 0 && !supports_stop_all) {
848 mHalInterface->stopRecognition(model->mHandle);
849 }
850 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
851 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
852 struct sound_trigger_phrase_recognition_event event;
853 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
854 event.num_phrases = model->mConfig.num_phrases;
855 for (size_t i = 0; i < event.num_phrases; i++) {
856 event.phrase_extras[i] = model->mConfig.phrases[i];
857 }
858 event.common.status = RECOGNITION_STATUS_ABORT;
859 event.common.type = model->mType;
860 event.common.model = model->mHandle;
861 event.common.data_size = 0;
862 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
863 if (eventMemory != 0) {
864 events.add(eventMemory);
865 }
866 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
867 struct sound_trigger_generic_recognition_event event;
868 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
869 event.common.status = RECOGNITION_STATUS_ABORT;
870 event.common.type = model->mType;
871 event.common.model = model->mHandle;
872 event.common.data_size = 0;
873 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
874 if (eventMemory != 0) {
875 events.add(eventMemory);
876 }
877 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
878 struct sound_trigger_phrase_recognition_event event;
879 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
880 event.common.status = RECOGNITION_STATUS_ABORT;
881 event.common.type = model->mType;
882 event.common.model = model->mHandle;
883 event.common.data_size = 0;
884 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
885 if (eventMemory != 0) {
886 events.add(eventMemory);
887 }
888 } else {
889 goto exit;
890 }
891 }
892 }
893 }
894
895 for (size_t i = 0; i < events.size(); i++) {
896 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
897 events[i]);
898 callbackEvent->setModule(this);
899 service->sendCallbackEvent(callbackEvent);
900 }
901
902 exit:
903 service->sendServiceStateEvent(state, this);
904 }
905
906
Model(sound_model_handle_t handle,audio_session_t session,audio_io_handle_t ioHandle,audio_devices_t device,sound_trigger_sound_model_type_t type,sp<ModuleClient> & moduleClient)907 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
908 audio_io_handle_t ioHandle, audio_devices_t device,
909 sound_trigger_sound_model_type_t type,
910 sp<ModuleClient>& moduleClient) :
911 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
912 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
913 mModuleClient(moduleClient)
914 {
915 }
916
917 #undef LOG_TAG
918 #define LOG_TAG "SoundTriggerHwService::ModuleClient"
919
ModuleClient(const sp<Module> & module,const sp<ISoundTriggerClient> & client,const String16 & opPackageName)920 SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
921 const sp<ISoundTriggerClient>& client,
922 const String16& opPackageName)
923 : mModule(module), mClient(client), mOpPackageName(opPackageName)
924 {
925 }
926
onFirstRef()927 void SoundTriggerHwService::ModuleClient::onFirstRef()
928 {
929 sp<IBinder> binder = IInterface::asBinder(mClient);
930 if (binder != 0) {
931 binder->linkToDeath(this);
932 }
933 }
934
~ModuleClient()935 SoundTriggerHwService::ModuleClient::~ModuleClient()
936 {
937 }
938
dump(int fd __unused,const Vector<String16> & args __unused)939 status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
940 const Vector<String16>& args __unused) {
941 String8 result;
942 return NO_ERROR;
943 }
944
detach()945 void SoundTriggerHwService::ModuleClient::detach() {
946 ALOGV("detach()");
947 if (!captureHotwordAllowed(mOpPackageName,
948 IPCThreadState::self()->getCallingPid(),
949 IPCThreadState::self()->getCallingUid())) {
950 return;
951 }
952
953 {
954 AutoMutex lock(mLock);
955 if (mClient != 0) {
956 IInterface::asBinder(mClient)->unlinkToDeath(this);
957 mClient.clear();
958 }
959 }
960
961 sp<Module> module = mModule.promote();
962 if (module == 0) {
963 return;
964 }
965 module->detach(this);
966 }
967
loadSoundModel(const sp<IMemory> & modelMemory,sound_model_handle_t * handle)968 status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
969 sound_model_handle_t *handle)
970 {
971 ALOGV("loadSoundModel() handle");
972 if (!captureHotwordAllowed(mOpPackageName,
973 IPCThreadState::self()->getCallingPid(),
974 IPCThreadState::self()->getCallingUid())) {
975 return PERMISSION_DENIED;
976 }
977 if (checkIMemory(modelMemory) != NO_ERROR) {
978 return BAD_VALUE;
979 }
980
981 sp<Module> module = mModule.promote();
982 if (module == 0) {
983 return NO_INIT;
984 }
985 return module->loadSoundModel(modelMemory, this, handle);
986 }
987
unloadSoundModel(sound_model_handle_t handle)988 status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
989 {
990 ALOGV("unloadSoundModel() model handle %d", handle);
991 if (!captureHotwordAllowed(mOpPackageName,
992 IPCThreadState::self()->getCallingPid(),
993 IPCThreadState::self()->getCallingUid())) {
994 return PERMISSION_DENIED;
995 }
996
997 sp<Module> module = mModule.promote();
998 if (module == 0) {
999 return NO_INIT;
1000 }
1001 return module->unloadSoundModel(handle);
1002 }
1003
startRecognition(sound_model_handle_t handle,const sp<IMemory> & dataMemory)1004 status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1005 const sp<IMemory>& dataMemory)
1006 {
1007 ALOGV("startRecognition() model handle %d", handle);
1008 if (!captureHotwordAllowed(mOpPackageName,
1009 IPCThreadState::self()->getCallingPid(),
1010 IPCThreadState::self()->getCallingUid())) {
1011 return PERMISSION_DENIED;
1012 }
1013 if (checkIMemory(dataMemory) != NO_ERROR) {
1014 return BAD_VALUE;
1015 }
1016
1017 sp<Module> module = mModule.promote();
1018 if (module == 0) {
1019 return NO_INIT;
1020 }
1021 return module->startRecognition(handle, dataMemory);
1022 }
1023
stopRecognition(sound_model_handle_t handle)1024 status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1025 {
1026 ALOGV("stopRecognition() model handle %d", handle);
1027 if (!captureHotwordAllowed(mOpPackageName,
1028 IPCThreadState::self()->getCallingPid(),
1029 IPCThreadState::self()->getCallingUid())) {
1030 return PERMISSION_DENIED;
1031 }
1032
1033 sp<Module> module = mModule.promote();
1034 if (module == 0) {
1035 return NO_INIT;
1036 }
1037 return module->stopRecognition(handle);
1038 }
1039
getModelState(sound_model_handle_t handle)1040 status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
1041 {
1042 ALOGV("getModelState() model handle %d", handle);
1043 if (!captureHotwordAllowed(mOpPackageName,
1044 IPCThreadState::self()->getCallingPid(),
1045 IPCThreadState::self()->getCallingUid())) {
1046 return PERMISSION_DENIED;
1047 }
1048
1049 sp<Module> module = mModule.promote();
1050 if (module == 0) {
1051 return NO_INIT;
1052 }
1053 return module->getModelState(handle);
1054 }
1055
setCaptureState_l(bool active)1056 void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1057 {
1058 ALOGV("ModuleClient::setCaptureState_l %d", active);
1059 sp<SoundTriggerHwService> service;
1060 sound_trigger_service_state_t state;
1061
1062 sp<Module> module = mModule.promote();
1063 if (module == 0) {
1064 return;
1065 }
1066 {
1067 AutoMutex lock(mLock);
1068 state = (active && !module->isConcurrentCaptureAllowed()) ?
1069 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1070
1071 service = module->service().promote();
1072 if (service == 0) {
1073 return;
1074 }
1075 }
1076 service->sendServiceStateEvent(state, this);
1077 }
1078
onCallbackEvent(const sp<CallbackEvent> & event)1079 void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1080 {
1081 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1082
1083 sp<IMemory> eventMemory = event->mMemory;
1084
1085 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1086 return;
1087 }
1088
1089 sp<ISoundTriggerClient> client;
1090 {
1091 AutoMutex lock(mLock);
1092 client = mClient;
1093 }
1094
1095 if (client != 0) {
1096 switch (event->mType) {
1097 case CallbackEvent::TYPE_RECOGNITION: {
1098 client->onRecognitionEvent(eventMemory);
1099 } break;
1100 case CallbackEvent::TYPE_SOUNDMODEL: {
1101 client->onSoundModelEvent(eventMemory);
1102 } break;
1103 case CallbackEvent::TYPE_SERVICE_STATE: {
1104 client->onServiceStateChange(eventMemory);
1105 } break;
1106 default:
1107 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1108 }
1109 }
1110 }
1111
binderDied(const wp<IBinder> & who __unused)1112 void SoundTriggerHwService::ModuleClient::binderDied(
1113 const wp<IBinder> &who __unused) {
1114 ALOGW("client binder died for client %p", this);
1115 detach();
1116 }
1117
1118 }; // namespace android
1119