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"); 927504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 937504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 948ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent return PERMISSION_DENIED; 958ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent } 968ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent 97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModules == NULL || (*numModules != 0 && modules == NULL)) { 99b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent size_t maxModules = *numModules; 102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent *numModules = mModules.size(); 103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (size_t i = 0; i < mModules.size() && i < maxModules; i++) { 104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent modules[i] = mModules.valueAt(i)->descriptor(); 105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle, 110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<ISoundTriggerClient>& client, 111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTrigger>& moduleInterface) 112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("attach module %d", handle); 1147504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 1157504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 1168ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent return PERMISSION_DENIED; 1178ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent } 1188ba53d87a2d311ff4b3f04e30b2e09309ae7421cEric Laurent 119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent moduleInterface.clear(); 121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (client == 0) { 122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModules.indexOfKey(handle); 125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index < 0) { 126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module = mModules.valueAt(index); 129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 130e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient = module->addClient(client); 131e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (moduleClient == 0) { 132e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 133e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 135e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient->setCaptureState_l(mCaptureState); 136e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleInterface = moduleClient; 137df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 141df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t SoundTriggerHwService::setCaptureState(bool active) 142df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 143df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("setCaptureState %d", active); 144df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 145df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mCaptureState = active; 146df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 147df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mModules.valueAt(i)->setCaptureState_l(active); 148df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 149df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 150df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 151df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 152df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockRetries = 50; 154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockSleep = 60000; 155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic bool tryLock(Mutex& mutex) 157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = false; 159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (int i = 0; i < kDumpLockRetries; ++i) { 160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mutex.tryLock() == NO_ERROR) { 161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent locked = true; 162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent usleep(kDumpLockSleep); 165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return locked; 167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) { 170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.appendFormat("Permission Denial: can't dump SoundTriggerHwService"); 173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } else { 175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = tryLock(mServiceLock); 176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent // failed to lock - SoundTriggerHwService is probably deadlocked 177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (!locked) { 178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.append("SoundTriggerHwService may be deadlocked\n"); 179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (locked) mServiceLock.unlock(); 183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 184b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 185b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 186b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 187b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::onTransact( 188b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 189b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BnSoundTriggerHwService::onTransact(code, data, reply, flags); 190b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 191b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 192b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 193b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// static 194b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event, 195b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent void *cookie) 196b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 197b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Module *module = (Module *)cookie; 198b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == NULL) { 199b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 200b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 201df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service = module->service().promote(); 202df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 203df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 204df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 205df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 206df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendRecognitionEvent(event, module); 207df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 208df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 209df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l( 210df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_recognition_event *event) 211df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 212df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 213df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 214df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent //sanitize event 215df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent switch (event->type) { 216df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case SOUND_MODEL_TYPE_KEYPHRASE: 217df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW_IF(event->data_size != 0 && event->data_offset != 218df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sizeof(struct sound_trigger_phrase_recognition_event), 219df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type", 220df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset); 221df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event); 222df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 22300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta case SOUND_MODEL_TYPE_GENERIC: 22400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta ALOGW_IF(event->data_size != 0 && event->data_offset != 22500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sizeof(struct sound_trigger_generic_recognition_event), 22600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta "prepareRecognitionEvent_l(): invalid data offset %u for generic event type", 22700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event->data_offset); 22800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event->data_offset = sizeof(struct sound_trigger_generic_recognition_event); 22900a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta break; 230df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case SOUND_MODEL_TYPE_UNKNOWN: 231df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGW_IF(event->data_size != 0 && event->data_offset != 232df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sizeof(struct sound_trigger_recognition_event), 233df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type", 234df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset); 235df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->data_offset = sizeof(struct sound_trigger_recognition_event); 236df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 237df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent default: 238886561f06ddaea86a51def1e918367430240b5acEric Laurent return eventMemory; 239df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 240df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 241df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = event->data_offset + event->data_size; 242df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 243df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 244df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 245df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 246df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 247df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent memcpy(eventMemory->pointer(), event, size); 248df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 249df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 250df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 251df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 252df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event, 253df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 254df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 255df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 256df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (module == NULL) { 257df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 258df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 259df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareRecognitionEvent_l(event); 260df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 261df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 262df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 263df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 264df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 265df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 266df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 267df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 268df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 269df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 270df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 271df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 272df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 273df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 274e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 275e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 276e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 277e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 278b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 279b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 280df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// static 281df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event, 282df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent void *cookie) 283df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 284df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module = (Module *)cookie; 285df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (module == NULL) { 286df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 287df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 288df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service = module->service().promote(); 289df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 290df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 291df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 292df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 293df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendSoundModelEvent(event, module); 294df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 295b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 296df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event) 297b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 298df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 299df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 300df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = event->data_offset + event->data_size; 301df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 302df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 303df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 304df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 305df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 306df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent memcpy(eventMemory->pointer(), event, size); 307df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 308df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 309b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 310b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 311df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event, 312df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 313b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 314df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 315df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareSoundModelEvent_l(event); 316df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 317df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 318df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 319df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 320df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 321df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 322df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 323df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 324df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 325df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 326df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 327df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 328df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 329e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL, 330e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 331e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 332e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 333df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 334df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 335df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 336df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentsp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state) 337df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 338df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory; 339df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 340df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent size_t size = sizeof(sound_trigger_service_state_t); 341df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory = mMemoryDealer->allocate(size); 342df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 343df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent eventMemory.clear(); 344df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 345df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 346df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent *((sound_trigger_service_state_t *)eventMemory->pointer()) = state; 347df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return eventMemory; 348df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 349df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 350df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// call with mServiceLock held 351df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state, 352df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Module *module) 353df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 354df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = prepareServiceStateEvent_l(state); 355df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (eventMemory == 0) { 356df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 357df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 358df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Module> strongModule; 359df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 360df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mModules.valueAt(i).get() == module) { 361df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent strongModule = mModules.valueAt(i); 362df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent break; 363df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 364df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 365df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (strongModule == 0) { 366df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 367df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 368e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE, 369e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 370e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(strongModule); 371e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 372e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 373e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 374e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state, 375e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ModuleClient *moduleClient) 376e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 377e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<IMemory> eventMemory = prepareServiceStateEvent_l(state); 378e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (eventMemory == 0) { 379e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 380e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 381e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE, 382e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George eventMemory); 383e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModuleClient(moduleClient); 384e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sendCallbackEvent_l(callbackEvent); 385df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 386df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 387df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// call with mServiceLock held 388df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event) 389df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 390df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mCallbackThread->sendCallbackEvent(event); 391df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent} 392df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 393df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event) 394df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{ 395df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("onCallbackEvent"); 396b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module; 397e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient; 398b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 399b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 400e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George //CallbackEvent is either for Module or ModuleClient 401b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module = event->mModule.promote(); 402b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == 0) { 403e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient = event->mModuleClient.promote(); 404e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (moduleClient == 0) { 405e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 406e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 407b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 408b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 409e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module != 0) { 410e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("onCallbackEvent for module"); 411e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George module->onCallbackEvent(event); 412e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } else if (moduleClient != 0) { 413e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("onCallbackEvent for moduleClient"); 414e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient->onCallbackEvent(event); 415e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 416df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 417df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mServiceLock); 418df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent // clear now to execute with mServiceLock locked 419df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent event->mMemory.clear(); 420df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 421b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 422b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 423b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 424b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::CallbackThread" 425b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 426b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service) 427b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : mService(service) 428b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 429b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 430b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 431b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::~CallbackThread() 432b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 433df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent while (!mEventQueue.isEmpty()) { 434df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mEventQueue[0]->mMemory.clear(); 435df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mEventQueue.removeAt(0); 436df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 437b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 438b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 439b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::onFirstRef() 440b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 441b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO); 442b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 443b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 444b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentbool SoundTriggerHwService::CallbackThread::threadLoop() 445b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 446b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (!exitPending()) { 447df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<CallbackEvent> event; 448b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<SoundTriggerHwService> service; 449b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 450b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 451b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (mEventQueue.isEmpty() && !exitPending()) { 452b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() sleep"); 453b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.wait(mCallbackLock); 454b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() wake up"); 455b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 456b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (exitPending()) { 457b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 458b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 459b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event = mEventQueue[0]; 460b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.removeAt(0); 461b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service = mService.promote(); 462b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 463b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (service != 0) { 464df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->onCallbackEvent(event); 465b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 466b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 467b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return false; 468b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 469b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 470b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::exit() 471b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 472b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 473b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent requestExit(); 474b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.broadcast(); 475b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 476b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 477df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::CallbackThread::sendCallbackEvent( 478df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent const sp<SoundTriggerHwService::CallbackEvent>& event) 479b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 480b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mCallbackLock); 481b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.add(event); 482b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.signal(); 483b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 484b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 485e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory) 486e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George : mType(type), mMemory(memory) 487b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 488b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 489b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 490df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric LaurentSoundTriggerHwService::CallbackEvent::~CallbackEvent() 491b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 492b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 493b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 494df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 495b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 496b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::Module" 497b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 498b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service, 4997a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent const sp<SoundTriggerHalInterface>& halInterface, 500e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_module_descriptor descriptor) 5017a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent : mService(service), mHalInterface(halInterface), mDescriptor(descriptor), 502e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mServiceState(SOUND_TRIGGER_STATE_NO_INIT) 503b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 504b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 505b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 506b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::~Module() { 507e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClients.clear(); 508b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 509b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 510e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgesp<SoundTriggerHwService::ModuleClient> 511e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client) 512e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 513e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 514e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient; 515e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 516e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < mModuleClients.size(); i++) { 517e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients[i]->client() == client) { 518e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George // Client already present, reuse client 519e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return moduleClient; 520e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 521e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 522e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George moduleClient = new ModuleClient(this, client); 523e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 524e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("addClient() client %p", moduleClient.get()); 525e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClients.add(moduleClient); 526e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 527e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return moduleClient; 528e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 529e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 530e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient) 531e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 532e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("Module::detach()"); 533338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent Vector<audio_session_t> releasedSessions; 534e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 535338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent { 536338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AutoMutex lock(mLock); 537338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent ssize_t index = -1; 538e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 539338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent for (size_t i = 0; i < mModuleClients.size(); i++) { 540338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (mModuleClients[i] == moduleClient) { 541338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent index = i; 542338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent break; 543338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 544338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 545338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (index == -1) { 546338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent return; 547338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 548e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 549338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent ALOGV("remove client %p", moduleClient.get()); 550338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mModuleClients.removeAt(index); 551338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent 552338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent // Iterate in reverse order as models are removed from list inside the loop. 553338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent for (size_t i = mModels.size(); i > 0; i--) { 554338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent sp<Model> model = mModels.valueAt(i - 1); 555338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (moduleClient == model->mModuleClient) { 556338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mModels.removeItemsAt(i - 1); 557338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent ALOGV("detach() unloading model %d", model->mHandle); 558338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (mHalInterface != 0) { 559338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 560338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mHalInterface->stopRecognition(model->mHandle); 561338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 562338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mHalInterface->unloadSoundModel(model->mHandle); 5637a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 564338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent releasedSessions.add(model->mCaptureSession); 565b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 566b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 567b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 568338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent 569338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent for (size_t i = 0; i < releasedSessions.size(); i++) { 570338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent // do not call AudioSystem methods with mLock held 571338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AudioSystem::releaseSoundTriggerSession(releasedSessions[i]); 572338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 573b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 574b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 575b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory, 576e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient> moduleClient, 577e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_model_handle_t *handle) 578b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 579b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("loadSoundModel() handle"); 5807a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 5817a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 5827a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 583b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (modelMemory == 0 || modelMemory->pointer() == NULL) { 584b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()"); 585b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 586b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 587b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_sound_model *sound_model = 588b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (struct sound_trigger_sound_model *)modelMemory->pointer(); 589b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 590bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent size_t structSize; 591bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { 592bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent structSize = sizeof(struct sound_trigger_phrase_sound_model); 593bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } else { 594bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent structSize = sizeof(struct sound_trigger_sound_model); 595bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 596bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 597bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (sound_model->data_offset < structSize || 598bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent sound_model->data_size > (UINT_MAX - sound_model->data_offset) || 599bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent modelMemory->size() < sound_model->data_offset || 600bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { 601bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent android_errorWriteLog(0x534e4554, "30148546"); 602bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("loadSoundModel() data_size is too big"); 603bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent return BAD_VALUE; 604bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 605bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 606df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_session_t session; 607df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t ioHandle; 608df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_devices_t device; 609338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent // do not call AudioSystem methods with mLock held 610338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device); 611df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status != NO_ERROR) { 612df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 613b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 614b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 615338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent { 616338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AutoMutex lock(mLock); 617338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent 618338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (mModels.size() >= mDescriptor.properties.max_sound_models) { 619338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded", 620338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mDescriptor.properties.max_sound_models); 621338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent status = INVALID_OPERATION; 622338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent goto exit; 623338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 624df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 625338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent status = mHalInterface->loadSoundModel(sound_model, 626338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent SoundTriggerHwService::soundModelCallback, 627338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent this, handle); 628338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (status != NO_ERROR) { 629338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent goto exit; 630338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 631338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent 632338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type, 633338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent moduleClient); 634338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mModels.replaceValueFor(*handle, model); 635338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 636338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurentexit: 637338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (status != NO_ERROR) { 638338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent // do not call AudioSystem methods with mLock held 639338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AudioSystem::releaseSoundTriggerSession(session); 640338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 641b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return status; 642b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 643b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 644b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle) 645b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 646b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("unloadSoundModel() model handle %d", handle); 647338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent status_t status; 648338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent audio_session_t session; 64902eb47cf18793effe9fc7ab34e1b0fe9ea6635bcEric Laurent 650338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent { 651338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AutoMutex lock(mLock); 652338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (mHalInterface == 0) { 653338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent return NO_INIT; 654338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 655338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent ssize_t index = mModels.indexOfKey(handle); 656338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (index < 0) { 657338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent return BAD_VALUE; 658338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 659338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent sp<Model> model = mModels.valueAt(index); 660338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mModels.removeItem(handle); 661338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 662338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent mHalInterface->stopRecognition(model->mHandle); 663338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent model->mState = Model::STATE_IDLE; 664338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent } 665338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent status = mHalInterface->unloadSoundModel(handle); 666338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent session = model->mCaptureSession; 6671a1cba8f9a93db188b09d9754987354029129113Eric Laurent } 668338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent // do not call AudioSystem methods with mLock held 669338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent AudioSystem::releaseSoundTriggerSession(session); 670338e8ba374432cc4ee853f4fcefcf7bd7bae3bb9Eric Laurent return status; 671b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 672b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 673b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle, 6740832b2d7d190f4fbe6f134446b2610df0cccdbbbEric Laurent const sp<IMemory>& dataMemory) 675b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 676b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("startRecognition() model handle %d", handle); 6777a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 6787a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 6797a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 680bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (dataMemory == 0 || dataMemory->pointer() == NULL) { 681bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); 682b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 683b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 684b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 685bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 686bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent struct sound_trigger_recognition_config *config = 687bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent (struct sound_trigger_recognition_config *)dataMemory->pointer(); 688bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 689bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || 690bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent config->data_size > (UINT_MAX - config->data_offset) || 691bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent dataMemory->size() < config->data_offset || 692bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent config->data_size > (dataMemory->size() - config->data_offset)) { 693bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent ALOGE("startRecognition() data_size is too big"); 694bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent return BAD_VALUE; 695bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent } 696bb00d8f139ff51336ab3c810d35685003949bcf8Eric Laurent 697b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 698df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { 699df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return INVALID_OPERATION; 700df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 701b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 702b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 703b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 704b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 705b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 706b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 707b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 708b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 709b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 710b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 711b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent //TODO: get capture handle and device from audio policy service 712df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent config->capture_handle = model->mCaptureIOHandle; 713df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent config->capture_device = model->mCaptureDevice; 7147a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent status_t status = mHalInterface->startRecognition(handle, config, 715b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SoundTriggerHwService::recognitionCallback, 7160832b2d7d190f4fbe6f134446b2610df0cccdbbbEric Laurent this); 717df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 718df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status == NO_ERROR) { 719df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent model->mState = Model::STATE_ACTIVE; 720df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent model->mConfig = *config; 721df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 722df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 723df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 724b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 725b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 726b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle) 727b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 728b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("stopRecognition() model handle %d", handle); 7297a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface == 0) { 7307a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent return NO_INIT; 7317a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent } 732b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 733b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 734b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 735b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 736b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 737b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 738b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState != Model::STATE_ACTIVE) { 739b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 740b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 7417a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(handle); 742b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->mState = Model::STATE_IDLE; 743b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 744b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 745b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 746df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event) 747b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 748df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("onCallbackEvent type %d", event->mType); 749b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 750df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<IMemory> eventMemory = event->mMemory; 751b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 752b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 753b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 754b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 755e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients.isEmpty()) { 756e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGI("%s no clients", __func__); 757b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 758b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 759df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 760df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent switch (event->mType) { 761df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_RECOGNITION: { 762df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_recognition_event *recognitionEvent = 763df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent (struct sound_trigger_recognition_event *)eventMemory->pointer(); 764886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<ISoundTriggerClient> client; 765886561f06ddaea86a51def1e918367430240b5acEric Laurent { 766886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 767886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<Model> model = getModel(recognitionEvent->model); 768886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model == 0) { 769886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGW("%s model == 0", __func__); 770886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 771886561f06ddaea86a51def1e918367430240b5acEric Laurent } 772886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model->mState != Model::STATE_ACTIVE) { 773886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 774886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 775886561f06ddaea86a51def1e918367430240b5acEric Laurent } 776df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 777886561f06ddaea86a51def1e918367430240b5acEric Laurent recognitionEvent->capture_session = model->mCaptureSession; 778886561f06ddaea86a51def1e918367430240b5acEric Laurent model->mState = Model::STATE_IDLE; 779e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = model->mModuleClient->client(); 780df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 781886561f06ddaea86a51def1e918367430240b5acEric Laurent if (client != 0) { 782886561f06ddaea86a51def1e918367430240b5acEric Laurent client->onRecognitionEvent(eventMemory); 783df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 784df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 785df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_SOUNDMODEL: { 786df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent struct sound_trigger_model_event *soundmodelEvent = 787df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent (struct sound_trigger_model_event *)eventMemory->pointer(); 788886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<ISoundTriggerClient> client; 789886561f06ddaea86a51def1e918367430240b5acEric Laurent { 790886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 791886561f06ddaea86a51def1e918367430240b5acEric Laurent sp<Model> model = getModel(soundmodelEvent->model); 792886561f06ddaea86a51def1e918367430240b5acEric Laurent if (model == 0) { 793886561f06ddaea86a51def1e918367430240b5acEric Laurent ALOGW("%s model == 0", __func__); 794886561f06ddaea86a51def1e918367430240b5acEric Laurent return; 795886561f06ddaea86a51def1e918367430240b5acEric Laurent } 796e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = model->mModuleClient->client(); 797886561f06ddaea86a51def1e918367430240b5acEric Laurent } 798886561f06ddaea86a51def1e918367430240b5acEric Laurent if (client != 0) { 799886561f06ddaea86a51def1e918367430240b5acEric Laurent client->onSoundModelEvent(eventMemory); 800df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 801df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 802df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case CallbackEvent::TYPE_SERVICE_STATE: { 803e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George Vector< sp<ISoundTriggerClient> > clients; 804886561f06ddaea86a51def1e918367430240b5acEric Laurent { 805886561f06ddaea86a51def1e918367430240b5acEric Laurent AutoMutex lock(mLock); 806e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < mModuleClients.size(); i++) { 807e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mModuleClients[i] != 0) { 808e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George clients.add(mModuleClients[i]->client()); 809e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 810e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 811886561f06ddaea86a51def1e918367430240b5acEric Laurent } 812e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George for (size_t i = 0; i < clients.size(); i++) { 813e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George clients[i]->onServiceStateChange(eventMemory); 814886561f06ddaea86a51def1e918367430240b5acEric Laurent } 815df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 816df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent default: 817df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 818df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 819b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 820b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 821b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentsp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel( 822b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_model_handle_t handle) 823b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 824b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model; 825b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModels.indexOfKey(handle); 826b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index >= 0) { 827b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model = mModels.valueAt(index); 828b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 829b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return model; 830b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 831b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 832df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent// Called with mServiceLock held 833df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTriggerHwService::Module::setCaptureState_l(bool active) 834b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 835df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent ALOGV("Module::setCaptureState_l %d", active); 836df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<SoundTriggerHwService> service; 837df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sound_trigger_service_state_t state; 838b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 839df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Vector< sp<IMemory> > events; 840df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 841df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent AutoMutex lock(mLock); 842df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent state = (active && !mDescriptor.properties.concurrent_capture) ? 843df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 844b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 845df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (state == mServiceState) { 846df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 847df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 848b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 849df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mServiceState = state; 850df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 851df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service = mService.promote(); 852df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (service == 0) { 853df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return; 854df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 855df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 856df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (state == SOUND_TRIGGER_STATE_ENABLED) { 857df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent goto exit; 858df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 859df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 860efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton const bool supports_stop_all = 861de22f8acdc8e3adf94a9770b867b355e3ca88f62Chris Thornton (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS); 862efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton 863df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < mModels.size(); i++) { 864df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent sp<Model> model = mModels.valueAt(i); 865df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 8667a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent if (mHalInterface != 0 && !supports_stop_all) { 8677a544b44b7872b300f50e16fef480f76e9145fbbEric Laurent mHalInterface->stopRecognition(model->mHandle); 868efcf16c9fd2a2f0d865a2bcca98527d3804f83d6Chris Thornton } 869df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent // keep model in ACTIVE state so that event is processed by onCallbackEvent() 87000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) { 87100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta struct sound_trigger_phrase_recognition_event event; 87200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 87300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.num_phrases = model->mConfig.num_phrases; 87400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta for (size_t i = 0; i < event.num_phrases; i++) { 87500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.phrase_extras[i] = model->mConfig.phrases[i]; 876df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 87700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 87800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.type = model->mType; 87900a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.model = model->mHandle; 88000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.data_size = 0; 88100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 88200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (eventMemory != 0) { 88300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta events.add(eventMemory); 88400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } 88500a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) { 88600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta struct sound_trigger_generic_recognition_event event; 88700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event)); 88800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 88900a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.type = model->mType; 89000a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.model = model->mHandle; 89100a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta event.common.data_size = 0; 89200a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 89300a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta if (eventMemory != 0) { 89400a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta events.add(eventMemory); 8959609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta } 8969609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) { 8979609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta struct sound_trigger_phrase_recognition_event event; 8989609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event)); 8999609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.status = RECOGNITION_STATUS_ABORT; 9009609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.type = model->mType; 9019609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.model = model->mHandle; 9029609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta event.common.data_size = 0; 9039609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common); 9049609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta if (eventMemory != 0) { 9059609a91f8560622735f6725f7f597be47a8e2f5fRyan Bavetta events.add(eventMemory); 90600a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } 90700a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta } else { 90800a727c430c474f77f8835675a9d773f0314fb68Ryan Bavetta goto exit; 909df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 910df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 911df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 912b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 913df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 914df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent for (size_t i = 0; i < events.size(); i++) { 915e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION, 916e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George events[i]); 917e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George callbackEvent->setModule(this); 918e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service->sendCallbackEvent_l(callbackEvent); 919df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 920df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 921df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentexit: 922df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent service->sendServiceStateEvent_l(state, this); 923b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 924b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 925df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 926df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric LaurentSoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session, 927df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent audio_io_handle_t ioHandle, audio_devices_t device, 928e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_sound_model_type_t type, 929e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ModuleClient>& moduleClient) : 930df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent mHandle(handle), mState(STATE_IDLE), mCaptureSession(session), 931e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type), 932e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mModuleClient(moduleClient) 933e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 934e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 935e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 936e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George#undef LOG_TAG 937e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George#define LOG_TAG "SoundTriggerHwService::ModuleClient" 938e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 939e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module, 940e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const sp<ISoundTriggerClient>& client) 941e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George : mModule(module), mClient(client) 942b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 943e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 944df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 945e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::onFirstRef() 946e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 947c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton sp<IBinder> binder = IInterface::asBinder(mClient); 948c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton if (binder != 0) { 949c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton binder->linkToDeath(this); 950c8a9f4ad35f24ac59645bb262bd8f16fd4f6f0d8Chris Thornton } 951b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 952b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 953e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew GeorgeSoundTriggerHwService::ModuleClient::~ModuleClient() 954e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 955e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 956e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 957e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::dump(int fd __unused, 958e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const Vector<String16>& args __unused) { 959b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 960b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 961b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 962b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 963e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::detach() { 964e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("detach()"); 9657504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 9667504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 967e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 968e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 969e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 970e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 971e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 972e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (mClient != 0) { 973e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George IInterface::asBinder(mClient)->unlinkToDeath(this); 974e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George mClient.clear(); 975e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 976e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 977e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 978e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 979e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 980e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 981e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 982e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George module->detach(this); 983e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 984e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 985e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory, 986e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_model_handle_t *handle) 987e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 988e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("loadSoundModel() handle"); 9897504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 9907504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 991e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 992e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 993e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 994e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 995e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 996e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 997e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 998e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->loadSoundModel(modelMemory, this, handle); 999e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1000e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1001e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle) 1002e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1003e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("unloadSoundModel() model handle %d", handle); 10047504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 10057504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 1006e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 1007e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1008e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1009e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1010e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1011e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 1012e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1013e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->unloadSoundModel(handle); 1014e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1015e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1016e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle, 1017e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const sp<IMemory>& dataMemory) 1018e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1019e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("startRecognition() model handle %d", handle); 10207504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 10217504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 1022e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 1023e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1024e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1025e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1026e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1027e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 1028e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1029e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->startRecognition(handle, dataMemory); 1030e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1031e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1032e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgestatus_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle) 1033e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1034e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("stopRecognition() model handle %d", handle); 10357504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(), 10367504b9eb4561df88550f874cf0ce95b6f4d09927Eric Laurent IPCThreadState::self()->getCallingUid())) { 1037e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return PERMISSION_DENIED; 1038e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1039e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1040e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1041e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1042e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return NO_INIT; 1043e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1044e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return module->stopRecognition(handle); 1045e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1046e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1047e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active) 1048e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1049e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("ModuleClient::setCaptureState_l %d", active); 1050e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<SoundTriggerHwService> service; 1051e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sound_trigger_service_state_t state; 1052e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1053e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<Module> module = mModule.promote(); 1054e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (module == 0) { 1055e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1056e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1057e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 1058e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 1059e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George state = (active && !module->isConcurrentCaptureAllowed()) ? 1060e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED; 1061e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1062e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service = module->service().promote(); 1063e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (service == 0) { 1064e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1065e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1066e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1067e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George service->sendServiceStateEvent_l(state, this); 1068e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1069e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1070e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event) 1071e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George{ 1072e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGV("ModuleClient onCallbackEvent type %d", event->mType); 1073e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1074e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<IMemory> eventMemory = event->mMemory; 1075e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1076e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (eventMemory == 0 || eventMemory->pointer() == NULL) { 1077e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George return; 1078e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1079e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1080e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George switch (event->mType) { 1081e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George case CallbackEvent::TYPE_SERVICE_STATE: { 1082e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George sp<ISoundTriggerClient> client; 1083e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George { 1084e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George AutoMutex lock(mLock); 1085e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client = mClient; 1086e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1087e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George if (client !=0 ) { 1088e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George client->onServiceStateChange(eventMemory); 1089e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1090e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } break; 1091e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George default: 1092e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); 1093e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George } 1094e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1095e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1096e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew Georgevoid SoundTriggerHwService::ModuleClient::binderDied( 1097e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George const wp<IBinder> &who __unused) { 1098e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George ALOGW("client binder died for client %p", this); 1099e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George detach(); 1100e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George} 1101e52c500c096fce010c99e92c4fc3ef51832e67c6Haynes Mathew George 1102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android 1103