IAAudioService.cpp revision 901f65deb49786f4dffd39ac965c0bb681392c0b
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
31namespace android {
32
33using 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 */
40class BpAAudioService : public BpInterface<IAAudioService>
41{
42public:
43    explicit BpAAudioService(const sp<IBinder>& impl)
44        : BpInterface<IAAudioService>(impl)
45    {
46    }
47
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
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
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
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        //parcelable.dump();
130        result = parcelable.validate();
131        if (result != AAUDIO_OK) {
132            ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result);
133            return result;
134        }
135        return result;
136    }
137
138    // TODO should we wait for a reply?
139    virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
140        Parcel data, reply;
141        // send command
142        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
143        data.writeInt32(streamHandle);
144        status_t err = remote()->transact(START_STREAM, data, &reply);
145        if (err != NO_ERROR) {
146            return AAudioConvert_androidToAAudioResult(err);
147        }
148        // parse reply
149        aaudio_result_t res;
150        reply.readInt32(&res);
151        return res;
152    }
153
154    virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
155        Parcel data, reply;
156        // send command
157        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
158        data.writeInt32(streamHandle);
159        status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
160        if (err != NO_ERROR) {
161            return AAudioConvert_androidToAAudioResult(err);
162        }
163        // parse reply
164        aaudio_result_t res;
165        reply.readInt32(&res);
166        return res;
167    }
168
169    virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
170        Parcel data, reply;
171        // send command
172        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
173        data.writeInt32(streamHandle);
174        status_t err = remote()->transact(STOP_STREAM, data, &reply);
175        if (err != NO_ERROR) {
176            return AAudioConvert_androidToAAudioResult(err);
177        }
178        // parse reply
179        aaudio_result_t res;
180        reply.readInt32(&res);
181        return res;
182    }
183
184    virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
185        Parcel data, reply;
186        // send command
187        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
188        data.writeInt32(streamHandle);
189        status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
190        if (err != NO_ERROR) {
191            return AAudioConvert_androidToAAudioResult(err);
192        }
193        // parse reply
194        aaudio_result_t res;
195        reply.readInt32(&res);
196        return res;
197    }
198
199    virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
200                                                pid_t clientThreadId,
201                                                int64_t periodNanoseconds)
202    override {
203        Parcel data, reply;
204        // send command
205        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
206        data.writeInt32(streamHandle);
207        data.writeInt32((int32_t) clientThreadId);
208        data.writeInt64(periodNanoseconds);
209        status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
210        if (err != NO_ERROR) {
211            return AAudioConvert_androidToAAudioResult(err);
212        }
213        // parse reply
214        aaudio_result_t res;
215        reply.readInt32(&res);
216        return res;
217    }
218
219    virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
220                                                  pid_t clientThreadId)
221    override {
222        Parcel data, reply;
223        // send command
224        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
225        data.writeInt32(streamHandle);
226        data.writeInt32((int32_t) clientThreadId);
227        status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
228        if (err != NO_ERROR) {
229            return AAudioConvert_androidToAAudioResult(err);
230        }
231        // parse reply
232        aaudio_result_t res;
233        reply.readInt32(&res);
234        return res;
235    }
236
237};
238
239// Implement an interface to the service.
240// This is here so that you don't have to link with libaaudio static library.
241IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
242
243// The order of parameters in the Parcels must match with code in BpAAudioService
244
245status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
246                                        Parcel* reply, uint32_t flags) {
247    aaudio_handle_t streamHandle;
248    aaudio::AAudioStreamRequest request;
249    aaudio::AAudioStreamConfiguration configuration;
250    pid_t tid;
251    int64_t nanoseconds;
252    aaudio_result_t result;
253    ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
254
255    switch(code) {
256        case REGISTER_CLIENT: {
257            CHECK_INTERFACE(IAAudioService, data, reply);
258            sp<IAAudioClient> client = interface_cast<IAAudioClient>(
259                    data.readStrongBinder());
260            registerClient(client);
261            return NO_ERROR;
262        } break;
263
264        case OPEN_STREAM: {
265            CHECK_INTERFACE(IAAudioService, data, reply);
266            request.readFromParcel(&data);
267            result = request.validate();
268            if (result != AAUDIO_OK) {
269                streamHandle = result;
270            } else {
271                //ALOGD("BnAAudioService::client openStream request dump --------------------");
272                //request.dump();
273                // Override the uid and pid from the client in case they are incorrect.
274                request.setUserId(IPCThreadState::self()->getCallingUid());
275                request.setProcessId(IPCThreadState::self()->getCallingPid());
276                streamHandle = openStream(request, configuration);
277                //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X",
278                //        streamHandle);
279            }
280            reply->writeInt32(streamHandle);
281            configuration.writeToParcel(reply);
282            return NO_ERROR;
283        } break;
284
285        case CLOSE_STREAM: {
286            CHECK_INTERFACE(IAAudioService, data, reply);
287            data.readInt32(&streamHandle);
288            result = closeStream(streamHandle);
289            //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
290            //      streamHandle, result);
291            reply->writeInt32(result);
292            return NO_ERROR;
293        } break;
294
295        case GET_STREAM_DESCRIPTION: {
296            CHECK_INTERFACE(IAAudioService, data, reply);
297            data.readInt32(&streamHandle);
298            aaudio::AudioEndpointParcelable parcelable;
299            result = getStreamDescription(streamHandle, parcelable);
300            if (result != AAUDIO_OK) {
301                return AAudioConvert_aaudioToAndroidStatus(result);
302            }
303            result = parcelable.validate();
304            if (result != AAUDIO_OK) {
305                ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
306                parcelable.dump();
307                return AAudioConvert_aaudioToAndroidStatus(result);
308            }
309            reply->writeInt32(result);
310            parcelable.writeToParcel(reply);
311            return NO_ERROR;
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