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