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