SoundTriggerHwService.cpp revision b7a11d83f749ad0200778c4815e907d011d4b5d3
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 25b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IServiceManager.h> 26b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/MemoryBase.h> 27b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/MemoryHeapBase.h> 28b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <cutils/atomic.h> 29b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <cutils/properties.h> 30b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <hardware/hardware.h> 31b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Errors.h> 32b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Log.h> 33b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 34b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include "SoundTriggerHwService.h" 35b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <system/sound_trigger.h> 36b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <hardware/sound_trigger.h> 37b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace android { 39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 40b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#ifdef SOUND_TRIGGER_USE_STUB_MODULE 41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define HW_MODULE_PREFIX "stub" 42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#else 43b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define HW_MODULE_PREFIX "primary" 44b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#endif 45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::SoundTriggerHwService() 47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : BnSoundTriggerHwService(), 48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mNextUniqueId(1) 49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::onFirstRef() 53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const hw_module_t *mod; 55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent int rc; 56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_hw_device *dev; 57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 58b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod); 59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (rc != 0) { 60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("couldn't load sound trigger module %s.%s (%s)", 61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc)); 62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent rc = sound_trigger_hw_device_open(mod, &dev); 65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (rc != 0) { 66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("couldn't open sound trigger hw device in %s.%s (%s)", 67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc)); 68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (dev->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) { 71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("wrong sound trigger hw device version %04x", dev->common.version); 72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_module_descriptor descriptor; 76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent rc = dev->get_properties(dev, &descriptor.properties); 77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (rc != 0) { 78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("could not read implementation properties"); 79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent descriptor.handle = 82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId); 83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGI("loaded default module %s, handle %d", descriptor.properties.description, 84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent descriptor.handle); 85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTriggerClient> client; 87b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module = new Module(this, dev, descriptor, client); 88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModules.add(descriptor.handle, module); 89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackThread = new CallbackThread(this); 90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 92b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::~SoundTriggerHwService() 93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mCallbackThread != 0) { 95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackThread->exit(); 96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (size_t i = 0; i < mModules.size(); i++) { 98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_hw_device_close(mModules.valueAt(i)->hwDevice()); 99b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules, 103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t *numModules) 104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("listModules"); 106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModules == NULL || (*numModules != 0 && modules == NULL)) { 108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent size_t maxModules = *numModules; 111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent *numModules = mModules.size(); 112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (size_t i = 0; i < mModules.size() && i < maxModules; i++) { 113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent modules[i] = mModules.valueAt(i)->descriptor(); 114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle, 119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<ISoundTriggerClient>& client, 120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTrigger>& moduleInterface) 121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("attach module %d", handle); 123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent moduleInterface.clear(); 125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (client == 0) { 126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModules.indexOfKey(handle); 129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index < 0) { 130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 131b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module = mModules.valueAt(index); 133b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module->setClient(client); 135b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent client->asBinder()->linkToDeath(module); 136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent moduleInterface = module; 137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::detachModule(sp<Module> module) { 142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("detachModule"); 144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module->clearClient(); 145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockRetries = 50; 148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic const int kDumpLockSleep = 60000; 149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatic bool tryLock(Mutex& mutex) 151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = false; 153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (int i = 0; i < kDumpLockRetries; ++i) { 154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mutex.tryLock() == NO_ERROR) { 155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent locked = true; 156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent usleep(kDumpLockSleep); 159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return locked; 161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) { 164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.appendFormat("Permission Denial: can't dump SoundTriggerHwService"); 167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } else { 169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent bool locked = tryLock(mServiceLock); 170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent // failed to lock - SoundTriggerHwService is probably deadlocked 171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (!locked) { 172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent result.append("SoundTriggerHwService may be deadlocked\n"); 173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent write(fd, result.string(), result.size()); 174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (locked) mServiceLock.unlock(); 177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::onTransact( 182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BnSoundTriggerHwService::onTransact(code, data, reply, flags); 184b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 185b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 186b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 187b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// static 188b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event, 189b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent void *cookie) 190b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 191b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Module *module = (Module *)cookie; 192b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == NULL) { 193b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 194b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 195b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module->sendRecognitionEvent(event); 196b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 197b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 198b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 199b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::sendRecognitionEvent(const sp<RecognitionEvent>& event) 200b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 201b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackThread->sendRecognitionEvent(event); 202b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 203b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 204b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::onRecognitionEvent(const sp<RecognitionEvent>& event) 205b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 206b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("onRecognitionEvent"); 207b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Module> module; 208b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 209b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mServiceLock); 210b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module = event->mModule.promote(); 211b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module == 0) { 212b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 213b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 214b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 215b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module->onRecognitionEvent(event->mEventMemory); 216b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 217b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 218b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// static 219b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event __unused, 220b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent void *cookie) 221b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 222b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Module *module = (Module *)cookie; 223b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 224b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 225b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 226b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 227b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::CallbackThread" 228b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 229b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service) 230b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : mService(service) 231b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 232b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 233b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 234b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::CallbackThread::~CallbackThread() 235b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 236b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.clear(); 237b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 238b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 239b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::onFirstRef() 240b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 241b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO); 242b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 243b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 244b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentbool SoundTriggerHwService::CallbackThread::threadLoop() 245b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 246b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (!exitPending()) { 247b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<RecognitionEvent> event; 248b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<SoundTriggerHwService> service; 249b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 250b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 251b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent while (mEventQueue.isEmpty() && !exitPending()) { 252b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() sleep"); 253b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.wait(mCallbackLock); 254b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("CallbackThread::threadLoop() wake up"); 255b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 256b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (exitPending()) { 257b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 258b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 259b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event = mEventQueue[0]; 260b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.removeAt(0); 261b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service = mService.promote(); 262b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 263b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (service != 0) { 264b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service->onRecognitionEvent(event); 265b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 266b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 267b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return false; 268b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 269b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 270b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::exit() 271b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 272b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Mutex::Autolock _l(mCallbackLock); 273b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent requestExit(); 274b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.broadcast(); 275b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 276b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 277b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::CallbackThread::sendRecognitionEvent( 278b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<SoundTriggerHwService::RecognitionEvent>& event) 279b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 280b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mCallbackLock); 281b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mEventQueue.add(event); 282b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCallbackCond.signal(); 283b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 284b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 285b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::RecognitionEvent::RecognitionEvent( 286b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<IMemory> eventMemory, 287b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent wp<Module> module) 288b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : mEventMemory(eventMemory), mModule(module) 289b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 290b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 291b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 292b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::RecognitionEvent::~RecognitionEvent() 293b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 294b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 295b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 296b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#undef LOG_TAG 297b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTriggerHwService::Module" 298b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 299b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service, 300b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_hw_device* hwDevice, 301b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_module_descriptor descriptor, 302b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<ISoundTriggerClient>& client) 303b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : mService(service), mHwDevice(hwDevice), mDescriptor(descriptor), 304b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mClient(client) 305b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 306b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 307b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 308b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Module::~Module() { 309b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 310b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 311b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::Module::detach() { 312b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("detach()"); 313b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 314b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 315b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent for (size_t i = 0; i < mModels.size(); i++) { 316b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = mModels.valueAt(i); 317b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("detach() unloading model %d", model->mHandle); 318b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 319b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mHwDevice->stop_recognition(mHwDevice, model->mHandle); 320b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->deallocateMemory(); 321b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 322b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mHwDevice->unload_sound_model(mHwDevice, model->mHandle); 323b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 324b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModels.clear(); 325b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 326b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mClient != 0) { 327b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mClient->asBinder()->unlinkToDeath(this); 328b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 329b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<SoundTriggerHwService> service = mService.promote(); 330b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (service == 0) { 331b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 332b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 333b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service->detachModule(this); 334b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 335b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 336b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory, 337b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_model_handle_t *handle) 338b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 339b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("loadSoundModel() handle"); 340b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 341b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (modelMemory == 0 || modelMemory->pointer() == NULL) { 342b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()"); 343b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 344b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 345b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_sound_model *sound_model = 346b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (struct sound_trigger_sound_model *)modelMemory->pointer(); 347b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 348b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 349b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent status_t status = mHwDevice->load_sound_model(mHwDevice, 350b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_model, 351b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SoundTriggerHwService::soundModelCallback, 352b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent this, 353b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent handle); 354b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (status == NO_ERROR) { 355b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModels.replaceValueFor(*handle, new Model(*handle)); 356b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 357b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 358b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return status; 359b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 360b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 361b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle) 362b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 363b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("unloadSoundModel() model handle %d", handle); 364b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 365b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 366b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModels.indexOfKey(handle); 367b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index < 0) { 368b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 369b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 370b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mModels.removeItem(handle); 371b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 372b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return mHwDevice->unload_sound_model(mHwDevice, handle); 373b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 374b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 375b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle, 376b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<IMemory>& dataMemory) 377b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 378b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("startRecognition() model handle %d", handle); 379b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 380b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (dataMemory != 0 && dataMemory->pointer() == NULL) { 381b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()"); 382b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 383b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 384b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 385b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 386b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 387b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 388b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 389b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 390b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 391b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState == Model::STATE_ACTIVE) { 392b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 393b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 394b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->mState = Model::STATE_ACTIVE; 395b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 396b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent char *data = NULL; 397b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent unsigned int data_size = 0; 398b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (dataMemory != 0 && dataMemory->size() != 0) { 399b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data_size = (unsigned int)dataMemory->size(); 400b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data = (char *)dataMemory->pointer(); 401b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("startRecognition() data size %d data %d - %d", 402b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data_size, data[0], data[data_size - 1]); 403b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 404b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 405b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent //TODO: get capture handle and device from audio policy service 406b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent audio_io_handle_t capture_handle = 0; 407b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return mHwDevice->start_recognition(mHwDevice, handle, capture_handle, AUDIO_DEVICE_NONE, 408b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent SoundTriggerHwService::recognitionCallback, 409b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent this, 410b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data_size, 411b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data); 412b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 413b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 414b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle) 415b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 416b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("stopRecognition() model handle %d", handle); 417b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 418b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 419b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(handle); 420b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 421b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 422b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 423b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 424b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState != Model::STATE_ACTIVE) { 425b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return INVALID_OPERATION; 426b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 427b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mHwDevice->stop_recognition(mHwDevice, handle); 428b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->deallocateMemory(); 429b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->mState = Model::STATE_IDLE; 430b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 431b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 432b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 433b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::Module::sendRecognitionEvent( 434b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_recognition_event *event) 435b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 436b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<SoundTriggerHwService> service; 437b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<IMemory> eventMemory; 438b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("sendRecognitionEvent for model %d", event->model); 439b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 440b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 441b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(event->model); 442b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 443b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 444b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 445b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState != Model::STATE_ACTIVE) { 446b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("sendRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 447b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 448b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 449b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mClient == 0) { 450b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 451b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 452b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service = mService.promote(); 453b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (service == 0) { 454b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 455b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 456b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 457b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent //sanitize event 458b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent switch (event->type) { 459b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent case SOUND_MODEL_TYPE_KEYPHRASE: 460b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGW_IF(event->data_offset != 461b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sizeof(struct sound_trigger_phrase_recognition_event), 462b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent "sendRecognitionEvent(): invalid data offset %u for keyphrase event type", 463b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event->data_offset); 464b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event); 465b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 466b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent case SOUND_MODEL_TYPE_UNKNOWN: 467b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGW_IF(event->data_offset != 468b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sizeof(struct sound_trigger_recognition_event), 469b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent "sendRecognitionEvent(): invalid data offset %u for unknown event type", 470b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event->data_offset); 471b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent event->data_offset = sizeof(struct sound_trigger_recognition_event); 472b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent break; 473b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent default: 474b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 475b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 476b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 477b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent size_t size = event->data_offset + event->data_size; 478b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent eventMemory = model->allocateMemory(size); 479b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 480b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 481b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 482b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent memcpy(eventMemory->pointer(), event, size); 483b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 484b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent service->sendRecognitionEvent(new RecognitionEvent(eventMemory, this)); 485b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 486b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 487b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::Module::onRecognitionEvent(sp<IMemory> eventMemory) 488b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 489b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("Module::onRecognitionEvent"); 490b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 491b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent AutoMutex lock(mLock); 492b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 493b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 494b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 495b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 496b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_recognition_event *event = 497b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (struct sound_trigger_recognition_event *)eventMemory->pointer(); 498b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 499b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model = getModel(event->model); 500b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model == 0) { 501b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGI("%s model == 0", __func__); 502b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 503b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 504b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (model->mState != Model::STATE_ACTIVE) { 505b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("onRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState); 506b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 507b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 508b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mClient == 0) { 509b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGI("%s mClient == 0", __func__); 510b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return; 511b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 512b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mClient->onRecognitionEvent(eventMemory); 513b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->mState = Model::STATE_IDLE; 514b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model->deallocateMemory(); 515b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 516b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 517b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentsp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel( 518b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_model_handle_t handle) 519b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 520b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<Model> model; 521b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ssize_t index = mModels.indexOfKey(handle); 522b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (index >= 0) { 523b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent model = mModels.valueAt(index); 524b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 525b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return model; 526b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 527b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 528b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::Module::binderDied( 529b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const wp<IBinder> &who __unused) { 530b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGW("client binder died for module %d", mDescriptor.handle); 531b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent detach(); 532b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 533b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 534b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 535b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTriggerHwService::Model::Model(sound_model_handle_t handle) : 536b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mHandle(handle), mState(STATE_IDLE), mInputHandle(AUDIO_IO_HANDLE_NONE), 537b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mCaptureSession(AUDIO_SESSION_ALLOCATE), 538b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mMemoryDealer(new MemoryDealer(sizeof(struct sound_trigger_recognition_event), 539b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent "SoundTriggerHwService::Event")) 540b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 541b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 542b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 543b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 544b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 545b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentsp<IMemory> SoundTriggerHwService::Model::allocateMemory(size_t size) 546b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 547b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<IMemory> memory; 548b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (mMemoryDealer->getMemoryHeap()->getSize() < size) { 549b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mMemoryDealer = new MemoryDealer(size, "SoundTriggerHwService::Event"); 550b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 551b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent memory = mMemoryDealer->allocate(size); 552b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return memory; 553b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 554b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 555b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTriggerHwService::Model::deallocateMemory() 556b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 557b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent mMemoryDealer->deallocate(0); 558b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 559b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 560b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTriggerHwService::Module::dump(int fd __unused, 561b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const Vector<String16>& args __unused) { 562b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent String8 result; 563b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 564b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 565b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 566b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android 567