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 <hardware/sound_trigger.h> 36 #include <ServiceUtilities.h> 37 #include "SoundTriggerHwService.h" 38 39 namespace android { 40 41 #ifdef SOUND_TRIGGER_USE_STUB_MODULE 42 #define HW_MODULE_PREFIX "stub" 43 #else 44 #define HW_MODULE_PREFIX "primary" 45 #endif 46 47 SoundTriggerHwService::SoundTriggerHwService() 48 : BnSoundTriggerHwService(), 49 mNextUniqueId(1), 50 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")), 51 mCaptureState(false) 52 { 53 } 54 55 void SoundTriggerHwService::onFirstRef() 56 { 57 const hw_module_t *mod; 58 int rc; 59 sound_trigger_hw_device *dev; 60 61 rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod); 62 if (rc != 0) { 63 ALOGE("couldn't load sound trigger module %s.%s (%s)", 64 SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc)); 65 return; 66 } 67 rc = sound_trigger_hw_device_open(mod, &dev); 68 if (rc != 0) { 69 ALOGE("couldn't open sound trigger hw device in %s.%s (%s)", 70 SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc)); 71 return; 72 } 73 if (dev->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 || 74 dev->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) { 75 ALOGE("wrong sound trigger hw device version %04x", dev->common.version); 76 return; 77 } 78 79 sound_trigger_module_descriptor descriptor; 80 rc = dev->get_properties(dev, &descriptor.properties); 81 if (rc != 0) { 82 ALOGE("could not read implementation properties"); 83 return; 84 } 85 descriptor.handle = 86 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId); 87 ALOGI("loaded default module %s, handle %d", descriptor.properties.description, 88 descriptor.handle); 89 90 sp<ISoundTriggerClient> client; 91 sp<Module> module = new Module(this, dev, descriptor, client); 92 mModules.add(descriptor.handle, module); 93 mCallbackThread = new CallbackThread(this); 94 } 95 96 SoundTriggerHwService::~SoundTriggerHwService() 97 { 98 if (mCallbackThread != 0) { 99 mCallbackThread->exit(); 100 } 101 for (size_t i = 0; i < mModules.size(); i++) { 102 sound_trigger_hw_device_close(mModules.valueAt(i)->hwDevice()); 103 } 104 } 105 106 status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules, 107 uint32_t *numModules) 108 { 109 ALOGV("listModules"); 110 if (!captureHotwordAllowed()) { 111 return PERMISSION_DENIED; 112 } 113 114 AutoMutex lock(mServiceLock); 115 if (numModules == NULL || (*numModules != 0 && modules == NULL)) { 116 return BAD_VALUE; 117 } 118 size_t maxModules = *numModules; 119 *numModules = mModules.size(); 120 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) { 121 modules[i] = mModules.valueAt(i)->descriptor(); 122 } 123 return NO_ERROR; 124 } 125 126 status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle, 127 const sp<ISoundTriggerClient>& client, 128 sp<ISoundTrigger>& moduleInterface) 129 { 130 ALOGV("attach module %d", handle); 131 if (!captureHotwordAllowed()) { 132 return PERMISSION_DENIED; 133 } 134 135 AutoMutex lock(mServiceLock); 136 moduleInterface.clear(); 137 if (client == 0) { 138 return BAD_VALUE; 139 } 140 ssize_t index = mModules.indexOfKey(handle); 141 if (index < 0) { 142 return BAD_VALUE; 143 } 144 sp<Module> module = mModules.valueAt(index); 145 146 module->setClient(client); 147 IInterface::asBinder(client)->linkToDeath(module); 148 moduleInterface = module; 149 150 module->setCaptureState_l(mCaptureState); 151 152 return NO_ERROR; 153 } 154 155 status_t SoundTriggerHwService::setCaptureState(bool active) 156 { 157 ALOGV("setCaptureState %d", active); 158 AutoMutex lock(mServiceLock); 159 mCaptureState = active; 160 for (size_t i = 0; i < mModules.size(); i++) { 161 mModules.valueAt(i)->setCaptureState_l(active); 162 } 163 return NO_ERROR; 164 } 165 166 167 void SoundTriggerHwService::detachModule(sp<Module> module) 168 { 169 ALOGV("detachModule"); 170 AutoMutex lock(mServiceLock); 171 module->clearClient(); 172 } 173 174 175 static const int kDumpLockRetries = 50; 176 static const int kDumpLockSleep = 60000; 177 178 static bool tryLock(Mutex& mutex) 179 { 180 bool locked = false; 181 for (int i = 0; i < kDumpLockRetries; ++i) { 182 if (mutex.tryLock() == NO_ERROR) { 183 locked = true; 184 break; 185 } 186 usleep(kDumpLockSleep); 187 } 188 return locked; 189 } 190 191 status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) { 192 String8 result; 193 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 194 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService"); 195 write(fd, result.string(), result.size()); 196 } else { 197 bool locked = tryLock(mServiceLock); 198 // failed to lock - SoundTriggerHwService is probably deadlocked 199 if (!locked) { 200 result.append("SoundTriggerHwService may be deadlocked\n"); 201 write(fd, result.string(), result.size()); 202 } 203 204 if (locked) mServiceLock.unlock(); 205 } 206 return NO_ERROR; 207 } 208 209 status_t SoundTriggerHwService::onTransact( 210 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 211 return BnSoundTriggerHwService::onTransact(code, data, reply, flags); 212 } 213 214 215 // static 216 void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event, 217 void *cookie) 218 { 219 Module *module = (Module *)cookie; 220 if (module == NULL) { 221 return; 222 } 223 sp<SoundTriggerHwService> service = module->service().promote(); 224 if (service == 0) { 225 return; 226 } 227 228 service->sendRecognitionEvent(event, module); 229 } 230 231 sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l( 232 struct sound_trigger_recognition_event *event) 233 { 234 sp<IMemory> eventMemory; 235 236 //sanitize event 237 switch (event->type) { 238 case SOUND_MODEL_TYPE_KEYPHRASE: 239 ALOGW_IF(event->data_size != 0 && event->data_offset != 240 sizeof(struct sound_trigger_phrase_recognition_event), 241 "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type", 242 event->data_offset); 243 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event); 244 break; 245 case SOUND_MODEL_TYPE_GENERIC: 246 ALOGW_IF(event->data_size != 0 && event->data_offset != 247 sizeof(struct sound_trigger_generic_recognition_event), 248 "prepareRecognitionEvent_l(): invalid data offset %u for generic event type", 249 event->data_offset); 250 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event); 251 break; 252 case SOUND_MODEL_TYPE_UNKNOWN: 253 ALOGW_IF(event->data_size != 0 && event->data_offset != 254 sizeof(struct sound_trigger_recognition_event), 255 "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type", 256 event->data_offset); 257 event->data_offset = sizeof(struct sound_trigger_recognition_event); 258 break; 259 default: 260 return eventMemory; 261 } 262 263 size_t size = event->data_offset + event->data_size; 264 eventMemory = mMemoryDealer->allocate(size); 265 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 266 eventMemory.clear(); 267 return eventMemory; 268 } 269 memcpy(eventMemory->pointer(), event, size); 270 271 return eventMemory; 272 } 273 274 void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event, 275 Module *module) 276 { 277 AutoMutex lock(mServiceLock); 278 if (module == NULL) { 279 return; 280 } 281 sp<IMemory> eventMemory = prepareRecognitionEvent_l(event); 282 if (eventMemory == 0) { 283 return; 284 } 285 sp<Module> strongModule; 286 for (size_t i = 0; i < mModules.size(); i++) { 287 if (mModules.valueAt(i).get() == module) { 288 strongModule = mModules.valueAt(i); 289 break; 290 } 291 } 292 if (strongModule == 0) { 293 return; 294 } 295 296 sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 297 eventMemory, strongModule)); 298 } 299 300 // static 301 void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event, 302 void *cookie) 303 { 304 Module *module = (Module *)cookie; 305 if (module == NULL) { 306 return; 307 } 308 sp<SoundTriggerHwService> service = module->service().promote(); 309 if (service == 0) { 310 return; 311 } 312 313 service->sendSoundModelEvent(event, module); 314 } 315 316 sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event) 317 { 318 sp<IMemory> eventMemory; 319 320 size_t size = event->data_offset + event->data_size; 321 eventMemory = mMemoryDealer->allocate(size); 322 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 323 eventMemory.clear(); 324 return eventMemory; 325 } 326 memcpy(eventMemory->pointer(), event, size); 327 328 return eventMemory; 329 } 330 331 void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event, 332 Module *module) 333 { 334 AutoMutex lock(mServiceLock); 335 sp<IMemory> eventMemory = prepareSoundModelEvent_l(event); 336 if (eventMemory == 0) { 337 return; 338 } 339 sp<Module> strongModule; 340 for (size_t i = 0; i < mModules.size(); i++) { 341 if (mModules.valueAt(i).get() == module) { 342 strongModule = mModules.valueAt(i); 343 break; 344 } 345 } 346 if (strongModule == 0) { 347 return; 348 } 349 sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL, 350 eventMemory, strongModule)); 351 } 352 353 354 sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state) 355 { 356 sp<IMemory> eventMemory; 357 358 size_t size = sizeof(sound_trigger_service_state_t); 359 eventMemory = mMemoryDealer->allocate(size); 360 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 361 eventMemory.clear(); 362 return eventMemory; 363 } 364 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state; 365 return eventMemory; 366 } 367 368 // call with mServiceLock held 369 void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state, 370 Module *module) 371 { 372 sp<IMemory> eventMemory = prepareServiceStateEvent_l(state); 373 if (eventMemory == 0) { 374 return; 375 } 376 sp<Module> strongModule; 377 for (size_t i = 0; i < mModules.size(); i++) { 378 if (mModules.valueAt(i).get() == module) { 379 strongModule = mModules.valueAt(i); 380 break; 381 } 382 } 383 if (strongModule == 0) { 384 return; 385 } 386 sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE, 387 eventMemory, strongModule)); 388 } 389 390 // call with mServiceLock held 391 void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event) 392 { 393 mCallbackThread->sendCallbackEvent(event); 394 } 395 396 void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event) 397 { 398 ALOGV("onCallbackEvent"); 399 sp<Module> module; 400 { 401 AutoMutex lock(mServiceLock); 402 module = event->mModule.promote(); 403 if (module == 0) { 404 return; 405 } 406 } 407 module->onCallbackEvent(event); 408 { 409 AutoMutex lock(mServiceLock); 410 // clear now to execute with mServiceLock locked 411 event->mMemory.clear(); 412 } 413 } 414 415 #undef LOG_TAG 416 #define LOG_TAG "SoundTriggerHwService::CallbackThread" 417 418 SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service) 419 : mService(service) 420 { 421 } 422 423 SoundTriggerHwService::CallbackThread::~CallbackThread() 424 { 425 while (!mEventQueue.isEmpty()) { 426 mEventQueue[0]->mMemory.clear(); 427 mEventQueue.removeAt(0); 428 } 429 } 430 431 void SoundTriggerHwService::CallbackThread::onFirstRef() 432 { 433 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO); 434 } 435 436 bool SoundTriggerHwService::CallbackThread::threadLoop() 437 { 438 while (!exitPending()) { 439 sp<CallbackEvent> event; 440 sp<SoundTriggerHwService> service; 441 { 442 Mutex::Autolock _l(mCallbackLock); 443 while (mEventQueue.isEmpty() && !exitPending()) { 444 ALOGV("CallbackThread::threadLoop() sleep"); 445 mCallbackCond.wait(mCallbackLock); 446 ALOGV("CallbackThread::threadLoop() wake up"); 447 } 448 if (exitPending()) { 449 break; 450 } 451 event = mEventQueue[0]; 452 mEventQueue.removeAt(0); 453 service = mService.promote(); 454 } 455 if (service != 0) { 456 service->onCallbackEvent(event); 457 } 458 } 459 return false; 460 } 461 462 void SoundTriggerHwService::CallbackThread::exit() 463 { 464 Mutex::Autolock _l(mCallbackLock); 465 requestExit(); 466 mCallbackCond.broadcast(); 467 } 468 469 void SoundTriggerHwService::CallbackThread::sendCallbackEvent( 470 const sp<SoundTriggerHwService::CallbackEvent>& event) 471 { 472 AutoMutex lock(mCallbackLock); 473 mEventQueue.add(event); 474 mCallbackCond.signal(); 475 } 476 477 SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory, 478 wp<Module> module) 479 : mType(type), mMemory(memory), mModule(module) 480 { 481 } 482 483 SoundTriggerHwService::CallbackEvent::~CallbackEvent() 484 { 485 } 486 487 488 #undef LOG_TAG 489 #define LOG_TAG "SoundTriggerHwService::Module" 490 491 SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service, 492 sound_trigger_hw_device* hwDevice, 493 sound_trigger_module_descriptor descriptor, 494 const sp<ISoundTriggerClient>& client) 495 : mService(service), mHwDevice(hwDevice), mDescriptor(descriptor), 496 mClient(client), mServiceState(SOUND_TRIGGER_STATE_NO_INIT) 497 { 498 } 499 500 SoundTriggerHwService::Module::~Module() { 501 } 502 503 void SoundTriggerHwService::Module::detach() { 504 ALOGV("detach()"); 505 if (!captureHotwordAllowed()) { 506 return; 507 } 508 { 509 AutoMutex lock(mLock); 510 for (size_t i = 0; i < mModels.size(); i++) { 511 sp<Model> model = mModels.valueAt(i); 512 ALOGV("detach() unloading model %d", model->mHandle); 513 if (model->mState == Model::STATE_ACTIVE) { 514 mHwDevice->stop_recognition(mHwDevice, model->mHandle); 515 } 516 mHwDevice->unload_sound_model(mHwDevice, model->mHandle); 517 } 518 mModels.clear(); 519 } 520 if (mClient != 0) { 521 IInterface::asBinder(mClient)->unlinkToDeath(this); 522 } 523 sp<SoundTriggerHwService> service = mService.promote(); 524 if (service == 0) { 525 return; 526 } 527 service->detachModule(this); 528 } 529 530 status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory, 531 sound_model_handle_t *handle) 532 { 533 ALOGV("loadSoundModel() handle"); 534 if (!captureHotwordAllowed()) { 535 return PERMISSION_DENIED; 536 } 537 538 if (modelMemory == 0 || modelMemory->pointer() == NULL) { 539 ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()"); 540 return BAD_VALUE; 541 } 542 struct sound_trigger_sound_model *sound_model = 543 (struct sound_trigger_sound_model *)modelMemory->pointer(); 544 545 size_t structSize; 546 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { 547 structSize = sizeof(struct sound_trigger_phrase_sound_model); 548 } else { 549 structSize = sizeof(struct sound_trigger_sound_model); 550 } 551 552 if (sound_model->data_offset < structSize || 553 sound_model->data_size > (UINT_MAX - sound_model->data_offset) || 554 modelMemory->size() < sound_model->data_offset || 555 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { 556 android_errorWriteLog(0x534e4554, "30148546"); 557 ALOGE("loadSoundModel() data_size is too big"); 558 return BAD_VALUE; 559 } 560 561 AutoMutex lock(mLock); 562 563 if (mModels.size() >= mDescriptor.properties.max_sound_models) { 564 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded", 565 mDescriptor.properties.max_sound_models); 566 return INVALID_OPERATION; 567 } 568 569 status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model, 570 SoundTriggerHwService::soundModelCallback, 571 this, handle); 572 573 if (status != NO_ERROR) { 574 return status; 575 } 576 audio_session_t session; 577 audio_io_handle_t ioHandle; 578 audio_devices_t device; 579 580 status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device); 581 if (status != NO_ERROR) { 582 return status; 583 } 584 585 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type); 586 mModels.replaceValueFor(*handle, model); 587 588 return status; 589 } 590 591 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle) 592 { 593 ALOGV("unloadSoundModel() model handle %d", handle); 594 if (!captureHotwordAllowed()) { 595 return PERMISSION_DENIED; 596 } 597 598 AutoMutex lock(mLock); 599 return unloadSoundModel_l(handle); 600 } 601 602 status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle) 603 { 604 ssize_t index = mModels.indexOfKey(handle); 605 if (index < 0) { 606 return BAD_VALUE; 607 } 608 sp<Model> model = mModels.valueAt(index); 609 mModels.removeItem(handle); 610 if (model->mState == Model::STATE_ACTIVE) { 611 mHwDevice->stop_recognition(mHwDevice, model->mHandle); 612 model->mState = Model::STATE_IDLE; 613 } 614 AudioSystem::releaseSoundTriggerSession(model->mCaptureSession); 615 return mHwDevice->unload_sound_model(mHwDevice, handle); 616 } 617 618 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle, 619 const sp<IMemory>& dataMemory) 620 { 621 ALOGV("startRecognition() model handle %d", handle); 622 if (!captureHotwordAllowed()) { 623 return PERMISSION_DENIED; 624 } 625 626 if (dataMemory == 0 || dataMemory->pointer() == NULL) { 627 ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); 628 return BAD_VALUE; 629 630 } 631 632 struct sound_trigger_recognition_config *config = 633 (struct sound_trigger_recognition_config *)dataMemory->pointer(); 634 635 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || 636 config->data_size > (UINT_MAX - config->data_offset) || 637 dataMemory->size() < config->data_offset || 638 config->data_size > (dataMemory->size() - config->data_offset)) { 639 ALOGE("startRecognition() data_size is too big"); 640 return BAD_VALUE; 641 } 642 643 AutoMutex lock(mLock); 644 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { 645 return INVALID_OPERATION; 646 } 647 sp<Model> model = getModel(handle); 648 if (model == 0) { 649 return BAD_VALUE; 650 } 651 652 if (model->mState == Model::STATE_ACTIVE) { 653 return INVALID_OPERATION; 654 } 655 656 657 //TODO: get capture handle and device from audio policy service 658 config->capture_handle = model->mCaptureIOHandle; 659 config->capture_device = model->mCaptureDevice; 660 status_t status = mHwDevice->start_recognition(mHwDevice, handle, config, 661 SoundTriggerHwService::recognitionCallback, 662 this); 663 664 if (status == NO_ERROR) { 665 model->mState = Model::STATE_ACTIVE; 666 model->mConfig = *config; 667 } 668 669 return status; 670 } 671 672 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle) 673 { 674 ALOGV("stopRecognition() model handle %d", handle); 675 if (!captureHotwordAllowed()) { 676 return PERMISSION_DENIED; 677 } 678 679 AutoMutex lock(mLock); 680 sp<Model> model = getModel(handle); 681 if (model == 0) { 682 return BAD_VALUE; 683 } 684 685 if (model->mState != Model::STATE_ACTIVE) { 686 return INVALID_OPERATION; 687 } 688 mHwDevice->stop_recognition(mHwDevice, handle); 689 model->mState = Model::STATE_IDLE; 690 return NO_ERROR; 691 } 692 693 694 void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event) 695 { 696 ALOGV("onCallbackEvent type %d", event->mType); 697 698 sp<IMemory> eventMemory = event->mMemory; 699 700 if (eventMemory == 0 || eventMemory->pointer() == NULL) { 701 return; 702 } 703 if (mClient == 0) { 704 ALOGI("%s mClient == 0", __func__); 705 return; 706 } 707 708 switch (event->mType) { 709 case CallbackEvent::TYPE_RECOGNITION: { 710 struct sound_trigger_recognition_event *recognitionEvent = 711 (struct sound_trigger_recognition_event *)eventMemory->pointer(); 712 sp<ISoundTriggerClient> client; 713 { 714 AutoMutex lock(mLock); 715 sp<Model> model = getModel(recognitionEvent->model); 716 if (model == 0) { 717 ALOGW("%s model == 0", __func__); 718 return; 719 } 720 if (model->mState != Model::STATE_ACTIVE) { 721 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 722 return; 723 } 724 725 recognitionEvent->capture_session = model->mCaptureSession; 726 model->mState = Model::STATE_IDLE; 727 client = mClient; 728 } 729 if (client != 0) { 730 client->onRecognitionEvent(eventMemory); 731 } 732 } break; 733 case CallbackEvent::TYPE_SOUNDMODEL: { 734 struct sound_trigger_model_event *soundmodelEvent = 735 (struct sound_trigger_model_event *)eventMemory->pointer(); 736 sp<ISoundTriggerClient> client; 737 { 738 AutoMutex lock(mLock); 739 sp<Model> model = getModel(soundmodelEvent->model); 740 if (model == 0) { 741 ALOGW("%s model == 0", __func__); 742 return; 743 } 744 client = mClient; 745 } 746 if (client != 0) { 747 client->onSoundModelEvent(eventMemory); 748 } 749 } break; 750 case CallbackEvent::TYPE_SERVICE_STATE: { 751 sp<ISoundTriggerClient> client; 752 { 753 AutoMutex lock(mLock); 754 client = mClient; 755 } 756 if (client != 0) { 757 client->onServiceStateChange(eventMemory); 758 } 759 } break; 760 default: 761 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 762 } 763 } 764 765 sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel( 766 sound_model_handle_t handle) 767 { 768 sp<Model> model; 769 ssize_t index = mModels.indexOfKey(handle); 770 if (index >= 0) { 771 model = mModels.valueAt(index); 772 } 773 return model; 774 } 775 776 void SoundTriggerHwService::Module::binderDied( 777 const wp<IBinder> &who __unused) { 778 ALOGW("client binder died for module %d", mDescriptor.handle); 779 detach(); 780 } 781 782 // Called with mServiceLock held 783 void SoundTriggerHwService::Module::setCaptureState_l(bool active) 784 { 785 ALOGV("Module::setCaptureState_l %d", active); 786 sp<SoundTriggerHwService> service; 787 sound_trigger_service_state_t state; 788 789 Vector< sp<IMemory> > events; 790 { 791 AutoMutex lock(mLock); 792 state = (active && !mDescriptor.properties.concurrent_capture) ? 793 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 794 795 if (state == mServiceState) { 796 return; 797 } 798 799 mServiceState = state; 800 801 service = mService.promote(); 802 if (service == 0) { 803 return; 804 } 805 806 if (state == SOUND_TRIGGER_STATE_ENABLED) { 807 goto exit; 808 } 809 810 const bool supports_stop_all = 811 (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 && 812 mHwDevice->stop_all_recognitions); 813 814 if (supports_stop_all) { 815 mHwDevice->stop_all_recognitions(mHwDevice); 816 } 817 818 for (size_t i = 0; i < mModels.size(); i++) { 819 sp<Model> model = mModels.valueAt(i); 820 if (model->mState == Model::STATE_ACTIVE) { 821 if (!supports_stop_all) { 822 mHwDevice->stop_recognition(mHwDevice, model->mHandle); 823 } 824 // keep model in ACTIVE state so that event is processed by onCallbackEvent() 825 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) { 826 struct sound_trigger_phrase_recognition_event event; 827 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 828 event.num_phrases = model->mConfig.num_phrases; 829 for (size_t i = 0; i < event.num_phrases; i++) { 830 event.phrase_extras[i] = model->mConfig.phrases[i]; 831 } 832 event.common.status = RECOGNITION_STATUS_ABORT; 833 event.common.type = model->mType; 834 event.common.model = model->mHandle; 835 event.common.data_size = 0; 836 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 837 if (eventMemory != 0) { 838 events.add(eventMemory); 839 } 840 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) { 841 struct sound_trigger_generic_recognition_event event; 842 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event)); 843 event.common.status = RECOGNITION_STATUS_ABORT; 844 event.common.type = model->mType; 845 event.common.model = model->mHandle; 846 event.common.data_size = 0; 847 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 848 if (eventMemory != 0) { 849 events.add(eventMemory); 850 } 851 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) { 852 struct sound_trigger_phrase_recognition_event event; 853 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 854 event.common.status = RECOGNITION_STATUS_ABORT; 855 event.common.type = model->mType; 856 event.common.model = model->mHandle; 857 event.common.data_size = 0; 858 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 859 if (eventMemory != 0) { 860 events.add(eventMemory); 861 } 862 } else { 863 goto exit; 864 } 865 } 866 } 867 } 868 869 for (size_t i = 0; i < events.size(); i++) { 870 service->sendCallbackEvent_l(new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, events[i], 871 this)); 872 } 873 874 exit: 875 service->sendServiceStateEvent_l(state, this); 876 } 877 878 879 SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session, 880 audio_io_handle_t ioHandle, audio_devices_t device, 881 sound_trigger_sound_model_type_t type) : 882 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session), 883 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type) 884 { 885 886 } 887 888 status_t SoundTriggerHwService::Module::dump(int fd __unused, 889 const Vector<String16>& args __unused) { 890 String8 result; 891 return NO_ERROR; 892 } 893 894 }; // namespace android 895