blob: e4bf82a0be82508ea381e108cf1f7f8c8ed93279 [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 Burka4eb0d82017-04-12 15:44:06 -070017#include <aaudio/AAudio.h>
Phil Burk2ac035f2017-06-23 14:51:14 -070018#include <binder/IPCThreadState.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080019
20#include "binding/AudioEndpointParcelable.h"
21#include "binding/AAudioStreamRequest.h"
Phil Burk3316d5e2017-02-15 11:23:01 -080022#include "binding/AAudioServiceDefinitions.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080023#include "binding/AAudioStreamConfiguration.h"
24#include "binding/IAAudioService.h"
25#include "utility/AAudioUtilities.h"
26
27namespace android {
28
Phil Burk3316d5e2017-02-15 11:23:01 -080029using aaudio::aaudio_handle_t;
30
Phil Burk5ed503c2017-02-01 09:38:15 -080031/**
32 * This is used by the AAudio Client to talk to the AAudio Service.
33 *
34 * The order of parameters in the Parcels must match with code in AAudioService.cpp.
35 */
36class BpAAudioService : public BpInterface<IAAudioService>
37{
38public:
39 explicit BpAAudioService(const sp<IBinder>& impl)
40 : BpInterface<IAAudioService>(impl)
41 {
42 }
43
Phil Burkc0c70e32017-02-09 13:18:38 -080044 virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
45 aaudio::AAudioStreamConfiguration &configurationOutput) override {
Phil Burk5ed503c2017-02-01 09:38:15 -080046 Parcel data, reply;
47 // send command
48 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
Phil Burk71f35bb2017-04-13 16:05:07 -070049 // request.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -080050 request.writeToParcel(&data);
51 status_t err = remote()->transact(OPEN_STREAM, data, &reply);
52 if (err != NO_ERROR) {
Phil Burk71f35bb2017-04-13 16:05:07 -070053 ALOGE("BpAAudioService::client openStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080054 return AAudioConvert_androidToAAudioResult(err);
55 }
56 // parse reply
57 aaudio_handle_t stream;
Phil Burk71f35bb2017-04-13 16:05:07 -070058 err = reply.readInt32(&stream);
Phil Burkec89b2e2017-06-20 15:05:06 -070059 ALOGD("BpAAudioService::client openStream returned stream = 0x%08x", stream);
Phil Burk71f35bb2017-04-13 16:05:07 -070060 if (err != NO_ERROR) {
61 ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
62 return AAudioConvert_androidToAAudioResult(err);
63 } else if (stream < 0) {
64 ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
65 return stream;
66 }
Phil Burkc0c70e32017-02-09 13:18:38 -080067 err = configurationOutput.readFromParcel(&reply);
68 if (err != NO_ERROR) {
69 ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
70 closeStream(stream);
71 return AAudioConvert_androidToAAudioResult(err);
72 }
Phil Burk5ed503c2017-02-01 09:38:15 -080073 return stream;
74 }
75
76 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
77 Parcel data, reply;
78 // send command
79 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
80 data.writeInt32(streamHandle);
81 status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
82 if (err != NO_ERROR) {
Phil Burk71f35bb2017-04-13 16:05:07 -070083 ALOGE("BpAAudioService::client closeStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080084 return AAudioConvert_androidToAAudioResult(err);
85 }
86 // parse reply
87 aaudio_result_t res;
88 reply.readInt32(&res);
89 return res;
90 }
91
92 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
93 aaudio::AudioEndpointParcelable &parcelable) {
94 Parcel data, reply;
95 // send command
96 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
97 data.writeInt32(streamHandle);
98 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
99 if (err != NO_ERROR) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800100 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -0800101 return AAudioConvert_androidToAAudioResult(err);
102 }
103 // parse reply
Phil Burkc0c70e32017-02-09 13:18:38 -0800104 aaudio_result_t result;
105 err = reply.readInt32(&result);
106 if (err != NO_ERROR) {
107 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
108 return AAudioConvert_androidToAAudioResult(err);
109 } else if (result != AAUDIO_OK) {
110 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800111 return result;
112 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800113 err = parcelable.readFromParcel(&reply);;
114 if (err != NO_ERROR) {
115 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
116 return AAudioConvert_androidToAAudioResult(err);
117 }
118 //parcelable.dump();
119 result = parcelable.validate();
120 if (result != AAUDIO_OK) {
121 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result);
122 return result;
123 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800124 return result;
125 }
126
127 // TODO should we wait for a reply?
128 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
129 Parcel data, reply;
130 // send command
131 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
132 data.writeInt32(streamHandle);
133 status_t err = remote()->transact(START_STREAM, data, &reply);
134 if (err != NO_ERROR) {
135 return AAudioConvert_androidToAAudioResult(err);
136 }
137 // parse reply
138 aaudio_result_t res;
139 reply.readInt32(&res);
140 return res;
141 }
142
143 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
144 Parcel data, reply;
145 // send command
146 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
147 data.writeInt32(streamHandle);
148 status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
149 if (err != NO_ERROR) {
150 return AAudioConvert_androidToAAudioResult(err);
151 }
152 // parse reply
153 aaudio_result_t res;
154 reply.readInt32(&res);
155 return res;
156 }
157
Phil Burk71f35bb2017-04-13 16:05:07 -0700158 virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
159 Parcel data, reply;
160 // send command
161 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
162 data.writeInt32(streamHandle);
163 status_t err = remote()->transact(STOP_STREAM, data, &reply);
164 if (err != NO_ERROR) {
165 return AAudioConvert_androidToAAudioResult(err);
166 }
167 // parse reply
168 aaudio_result_t res;
169 reply.readInt32(&res);
170 return res;
171 }
172
Phil Burk5ed503c2017-02-01 09:38:15 -0800173 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
174 Parcel data, reply;
175 // send command
176 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
177 data.writeInt32(streamHandle);
178 status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
179 if (err != NO_ERROR) {
180 return AAudioConvert_androidToAAudioResult(err);
181 }
182 // parse reply
183 aaudio_result_t res;
184 reply.readInt32(&res);
185 return res;
186 }
187
Phil Burkc0c70e32017-02-09 13:18:38 -0800188 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
Phil Burk2ac035f2017-06-23 14:51:14 -0700189 pid_t clientThreadId,
190 int64_t periodNanoseconds)
Phil Burk5ed503c2017-02-01 09:38:15 -0800191 override {
192 Parcel data, reply;
193 // send command
194 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
195 data.writeInt32(streamHandle);
196 data.writeInt32((int32_t) clientThreadId);
197 data.writeInt64(periodNanoseconds);
198 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
199 if (err != NO_ERROR) {
200 return AAudioConvert_androidToAAudioResult(err);
201 }
202 // parse reply
203 aaudio_result_t res;
204 reply.readInt32(&res);
205 return res;
206 }
207
Phil Burkc0c70e32017-02-09 13:18:38 -0800208 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
Phil Burkc0c70e32017-02-09 13:18:38 -0800209 pid_t clientThreadId)
Phil Burk5ed503c2017-02-01 09:38:15 -0800210 override {
211 Parcel data, reply;
212 // send command
213 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
214 data.writeInt32(streamHandle);
215 data.writeInt32((int32_t) clientThreadId);
216 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
217 if (err != NO_ERROR) {
218 return AAudioConvert_androidToAAudioResult(err);
219 }
220 // parse reply
221 aaudio_result_t res;
222 reply.readInt32(&res);
223 return res;
224 }
225
226};
227
228// Implement an interface to the service.
Phil Burkc0c70e32017-02-09 13:18:38 -0800229// This is here so that you don't have to link with libaaudio static library.
Phil Burk5ed503c2017-02-01 09:38:15 -0800230IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
231
232// The order of parameters in the Parcels must match with code in BpAAudioService
233
234status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
235 Parcel* reply, uint32_t flags) {
Phil Burk3316d5e2017-02-15 11:23:01 -0800236 aaudio_handle_t stream;
Phil Burk5ed503c2017-02-01 09:38:15 -0800237 aaudio::AAudioStreamRequest request;
238 aaudio::AAudioStreamConfiguration configuration;
Phil Burkc0c70e32017-02-09 13:18:38 -0800239 pid_t tid;
Phil Burk3316d5e2017-02-15 11:23:01 -0800240 int64_t nanoseconds;
Phil Burk5ed503c2017-02-01 09:38:15 -0800241 aaudio_result_t result;
242 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
Phil Burk5ed503c2017-02-01 09:38:15 -0800243
244 switch(code) {
245 case OPEN_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700246 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800247 request.readFromParcel(&data);
Phil Burk71f35bb2017-04-13 16:05:07 -0700248 //ALOGD("BnAAudioService::client openStream request dump --------------------");
249 //request.dump();
Phil Burk2ac035f2017-06-23 14:51:14 -0700250 // Override the uid and pid from the client in case they are incorrect.
251 request.setUserId(IPCThreadState::self()->getCallingUid());
252 request.setProcessId(IPCThreadState::self()->getCallingPid());
Phil Burk5ed503c2017-02-01 09:38:15 -0800253 stream = openStream(request, configuration);
Phil Burk2ac035f2017-06-23 14:51:14 -0700254 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X ----", stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800255 reply->writeInt32(stream);
256 configuration.writeToParcel(reply);
257 return NO_ERROR;
258 } break;
259
260 case CLOSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700261 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800262 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800263 result = closeStream(stream);
Phil Burk71f35bb2017-04-13 16:05:07 -0700264 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
265 // stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800266 reply->writeInt32(result);
267 return NO_ERROR;
268 } break;
269
270 case GET_STREAM_DESCRIPTION: {
Andy Hunga8805182017-06-27 16:17:40 -0700271 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800272 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800273 aaudio::AudioEndpointParcelable parcelable;
274 result = getStreamDescription(stream, parcelable);
275 if (result != AAUDIO_OK) {
276 return AAudioConvert_aaudioToAndroidStatus(result);
277 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800278 result = parcelable.validate();
279 if (result != AAUDIO_OK) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800280 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
281 parcelable.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -0800282 return AAudioConvert_aaudioToAndroidStatus(result);
283 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800284 reply->writeInt32(result);
Phil Burkc0c70e32017-02-09 13:18:38 -0800285 parcelable.writeToParcel(reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800286 return NO_ERROR;
287 } break;
288
289 case START_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700290 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800291 data.readInt32(&stream);
292 result = startStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800293 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800294 stream, result);
295 reply->writeInt32(result);
296 return NO_ERROR;
297 } break;
298
299 case PAUSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700300 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800301 data.readInt32(&stream);
302 result = pauseStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800303 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
Phil Burk71f35bb2017-04-13 16:05:07 -0700304 stream, result);
305 reply->writeInt32(result);
306 return NO_ERROR;
307 } break;
308
309 case STOP_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700310 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk71f35bb2017-04-13 16:05:07 -0700311 data.readInt32(&stream);
312 result = stopStream(stream);
313 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
314 stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800315 reply->writeInt32(result);
316 return NO_ERROR;
317 } break;
318
319 case FLUSH_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700320 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800321 data.readInt32(&stream);
322 result = flushStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800323 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800324 stream, result);
325 reply->writeInt32(result);
326 return NO_ERROR;
327 } break;
328
329 case REGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700330 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800331 data.readInt32(&stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800332 data.readInt32(&tid);
Phil Burk5ed503c2017-02-01 09:38:15 -0800333 data.readInt64(&nanoseconds);
Phil Burk2ac035f2017-06-23 14:51:14 -0700334 result = registerAudioThread(stream, tid, nanoseconds);
Phil Burkc0c70e32017-02-09 13:18:38 -0800335 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800336 stream, result);
337 reply->writeInt32(result);
338 return NO_ERROR;
339 } break;
340
341 case UNREGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700342 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800343 data.readInt32(&stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800344 data.readInt32(&tid);
Phil Burk2ac035f2017-06-23 14:51:14 -0700345 result = unregisterAudioThread(stream, tid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800346 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800347 stream, result);
348 reply->writeInt32(result);
349 return NO_ERROR;
350 } break;
351
352 default:
353 // ALOGW("BnAAudioService::onTransact not handled %u", code);
354 return BBinder::onTransact(code, data, reply, flags);
355 }
356}
357
358} /* namespace android */