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