blob: 97fbaaa004ea4f37678fc93654fa107f1c4c9674 [file] [log] [blame]
Phil Burk5ed503c2017-02-01 09:38:15 -08001/*
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
Phil Burk11e8d332017-05-24 09:59:02 -070017#define LOG_TAG "AAudio"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
Phil Burka4eb0d82017-04-12 15:44:06 -070021#include <aaudio/AAudio.h>
Phil Burk2ac035f2017-06-23 14:51:14 -070022#include <binder/IPCThreadState.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080023
24#include "binding/AudioEndpointParcelable.h"
25#include "binding/AAudioStreamRequest.h"
Phil Burk3316d5e2017-02-15 11:23:01 -080026#include "binding/AAudioServiceDefinitions.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080027#include "binding/AAudioStreamConfiguration.h"
28#include "binding/IAAudioService.h"
29#include "utility/AAudioUtilities.h"
30
31namespace android {
32
Phil Burk3316d5e2017-02-15 11:23:01 -080033using aaudio::aaudio_handle_t;
34
Phil Burk5ed503c2017-02-01 09:38:15 -080035/**
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
Phil Burk11e8d332017-05-24 09:59:02 -070048 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 {
Phil Burk5ed503c2017-02-01 09:38:15 -080058 Parcel data, reply;
59 // send command
60 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
Phil Burk71f35bb2017-04-13 16:05:07 -070061 // request.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -080062 request.writeToParcel(&data);
63 status_t err = remote()->transact(OPEN_STREAM, data, &reply);
64 if (err != NO_ERROR) {
Phil Burk71f35bb2017-04-13 16:05:07 -070065 ALOGE("BpAAudioService::client openStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080066 return AAudioConvert_androidToAAudioResult(err);
67 }
68 // parse reply
69 aaudio_handle_t stream;
Phil Burk71f35bb2017-04-13 16:05:07 -070070 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 }
Phil Burkc0c70e32017-02-09 13:18:38 -080078 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 }
Phil Burk5ed503c2017-02-01 09:38:15 -080084 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) {
Phil Burk71f35bb2017-04-13 16:05:07 -070094 ALOGE("BpAAudioService::client closeStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080095 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) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800111 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -0800112 return AAudioConvert_androidToAAudioResult(err);
113 }
114 // parse reply
Phil Burkc0c70e32017-02-09 13:18:38 -0800115 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);
Phil Burk5ed503c2017-02-01 09:38:15 -0800122 return result;
123 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800124 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 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800135 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
Phil Burk71f35bb2017-04-13 16:05:07 -0700169 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
Phil Burk5ed503c2017-02-01 09:38:15 -0800184 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
Phil Burkc0c70e32017-02-09 13:18:38 -0800199 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
Phil Burk2ac035f2017-06-23 14:51:14 -0700200 pid_t clientThreadId,
201 int64_t periodNanoseconds)
Phil Burk5ed503c2017-02-01 09:38:15 -0800202 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
Phil Burkc0c70e32017-02-09 13:18:38 -0800219 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800220 pid_t clientThreadId)
Phil Burk5ed503c2017-02-01 09:38:15 -0800221 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.
Phil Burkc0c70e32017-02-09 13:18:38 -0800240// This is here so that you don't have to link with libaaudio static library.
Phil Burk5ed503c2017-02-01 09:38:15 -0800241IMPLEMENT_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) {
Phil Burk11e8d332017-05-24 09:59:02 -0700247 aaudio_handle_t streamHandle;
Phil Burk5ed503c2017-02-01 09:38:15 -0800248 aaudio::AAudioStreamRequest request;
249 aaudio::AAudioStreamConfiguration configuration;
Phil Burkc0c70e32017-02-09 13:18:38 -0800250 pid_t tid;
Phil Burk3316d5e2017-02-15 11:23:01 -0800251 int64_t nanoseconds;
Phil Burk5ed503c2017-02-01 09:38:15 -0800252 aaudio_result_t result;
253 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
Phil Burk5ed503c2017-02-01 09:38:15 -0800254
255 switch(code) {
Phil Burk11e8d332017-05-24 09:59:02 -0700256 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
Phil Burk5ed503c2017-02-01 09:38:15 -0800264 case OPEN_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700265 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800266 request.readFromParcel(&data);
Phil Burk71f35bb2017-04-13 16:05:07 -0700267 //ALOGD("BnAAudioService::client openStream request dump --------------------");
268 //request.dump();
Phil Burk2ac035f2017-06-23 14:51:14 -0700269 // Override the uid and pid from the client in case they are incorrect.
270 request.setUserId(IPCThreadState::self()->getCallingUid());
271 request.setProcessId(IPCThreadState::self()->getCallingPid());
Phil Burk11e8d332017-05-24 09:59:02 -0700272 streamHandle = openStream(request, configuration);
273 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", streamHandle);
274 reply->writeInt32(streamHandle);
Phil Burk5ed503c2017-02-01 09:38:15 -0800275 configuration.writeToParcel(reply);
276 return NO_ERROR;
277 } break;
278
279 case CLOSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700280 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700281 data.readInt32(&streamHandle);
282 result = closeStream(streamHandle);
Phil Burk71f35bb2017-04-13 16:05:07 -0700283 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700284 // streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800285 reply->writeInt32(result);
286 return NO_ERROR;
287 } break;
288
289 case GET_STREAM_DESCRIPTION: {
Andy Hunga8805182017-06-27 16:17:40 -0700290 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700291 data.readInt32(&streamHandle);
Phil Burk5ed503c2017-02-01 09:38:15 -0800292 aaudio::AudioEndpointParcelable parcelable;
Phil Burk11e8d332017-05-24 09:59:02 -0700293 result = getStreamDescription(streamHandle, parcelable);
Phil Burk5ed503c2017-02-01 09:38:15 -0800294 if (result != AAUDIO_OK) {
295 return AAudioConvert_aaudioToAndroidStatus(result);
296 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800297 result = parcelable.validate();
298 if (result != AAUDIO_OK) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800299 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
300 parcelable.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -0800301 return AAudioConvert_aaudioToAndroidStatus(result);
302 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800303 reply->writeInt32(result);
Phil Burkc0c70e32017-02-09 13:18:38 -0800304 parcelable.writeToParcel(reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800305 return NO_ERROR;
306 } break;
307
308 case START_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700309 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700310 data.readInt32(&streamHandle);
311 result = startStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800312 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700313 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800314 reply->writeInt32(result);
315 return NO_ERROR;
316 } break;
317
318 case PAUSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700319 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700320 data.readInt32(&streamHandle);
321 result = pauseStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800322 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700323 streamHandle, result);
Phil Burk71f35bb2017-04-13 16:05:07 -0700324 reply->writeInt32(result);
325 return NO_ERROR;
326 } break;
327
328 case STOP_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700329 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700330 data.readInt32(&streamHandle);
331 result = stopStream(streamHandle);
Phil Burk71f35bb2017-04-13 16:05:07 -0700332 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700333 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800334 reply->writeInt32(result);
335 return NO_ERROR;
336 } break;
337
338 case FLUSH_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700339 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700340 data.readInt32(&streamHandle);
341 result = flushStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800342 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700343 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800344 reply->writeInt32(result);
345 return NO_ERROR;
346 } break;
347
348 case REGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700349 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700350 data.readInt32(&streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800351 data.readInt32(&tid);
Phil Burk5ed503c2017-02-01 09:38:15 -0800352 data.readInt64(&nanoseconds);
Phil Burk11e8d332017-05-24 09:59:02 -0700353 result = registerAudioThread(streamHandle, tid, nanoseconds);
Phil Burkc0c70e32017-02-09 13:18:38 -0800354 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700355 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800356 reply->writeInt32(result);
357 return NO_ERROR;
358 } break;
359
360 case UNREGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700361 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk11e8d332017-05-24 09:59:02 -0700362 data.readInt32(&streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800363 data.readInt32(&tid);
Phil Burk11e8d332017-05-24 09:59:02 -0700364 result = unregisterAudioThread(streamHandle, tid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800365 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700366 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800367 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 */