blob: 899ebc0cb4492c5a5427bf4d7ff42d3cad0cd3d9 [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
17#include <aaudio/AAudioDefinitions.h>
18
19#include "binding/AudioEndpointParcelable.h"
20#include "binding/AAudioStreamRequest.h"
21#include "binding/AAudioStreamConfiguration.h"
22#include "binding/IAAudioService.h"
23#include "utility/AAudioUtilities.h"
24
25namespace android {
26
27/**
28 * This is used by the AAudio Client to talk to the AAudio Service.
29 *
30 * The order of parameters in the Parcels must match with code in AAudioService.cpp.
31 */
32class BpAAudioService : public BpInterface<IAAudioService>
33{
34public:
35 explicit BpAAudioService(const sp<IBinder>& impl)
36 : BpInterface<IAAudioService>(impl)
37 {
38 }
39
40 virtual aaudio_handle_t openStream(aaudio::AAudioStreamRequest &request,
41 aaudio::AAudioStreamConfiguration &configuration) override {
42 Parcel data, reply;
43 // send command
44 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
45 request.writeToParcel(&data);
46 status_t err = remote()->transact(OPEN_STREAM, data, &reply);
47 if (err != NO_ERROR) {
48 return AAudioConvert_androidToAAudioResult(err);
49 }
50 // parse reply
51 aaudio_handle_t stream;
52 reply.readInt32(&stream);
53 configuration.readFromParcel(&reply);
54 return stream;
55 }
56
57 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
58 Parcel data, reply;
59 // send command
60 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
61 data.writeInt32(streamHandle);
62 status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
63 if (err != NO_ERROR) {
64 return AAudioConvert_androidToAAudioResult(err);
65 }
66 // parse reply
67 aaudio_result_t res;
68 reply.readInt32(&res);
69 return res;
70 }
71
72 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
73 aaudio::AudioEndpointParcelable &parcelable) {
74 Parcel data, reply;
75 // send command
76 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
77 data.writeInt32(streamHandle);
78 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
79 if (err != NO_ERROR) {
80 return AAudioConvert_androidToAAudioResult(err);
81 }
82 // parse reply
83 parcelable.readFromParcel(&reply);
84 parcelable.dump();
85 aaudio_result_t result = parcelable.validate();
86 if (result != AAUDIO_OK) {
87 return result;
88 }
89 reply.readInt32(&result);
90 return result;
91 }
92
93 // TODO should we wait for a reply?
94 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
95 Parcel data, reply;
96 // send command
97 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
98 data.writeInt32(streamHandle);
99 status_t err = remote()->transact(START_STREAM, data, &reply);
100 if (err != NO_ERROR) {
101 return AAudioConvert_androidToAAudioResult(err);
102 }
103 // parse reply
104 aaudio_result_t res;
105 reply.readInt32(&res);
106 return res;
107 }
108
109 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
110 Parcel data, reply;
111 // send command
112 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
113 data.writeInt32(streamHandle);
114 status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
115 if (err != NO_ERROR) {
116 return AAudioConvert_androidToAAudioResult(err);
117 }
118 // parse reply
119 aaudio_result_t res;
120 reply.readInt32(&res);
121 return res;
122 }
123
124 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
125 Parcel data, reply;
126 // send command
127 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
128 data.writeInt32(streamHandle);
129 status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
130 if (err != NO_ERROR) {
131 return AAudioConvert_androidToAAudioResult(err);
132 }
133 // parse reply
134 aaudio_result_t res;
135 reply.readInt32(&res);
136 return res;
137 }
138
139 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId,
140 aaudio_nanoseconds_t periodNanoseconds)
141 override {
142 Parcel data, reply;
143 // send command
144 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
145 data.writeInt32(streamHandle);
146 data.writeInt32((int32_t) clientThreadId);
147 data.writeInt64(periodNanoseconds);
148 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, 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
158 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId)
159 override {
160 Parcel data, reply;
161 // send command
162 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
163 data.writeInt32(streamHandle);
164 data.writeInt32((int32_t) clientThreadId);
165 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
166 if (err != NO_ERROR) {
167 return AAudioConvert_androidToAAudioResult(err);
168 }
169 // parse reply
170 aaudio_result_t res;
171 reply.readInt32(&res);
172 return res;
173 }
174
175};
176
177// Implement an interface to the service.
178// This is here so that you don't have to link with liboboe static library.
179IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
180
181// The order of parameters in the Parcels must match with code in BpAAudioService
182
183status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
184 Parcel* reply, uint32_t flags) {
185 AAudioStream stream;
186 aaudio::AAudioStreamRequest request;
187 aaudio::AAudioStreamConfiguration configuration;
188 pid_t pid;
189 aaudio_nanoseconds_t nanoseconds;
190 aaudio_result_t result;
191 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
192 data.checkInterface(this);
193
194 switch(code) {
195 case OPEN_STREAM: {
196 request.readFromParcel(&data);
197 stream = openStream(request, configuration);
198 ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream);
199 reply->writeInt32(stream);
200 configuration.writeToParcel(reply);
201 return NO_ERROR;
202 } break;
203
204 case CLOSE_STREAM: {
205 data.readInt32(&stream);
206 ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X", stream);
207 result = closeStream(stream);
208 reply->writeInt32(result);
209 return NO_ERROR;
210 } break;
211
212 case GET_STREAM_DESCRIPTION: {
213 data.readInt32(&stream);
214 ALOGD("BnAAudioService::onTransact GET_STREAM_DESCRIPTION 0x%08X", stream);
215 aaudio::AudioEndpointParcelable parcelable;
216 result = getStreamDescription(stream, parcelable);
217 if (result != AAUDIO_OK) {
218 return AAudioConvert_aaudioToAndroidStatus(result);
219 }
220 parcelable.dump();
221 result = parcelable.validate();
222 if (result != AAUDIO_OK) {
223 return AAudioConvert_aaudioToAndroidStatus(result);
224 }
225 parcelable.writeToParcel(reply);
226 reply->writeInt32(result);
227 return NO_ERROR;
228 } break;
229
230 case START_STREAM: {
231 data.readInt32(&stream);
232 result = startStream(stream);
233 ALOGD("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
234 stream, result);
235 reply->writeInt32(result);
236 return NO_ERROR;
237 } break;
238
239 case PAUSE_STREAM: {
240 data.readInt32(&stream);
241 result = pauseStream(stream);
242 ALOGD("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
243 stream, result);
244 reply->writeInt32(result);
245 return NO_ERROR;
246 } break;
247
248 case FLUSH_STREAM: {
249 data.readInt32(&stream);
250 result = flushStream(stream);
251 ALOGD("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
252 stream, result);
253 reply->writeInt32(result);
254 return NO_ERROR;
255 } break;
256
257 case REGISTER_AUDIO_THREAD: {
258 data.readInt32(&stream);
259 data.readInt32(&pid);
260 data.readInt64(&nanoseconds);
261 result = registerAudioThread(stream, pid, nanoseconds);
262 ALOGD("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
263 stream, result);
264 reply->writeInt32(result);
265 return NO_ERROR;
266 } break;
267
268 case UNREGISTER_AUDIO_THREAD: {
269 data.readInt32(&stream);
270 data.readInt32(&pid);
271 result = unregisterAudioThread(stream, pid);
272 ALOGD("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
273 stream, result);
274 reply->writeInt32(result);
275 return NO_ERROR;
276 } break;
277
278 default:
279 // ALOGW("BnAAudioService::onTransact not handled %u", code);
280 return BBinder::onTransact(code, data, reply, flags);
281 }
282}
283
284} /* namespace android */