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 SoundTriggerHwService::SoundTriggerHwService() 44 : BnSoundTriggerHwService(), 45 mNextUniqueId(1), 46 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")), 47 mCaptureState(false) 48 { 49 } 50 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 78 SoundTriggerHwService::~SoundTriggerHwService() 79 { 80 if (mCallbackThread != 0) { 81 mCallbackThread->exit(); 82 } 83 } 84 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 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 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 156 static bool dumpTryLock(Mutex& mutex) 157 { 158 status_t err = mutex.timedLock(kDumpLockTimeoutNs); 159 return err == NO_ERROR; 160 } 161 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 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 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 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 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 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 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 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 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 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 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 350 void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event) 351 { 352 mCallbackThread->sendCallbackEvent(event); 353 } 354 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 401 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service) 402 : mService(service) 403 { 404 } 405 406 SoundTriggerHwService::CallbackThread::~CallbackThread() 407 { 408 while (!mEventQueue.isEmpty()) { 409 mEventQueue[0]->mMemory.clear(); 410 mEventQueue.removeAt(0); 411 } 412 } 413 414 void SoundTriggerHwService::CallbackThread::onFirstRef() 415 { 416 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO); 417 } 418 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 445 void SoundTriggerHwService::CallbackThread::exit() 446 { 447 Mutex::Autolock _l(mCallbackLock); 448 requestExit(); 449 mCallbackCond.broadcast(); 450 } 451 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 460 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory) 461 : mType(type), mMemory(memory) 462 { 463 } 464 465 SoundTriggerHwService::CallbackEvent::~CallbackEvent() 466 { 467 } 468 469 470 #undef LOG_TAG 471 #define LOG_TAG "SoundTriggerHwService::Module" 472 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 481 SoundTriggerHwService::Module::~Module() { 482 mModuleClients.clear(); 483 } 484 485 sp<SoundTriggerHwService::ModuleClient> 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 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 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 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 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 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 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 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 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 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 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 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 927 void SoundTriggerHwService::ModuleClient::onFirstRef() 928 { 929 sp<IBinder> binder = IInterface::asBinder(mClient); 930 if (binder != 0) { 931 binder->linkToDeath(this); 932 } 933 } 934 935 SoundTriggerHwService::ModuleClient::~ModuleClient() 936 { 937 } 938 939 status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused, 940 const Vector<String16>& args __unused) { 941 String8 result; 942 return NO_ERROR; 943 } 944 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 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 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 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 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 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 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 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 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