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 "ISoundTrigger" 19 #include <utils/Log.h> 20 #include <utils/Errors.h> 21 #include <binder/IMemory.h> 22 #include <soundtrigger/ISoundTrigger.h> 23 #include <soundtrigger/ISoundTriggerHwService.h> 24 #include <soundtrigger/ISoundTriggerClient.h> 25 #include <system/sound_trigger.h> 26 27 namespace android { 28 29 enum { 30 DETACH = IBinder::FIRST_CALL_TRANSACTION, 31 LOAD_SOUND_MODEL, 32 UNLOAD_SOUND_MODEL, 33 START_RECOGNITION, 34 STOP_RECOGNITION, 35 }; 36 37 class BpSoundTrigger: public BpInterface<ISoundTrigger> 38 { 39 public: 40 explicit BpSoundTrigger(const sp<IBinder>& impl) 41 : BpInterface<ISoundTrigger>(impl) 42 { 43 } 44 45 void detach() 46 { 47 ALOGV("detach"); 48 Parcel data, reply; 49 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 50 remote()->transact(DETACH, data, &reply); 51 } 52 53 status_t loadSoundModel(const sp<IMemory>& modelMemory, 54 sound_model_handle_t *handle) 55 { 56 if (modelMemory == 0 || handle == NULL) { 57 return BAD_VALUE; 58 } 59 Parcel data, reply; 60 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 61 data.writeStrongBinder(IInterface::asBinder(modelMemory)); 62 status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply); 63 if (status != NO_ERROR) { 64 return status; 65 } 66 status = (status_t)reply.readInt32(); 67 if (status == NO_ERROR) { 68 reply.read(handle, sizeof(sound_model_handle_t)); 69 } 70 return status; 71 } 72 73 virtual status_t unloadSoundModel(sound_model_handle_t handle) 74 { 75 Parcel data, reply; 76 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 77 data.write(&handle, sizeof(sound_model_handle_t)); 78 status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply); 79 if (status == NO_ERROR) { 80 status = (status_t)reply.readInt32(); 81 } 82 return status; 83 } 84 85 virtual status_t startRecognition(sound_model_handle_t handle, 86 const sp<IMemory>& dataMemory) 87 { 88 Parcel data, reply; 89 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 90 data.write(&handle, sizeof(sound_model_handle_t)); 91 if (dataMemory == 0) { 92 data.writeInt32(0); 93 } else { 94 data.writeInt32(dataMemory->size()); 95 } 96 data.writeStrongBinder(IInterface::asBinder(dataMemory)); 97 status_t status = remote()->transact(START_RECOGNITION, data, &reply); 98 if (status == NO_ERROR) { 99 status = (status_t)reply.readInt32(); 100 } 101 return status; 102 } 103 104 virtual status_t stopRecognition(sound_model_handle_t handle) 105 { 106 Parcel data, reply; 107 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 108 data.write(&handle, sizeof(sound_model_handle_t)); 109 status_t status = remote()->transact(STOP_RECOGNITION, data, &reply); 110 if (status == NO_ERROR) { 111 status = (status_t)reply.readInt32(); 112 } 113 return status; 114 } 115 116 }; 117 118 IMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger"); 119 120 // ---------------------------------------------------------------------- 121 122 status_t BnSoundTrigger::onTransact( 123 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 124 { 125 switch(code) { 126 case DETACH: { 127 ALOGV("DETACH"); 128 CHECK_INTERFACE(ISoundTrigger, data, reply); 129 detach(); 130 return NO_ERROR; 131 } break; 132 case LOAD_SOUND_MODEL: { 133 CHECK_INTERFACE(ISoundTrigger, data, reply); 134 sp<IMemory> modelMemory = interface_cast<IMemory>( 135 data.readStrongBinder()); 136 sound_model_handle_t handle; 137 status_t status = loadSoundModel(modelMemory, &handle); 138 reply->writeInt32(status); 139 if (status == NO_ERROR) { 140 reply->write(&handle, sizeof(sound_model_handle_t)); 141 } 142 return NO_ERROR; 143 } 144 case UNLOAD_SOUND_MODEL: { 145 CHECK_INTERFACE(ISoundTrigger, data, reply); 146 sound_model_handle_t handle; 147 data.read(&handle, sizeof(sound_model_handle_t)); 148 status_t status = unloadSoundModel(handle); 149 reply->writeInt32(status); 150 return NO_ERROR; 151 } 152 case START_RECOGNITION: { 153 CHECK_INTERFACE(ISoundTrigger, data, reply); 154 sound_model_handle_t handle; 155 data.read(&handle, sizeof(sound_model_handle_t)); 156 sp<IMemory> dataMemory; 157 if (data.readInt32() != 0) { 158 dataMemory = interface_cast<IMemory>(data.readStrongBinder()); 159 } 160 status_t status = startRecognition(handle, dataMemory); 161 reply->writeInt32(status); 162 return NO_ERROR; 163 } 164 case STOP_RECOGNITION: { 165 CHECK_INTERFACE(ISoundTrigger, data, reply); 166 sound_model_handle_t handle; 167 data.read(&handle, sizeof(sound_model_handle_t)); 168 status_t status = stopRecognition(handle); 169 reply->writeInt32(status); 170 return NO_ERROR; 171 } 172 default: 173 return BBinder::onTransact(code, data, reply, flags); 174 } 175 } 176 177 // ---------------------------------------------------------------------------- 178 179 }; // namespace android 180