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