1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "AAudio"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20
21 #include <aaudio/AAudio.h>
22 #include <binder/IPCThreadState.h>
23
24 #include "binding/AudioEndpointParcelable.h"
25 #include "binding/AAudioStreamRequest.h"
26 #include "binding/AAudioServiceDefinitions.h"
27 #include "binding/AAudioStreamConfiguration.h"
28 #include "binding/IAAudioService.h"
29 #include "utility/AAudioUtilities.h"
30
31 namespace android {
32
33 using aaudio::aaudio_handle_t;
34
35 /**
36 * This is used by the AAudio Client to talk to the AAudio Service.
37 *
38 * The order of parameters in the Parcels must match with code in AAudioService.cpp.
39 */
40 class BpAAudioService : public BpInterface<IAAudioService>
41 {
42 public:
BpAAudioService(const sp<IBinder> & impl)43 explicit BpAAudioService(const sp<IBinder>& impl)
44 : BpInterface<IAAudioService>(impl)
45 {
46 }
47
registerClient(const sp<IAAudioClient> & client)48 void registerClient(const sp<IAAudioClient>& client) override
49 {
50 Parcel data, reply;
51 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
52 data.writeStrongBinder(IInterface::asBinder(client));
53 remote()->transact(REGISTER_CLIENT, data, &reply);
54 }
55
openStream(const aaudio::AAudioStreamRequest & request,aaudio::AAudioStreamConfiguration & configurationOutput)56 aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
57 aaudio::AAudioStreamConfiguration &configurationOutput) override {
58 Parcel data, reply;
59 // send command
60 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
61 // request.dump();
62 request.writeToParcel(&data);
63 status_t err = remote()->transact(OPEN_STREAM, data, &reply);
64 if (err != NO_ERROR) {
65 ALOGE("BpAAudioService::client openStream transact failed %d", err);
66 return AAudioConvert_androidToAAudioResult(err);
67 }
68 // parse reply
69 aaudio_handle_t stream;
70 err = reply.readInt32(&stream);
71 if (err != NO_ERROR) {
72 ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
73 return AAudioConvert_androidToAAudioResult(err);
74 } else if (stream < 0) {
75 return stream;
76 }
77 err = configurationOutput.readFromParcel(&reply);
78 if (err != NO_ERROR) {
79 ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
80 closeStream(stream);
81 return AAudioConvert_androidToAAudioResult(err);
82 }
83 return stream;
84 }
85
closeStream(aaudio_handle_t streamHandle)86 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
87 Parcel data, reply;
88 // send command
89 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
90 data.writeInt32(streamHandle);
91 status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
92 if (err != NO_ERROR) {
93 ALOGE("BpAAudioService::client closeStream transact failed %d", err);
94 return AAudioConvert_androidToAAudioResult(err);
95 }
96 // parse reply
97 aaudio_result_t res;
98 reply.readInt32(&res);
99 return res;
100 }
101
getStreamDescription(aaudio_handle_t streamHandle,aaudio::AudioEndpointParcelable & parcelable)102 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
103 aaudio::AudioEndpointParcelable &parcelable) {
104 Parcel data, reply;
105 // send command
106 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
107 data.writeInt32(streamHandle);
108 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
109 if (err != NO_ERROR) {
110 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
111 return AAudioConvert_androidToAAudioResult(err);
112 }
113 // parse reply
114 aaudio_result_t result;
115 err = reply.readInt32(&result);
116 if (err != NO_ERROR) {
117 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
118 return AAudioConvert_androidToAAudioResult(err);
119 } else if (result != AAUDIO_OK) {
120 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
121 return result;
122 }
123 err = parcelable.readFromParcel(&reply);
124 if (err != NO_ERROR) {
125 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
126 return AAudioConvert_androidToAAudioResult(err);
127 }
128 return result;
129 }
130
131 // TODO should we wait for a reply?
startStream(aaudio_handle_t streamHandle)132 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
133 Parcel data, reply;
134 // send command
135 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
136 data.writeInt32(streamHandle);
137 status_t err = remote()->transact(START_STREAM, data, &reply);
138 if (err != NO_ERROR) {
139 return AAudioConvert_androidToAAudioResult(err);
140 }
141 // parse reply
142 aaudio_result_t res;
143 reply.readInt32(&res);
144 return res;
145 }
146
pauseStream(aaudio_handle_t streamHandle)147 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
148 Parcel data, reply;
149 // send command
150 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
151 data.writeInt32(streamHandle);
152 status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
153 if (err != NO_ERROR) {
154 return AAudioConvert_androidToAAudioResult(err);
155 }
156 // parse reply
157 aaudio_result_t res;
158 reply.readInt32(&res);
159 return res;
160 }
161
stopStream(aaudio_handle_t streamHandle)162 virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
163 Parcel data, reply;
164 // send command
165 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
166 data.writeInt32(streamHandle);
167 status_t err = remote()->transact(STOP_STREAM, data, &reply);
168 if (err != NO_ERROR) {
169 return AAudioConvert_androidToAAudioResult(err);
170 }
171 // parse reply
172 aaudio_result_t res;
173 reply.readInt32(&res);
174 return res;
175 }
176
flushStream(aaudio_handle_t streamHandle)177 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
178 Parcel data, reply;
179 // send command
180 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
181 data.writeInt32(streamHandle);
182 status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
183 if (err != NO_ERROR) {
184 return AAudioConvert_androidToAAudioResult(err);
185 }
186 // parse reply
187 aaudio_result_t res;
188 reply.readInt32(&res);
189 return res;
190 }
191
registerAudioThread(aaudio_handle_t streamHandle,pid_t clientThreadId,int64_t periodNanoseconds)192 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
193 pid_t clientThreadId,
194 int64_t periodNanoseconds)
195 override {
196 Parcel data, reply;
197 // send command
198 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
199 data.writeInt32(streamHandle);
200 data.writeInt32((int32_t) clientThreadId);
201 data.writeInt64(periodNanoseconds);
202 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
203 if (err != NO_ERROR) {
204 return AAudioConvert_androidToAAudioResult(err);
205 }
206 // parse reply
207 aaudio_result_t res;
208 reply.readInt32(&res);
209 return res;
210 }
211
unregisterAudioThread(aaudio_handle_t streamHandle,pid_t clientThreadId)212 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
213 pid_t clientThreadId)
214 override {
215 Parcel data, reply;
216 // send command
217 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
218 data.writeInt32(streamHandle);
219 data.writeInt32((int32_t) clientThreadId);
220 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
221 if (err != NO_ERROR) {
222 return AAudioConvert_androidToAAudioResult(err);
223 }
224 // parse reply
225 aaudio_result_t res;
226 reply.readInt32(&res);
227 return res;
228 }
229
230 };
231
232 // Implement an interface to the service.
233 // This is here so that you don't have to link with libaaudio static library.
234 IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
235
236 // The order of parameters in the Parcels must match with code in BpAAudioService
237
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)238 status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
239 Parcel* reply, uint32_t flags) {
240 aaudio_handle_t streamHandle;
241 aaudio::AAudioStreamRequest request;
242 aaudio::AAudioStreamConfiguration configuration;
243 pid_t tid;
244 int64_t nanoseconds;
245 aaudio_result_t result;
246 status_t status = NO_ERROR;
247 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
248
249 switch(code) {
250 case REGISTER_CLIENT: {
251 CHECK_INTERFACE(IAAudioService, data, reply);
252 sp<IAAudioClient> client = interface_cast<IAAudioClient>(
253 data.readStrongBinder());
254 // readStrongBinder() can return null
255 if (client.get() == nullptr) {
256 ALOGE("BnAAudioService::%s(REGISTER_CLIENT) client is NULL!", __func__);
257 android_errorWriteLog(0x534e4554, "116230453");
258 return DEAD_OBJECT;
259 } else {
260 registerClient(client);
261 return NO_ERROR;
262 }
263 } break;
264
265 case OPEN_STREAM: {
266 CHECK_INTERFACE(IAAudioService, data, reply);
267 request.readFromParcel(&data);
268 result = request.validate();
269 if (result != AAUDIO_OK) {
270 streamHandle = result;
271 } else {
272 //ALOGD("BnAAudioService::client openStream request dump --------------------");
273 //request.dump();
274 // Override the uid and pid from the client in case they are incorrect.
275 request.setUserId(IPCThreadState::self()->getCallingUid());
276 request.setProcessId(IPCThreadState::self()->getCallingPid());
277 streamHandle = openStream(request, configuration);
278 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X",
279 // streamHandle);
280 }
281 reply->writeInt32(streamHandle);
282 configuration.writeToParcel(reply);
283 return NO_ERROR;
284 } break;
285
286 case CLOSE_STREAM: {
287 CHECK_INTERFACE(IAAudioService, data, reply);
288 data.readInt32(&streamHandle);
289 result = closeStream(streamHandle);
290 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
291 // streamHandle, result);
292 reply->writeInt32(result);
293 return NO_ERROR;
294 } break;
295
296 case GET_STREAM_DESCRIPTION: {
297 CHECK_INTERFACE(IAAudioService, data, reply);
298 status = data.readInt32(&streamHandle);
299 if (status != NO_ERROR) {
300 return status;
301 }
302 aaudio::AudioEndpointParcelable parcelable;
303 result = getStreamDescription(streamHandle, parcelable);
304 if (result != AAUDIO_OK) {
305 return AAudioConvert_aaudioToAndroidStatus(result);
306 }
307 status = reply->writeInt32(result);
308 if (status != NO_ERROR) {
309 return status;
310 }
311 return parcelable.writeToParcel(reply);
312 } break;
313
314 case START_STREAM: {
315 CHECK_INTERFACE(IAAudioService, data, reply);
316 data.readInt32(&streamHandle);
317 result = startStream(streamHandle);
318 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
319 streamHandle, result);
320 reply->writeInt32(result);
321 return NO_ERROR;
322 } break;
323
324 case PAUSE_STREAM: {
325 CHECK_INTERFACE(IAAudioService, data, reply);
326 data.readInt32(&streamHandle);
327 result = pauseStream(streamHandle);
328 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
329 streamHandle, result);
330 reply->writeInt32(result);
331 return NO_ERROR;
332 } break;
333
334 case STOP_STREAM: {
335 CHECK_INTERFACE(IAAudioService, data, reply);
336 data.readInt32(&streamHandle);
337 result = stopStream(streamHandle);
338 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
339 streamHandle, result);
340 reply->writeInt32(result);
341 return NO_ERROR;
342 } break;
343
344 case FLUSH_STREAM: {
345 CHECK_INTERFACE(IAAudioService, data, reply);
346 data.readInt32(&streamHandle);
347 result = flushStream(streamHandle);
348 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
349 streamHandle, result);
350 reply->writeInt32(result);
351 return NO_ERROR;
352 } break;
353
354 case REGISTER_AUDIO_THREAD: {
355 CHECK_INTERFACE(IAAudioService, data, reply);
356 data.readInt32(&streamHandle);
357 data.readInt32(&tid);
358 data.readInt64(&nanoseconds);
359 result = registerAudioThread(streamHandle, tid, nanoseconds);
360 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
361 streamHandle, result);
362 reply->writeInt32(result);
363 return NO_ERROR;
364 } break;
365
366 case UNREGISTER_AUDIO_THREAD: {
367 CHECK_INTERFACE(IAAudioService, data, reply);
368 data.readInt32(&streamHandle);
369 data.readInt32(&tid);
370 result = unregisterAudioThread(streamHandle, tid);
371 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
372 streamHandle, result);
373 reply->writeInt32(result);
374 return NO_ERROR;
375 } break;
376
377 default:
378 // ALOGW("BnAAudioService::onTransact not handled %u", code);
379 return BBinder::onTransact(code, data, reply, flags);
380 }
381 }
382
383 } /* namespace android */
384