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