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 // Iterate in reverse order as models are removed from list inside the loop. 548 for (size_t i = mModels.size(); i > 0; i--) { 549 sp<Model> model = mModels.valueAt(i - 1); 550 if (moduleClient == model->mModuleClient) { 551 mModels.removeItemsAt(i - 1); 552 ALOGV("detach() unloading model %d", model->mHandle); 553 if (mHalInterface != 0) { 554 if (model->mState == Model::STATE_ACTIVE) { 555 mHalInterface->stopRecognition(model->mHandle); 556 } 557 mHalInterface->unloadSoundModel(model->mHandle); 558 } 559 AudioSystem::releaseSoundTriggerSession(model->mCaptureSession); 560 mHalInterface->unloadSoundModel(model->mHandle); 561 } 562 } 563} 564 565status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory, 566 sp<ModuleClient> moduleClient, 567 sound_model_handle_t *handle) 568{ 569 ALOGV("loadSoundModel() handle"); 570 if (mHalInterface == 0) { 571 return NO_INIT; 572 } 573 if (modelMemory == 0 || modelMemory->pointer() == NULL) { 574 ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()"); 575 return BAD_VALUE; 576 } 577 struct sound_trigger_sound_model *sound_model = 578 (struct sound_trigger_sound_model *)modelMemory->pointer(); 579 580 size_t structSize; 581 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { 582 structSize = sizeof(struct sound_trigger_phrase_sound_model); 583 } else { 584 structSize = sizeof(struct sound_trigger_sound_model); 585 } 586 587 if (sound_model->data_offset < structSize || 588 sound_model->data_size > (UINT_MAX - sound_model->data_offset) || 589 modelMemory->size() < sound_model->data_offset || 590 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { 591 android_errorWriteLog(0x534e4554, "30148546"); 592 ALOGE("loadSoundModel() data_size is too big"); 593 return BAD_VALUE; 594 } 595 596 AutoMutex lock(mLock); 597 598 if (mModels.size() >= mDescriptor.properties.max_sound_models) { 599 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded", 600 mDescriptor.properties.max_sound_models); 601 return INVALID_OPERATION; 602 } 603 604 status_t status = mHalInterface->loadSoundModel(sound_model, 605 SoundTriggerHwService::soundModelCallback, 606 this, handle); 607 608 if (status != NO_ERROR) { 609 return status; 610 } 611 audio_session_t session; 612 audio_io_handle_t ioHandle; 613 audio_devices_t device; 614 615 status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device); 616 if (status != NO_ERROR) { 617 return status; 618 } 619 620 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type, 621 moduleClient); 622 mModels.replaceValueFor(*handle, model); 623 624 return status; 625} 626 627status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle) 628{ 629 ALOGV("unloadSoundModel() model handle %d", handle); 630 AutoMutex lock(mLock); 631 return unloadSoundModel_l(handle); 632} 633 634status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle) 635{ 636 if (mHalInterface == 0) { 637 return NO_INIT; 638 } 639 ssize_t index = mModels.indexOfKey(handle); 640 if (index < 0) { 641 return BAD_VALUE; 642 } 643 sp<Model> model = mModels.valueAt(index); 644 mModels.removeItem(handle); 645 if (model->mState == Model::STATE_ACTIVE) { 646 mHalInterface->stopRecognition(model->mHandle); 647 model->mState = Model::STATE_IDLE; 648 } 649 AudioSystem::releaseSoundTriggerSession(model->mCaptureSession); 650 return mHalInterface->unloadSoundModel(handle); 651} 652 653status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle, 654 const sp<IMemory>& dataMemory) 655{ 656 ALOGV("startRecognition() model handle %d", handle); 657 if (mHalInterface == 0) { 658 return NO_INIT; 659 } 660 if (dataMemory == 0 || dataMemory->pointer() == NULL) { 661 ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); 662 return BAD_VALUE; 663 664 } 665 666 struct sound_trigger_recognition_config *config = 667 (struct sound_trigger_recognition_config *)dataMemory->pointer(); 668 669 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || 670 config->data_size > (UINT_MAX - config->data_offset) || 671 dataMemory->size() < config->data_offset || 672 config->data_size > (dataMemory->size() - config->data_offset)) { 673 ALOGE("startRecognition() data_size is too big"); 674 return BAD_VALUE; 675 } 676 677 AutoMutex lock(mLock); 678 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { 679 return INVALID_OPERATION; 680 } 681 sp<Model> model = getModel(handle); 682 if (model == 0) { 683 return BAD_VALUE; 684 } 685 686 if (model->mState == Model::STATE_ACTIVE) { 687 return INVALID_OPERATION; 688 } 689 690 691 //TODO: get capture handle and device from audio policy service 692 config->capture_handle = model->mCaptureIOHandle; 693 config->capture_device = model->mCaptureDevice; 694 status_t status = mHalInterface->startRecognition(handle, config, 695 SoundTriggerHwService::recognitionCallback, 696 this); 697 698 if (status == NO_ERROR) { 699 model->mState = Model::STATE_ACTIVE; 700 model->mConfig = *config; 701 } 702 703 return status; 704} 705 706status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle) 707{ 708 ALOGV("stopRecognition() model handle %d", handle); 709 if (mHalInterface == 0) { 710 return NO_INIT; 711 } 712 AutoMutex lock(mLock); 713 sp<Model> model = getModel(handle); 714 if (model == 0) { 715 return BAD_VALUE; 716 } 717 718 if (model->mState != Model::STATE_ACTIVE) { 719 return INVALID_OPERATION; 720 } 721 mHalInterface->stopRecognition(handle); 722 model->mState = Model::STATE_IDLE; 723 return NO_ERROR; 724} 725 726void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event) 727{ 728 ALOGV("onCallbackEvent type %d", event->mType); 729 730 sp<IMemory> eventMemory = event->mMemory; 731 732 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 733 return; 734 } 735 if (mModuleClients.isEmpty()) { 736 ALOGI("%s no clients", __func__); 737 return; 738 } 739 740 switch (event->mType) { 741 case CallbackEvent::TYPE_RECOGNITION: { 742 struct sound_trigger_recognition_event *recognitionEvent = 743 (struct sound_trigger_recognition_event *)eventMemory->pointer(); 744 sp<ISoundTriggerClient> client; 745 { 746 AutoMutex lock(mLock); 747 sp<Model> model = getModel(recognitionEvent->model); 748 if (model == 0) { 749 ALOGW("%s model == 0", __func__); 750 return; 751 } 752 if (model->mState != Model::STATE_ACTIVE) { 753 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 754 return; 755 } 756 757 recognitionEvent->capture_session = model->mCaptureSession; 758 model->mState = Model::STATE_IDLE; 759 client = model->mModuleClient->client(); 760 } 761 if (client != 0) { 762 client->onRecognitionEvent(eventMemory); 763 } 764 } break; 765 case CallbackEvent::TYPE_SOUNDMODEL: { 766 struct sound_trigger_model_event *soundmodelEvent = 767 (struct sound_trigger_model_event *)eventMemory->pointer(); 768 sp<ISoundTriggerClient> client; 769 { 770 AutoMutex lock(mLock); 771 sp<Model> model = getModel(soundmodelEvent->model); 772 if (model == 0) { 773 ALOGW("%s model == 0", __func__); 774 return; 775 } 776 client = model->mModuleClient->client(); 777 } 778 if (client != 0) { 779 client->onSoundModelEvent(eventMemory); 780 } 781 } break; 782 case CallbackEvent::TYPE_SERVICE_STATE: { 783 Vector< sp<ISoundTriggerClient> > clients; 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]->client()); 789 } 790 } 791 } 792 for (size_t i = 0; i < clients.size(); i++) { 793 clients[i]->onServiceStateChange(eventMemory); 794 } 795 } break; 796 default: 797 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 798 } 799} 800 801sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel( 802 sound_model_handle_t handle) 803{ 804 sp<Model> model; 805 ssize_t index = mModels.indexOfKey(handle); 806 if (index >= 0) { 807 model = mModels.valueAt(index); 808 } 809 return model; 810} 811 812// Called with mServiceLock held 813void SoundTriggerHwService::Module::setCaptureState_l(bool active) 814{ 815 ALOGV("Module::setCaptureState_l %d", active); 816 sp<SoundTriggerHwService> service; 817 sound_trigger_service_state_t state; 818 819 Vector< sp<IMemory> > events; 820 { 821 AutoMutex lock(mLock); 822 state = (active && !mDescriptor.properties.concurrent_capture) ? 823 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 824 825 if (state == mServiceState) { 826 return; 827 } 828 829 mServiceState = state; 830 831 service = mService.promote(); 832 if (service == 0) { 833 return; 834 } 835 836 if (state == SOUND_TRIGGER_STATE_ENABLED) { 837 goto exit; 838 } 839 840 const bool supports_stop_all = 841 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() == ENOSYS); 842 843 for (size_t i = 0; i < mModels.size(); i++) { 844 sp<Model> model = mModels.valueAt(i); 845 if (model->mState == Model::STATE_ACTIVE) { 846 if (mHalInterface != 0 && !supports_stop_all) { 847 mHalInterface->stopRecognition(model->mHandle); 848 } 849 // keep model in ACTIVE state so that event is processed by onCallbackEvent() 850 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) { 851 struct sound_trigger_phrase_recognition_event event; 852 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 853 event.num_phrases = model->mConfig.num_phrases; 854 for (size_t i = 0; i < event.num_phrases; i++) { 855 event.phrase_extras[i] = model->mConfig.phrases[i]; 856 } 857 event.common.status = RECOGNITION_STATUS_ABORT; 858 event.common.type = model->mType; 859 event.common.model = model->mHandle; 860 event.common.data_size = 0; 861 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 862 if (eventMemory != 0) { 863 events.add(eventMemory); 864 } 865 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) { 866 struct sound_trigger_generic_recognition_event event; 867 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event)); 868 event.common.status = RECOGNITION_STATUS_ABORT; 869 event.common.type = model->mType; 870 event.common.model = model->mHandle; 871 event.common.data_size = 0; 872 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 873 if (eventMemory != 0) { 874 events.add(eventMemory); 875 } 876 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) { 877 struct sound_trigger_phrase_recognition_event event; 878 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 879 event.common.status = RECOGNITION_STATUS_ABORT; 880 event.common.type = model->mType; 881 event.common.model = model->mHandle; 882 event.common.data_size = 0; 883 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 884 if (eventMemory != 0) { 885 events.add(eventMemory); 886 } 887 } else { 888 goto exit; 889 } 890 } 891 } 892 } 893 894 for (size_t i = 0; i < events.size(); i++) { 895 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 896 events[i]); 897 callbackEvent->setModule(this); 898 service->sendCallbackEvent_l(callbackEvent); 899 } 900 901exit: 902 service->sendServiceStateEvent_l(state, this); 903} 904 905 906SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session, 907 audio_io_handle_t ioHandle, audio_devices_t device, 908 sound_trigger_sound_model_type_t type, 909 sp<ModuleClient>& moduleClient) : 910 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session), 911 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type), 912 mModuleClient(moduleClient) 913{ 914} 915 916#undef LOG_TAG 917#define LOG_TAG "SoundTriggerHwService::ModuleClient" 918 919SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module, 920 const sp<ISoundTriggerClient>& client) 921 : mModule(module), mClient(client) 922{ 923} 924 925void SoundTriggerHwService::ModuleClient::onFirstRef() 926{ 927 sp<IBinder> binder = IInterface::asBinder(mClient); 928 if (binder != 0) { 929 binder->linkToDeath(this); 930 } 931} 932 933SoundTriggerHwService::ModuleClient::~ModuleClient() 934{ 935} 936 937status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused, 938 const Vector<String16>& args __unused) { 939 String8 result; 940 return NO_ERROR; 941} 942 943void SoundTriggerHwService::ModuleClient::detach() { 944 ALOGV("detach()"); 945 if (!captureHotwordAllowed()) { 946 return; 947 } 948 949 { 950 AutoMutex lock(mLock); 951 if (mClient != 0) { 952 IInterface::asBinder(mClient)->unlinkToDeath(this); 953 mClient.clear(); 954 } 955 } 956 957 sp<Module> module = mModule.promote(); 958 if (module == 0) { 959 return; 960 } 961 module->detach(this); 962} 963 964status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory, 965 sound_model_handle_t *handle) 966{ 967 ALOGV("loadSoundModel() handle"); 968 if (!captureHotwordAllowed()) { 969 return PERMISSION_DENIED; 970 } 971 972 sp<Module> module = mModule.promote(); 973 if (module == 0) { 974 return NO_INIT; 975 } 976 return module->loadSoundModel(modelMemory, this, handle); 977} 978 979status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle) 980{ 981 ALOGV("unloadSoundModel() model handle %d", handle); 982 if (!captureHotwordAllowed()) { 983 return PERMISSION_DENIED; 984 } 985 986 sp<Module> module = mModule.promote(); 987 if (module == 0) { 988 return NO_INIT; 989 } 990 return module->unloadSoundModel(handle); 991} 992 993status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle, 994 const sp<IMemory>& dataMemory) 995{ 996 ALOGV("startRecognition() model handle %d", handle); 997 if (!captureHotwordAllowed()) { 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 1008status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle) 1009{ 1010 ALOGV("stopRecognition() model handle %d", handle); 1011 if (!captureHotwordAllowed()) { 1012 return PERMISSION_DENIED; 1013 } 1014 1015 sp<Module> module = mModule.promote(); 1016 if (module == 0) { 1017 return NO_INIT; 1018 } 1019 return module->stopRecognition(handle); 1020} 1021 1022void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active) 1023{ 1024 ALOGV("ModuleClient::setCaptureState_l %d", active); 1025 sp<SoundTriggerHwService> service; 1026 sound_trigger_service_state_t state; 1027 1028 sp<Module> module = mModule.promote(); 1029 if (module == 0) { 1030 return; 1031 } 1032 { 1033 AutoMutex lock(mLock); 1034 state = (active && !module->isConcurrentCaptureAllowed()) ? 1035 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 1036 1037 service = module->service().promote(); 1038 if (service == 0) { 1039 return; 1040 } 1041 } 1042 service->sendServiceStateEvent_l(state, this); 1043} 1044 1045void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event) 1046{ 1047 ALOGV("ModuleClient onCallbackEvent type %d", event->mType); 1048 1049 sp<IMemory> eventMemory = event->mMemory; 1050 1051 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 1052 return; 1053 } 1054 1055 switch (event->mType) { 1056 case CallbackEvent::TYPE_SERVICE_STATE: { 1057 sp<ISoundTriggerClient> client; 1058 { 1059 AutoMutex lock(mLock); 1060 client = mClient; 1061 } 1062 if (client !=0 ) { 1063 client->onServiceStateChange(eventMemory); 1064 } 1065 } break; 1066 default: 1067 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 1068 } 1069} 1070 1071void SoundTriggerHwService::ModuleClient::binderDied( 1072 const wp<IBinder> &who __unused) { 1073 ALOGW("client binder died for client %p", this); 1074 detach(); 1075} 1076 1077}; // namespace android 1078