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