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 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 (status = (status_t)reply.readInt32()) != NO_ERROR) { 65 return status; 66 } 67 reply.read(handle, sizeof(sound_model_handle_t)); 68 return status; 69 } 70 71 virtual status_t unloadSoundModel(sound_model_handle_t handle) 72 { 73 Parcel data, reply; 74 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 75 data.write(&handle, sizeof(sound_model_handle_t)); 76 status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply); 77 if (status != NO_ERROR) { 78 status = (status_t)reply.readInt32(); 79 } 80 return status; 81 } 82 83 virtual status_t startRecognition(sound_model_handle_t handle, 84 const sp<IMemory>& dataMemory) 85 { 86 Parcel data, reply; 87 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 88 data.write(&handle, sizeof(sound_model_handle_t)); 89 if (dataMemory == 0) { 90 data.writeInt32(0); 91 } else { 92 data.writeInt32(dataMemory->size()); 93 } 94 data.writeStrongBinder(IInterface::asBinder(dataMemory)); 95 status_t status = remote()->transact(START_RECOGNITION, data, &reply); 96 if (status != NO_ERROR) { 97 status = (status_t)reply.readInt32(); 98 } 99 return status; 100 } 101 102 virtual status_t stopRecognition(sound_model_handle_t handle) 103 { 104 Parcel data, reply; 105 data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); 106 data.write(&handle, sizeof(sound_model_handle_t)); 107 status_t status = remote()->transact(STOP_RECOGNITION, data, &reply); 108 if (status != NO_ERROR) { 109 status = (status_t)reply.readInt32(); 110 } 111 return status; 112 } 113 114 }; 115 116 IMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger"); 117 118 // ---------------------------------------------------------------------- 119 120 status_t BnSoundTrigger::onTransact( 121 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 122 { 123 switch(code) { 124 case DETACH: { 125 ALOGV("DETACH"); 126 CHECK_INTERFACE(ISoundTrigger, data, reply); 127 detach(); 128 return NO_ERROR; 129 } break; 130 case LOAD_SOUND_MODEL: { 131 CHECK_INTERFACE(ISoundTrigger, data, reply); 132 sp<IMemory> modelMemory = interface_cast<IMemory>( 133 data.readStrongBinder()); 134 sound_model_handle_t handle; 135 status_t status = loadSoundModel(modelMemory, &handle); 136 reply->writeInt32(status); 137 if (status == NO_ERROR) { 138 reply->write(&handle, sizeof(sound_model_handle_t)); 139 } 140 return NO_ERROR; 141 } 142 case UNLOAD_SOUND_MODEL: { 143 CHECK_INTERFACE(ISoundTrigger, data, reply); 144 sound_model_handle_t handle; 145 data.read(&handle, sizeof(sound_model_handle_t)); 146 status_t status = unloadSoundModel(handle); 147 reply->writeInt32(status); 148 return NO_ERROR; 149 } 150 case START_RECOGNITION: { 151 CHECK_INTERFACE(ISoundTrigger, data, reply); 152 sound_model_handle_t handle; 153 data.read(&handle, sizeof(sound_model_handle_t)); 154 sp<IMemory> dataMemory; 155 if (data.readInt32() != 0) { 156 dataMemory = interface_cast<IMemory>(data.readStrongBinder()); 157 } 158 status_t status = startRecognition(handle, dataMemory); 159 reply->writeInt32(status); 160 return NO_ERROR; 161 } 162 case STOP_RECOGNITION: { 163 CHECK_INTERFACE(ISoundTrigger, data, reply); 164 sound_model_handle_t handle; 165 data.read(&handle, sizeof(sound_model_handle_t)); 166 status_t status = stopRecognition(handle); 167 reply->writeInt32(status); 168 return NO_ERROR; 169 } 170 default: 171 return BBinder::onTransact(code, data, reply, flags); 172 } 173 } 174 175 // ---------------------------------------------------------------------------- 176 177 }; // namespace android 178