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