blob: e017b3a122d5f391eb90618d3fc7eabad4bdacf2 [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) {
Phil Burk71f35bb2017-04-13 16:05:07 -070075 return stream;
76 }
Phil Burkc0c70e32017-02-09 13:18:38 -080077 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 }
Phil Burk5ed503c2017-02-01 09:38:15 -080083 return stream;
84 }
85
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) {
Phil Burk71f35bb2017-04-13 16:05:07 -070093 ALOGE("BpAAudioService::client closeStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080094 return AAudioConvert_androidToAAudioResult(err);
95 }
96 // parse reply
97 aaudio_result_t res;
98 reply.readInt32(&res);
99 return res;
100 }
101
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) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800110 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -0800111 return AAudioConvert_androidToAAudioResult(err);
112 }
113 // parse reply
Phil Burkc0c70e32017-02-09 13:18:38 -0800114 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);
Phil Burk5ed503c2017-02-01 09:38:15 -0800121 return result;
122 }
Phil Burka5891f42018-03-12 17:21:11 -0700123 err = parcelable.readFromParcel(&reply);
Phil Burkc0c70e32017-02-09 13:18:38 -0800124 if (err != NO_ERROR) {
125 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
126 return AAudioConvert_androidToAAudioResult(err);
127 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800128 return result;
129 }
130
131 // TODO should we wait for a reply?
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
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
Phil Burk71f35bb2017-04-13 16:05:07 -0700162 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
Phil Burk5ed503c2017-02-01 09:38:15 -0800177 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
Phil Burkc0c70e32017-02-09 13:18:38 -0800192 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
Phil Burk2ac035f2017-06-23 14:51:14 -0700193 pid_t clientThreadId,
194 int64_t periodNanoseconds)
Phil Burk5ed503c2017-02-01 09:38:15 -0800195 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
Phil Burkc0c70e32017-02-09 13:18:38 -0800212 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800213 pid_t clientThreadId)
Phil Burk5ed503c2017-02-01 09:38:15 -0800214 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.
Phil Burkc0c70e32017-02-09 13:18:38 -0800233// This is here so that you don't have to link with libaaudio static library.
Phil Burk5ed503c2017-02-01 09:38:15 -0800234IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
235
236// The order of parameters in the Parcels must match with code in BpAAudioService
237
238status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
239 Parcel* reply, uint32_t flags) {
Phil Burk25532c72020-01-29 14:23:04 -0800240 aaudio_handle_t streamHandle = 0;
Phil Burk5ed503c2017-02-01 09:38:15 -0800241 aaudio::AAudioStreamRequest request;
242 aaudio::AAudioStreamConfiguration configuration;
Phil Burk25532c72020-01-29 14:23:04 -0800243 pid_t tid = 0;
244 int64_t nanoseconds = 0;
245 aaudio_result_t result = AAUDIO_OK;
Phil Burka5891f42018-03-12 17:21:11 -0700246 status_t status = NO_ERROR;
Phil Burk5ed503c2017-02-01 09:38:15 -0800247 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
Phil Burk5ed503c2017-02-01 09:38:15 -0800248
249 switch(code) {
Phil Burk11e8d332017-05-24 09:59:02 -0700250 case REGISTER_CLIENT: {
251 CHECK_INTERFACE(IAAudioService, data, reply);
252 sp<IAAudioClient> client = interface_cast<IAAudioClient>(
253 data.readStrongBinder());
Phil Burkef7eaaf2019-05-01 11:26:35 -0700254 // 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 }
Phil Burk11e8d332017-05-24 09:59:02 -0700263 } break;
264
Phil Burk5ed503c2017-02-01 09:38:15 -0800265 case OPEN_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700266 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800267 request.readFromParcel(&data);
jiabin901f65d2017-07-12 17:56:35 -0700268 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 }
Phil Burk11e8d332017-05-24 09:59:02 -0700281 reply->writeInt32(streamHandle);
Phil Burk5ed503c2017-02-01 09:38:15 -0800282 configuration.writeToParcel(reply);
283 return NO_ERROR;
284 } break;
285
286 case CLOSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700287 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800288 status = data.readInt32(&streamHandle);
289 if (status != NO_ERROR) {
290 ALOGE("BnAAudioService::%s(CLOSE_STREAM) streamHandle failed!", __func__);
291 return status;
292 }
Phil Burk11e8d332017-05-24 09:59:02 -0700293 result = closeStream(streamHandle);
Phil Burk71f35bb2017-04-13 16:05:07 -0700294 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700295 // streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800296 reply->writeInt32(result);
297 return NO_ERROR;
298 } break;
299
300 case GET_STREAM_DESCRIPTION: {
Andy Hunga8805182017-06-27 16:17:40 -0700301 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burka5891f42018-03-12 17:21:11 -0700302 status = data.readInt32(&streamHandle);
303 if (status != NO_ERROR) {
Phil Burk25532c72020-01-29 14:23:04 -0800304 ALOGE("BnAAudioService::%s(GET_STREAM_DESCRIPTION) streamHandle failed!", __func__);
Phil Burka5891f42018-03-12 17:21:11 -0700305 return status;
306 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800307 aaudio::AudioEndpointParcelable parcelable;
Phil Burk11e8d332017-05-24 09:59:02 -0700308 result = getStreamDescription(streamHandle, parcelable);
Phil Burk5ed503c2017-02-01 09:38:15 -0800309 if (result != AAUDIO_OK) {
310 return AAudioConvert_aaudioToAndroidStatus(result);
311 }
Phil Burka5891f42018-03-12 17:21:11 -0700312 status = reply->writeInt32(result);
313 if (status != NO_ERROR) {
314 return status;
Phil Burk5ed503c2017-02-01 09:38:15 -0800315 }
Phil Burka5891f42018-03-12 17:21:11 -0700316 return parcelable.writeToParcel(reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800317 } break;
318
319 case START_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700320 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800321 status = data.readInt32(&streamHandle);
322 if (status != NO_ERROR) {
323 ALOGE("BnAAudioService::%s(START_STREAM) streamHandle failed!", __func__);
324 return status;
325 }
Phil Burk11e8d332017-05-24 09:59:02 -0700326 result = startStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800327 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700328 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800329 reply->writeInt32(result);
330 return NO_ERROR;
331 } break;
332
333 case PAUSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700334 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800335 status = data.readInt32(&streamHandle);
336 if (status != NO_ERROR) {
337 ALOGE("BnAAudioService::%s(PAUSE_STREAM) streamHandle failed!", __func__);
338 return status;
339 }
Phil Burk11e8d332017-05-24 09:59:02 -0700340 result = pauseStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800341 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700342 streamHandle, result);
Phil Burk71f35bb2017-04-13 16:05:07 -0700343 reply->writeInt32(result);
344 return NO_ERROR;
345 } break;
346
347 case STOP_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700348 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800349 status = data.readInt32(&streamHandle);
350 if (status != NO_ERROR) {
351 ALOGE("BnAAudioService::%s(STOP_STREAM) streamHandle failed!", __func__);
352 return status;
353 }
Phil Burk11e8d332017-05-24 09:59:02 -0700354 result = stopStream(streamHandle);
Phil Burk71f35bb2017-04-13 16:05:07 -0700355 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700356 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800357 reply->writeInt32(result);
358 return NO_ERROR;
359 } break;
360
361 case FLUSH_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700362 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800363 status = data.readInt32(&streamHandle);
364 if (status != NO_ERROR) {
365 ALOGE("BnAAudioService::%s(FLUSH_STREAM) streamHandle failed!", __func__);
366 return status;
367 }
Phil Burk11e8d332017-05-24 09:59:02 -0700368 result = flushStream(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800369 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700370 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800371 reply->writeInt32(result);
372 return NO_ERROR;
373 } break;
374
375 case REGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700376 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800377 status = data.readInt32(&streamHandle);
378 if (status != NO_ERROR) {
379 ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
380 return status;
381 }
382 status = data.readInt32(&tid);
383 if (status != NO_ERROR) {
384 ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) tid failed!", __func__);
385 return status;
386 }
387 status = data.readInt64(&nanoseconds);
388 if (status != NO_ERROR) {
389 ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) nanoseconds failed!", __func__);
390 return status;
391 }
Phil Burk11e8d332017-05-24 09:59:02 -0700392 result = registerAudioThread(streamHandle, tid, nanoseconds);
Phil Burk25532c72020-01-29 14:23:04 -0800393 ALOGV("BnAAudioService::%s(REGISTER_AUDIO_THREAD) 0x%08X, result = %d",
394 __func__, streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800395 reply->writeInt32(result);
396 return NO_ERROR;
397 } break;
398
399 case UNREGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700400 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk25532c72020-01-29 14:23:04 -0800401 status = data.readInt32(&streamHandle);
402 if (status != NO_ERROR) {
403 ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
404 return status;
405 }
406 status = data.readInt32(&tid);
407 if (status != NO_ERROR) {
408 ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) tid failed!", __func__);
409 return status;
410 }
Phil Burk11e8d332017-05-24 09:59:02 -0700411 result = unregisterAudioThread(streamHandle, tid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800412 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk11e8d332017-05-24 09:59:02 -0700413 streamHandle, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800414 reply->writeInt32(result);
415 return NO_ERROR;
416 } break;
417
418 default:
419 // ALOGW("BnAAudioService::onTransact not handled %u", code);
420 return BBinder::onTransact(code, data, reply, flags);
421 }
422}
423
424} /* namespace android */