1b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent/* 2b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** 3b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Copyright 2014, The Android Open Source Project 4b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** 5b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 6b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** you may not use this file except in compliance with the License. 7b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** You may obtain a copy of the License at 8b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** 9b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** http://www.apache.org/licenses/LICENSE-2.0 10b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** 11b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Unless required by applicable law or agreed to in writing, software 12b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 13b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** See the License for the specific language governing permissions and 15b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** limitations under the License. 16b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent*/ 17b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 18b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "BpSoundTriggerHwService" 19b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent//#define LOG_NDEBUG 0 20b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 21b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Log.h> 22b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Errors.h> 23b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 24b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <stdint.h> 25b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <sys/types.h> 26b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IMemory.h> 27b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/Parcel.h> 28b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IPCThreadState.h> 29b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IServiceManager.h> 30b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 31b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerHwService.h> 32b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTrigger.h> 33b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerClient.h> 34b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 35b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace android { 36b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 37b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentenum { 38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION, 39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ATTACH, 40df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent SET_CAPTURE_STATE, 41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; 42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 43b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent#define MAX_ITEMS_PER_LIST 1024 44b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent 45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentclass BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService> 46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentpublic: 48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent BpSoundTriggerHwService(const sp<IBinder>& impl) 49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent : BpInterface<ISoundTriggerHwService>(impl) 50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent virtual status_t listModules(struct sound_trigger_module_descriptor *modules, 54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t *numModules) 55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModules == NULL || (*numModules != 0 && modules == NULL)) { 57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BAD_VALUE; 58b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Parcel data, reply; 60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor()); 61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules; 62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data.writeInt32(numModulesReq); 63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent status_t status = remote()->transact(LIST_MODULES, data, &reply); 64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (status == NO_ERROR) { 65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent status = (status_t)reply.readInt32(); 66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent *numModules = (unsigned int)reply.readInt32(); 67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("listModules() status %d got *numModules %d", status, *numModules); 69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (status == NO_ERROR) { 70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModulesReq > *numModules) { 71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent numModulesReq = *numModules; 72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModulesReq > 0) { 74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor)); 75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return status; 78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent virtual status_t attach(const sound_trigger_module_handle_t handle, 81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent const sp<ISoundTriggerClient>& client, 82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTrigger>& module) 83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent { 84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent Parcel data, reply; 85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor()); 86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data.write(&handle, sizeof(sound_trigger_module_handle_t)); 8706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen data.writeStrongBinder(IInterface::asBinder(client)); 88014620f143eda403795642dab116fb82bda54200Eric Laurent status_t status = remote()->transact(ATTACH, data, &reply); 89014620f143eda403795642dab116fb82bda54200Eric Laurent if (status != NO_ERROR) { 90014620f143eda403795642dab116fb82bda54200Eric Laurent return status; 91014620f143eda403795642dab116fb82bda54200Eric Laurent } 92014620f143eda403795642dab116fb82bda54200Eric Laurent status = reply.readInt32(); 93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (reply.readInt32() != 0) { 94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent module = interface_cast<ISoundTrigger>(reply.readStrongBinder()); 95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return status; 97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 99df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent virtual status_t setCaptureState(bool active) 100df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent { 101df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent Parcel data, reply; 102df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor()); 103df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent data.writeInt32(active); 104df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent status_t status = remote()->transact(SET_CAPTURE_STATE, data, &reply); 105df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent if (status == NO_ERROR) { 106df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent status = reply.readInt32(); 107df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 108df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return status; 109df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } 110df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; 112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentIMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService"); 114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ---------------------------------------------------------------------- 116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t BnSoundTriggerHwService::onTransact( 118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{ 120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent switch(code) { 121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent case LIST_MODULES: { 122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent CHECK_INTERFACE(ISoundTriggerHwService, data, reply); 123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent unsigned int numModulesReq = data.readInt32(); 124b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent if (numModulesReq > MAX_ITEMS_PER_LIST) { 125b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent numModulesReq = MAX_ITEMS_PER_LIST; 126b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent } 127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent unsigned int numModules = numModulesReq; 128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent struct sound_trigger_module_descriptor *modules = 129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent (struct sound_trigger_module_descriptor *)calloc(numModulesReq, 130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sizeof(struct sound_trigger_module_descriptor)); 131b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent if (modules == NULL) { 132b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent reply->writeInt32(NO_MEMORY); 133b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent reply->writeInt32(0); 134b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent return NO_ERROR; 135b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent } 136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent status_t status = listModules(modules, &numModules); 137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->writeInt32(status); 138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->writeInt32(numModules); 139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent ALOGV("LIST_MODULES status %d got numModules %d", status, numModules); 140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (status == NO_ERROR) { 142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (numModulesReq > numModules) { 143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent numModulesReq = numModules; 144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->write(modules, 146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent numModulesReq * sizeof(struct sound_trigger_module_descriptor)); 147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent free(modules); 149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent case ATTACH: { 153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent CHECK_INTERFACE(ISoundTriggerHwService, data, reply); 154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sound_trigger_module_handle_t handle; 155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent data.read(&handle, sizeof(sound_trigger_module_handle_t)); 156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTriggerClient> client = 157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent interface_cast<ISoundTriggerClient>(data.readStrongBinder()); 158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent sp<ISoundTrigger> module; 159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent status_t status = attach(handle, client, module); 160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->writeInt32(status); 161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent if (module != 0) { 162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->writeInt32(1); 16306b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen reply->writeStrongBinder(IInterface::asBinder(module)); 164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } else { 165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent reply->writeInt32(0); 166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return NO_ERROR; 168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } break; 169df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 170df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent case SET_CAPTURE_STATE: { 171df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent CHECK_INTERFACE(ISoundTriggerHwService, data, reply); 172df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent reply->writeInt32(setCaptureState((bool)data.readInt32())); 173df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent return NO_ERROR; 174df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent } break; 175df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent 176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent default: 177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent return BBinder::onTransact(code, data, reply, flags); 178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent } 179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent} 180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ---------------------------------------------------------------------------- 182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent 183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android 184