blob: ef4a51ff3869d06f6466162db687b4b20a8e5a31 [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);
247 data.checkInterface(this);
248
249 switch(code) {
250 case OPEN_STREAM: {
251 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: {
264 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800265 result = closeStream(stream);
Phil Burk71f35bb2017-04-13 16:05:07 -0700266 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
267 // stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800268 reply->writeInt32(result);
269 return NO_ERROR;
270 } break;
271
272 case GET_STREAM_DESCRIPTION: {
273 data.readInt32(&stream);
Phil Burk5ed503c2017-02-01 09:38:15 -0800274 aaudio::AudioEndpointParcelable parcelable;
275 result = getStreamDescription(stream, parcelable);
276 if (result != AAUDIO_OK) {
277 return AAudioConvert_aaudioToAndroidStatus(result);
278 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800279 result = parcelable.validate();
280 if (result != AAUDIO_OK) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800281 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
282 parcelable.dump();
Phil Burk5ed503c2017-02-01 09:38:15 -0800283 return AAudioConvert_aaudioToAndroidStatus(result);
284 }
Phil Burk5ed503c2017-02-01 09:38:15 -0800285 reply->writeInt32(result);
Phil Burkc0c70e32017-02-09 13:18:38 -0800286 parcelable.writeToParcel(reply);
Phil Burk5ed503c2017-02-01 09:38:15 -0800287 return NO_ERROR;
288 } break;
289
290 case START_STREAM: {
291 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: {
300 data.readInt32(&stream);
301 result = pauseStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800302 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
Phil Burk71f35bb2017-04-13 16:05:07 -0700303 stream, result);
304 reply->writeInt32(result);
305 return NO_ERROR;
306 } break;
307
308 case STOP_STREAM: {
309 data.readInt32(&stream);
310 result = stopStream(stream);
311 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
312 stream, result);
Phil Burk5ed503c2017-02-01 09:38:15 -0800313 reply->writeInt32(result);
314 return NO_ERROR;
315 } break;
316
317 case FLUSH_STREAM: {
318 data.readInt32(&stream);
319 result = flushStream(stream);
Phil Burkc0c70e32017-02-09 13:18:38 -0800320 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800321 stream, result);
322 reply->writeInt32(result);
323 return NO_ERROR;
324 } break;
325
326 case REGISTER_AUDIO_THREAD: {
327 data.readInt32(&stream);
328 data.readInt32(&pid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800329 data.readInt32(&tid);
Phil Burk5ed503c2017-02-01 09:38:15 -0800330 data.readInt64(&nanoseconds);
Phil Burkc0c70e32017-02-09 13:18:38 -0800331 result = registerAudioThread(stream, pid, tid, nanoseconds);
332 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800333 stream, result);
334 reply->writeInt32(result);
335 return NO_ERROR;
336 } break;
337
338 case UNREGISTER_AUDIO_THREAD: {
339 data.readInt32(&stream);
340 data.readInt32(&pid);
Phil Burkc0c70e32017-02-09 13:18:38 -0800341 data.readInt32(&tid);
342 result = unregisterAudioThread(stream, pid, tid);
343 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
Phil Burk5ed503c2017-02-01 09:38:15 -0800344 stream, result);
345 reply->writeInt32(result);
346 return NO_ERROR;
347 } break;
348
349 default:
350 // ALOGW("BnAAudioService::onTransact not handled %u", code);
351 return BBinder::onTransact(code, data, reply, flags);
352 }
353}
354
355} /* namespace android */