blob: 247d1d25a7922816a74556b8657fdb58a05b98b9 [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 Burk5ed503c2017-02-01 09:38:15 -080018
19#include "binding/AudioEndpointParcelable.h"
20#include "binding/AAudioStreamRequest.h"
Phil Burk3316d5e2017-02-15 11:23:01 -080021#include "binding/AAudioServiceDefinitions.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080022#include "binding/AAudioStreamConfiguration.h"
23#include "binding/IAAudioService.h"
24#include "utility/AAudioUtilities.h"
25
26namespace android {
27
Phil Burk3316d5e2017-02-15 11:23:01 -080028using aaudio::aaudio_handle_t;
29
Phil Burk5ed503c2017-02-01 09:38:15 -080030/**
31 * This is used by the AAudio Client to talk to the AAudio Service.
32 *
33 * The order of parameters in the Parcels must match with code in AAudioService.cpp.
34 */
35class BpAAudioService : public BpInterface<IAAudioService>
36{
37public:
38 explicit BpAAudioService(const sp<IBinder>& impl)
39 : BpInterface<IAAudioService>(impl)
40 {
41 }
42
Phil Burkc0c70e32017-02-09 13:18:38 -080043 virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
44 aaudio::AAudioStreamConfiguration &configurationOutput) override {
Phil Burk5ed503c2017-02-01 09:38:15 -080045 Parcel data, reply;
46 // send command
47 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
Phil Burk71f35bb2017-04-13 16:05:07 -070048 // request.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -080049 request.writeToParcel(&data);
50 status_t err = remote()->transact(OPEN_STREAM, data, &reply);
51 if (err != NO_ERROR) {
Phil Burk71f35bb2017-04-13 16:05:07 -070052 ALOGE("BpAAudioService::client openStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080053 return AAudioConvert_androidToAAudioResult(err);
54 }
55 // parse reply
56 aaudio_handle_t stream;
Phil Burk71f35bb2017-04-13 16:05:07 -070057 err = reply.readInt32(&stream);
Phil Burkec89b2e2017-06-20 15:05:06 -070058 ALOGD("BpAAudioService::client openStream returned stream = 0x%08x", stream);
Phil Burk71f35bb2017-04-13 16:05:07 -070059 if (err != NO_ERROR) {
60 ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
61 return AAudioConvert_androidToAAudioResult(err);
62 } else if (stream < 0) {
63 ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
64 return stream;
65 }
Phil Burkc0c70e32017-02-09 13:18:38 -080066 err = configurationOutput.readFromParcel(&reply);
67 if (err != NO_ERROR) {
68 ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
69 closeStream(stream);
70 return AAudioConvert_androidToAAudioResult(err);
71 }
Phil Burk5ed503c2017-02-01 09:38:15 -080072 return stream;
73 }
74
75 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
76 Parcel data, reply;
77 // send command
78 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
79 data.writeInt32(streamHandle);
80 status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
81 if (err != NO_ERROR) {
Phil Burk71f35bb2017-04-13 16:05:07 -070082 ALOGE("BpAAudioService::client closeStream transact failed %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -080083 return AAudioConvert_androidToAAudioResult(err);
84 }
85 // parse reply
86 aaudio_result_t res;
87 reply.readInt32(&res);
88 return res;
89 }
90
91 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
92 aaudio::AudioEndpointParcelable &parcelable) {
93 Parcel data, reply;
94 // send command
95 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
96 data.writeInt32(streamHandle);
97 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
98 if (err != NO_ERROR) {
Phil Burkc0c70e32017-02-09 13:18:38 -080099 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
Phil Burk5ed503c2017-02-01 09:38:15 -0800100 return AAudioConvert_androidToAAudioResult(err);
101 }
102 // parse reply
Phil Burkc0c70e32017-02-09 13:18:38 -0800103 aaudio_result_t result;
104 err = reply.readInt32(&result);
105 if (err != NO_ERROR) {
106 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
107 return AAudioConvert_androidToAAudioResult(err);
108 } else if (result != AAUDIO_OK) {
109 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800110 return result;
111 }
Phil Burkc0c70e32017-02-09 13:18:38 -0800112 err = parcelable.readFromParcel(&reply);;
113 if (err != NO_ERROR) {
114 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
115 return AAudioConvert_androidToAAudioResult(err);
116 }
117 //parcelable.dump();
118 result = parcelable.validate();
119 if (result != AAUDIO_OK) {
120 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result);
121 return result;
122 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800123 return result;
124 }
125
126 // TODO should we wait for a reply?
127 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
128 Parcel data, reply;
129 // send command
130 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
131 data.writeInt32(streamHandle);
132 status_t err = remote()->transact(START_STREAM, data, &reply);
133 if (err != NO_ERROR) {
134 return AAudioConvert_androidToAAudioResult(err);
135 }
136 // parse reply
137 aaudio_result_t res;
138 reply.readInt32(&res);
139 return res;
140 }
141
142 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
143 Parcel data, reply;
144 // send command
145 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
146 data.writeInt32(streamHandle);
147 status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
148 if (err != NO_ERROR) {
149 return AAudioConvert_androidToAAudioResult(err);
150 }
151 // parse reply
152 aaudio_result_t res;
153 reply.readInt32(&res);
154 return res;
155 }
156
Phil Burk71f35bb2017-04-13 16:05:07 -0700157 virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
158 Parcel data, reply;
159 // send command
160 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
161 data.writeInt32(streamHandle);
162 status_t err = remote()->transact(STOP_STREAM, data, &reply);
163 if (err != NO_ERROR) {
164 return AAudioConvert_androidToAAudioResult(err);
165 }
166 // parse reply
167 aaudio_result_t res;
168 reply.readInt32(&res);
169 return res;
170 }
171
Phil Burk5ed503c2017-02-01 09:38:15 -0800172 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
173 Parcel data, reply;
174 // send command
175 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
176 data.writeInt32(streamHandle);
177 status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
178 if (err != NO_ERROR) {
179 return AAudioConvert_androidToAAudioResult(err);
180 }
181 // parse reply
182 aaudio_result_t res;
183 reply.readInt32(&res);
184 return res;
185 }
186
Phil Burkc0c70e32017-02-09 13:18:38 -0800187 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
188 pid_t clientProcessId,
189 pid_t clientThreadId,
Phil Burk3316d5e2017-02-15 11:23:01 -0800190 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);
Phil Burkc0c70e32017-02-09 13:18:38 -0800196 data.writeInt32((int32_t) clientProcessId);
Phil Burk5ed503c2017-02-01 09:38:15 -0800197 data.writeInt32((int32_t) clientThreadId);
198 data.writeInt64(periodNanoseconds);
199 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
200 if (err != NO_ERROR) {
201 return AAudioConvert_androidToAAudioResult(err);
202 }
203 // parse reply
204 aaudio_result_t res;
205 reply.readInt32(&res);
206 return res;
207 }
208
Phil Burkc0c70e32017-02-09 13:18:38 -0800209 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
210 pid_t clientProcessId,
211 pid_t clientThreadId)
Phil Burk5ed503c2017-02-01 09:38:15 -0800212 override {
213 Parcel data, reply;
214 // send command
215 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
216 data.writeInt32(streamHandle);
Phil Burkc0c70e32017-02-09 13:18:38 -0800217 data.writeInt32((int32_t) clientProcessId);
Phil Burk5ed503c2017-02-01 09:38:15 -0800218 data.writeInt32((int32_t) clientThreadId);
219 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
220 if (err != NO_ERROR) {
221 return AAudioConvert_androidToAAudioResult(err);
222 }
223 // parse reply
224 aaudio_result_t res;
225 reply.readInt32(&res);
226 return res;
227 }
228
229};
230
231// Implement an interface to the service.
Phil Burkc0c70e32017-02-09 13:18:38 -0800232// This is here so that you don't have to link with libaaudio static library.
Phil Burk5ed503c2017-02-01 09:38:15 -0800233IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
234
235// The order of parameters in the Parcels must match with code in BpAAudioService
236
237status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
238 Parcel* reply, uint32_t flags) {
Phil Burk3316d5e2017-02-15 11:23:01 -0800239 aaudio_handle_t stream;
Phil Burk5ed503c2017-02-01 09:38:15 -0800240 aaudio::AAudioStreamRequest request;
241 aaudio::AAudioStreamConfiguration configuration;
242 pid_t pid;
Phil Burkc0c70e32017-02-09 13:18:38 -0800243 pid_t tid;
Phil Burk3316d5e2017-02-15 11:23:01 -0800244 int64_t nanoseconds;
Phil Burk5ed503c2017-02-01 09:38:15 -0800245 aaudio_result_t result;
246 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
Phil Burk5ed503c2017-02-01 09:38:15 -0800247
248 switch(code) {
249 case OPEN_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700250 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800251 request.readFromParcel(&data);
Phil Burkc0c70e32017-02-09 13:18:38 -0800252
Phil Burk71f35bb2017-04-13 16:05:07 -0700253 //ALOGD("BnAAudioService::client openStream request dump --------------------");
254 //request.dump();
Phil Burkc0c70e32017-02-09 13:18:38 -0800255
Phil Burk5ed503c2017-02-01 09:38:15 -0800256 stream = openStream(request, configuration);
Phil Burk71f35bb2017-04-13 16:05:07 -0700257 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800258 reply->writeInt32(stream);
259 configuration.writeToParcel(reply);
260 return NO_ERROR;
261 } break;
262
263 case CLOSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700264 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800265 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800266 result = closeStream(stream);
Phil Burk71f35bb2017-04-13 16:05:07 -0700267 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
268 // stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800269 reply->writeInt32(result);
270 return NO_ERROR;
271 } break;
272
273 case GET_STREAM_DESCRIPTION: {
Andy Hunga8805182017-06-27 16:17:40 -0700274 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800275 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800276 aaudio::AudioEndpointParcelable parcelable;
277 result = getStreamDescription(stream, parcelable);
278 if (result != AAUDIO_OK) {
279 return AAudioConvert_aaudioToAndroidStatus(result);
280 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800281 result = parcelable.validate();
282 if (result != AAUDIO_OK) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800283 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
284 parcelable.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -0800285 return AAudioConvert_aaudioToAndroidStatus(result);
286 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800287 reply->writeInt32(result);
Phil Burkc0c70e32017-02-09 13:18:38 -0800288 parcelable.writeToParcel(reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800289 return NO_ERROR;
290 } break;
291
292 case START_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700293 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800294 data.readInt32(&stream);
295 result = startStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800296 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800297 stream, result);
298 reply->writeInt32(result);
299 return NO_ERROR;
300 } break;
301
302 case PAUSE_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700303 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800304 data.readInt32(&stream);
305 result = pauseStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800306 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
Phil Burk71f35bb2017-04-13 16:05:07 -0700307 stream, result);
308 reply->writeInt32(result);
309 return NO_ERROR;
310 } break;
311
312 case STOP_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700313 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk71f35bb2017-04-13 16:05:07 -0700314 data.readInt32(&stream);
315 result = stopStream(stream);
316 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
317 stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800318 reply->writeInt32(result);
319 return NO_ERROR;
320 } break;
321
322 case FLUSH_STREAM: {
Andy Hunga8805182017-06-27 16:17:40 -0700323 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800324 data.readInt32(&stream);
325 result = flushStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800326 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800327 stream, result);
328 reply->writeInt32(result);
329 return NO_ERROR;
330 } break;
331
332 case REGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700333 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800334 data.readInt32(&stream);
335 data.readInt32(&pid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800336 data.readInt32(&tid);
Phil Burk5ed503c2017-02-01 09:38:15 -0800337 data.readInt64(&nanoseconds);
Phil Burkc0c70e32017-02-09 13:18:38 -0800338 result = registerAudioThread(stream, pid, tid, nanoseconds);
339 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800340 stream, result);
341 reply->writeInt32(result);
342 return NO_ERROR;
343 } break;
344
345 case UNREGISTER_AUDIO_THREAD: {
Andy Hunga8805182017-06-27 16:17:40 -0700346 CHECK_INTERFACE(IAAudioService, data, reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800347 data.readInt32(&stream);
348 data.readInt32(&pid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800349 data.readInt32(&tid);
350 result = unregisterAudioThread(stream, pid, tid);
351 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800352 stream, result);
353 reply->writeInt32(result);
354 return NO_ERROR;
355 } break;
356
357 default:
358 // ALOGW("BnAAudioService::onTransact not handled %u", code);
359 return BBinder::onTransact(code, data, reply, flags);
360 }
361}
362
363} /* namespace android */