1b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent/* 2b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * Copyright (C) 2014 The Android Open Source Project 3b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * 4b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * you may not use this file except in compliance with the License. 6b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * You may obtain a copy of the License at 7b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * 8b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * 10b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * Unless required by applicable law or agreed to in writing, software 11b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * See the License for the specific language governing permissions and 14b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent * limitations under the License. 15b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent */ 16b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 17b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService" 18b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent//#define LOG_NDEBUG 0 19b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 20b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <stdio.h> 21b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <string.h> 22b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <sys/types.h> 23b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <pthread.h> 24b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 258ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include <system/sound_trigger.h> 26936c84a5b743dce2a2572fdf54b37b187bc88b60Eric Laurent#include <cutils/atomic.h> 27936c84a5b743dce2a2572fdf54b37b187bc88b60Eric Laurent#include <cutils/properties.h> 28df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <hardware/hardware.h> 29df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <media/AudioSystem.h> 30936c84a5b743dce2a2572fdf54b37b187bc88b60Eric Laurent#include <utils/Errors.h> 31936c84a5b743dce2a2572fdf54b37b187bc88b60Eric Laurent#include <utils/Log.h> 328ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include <binder/IServiceManager.h> 338ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include <binder/MemoryBase.h> 348ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include <binder/MemoryHeapBase.h> 357a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent#include <system/sound_trigger.h> 368ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include <ServiceUtilities.h> 378ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent#include "SoundTriggerHwService.h" 38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#ifdef SOUND_TRIGGER_USE_STUB_MODULE 40b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define HW_MODULE_PREFIX "stub" 41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#else 42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define HW_MODULE_PREFIX "primary" 43b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#endif 447a544b44b7872b300f50e16fef480f76e9145fbbEric Laurentnamespace android { 45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::SoundTriggerHwService() 47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : BnSoundTriggerHwService(), 48df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mNextUniqueId(1), 49df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")), 50df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mCaptureState(false) 51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::onFirstRef() 55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent int rc; 57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 587a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent sp<SoundTriggerHalInterface> halInterface = 597a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX); 607a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent 617a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (halInterface == 0) { 627a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent ALOGW("could not connect to HAL"); 63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_module_descriptor descriptor; 667a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent rc = halInterface->getProperties(&descriptor.properties); 67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (rc != 0) { 68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("could not read implementation properties"); 69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent descriptor.handle = 72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId); 73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGI("loaded default module %s, handle %d", descriptor.properties.description, 74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent descriptor.handle); 75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 76e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = new Module(this, halInterface, descriptor); 77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModules.add(descriptor.handle, module); 78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackThread = new CallbackThread(this); 79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::~SoundTriggerHwService() 82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mCallbackThread != 0) { 84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackThread->exit(); 85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 87b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules, 89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t *numModules) 90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("listModules"); 928ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent if (!captureHotwordAllowed()) { 938ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent return PERMISSION_DENIED; 948ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent } 958ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent 96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModules == NULL || (*numModules != 0 && modules == NULL)) { 98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 99b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent size_t maxModules = *numModules; 101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent *numModules = mModules.size(); 102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (size_t i = 0; i < mModules.size() && i < maxModules; i++) { 103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent modules[i] = mModules.valueAt(i)->descriptor(); 104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle, 109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<ISoundTriggerClient>& client, 110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTrigger>& moduleInterface) 111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("attach module %d", handle); 1138ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent if (!captureHotwordAllowed()) { 1148ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent return PERMISSION_DENIED; 1158ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent } 1168ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent 117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent moduleInterface.clear(); 119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (client == 0) { 120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModules.indexOfKey(handle); 123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index < 0) { 124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module = mModules.valueAt(index); 127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 128e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient = module->addClient(client); 129e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (moduleClient == 0) { 130e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 131e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 133e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient->setCaptureState_l(mCaptureState); 134e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleInterface = moduleClient; 135df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 139df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t SoundTriggerHwService::setCaptureState(bool active) 140df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 141df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("setCaptureState %d", active); 142df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 143df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mCaptureState = active; 144df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 145df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mModules.valueAt(i)->setCaptureState_l(active); 146df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 147df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 148df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 149df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 150df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockRetries = 50; 152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockSleep = 60000; 153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic bool tryLock(Mutex& mutex) 155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = false; 157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (int i = 0; i < kDumpLockRetries; ++i) { 158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mutex.tryLock() == NO_ERROR) { 159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent locked = true; 160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent usleep(kDumpLockSleep); 163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return locked; 165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) { 168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.appendFormat("Permission Denial: can't dump SoundTriggerHwService"); 171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } else { 173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = tryLock(mServiceLock); 174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent // failed to lock - SoundTriggerHwService is probably deadlocked 175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (!locked) { 176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.append("SoundTriggerHwService may be deadlocked\n"); 177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (locked) mServiceLock.unlock(); 181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 184b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 185b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::onTransact( 186b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 187b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BnSoundTriggerHwService::onTransact(code, data, reply, flags); 188b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 189b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 190b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 191b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// static 192b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event, 193b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent void *cookie) 194b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 195b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Module *module = (Module *)cookie; 196b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == NULL) { 197b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 198b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 199df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service = module->service().promote(); 200df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 201df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 202df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 203df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 204df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendRecognitionEvent(event, module); 205df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 206df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 207df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l( 208df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_recognition_event *event) 209df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 210df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 211df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 212df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent //sanitize event 213df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent switch (event->type) { 214df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case SOUND_MODEL_TYPE_KEYPHRASE: 215df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW_IF(event->data_size != 0 && event->data_offset != 216df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sizeof(struct sound_trigger_phrase_recognition_event), 217df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type", 218df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset); 219df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event); 220df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 22100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta case SOUND_MODEL_TYPE_GENERIC: 22200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta ALOGW_IF(event->data_size != 0 && event->data_offset != 22300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sizeof(struct sound_trigger_generic_recognition_event), 22400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta "prepareRecognitionEvent_l(): invalid data offset %u for generic event type", 22500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event->data_offset); 22600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event->data_offset = sizeof(struct sound_trigger_generic_recognition_event); 22700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta break; 228df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case SOUND_MODEL_TYPE_UNKNOWN: 229df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW_IF(event->data_size != 0 && event->data_offset != 230df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sizeof(struct sound_trigger_recognition_event), 231df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type", 232df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset); 233df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset = sizeof(struct sound_trigger_recognition_event); 234df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 235df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent default: 236886561f06ddaea86a51def1e918367430240b5acEric Laurent return eventMemory; 237df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 238df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 239df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = event->data_offset + event->data_size; 240df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 241df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 242df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 243df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 244df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 245df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent memcpy(eventMemory->pointer(), event, size); 246df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 247df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 248df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 249df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 250df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event, 251df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 252df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 253df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 254df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (module == NULL) { 255df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 256df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 257df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareRecognitionEvent_l(event); 258df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 259df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 260df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 261df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 262df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 263df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 264df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 265df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 266df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 267df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 268df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 269df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 270df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 271df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 272e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 273e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 274e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 275e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 276b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 277b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 278df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// static 279df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event, 280df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent void *cookie) 281df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 282df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module = (Module *)cookie; 283df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (module == NULL) { 284df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 285df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 286df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service = module->service().promote(); 287df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 288df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 289df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 290df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 291df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendSoundModelEvent(event, module); 292df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 293b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 294df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event) 295b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 296df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 297df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 298df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = event->data_offset + event->data_size; 299df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 300df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 301df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 302df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 303df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 304df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent memcpy(eventMemory->pointer(), event, size); 305df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 306df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 307b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 308b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 309df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event, 310df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 311b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 312df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 313df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareSoundModelEvent_l(event); 314df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 315df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 316df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 317df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 318df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 319df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 320df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 321df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 322df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 323df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 324df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 325df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 326df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 327e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL, 328e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 329e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 330e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 331df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 332df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 333df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 334df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state) 335df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 336df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 337df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 338df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = sizeof(sound_trigger_service_state_t); 339df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 340df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 341df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 342df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 343df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 344df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *((sound_trigger_service_state_t *)eventMemory->pointer()) = state; 345df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 346df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 347df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 348df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// call with mServiceLock held 349df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state, 350df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 351df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 352df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareServiceStateEvent_l(state); 353df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 354df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 355df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 356df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 357df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 358df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 359df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 360df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 361df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 362df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 363df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 364df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 365df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 366e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE, 367e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 368e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 369e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 370e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 371e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 372e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state, 373e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ModuleClient *moduleClient) 374e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 375e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<IMemory> eventMemory = prepareServiceStateEvent_l(state); 376e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (eventMemory == 0) { 377e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 378e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 379e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE, 380e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 381e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModuleClient(moduleClient); 382e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 383df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 384df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 385df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// call with mServiceLock held 386df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event) 387df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 388df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mCallbackThread->sendCallbackEvent(event); 389df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 390df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 391df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event) 392df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 393df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("onCallbackEvent"); 394b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module; 395e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient; 396b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 397b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 398e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George //CallbackEvent is either for Module or ModuleClient 399b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module = event->mModule.promote(); 400b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == 0) { 401e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient = event->mModuleClient.promote(); 402e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (moduleClient == 0) { 403e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 404e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 405b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 406b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 407e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module != 0) { 408e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("onCallbackEvent for module"); 409e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George module->onCallbackEvent(event); 410e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } else if (moduleClient != 0) { 411e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("onCallbackEvent for moduleClient"); 412e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient->onCallbackEvent(event); 413e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 414df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 415df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 416df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent // clear now to execute with mServiceLock locked 417df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->mMemory.clear(); 418df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 419b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 420b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 421b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 422b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::CallbackThread" 423b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 424b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service) 425b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : mService(service) 426b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 427b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 428b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 429b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::~CallbackThread() 430b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 431df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent while (!mEventQueue.isEmpty()) { 432df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mEventQueue[0]->mMemory.clear(); 433df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mEventQueue.removeAt(0); 434df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 435b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 436b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 437b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::onFirstRef() 438b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 439b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO); 440b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 441b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 442b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentbool SoundTriggerHwService::CallbackThread::threadLoop() 443b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 444b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (!exitPending()) { 445df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<CallbackEvent> event; 446b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<SoundTriggerHwService> service; 447b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 448b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 449b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (mEventQueue.isEmpty() && !exitPending()) { 450b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() sleep"); 451b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.wait(mCallbackLock); 452b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() wake up"); 453b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 454b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (exitPending()) { 455b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 456b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 457b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event = mEventQueue[0]; 458b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.removeAt(0); 459b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service = mService.promote(); 460b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 461b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (service != 0) { 462df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->onCallbackEvent(event); 463b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 464b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 465b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return false; 466b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 467b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 468b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::exit() 469b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 470b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 471b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent requestExit(); 472b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.broadcast(); 473b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 474b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 475df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::CallbackThread::sendCallbackEvent( 476df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent const sp<SoundTriggerHwService::CallbackEvent>& event) 477b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 478b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mCallbackLock); 479b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.add(event); 480b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.signal(); 481b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 482b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 483e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory) 484e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George : mType(type), mMemory(memory) 485b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 486b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 487b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 488df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric LaurentSoundTriggerHwService::CallbackEvent::~CallbackEvent() 489b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 490b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 491b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 492df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 493b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 494b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::Module" 495b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 496b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service, 4977a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent const sp<SoundTriggerHalInterface>& halInterface, 498e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_module_descriptor descriptor) 4997a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent : mService(service), mHalInterface(halInterface), mDescriptor(descriptor), 500e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mServiceState(SOUND_TRIGGER_STATE_NO_INIT) 501b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 502b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 503b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 504b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::~Module() { 505e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClients.clear(); 506b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 507b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 508e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgesp<SoundTriggerHwService::ModuleClient> 509e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client) 510e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 511e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 512e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient; 513e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 514e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < mModuleClients.size(); i++) { 515e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients[i]->client() == client) { 516e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George // Client already present, reuse client 517e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return moduleClient; 518e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 519e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 520e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient = new ModuleClient(this, client); 521e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 522e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("addClient() client %p", moduleClient.get()); 523e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClients.add(moduleClient); 524e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 525e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return moduleClient; 526e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 527e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 528e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient) 529e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 530e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("Module::detach()"); 531e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 532e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ssize_t index = -1; 533e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 534e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < mModuleClients.size(); i++) { 535e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients[i] == moduleClient) { 536e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George index = i; 537e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George break; 538e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 539e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 540e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (index == -1) { 5418ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent return; 5428ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent } 543e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 544e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("remove client %p", moduleClient.get()); 545e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClients.removeAt(index); 546e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 5470012417ddc1320c6df79258266da1e869036b211Dhananjay Kumar // Iterate in reverse order as models are removed from list inside the loop. 5480012417ddc1320c6df79258266da1e869036b211Dhananjay Kumar for (size_t i = mModels.size(); i > 0; i--) { 5490012417ddc1320c6df79258266da1e869036b211Dhananjay Kumar sp<Model> model = mModels.valueAt(i - 1); 550e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (moduleClient == model->mModuleClient) { 5510012417ddc1320c6df79258266da1e869036b211Dhananjay Kumar mModels.removeItemsAt(i - 1); 552b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("detach() unloading model %d", model->mHandle); 5537a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface != 0) { 5547a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (model->mState == Model::STATE_ACTIVE) { 5557a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(model->mHandle); 5567a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 5577a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->unloadSoundModel(model->mHandle); 558b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 559e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AudioSystem::releaseSoundTriggerSession(model->mCaptureSession); 560e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mHalInterface->unloadSoundModel(model->mHandle); 561b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 562b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 563b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 564b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 565b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory, 566e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient, 567e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_model_handle_t *handle) 568b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 569b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("loadSoundModel() handle"); 5707a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 5717a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 5727a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 573b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (modelMemory == 0 || modelMemory->pointer() == NULL) { 574b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()"); 575b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 576b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 577b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_sound_model *sound_model = 578b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (struct sound_trigger_sound_model *)modelMemory->pointer(); 579b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 580bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent size_t structSize; 581bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { 582bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent structSize = sizeof(struct sound_trigger_phrase_sound_model); 583bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } else { 584bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent structSize = sizeof(struct sound_trigger_sound_model); 585bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 586bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 587bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (sound_model->data_offset < structSize || 588bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent sound_model->data_size > (UINT_MAX - sound_model->data_offset) || 589bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent modelMemory->size() < sound_model->data_offset || 590bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { 591bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent android_errorWriteLog(0x534e4554, "30148546"); 592bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("loadSoundModel() data_size is too big"); 593bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent return BAD_VALUE; 594bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 595bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 596b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 59702eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent 59802eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent if (mModels.size() >= mDescriptor.properties.max_sound_models) { 599ad65899e5f7d46e30a4dcca07aa0503fc014a3b9Ryan Bavetta ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded", 600ad65899e5f7d46e30a4dcca07aa0503fc014a3b9Ryan Bavetta mDescriptor.properties.max_sound_models); 601ad65899e5f7d46e30a4dcca07aa0503fc014a3b9Ryan Bavetta return INVALID_OPERATION; 60202eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent } 60302eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent 6047a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent status_t status = mHalInterface->loadSoundModel(sound_model, 605b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SoundTriggerHwService::soundModelCallback, 6062c561209f00320f7ca2b75998bbe72ecec527210Ryan Bavetta this, handle); 6072c561209f00320f7ca2b75998bbe72ecec527210Ryan Bavetta 608df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status != NO_ERROR) { 609df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 610df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 611df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_session_t session; 612df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t ioHandle; 613df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_devices_t device; 614df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 615df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device); 616df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status != NO_ERROR) { 617df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 618b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 619b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 620e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type, 621e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient); 622df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mModels.replaceValueFor(*handle, model); 623df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 624b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return status; 625b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 626b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 627b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle) 628b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 629b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("unloadSoundModel() model handle %d", handle); 630b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 63102eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent return unloadSoundModel_l(handle); 63202eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent} 63302eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent 63402eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurentstatus_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle) 63502eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent{ 6367a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 6377a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 6387a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 639b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModels.indexOfKey(handle); 640b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index < 0) { 641b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 642b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 6431a1cba8f9a93db188b09d9754987354029129113Eric Laurent sp<Model> model = mModels.valueAt(index); 644b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModels.removeItem(handle); 6451a1cba8f9a93db188b09d9754987354029129113Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 6467a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(model->mHandle); 64702eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent model->mState = Model::STATE_IDLE; 6481a1cba8f9a93db188b09d9754987354029129113Eric Laurent } 649df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AudioSystem::releaseSoundTriggerSession(model->mCaptureSession); 6507a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return mHalInterface->unloadSoundModel(handle); 651b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 652b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 653b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle, 6540832b2d7d190f4fbe6f134446b2610df0cccdbbbEric Laurent const sp<IMemory>& dataMemory) 655b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 656b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("startRecognition() model handle %d", handle); 6577a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 6587a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 6597a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 660bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (dataMemory == 0 || dataMemory->pointer() == NULL) { 661bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); 662b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 663b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 664b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 665bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 666bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent struct sound_trigger_recognition_config *config = 667bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent (struct sound_trigger_recognition_config *)dataMemory->pointer(); 668bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 669bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || 670bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent config->data_size > (UINT_MAX - config->data_offset) || 671bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent dataMemory->size() < config->data_offset || 672bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent config->data_size > (dataMemory->size() - config->data_offset)) { 673bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("startRecognition() data_size is too big"); 674bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent return BAD_VALUE; 675bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 676bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 677b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 678df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { 679df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return INVALID_OPERATION; 680df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 681b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 682b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 683b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 684b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 685b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 686b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 687b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 688b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 689b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 690b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 691b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent //TODO: get capture handle and device from audio policy service 692df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent config->capture_handle = model->mCaptureIOHandle; 693df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent config->capture_device = model->mCaptureDevice; 6947a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent status_t status = mHalInterface->startRecognition(handle, config, 695b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SoundTriggerHwService::recognitionCallback, 6960832b2d7d190f4fbe6f134446b2610df0cccdbbbEric Laurent this); 697df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 698df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status == NO_ERROR) { 699df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent model->mState = Model::STATE_ACTIVE; 700df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent model->mConfig = *config; 701df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 702df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 703df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 704b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 705b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 706b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle) 707b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 708b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("stopRecognition() model handle %d", handle); 7097a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 7107a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 7117a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 712b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 713b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 714b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 715b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 716b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 717b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 718b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState != Model::STATE_ACTIVE) { 719b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 720b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 7217a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(handle); 722b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->mState = Model::STATE_IDLE; 723b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 724b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 725b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 726df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event) 727b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 728df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("onCallbackEvent type %d", event->mType); 729b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 730df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = event->mMemory; 731b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 732b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 733b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 734b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 735e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients.isEmpty()) { 736e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGI("%s no clients", __func__); 737b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 738b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 739df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 740df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent switch (event->mType) { 741df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_RECOGNITION: { 742df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_recognition_event *recognitionEvent = 743df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent (struct sound_trigger_recognition_event *)eventMemory->pointer(); 744886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<ISoundTriggerClient> client; 745886561f06ddaea86a51def1e918367430240b5acEric Laurent { 746886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 747886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<Model> model = getModel(recognitionEvent->model); 748886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model == 0) { 749886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGW("%s model == 0", __func__); 750886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 751886561f06ddaea86a51def1e918367430240b5acEric Laurent } 752886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model->mState != Model::STATE_ACTIVE) { 753886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 754886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 755886561f06ddaea86a51def1e918367430240b5acEric Laurent } 756df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 757886561f06ddaea86a51def1e918367430240b5acEric Laurent recognitionEvent->capture_session = model->mCaptureSession; 758886561f06ddaea86a51def1e918367430240b5acEric Laurent model->mState = Model::STATE_IDLE; 759e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = model->mModuleClient->client(); 760df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 761886561f06ddaea86a51def1e918367430240b5acEric Laurent if (client != 0) { 762886561f06ddaea86a51def1e918367430240b5acEric Laurent client->onRecognitionEvent(eventMemory); 763df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 764df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 765df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_SOUNDMODEL: { 766df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_model_event *soundmodelEvent = 767df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent (struct sound_trigger_model_event *)eventMemory->pointer(); 768886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<ISoundTriggerClient> client; 769886561f06ddaea86a51def1e918367430240b5acEric Laurent { 770886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 771886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<Model> model = getModel(soundmodelEvent->model); 772886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model == 0) { 773886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGW("%s model == 0", __func__); 774886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 775886561f06ddaea86a51def1e918367430240b5acEric Laurent } 776e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = model->mModuleClient->client(); 777886561f06ddaea86a51def1e918367430240b5acEric Laurent } 778886561f06ddaea86a51def1e918367430240b5acEric Laurent if (client != 0) { 779886561f06ddaea86a51def1e918367430240b5acEric Laurent client->onSoundModelEvent(eventMemory); 780df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 781df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 782df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_SERVICE_STATE: { 783e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George Vector< sp<ISoundTriggerClient> > clients; 784886561f06ddaea86a51def1e918367430240b5acEric Laurent { 785886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 786e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < mModuleClients.size(); i++) { 787e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients[i] != 0) { 788e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George clients.add(mModuleClients[i]->client()); 789e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 790e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 791886561f06ddaea86a51def1e918367430240b5acEric Laurent } 792e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < clients.size(); i++) { 793e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George clients[i]->onServiceStateChange(eventMemory); 794886561f06ddaea86a51def1e918367430240b5acEric Laurent } 795df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 796df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent default: 797df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 798df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 799b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 800b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 801b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentsp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel( 802b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_model_handle_t handle) 803b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 804b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model; 805b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModels.indexOfKey(handle); 806b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index >= 0) { 807b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model = mModels.valueAt(index); 808b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 809b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return model; 810b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 811b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 812df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// Called with mServiceLock held 813df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::Module::setCaptureState_l(bool active) 814b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 815df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("Module::setCaptureState_l %d", active); 816df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service; 817df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sound_trigger_service_state_t state; 818b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 819df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Vector< sp<IMemory> > events; 820df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 821df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mLock); 822df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent state = (active && !mDescriptor.properties.concurrent_capture) ? 823df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 824b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 825df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (state == mServiceState) { 826df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 827df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 828b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 829df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mServiceState = state; 830df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 831df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service = mService.promote(); 832df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 833df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 834df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 835df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 836df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (state == SOUND_TRIGGER_STATE_ENABLED) { 837df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent goto exit; 838df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 839df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 840efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton const bool supports_stop_all = 8417a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() == ENOSYS); 842efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton 843df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModels.size(); i++) { 844df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Model> model = mModels.valueAt(i); 845df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 8467a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface != 0 && !supports_stop_all) { 8477a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(model->mHandle); 848efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton } 849df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent // keep model in ACTIVE state so that event is processed by onCallbackEvent() 85000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) { 85100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta struct sound_trigger_phrase_recognition_event event; 85200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 85300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.num_phrases = model->mConfig.num_phrases; 85400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta for (size_t i = 0; i < event.num_phrases; i++) { 85500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.phrase_extras[i] = model->mConfig.phrases[i]; 856df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 85700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 85800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.type = model->mType; 85900a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.model = model->mHandle; 86000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.data_size = 0; 86100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 86200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (eventMemory != 0) { 86300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta events.add(eventMemory); 86400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } 86500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) { 86600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta struct sound_trigger_generic_recognition_event event; 86700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event)); 86800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 86900a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.type = model->mType; 87000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.model = model->mHandle; 87100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.data_size = 0; 87200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 87300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (eventMemory != 0) { 87400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta events.add(eventMemory); 8759609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta } 8769609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) { 8779609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta struct sound_trigger_phrase_recognition_event event; 8789609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 8799609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 8809609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.type = model->mType; 8819609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.model = model->mHandle; 8829609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.data_size = 0; 8839609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 8849609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta if (eventMemory != 0) { 8859609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta events.add(eventMemory); 88600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } 88700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } else { 88800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta goto exit; 889df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 890df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 891df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 892b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 893df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 894df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < events.size(); i++) { 895e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 896e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George events[i]); 897e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(this); 898e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service->sendCallbackEvent_l(callbackEvent); 899df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 900df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 901df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentexit: 902df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendServiceStateEvent_l(state, this); 903b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 904b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 905df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 906df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric LaurentSoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session, 907df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t ioHandle, audio_devices_t device, 908e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_sound_model_type_t type, 909e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient>& moduleClient) : 910df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mHandle(handle), mState(STATE_IDLE), mCaptureSession(session), 911e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type), 912e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClient(moduleClient) 913e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 914e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 915e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 916e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George#undef LOG_TAG 917e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George#define LOG_TAG "SoundTriggerHwService::ModuleClient" 918e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 919e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module, 920e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const sp<ISoundTriggerClient>& client) 921e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George : mModule(module), mClient(client) 922b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 923e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 924df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 925e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::onFirstRef() 926e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 927c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton sp<IBinder> binder = IInterface::asBinder(mClient); 928c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton if (binder != 0) { 929c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton binder->linkToDeath(this); 930c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton } 931b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 932b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 933e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::ModuleClient::~ModuleClient() 934e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 935e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 936e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 937e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::dump(int fd __unused, 938e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const Vector<String16>& args __unused) { 939b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 940b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 941b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 942b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 943e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::detach() { 944e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("detach()"); 945e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (!captureHotwordAllowed()) { 946e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 947e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 948e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 949e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 950e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 951e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mClient != 0) { 952e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George IInterface::asBinder(mClient)->unlinkToDeath(this); 953e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mClient.clear(); 954e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 955e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 956e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 957e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 958e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 959e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 960e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 961e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George module->detach(this); 962e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 963e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 964e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory, 965e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_model_handle_t *handle) 966e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 967e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("loadSoundModel() handle"); 968e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (!captureHotwordAllowed()) { 969e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 970e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 971e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 972e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 973e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 974e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 975e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 976e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->loadSoundModel(modelMemory, this, handle); 977e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 978e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 979e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle) 980e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 981e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("unloadSoundModel() model handle %d", handle); 982e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (!captureHotwordAllowed()) { 983e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 984e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 985e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 986e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 987e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 988e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 989e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 990e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->unloadSoundModel(handle); 991e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 992e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 993e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle, 994e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const sp<IMemory>& dataMemory) 995e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 996e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("startRecognition() model handle %d", handle); 997e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (!captureHotwordAllowed()) { 998e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 999e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1000e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1001e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1002e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1003e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 1004e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1005e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->startRecognition(handle, dataMemory); 1006e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1007e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1008e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle) 1009e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1010e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("stopRecognition() model handle %d", handle); 1011e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (!captureHotwordAllowed()) { 1012e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 1013e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1014e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1015e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1016e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1017e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 1018e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1019e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->stopRecognition(handle); 1020e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1021e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1022e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active) 1023e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1024e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("ModuleClient::setCaptureState_l %d", active); 1025e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<SoundTriggerHwService> service; 1026e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_service_state_t state; 1027e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1028e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1029e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1030e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1031e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1032e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 1033e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 1034e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George state = (active && !module->isConcurrentCaptureAllowed()) ? 1035e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 1036e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1037e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service = module->service().promote(); 1038e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (service == 0) { 1039e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1040e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1041e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1042e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service->sendServiceStateEvent_l(state, this); 1043e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1044e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1045e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event) 1046e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1047e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("ModuleClient onCallbackEvent type %d", event->mType); 1048e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1049e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<IMemory> eventMemory = event->mMemory; 1050e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1051e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (eventMemory == 0 || eventMemory->pointer() == NULL) { 1052e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1053e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1054e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1055e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George switch (event->mType) { 1056e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George case CallbackEvent::TYPE_SERVICE_STATE: { 1057e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ISoundTriggerClient> client; 1058e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 1059e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 1060e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = mClient; 1061e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1062e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (client !=0 ) { 1063e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client->onServiceStateChange(eventMemory); 1064e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1065e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } break; 1066e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George default: 1067e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 1068e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1069e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1070e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1071e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::binderDied( 1072e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const wp<IBinder> &who __unused) { 1073e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGW("client binder died for client %p", this); 1074e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George detach(); 1075e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1076e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1077b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android 1078