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             ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
76             return stream;
77         }
78         err = configurationOutput.readFromParcel(&reply);
79         if (err != NO_ERROR) {
80             ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
81             closeStream(stream);
82             return AAudioConvert_androidToAAudioResult(err);
83         }
84         return stream;
85     }
86 
closeStream(aaudio_handle_t streamHandle)87     virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
88         Parcel data, reply;
89         // send command
90         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
91         data.writeInt32(streamHandle);
92         status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
93         if (err != NO_ERROR) {
94             ALOGE("BpAAudioService::client closeStream transact failed %d", err);
95             return AAudioConvert_androidToAAudioResult(err);
96         }
97         // parse reply
98         aaudio_result_t res;
99         reply.readInt32(&res);
100         return res;
101     }
102 
getStreamDescription(aaudio_handle_t streamHandle,aaudio::AudioEndpointParcelable & parcelable)103     virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
104                                                aaudio::AudioEndpointParcelable &parcelable)   {
105         Parcel data, reply;
106         // send command
107         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
108         data.writeInt32(streamHandle);
109         status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
110         if (err != NO_ERROR) {
111             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
112             return AAudioConvert_androidToAAudioResult(err);
113         }
114         // parse reply
115         aaudio_result_t result;
116         err = reply.readInt32(&result);
117         if (err != NO_ERROR) {
118             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
119             return AAudioConvert_androidToAAudioResult(err);
120         } else if (result != AAUDIO_OK) {
121             ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
122             return result;
123         }
124         err = parcelable.readFromParcel(&reply);
125         if (err != NO_ERROR) {
126             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
127             return AAudioConvert_androidToAAudioResult(err);
128         }
129         return result;
130     }
131 
132     // TODO should we wait for a reply?
startStream(aaudio_handle_t streamHandle)133     virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
134         Parcel data, reply;
135         // send command
136         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
137         data.writeInt32(streamHandle);
138         status_t err = remote()->transact(START_STREAM, data, &reply);
139         if (err != NO_ERROR) {
140             return AAudioConvert_androidToAAudioResult(err);
141         }
142         // parse reply
143         aaudio_result_t res;
144         reply.readInt32(&res);
145         return res;
146     }
147 
pauseStream(aaudio_handle_t streamHandle)148     virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
149         Parcel data, reply;
150         // send command
151         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
152         data.writeInt32(streamHandle);
153         status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
154         if (err != NO_ERROR) {
155             return AAudioConvert_androidToAAudioResult(err);
156         }
157         // parse reply
158         aaudio_result_t res;
159         reply.readInt32(&res);
160         return res;
161     }
162 
stopStream(aaudio_handle_t streamHandle)163     virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
164         Parcel data, reply;
165         // send command
166         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
167         data.writeInt32(streamHandle);
168         status_t err = remote()->transact(STOP_STREAM, data, &reply);
169         if (err != NO_ERROR) {
170             return AAudioConvert_androidToAAudioResult(err);
171         }
172         // parse reply
173         aaudio_result_t res;
174         reply.readInt32(&res);
175         return res;
176     }
177 
flushStream(aaudio_handle_t streamHandle)178     virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
179         Parcel data, reply;
180         // send command
181         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
182         data.writeInt32(streamHandle);
183         status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
184         if (err != NO_ERROR) {
185             return AAudioConvert_androidToAAudioResult(err);
186         }
187         // parse reply
188         aaudio_result_t res;
189         reply.readInt32(&res);
190         return res;
191     }
192 
registerAudioThread(aaudio_handle_t streamHandle,pid_t clientThreadId,int64_t periodNanoseconds)193     virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
194                                                 pid_t clientThreadId,
195                                                 int64_t periodNanoseconds)
196     override {
197         Parcel data, reply;
198         // send command
199         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
200         data.writeInt32(streamHandle);
201         data.writeInt32((int32_t) clientThreadId);
202         data.writeInt64(periodNanoseconds);
203         status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
204         if (err != NO_ERROR) {
205             return AAudioConvert_androidToAAudioResult(err);
206         }
207         // parse reply
208         aaudio_result_t res;
209         reply.readInt32(&res);
210         return res;
211     }
212 
unregisterAudioThread(aaudio_handle_t streamHandle,pid_t clientThreadId)213     virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
214                                                   pid_t clientThreadId)
215     override {
216         Parcel data, reply;
217         // send command
218         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
219         data.writeInt32(streamHandle);
220         data.writeInt32((int32_t) clientThreadId);
221         status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
222         if (err != NO_ERROR) {
223             return AAudioConvert_androidToAAudioResult(err);
224         }
225         // parse reply
226         aaudio_result_t res;
227         reply.readInt32(&res);
228         return res;
229     }
230 
231 };
232 
233 // Implement an interface to the service.
234 // This is here so that you don't have to link with libaaudio static library.
235 IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
236 
237 // The order of parameters in the Parcels must match with code in BpAAudioService
238 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)239 status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
240                                         Parcel* reply, uint32_t flags) {
241     aaudio_handle_t streamHandle;
242     aaudio::AAudioStreamRequest request;
243     aaudio::AAudioStreamConfiguration configuration;
244     pid_t tid;
245     int64_t nanoseconds;
246     aaudio_result_t result;
247     status_t status = NO_ERROR;
248     ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
249 
250     switch(code) {
251         case REGISTER_CLIENT: {
252             CHECK_INTERFACE(IAAudioService, data, reply);
253             sp<IAAudioClient> client = interface_cast<IAAudioClient>(
254                     data.readStrongBinder());
255             registerClient(client);
256             return NO_ERROR;
257         } break;
258 
259         case OPEN_STREAM: {
260             CHECK_INTERFACE(IAAudioService, data, reply);
261             request.readFromParcel(&data);
262             result = request.validate();
263             if (result != AAUDIO_OK) {
264                 streamHandle = result;
265             } else {
266                 //ALOGD("BnAAudioService::client openStream request dump --------------------");
267                 //request.dump();
268                 // Override the uid and pid from the client in case they are incorrect.
269                 request.setUserId(IPCThreadState::self()->getCallingUid());
270                 request.setProcessId(IPCThreadState::self()->getCallingPid());
271                 streamHandle = openStream(request, configuration);
272                 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X",
273                 //        streamHandle);
274             }
275             reply->writeInt32(streamHandle);
276             configuration.writeToParcel(reply);
277             return NO_ERROR;
278         } break;
279 
280         case CLOSE_STREAM: {
281             CHECK_INTERFACE(IAAudioService, data, reply);
282             data.readInt32(&streamHandle);
283             result = closeStream(streamHandle);
284             //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
285             //      streamHandle, result);
286             reply->writeInt32(result);
287             return NO_ERROR;
288         } break;
289 
290         case GET_STREAM_DESCRIPTION: {
291             CHECK_INTERFACE(IAAudioService, data, reply);
292             status = data.readInt32(&streamHandle);
293             if (status != NO_ERROR) {
294                 return status;
295             }
296             aaudio::AudioEndpointParcelable parcelable;
297             result = getStreamDescription(streamHandle, parcelable);
298             if (result != AAUDIO_OK) {
299                 return AAudioConvert_aaudioToAndroidStatus(result);
300             }
301             status = reply->writeInt32(result);
302             if (status != NO_ERROR) {
303                 return status;
304             }
305             return parcelable.writeToParcel(reply);
306         } break;
307 
308         case START_STREAM: {
309             CHECK_INTERFACE(IAAudioService, data, reply);
310             data.readInt32(&streamHandle);
311             result = startStream(streamHandle);
312             ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
313                     streamHandle, result);
314             reply->writeInt32(result);
315             return NO_ERROR;
316         } break;
317 
318         case PAUSE_STREAM: {
319             CHECK_INTERFACE(IAAudioService, data, reply);
320             data.readInt32(&streamHandle);
321             result = pauseStream(streamHandle);
322             ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
323                   streamHandle, result);
324             reply->writeInt32(result);
325             return NO_ERROR;
326         } break;
327 
328         case STOP_STREAM: {
329             CHECK_INTERFACE(IAAudioService, data, reply);
330             data.readInt32(&streamHandle);
331             result = stopStream(streamHandle);
332             ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
333                   streamHandle, result);
334             reply->writeInt32(result);
335             return NO_ERROR;
336         } break;
337 
338         case FLUSH_STREAM: {
339             CHECK_INTERFACE(IAAudioService, data, reply);
340             data.readInt32(&streamHandle);
341             result = flushStream(streamHandle);
342             ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
343                     streamHandle, result);
344             reply->writeInt32(result);
345             return NO_ERROR;
346         } break;
347 
348         case REGISTER_AUDIO_THREAD: {
349             CHECK_INTERFACE(IAAudioService, data, reply);
350             data.readInt32(&streamHandle);
351             data.readInt32(&tid);
352             data.readInt64(&nanoseconds);
353             result = registerAudioThread(streamHandle, tid, nanoseconds);
354             ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
355                     streamHandle, result);
356             reply->writeInt32(result);
357             return NO_ERROR;
358         } break;
359 
360         case UNREGISTER_AUDIO_THREAD: {
361             CHECK_INTERFACE(IAAudioService, data, reply);
362             data.readInt32(&streamHandle);
363             data.readInt32(&tid);
364             result = unregisterAudioThread(streamHandle, tid);
365             ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
366                     streamHandle, result);
367             reply->writeInt32(result);
368             return NO_ERROR;
369         } break;
370 
371         default:
372             // ALOGW("BnAAudioService::onTransact not handled %u", code);
373             return BBinder::onTransact(code, data, reply, flags);
374     }
375 }
376 
377 } /* namespace android */
378