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