blob: adff05787ac018694d569d227200137dcf434e2b [file] [log] [blame]
Glenn Kasten99e53b82012-01-19 08:59:58 -08001/*
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08002**
3** Copyright 2007, The Android Open Source Project
4**
Glenn Kastene53b9ea2012-03-12 16:29:55 -07005** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08008**
Glenn Kastene53b9ea2012-03-12 16:29:55 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080010**
Glenn Kastene53b9ea2012-03-12 16:29:55 -070011** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
Eric Laurent34f1d8e2009-11-04 08:27:26 -080018#define LOG_TAG "IAudioTrack"
19//#define LOG_NDEBUG 0
20#include <utils/Log.h>
21
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080022#include <stdint.h>
23#include <sys/types.h>
24
Mathias Agopian75624082009-05-19 19:08:10 -070025#include <binder/Parcel.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080026
27#include <media/IAudioTrack.h>
28
29namespace android {
30
Ivan Lozano8cf3a072017-08-09 09:01:33 -070031using media::VolumeShaper;
32
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080033enum {
34 GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
35 START,
36 STOP,
37 FLUSH,
Glenn Kastene4756fe2012-11-29 13:38:14 -080038 RESERVED, // was MUTE
Eric Laurentbe916aa2010-06-01 23:49:17 -070039 PAUSE,
John Grossman4ff14ba2012-02-08 16:37:41 -080040 ATTACH_AUX_EFFECT,
Glenn Kasten53cec222013-08-29 09:01:02 -070041 SET_PARAMETERS,
42 GET_TIMESTAMP,
Eric Laurent59fe0102013-09-27 18:48:26 -070043 SIGNAL,
Andy Hung9fc8b5c2017-01-24 13:36:48 -080044 APPLY_VOLUME_SHAPER,
45 GET_VOLUME_SHAPER_STATE,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080046};
47
48class BpAudioTrack : public BpInterface<IAudioTrack>
49{
50public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070051 explicit BpAudioTrack(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080052 : BpInterface<IAudioTrack>(impl)
53 {
54 }
Glenn Kastene53b9ea2012-03-12 16:29:55 -070055
Glenn Kasten10995862012-01-03 14:50:23 -080056 virtual sp<IMemory> getCblk() const
57 {
58 Parcel data, reply;
59 sp<IMemory> cblk;
60 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
61 status_t status = remote()->transact(GET_CBLK, data, &reply);
62 if (status == NO_ERROR) {
63 cblk = interface_cast<IMemory>(reply.readStrongBinder());
Glenn Kastena1d401d2013-11-20 14:37:13 -080064 if (cblk != 0 && cblk->pointer() == NULL) {
65 cblk.clear();
66 }
Glenn Kasten10995862012-01-03 14:50:23 -080067 }
68 return cblk;
69 }
70
Glenn Kasten3acbd052012-02-28 10:39:56 -080071 virtual status_t start()
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080072 {
73 Parcel data, reply;
74 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
Eric Laurent34f1d8e2009-11-04 08:27:26 -080075 status_t status = remote()->transact(START, data, &reply);
76 if (status == NO_ERROR) {
77 status = reply.readInt32();
78 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +000079 ALOGW("start() error: %s", strerror(-status));
Eric Laurent34f1d8e2009-11-04 08:27:26 -080080 }
81 return status;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080082 }
Glenn Kastene53b9ea2012-03-12 16:29:55 -070083
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080084 virtual void stop()
85 {
86 Parcel data, reply;
87 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
88 remote()->transact(STOP, data, &reply);
89 }
Glenn Kastene53b9ea2012-03-12 16:29:55 -070090
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080091 virtual void flush()
92 {
93 Parcel data, reply;
94 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
95 remote()->transact(FLUSH, data, &reply);
96 }
97
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080098 virtual void pause()
99 {
100 Parcel data, reply;
101 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
102 remote()->transact(PAUSE, data, &reply);
103 }
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700104
Eric Laurentbe916aa2010-06-01 23:49:17 -0700105 virtual status_t attachAuxEffect(int effectId)
106 {
107 Parcel data, reply;
108 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
109 data.writeInt32(effectId);
110 status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
111 if (status == NO_ERROR) {
112 status = reply.readInt32();
113 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000114 ALOGW("attachAuxEffect() error: %s", strerror(-status));
Eric Laurentbe916aa2010-06-01 23:49:17 -0700115 }
116 return status;
117 }
John Grossman4ff14ba2012-02-08 16:37:41 -0800118
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000119 virtual status_t setParameters(const String8& keyValuePairs) {
120 Parcel data, reply;
121 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
122 data.writeString8(keyValuePairs);
123 status_t status = remote()->transact(SET_PARAMETERS, data, &reply);
124 if (status == NO_ERROR) {
125 status = reply.readInt32();
126 }
127 return status;
128 }
Glenn Kasten53cec222013-08-29 09:01:02 -0700129
130 virtual status_t getTimestamp(AudioTimestamp& timestamp) {
131 Parcel data, reply;
132 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
133 status_t status = remote()->transact(GET_TIMESTAMP, data, &reply);
134 if (status == NO_ERROR) {
135 status = reply.readInt32();
136 if (status == NO_ERROR) {
137 timestamp.mPosition = reply.readInt32();
138 timestamp.mTime.tv_sec = reply.readInt32();
139 timestamp.mTime.tv_nsec = reply.readInt32();
140 }
141 }
142 return status;
143 }
Eric Laurent59fe0102013-09-27 18:48:26 -0700144
145 virtual void signal() {
146 Parcel data, reply;
147 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
148 remote()->transact(SIGNAL, data, &reply);
149 }
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800150
151 virtual VolumeShaper::Status applyVolumeShaper(
152 const sp<VolumeShaper::Configuration>& configuration,
153 const sp<VolumeShaper::Operation>& operation) {
154 Parcel data, reply;
155 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
156
157 status_t status = configuration.get() == nullptr
158 ? data.writeInt32(0)
159 : data.writeInt32(1)
160 ?: configuration->writeToParcel(&data);
161 if (status != NO_ERROR) {
162 return VolumeShaper::Status(status);
163 }
164
165 status = operation.get() == nullptr
166 ? status = data.writeInt32(0)
167 : data.writeInt32(1)
168 ?: operation->writeToParcel(&data);
169 if (status != NO_ERROR) {
170 return VolumeShaper::Status(status);
171 }
172
173 int32_t remoteVolumeShaperStatus;
174 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply)
175 ?: reply.readInt32(&remoteVolumeShaperStatus);
176
177 return VolumeShaper::Status(status ?: remoteVolumeShaperStatus);
178 }
179
180 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
181 Parcel data, reply;
182 data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
183
184 data.writeInt32(id);
185 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
186 if (status != NO_ERROR) {
187 return nullptr;
188 }
189 sp<VolumeShaper::State> state = new VolumeShaper::State;
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700190 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800191 if (status != NO_ERROR) {
192 return nullptr;
193 }
194 return state;
195 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800196};
197
198IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
199
200// ----------------------------------------------------------------------
201
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800202status_t BnAudioTrack::onTransact(
203 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
204{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700205 switch (code) {
206 case GET_CBLK: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800207 CHECK_INTERFACE(IAudioTrack, data, reply);
Marco Nelissen06b46062014-11-14 07:58:25 -0800208 reply->writeStrongBinder(IInterface::asBinder(getCblk()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800209 return NO_ERROR;
210 } break;
211 case START: {
212 CHECK_INTERFACE(IAudioTrack, data, reply);
Glenn Kasten3acbd052012-02-28 10:39:56 -0800213 reply->writeInt32(start());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800214 return NO_ERROR;
215 } break;
216 case STOP: {
217 CHECK_INTERFACE(IAudioTrack, data, reply);
218 stop();
219 return NO_ERROR;
220 } break;
221 case FLUSH: {
222 CHECK_INTERFACE(IAudioTrack, data, reply);
223 flush();
224 return NO_ERROR;
225 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800226 case PAUSE: {
227 CHECK_INTERFACE(IAudioTrack, data, reply);
228 pause();
229 return NO_ERROR;
230 }
Eric Laurentbe916aa2010-06-01 23:49:17 -0700231 case ATTACH_AUX_EFFECT: {
232 CHECK_INTERFACE(IAudioTrack, data, reply);
233 reply->writeInt32(attachAuxEffect(data.readInt32()));
234 return NO_ERROR;
235 } break;
Richard Fitzgeraldad3af332013-03-25 16:54:37 +0000236 case SET_PARAMETERS: {
237 CHECK_INTERFACE(IAudioTrack, data, reply);
238 String8 keyValuePairs(data.readString8());
239 reply->writeInt32(setParameters(keyValuePairs));
240 return NO_ERROR;
241 } break;
Glenn Kasten53cec222013-08-29 09:01:02 -0700242 case GET_TIMESTAMP: {
243 CHECK_INTERFACE(IAudioTrack, data, reply);
244 AudioTimestamp timestamp;
245 status_t status = getTimestamp(timestamp);
246 reply->writeInt32(status);
247 if (status == NO_ERROR) {
248 reply->writeInt32(timestamp.mPosition);
249 reply->writeInt32(timestamp.mTime.tv_sec);
250 reply->writeInt32(timestamp.mTime.tv_nsec);
251 }
252 return NO_ERROR;
253 } break;
Eric Laurent59fe0102013-09-27 18:48:26 -0700254 case SIGNAL: {
255 CHECK_INTERFACE(IAudioTrack, data, reply);
256 signal();
257 return NO_ERROR;
258 } break;
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800259 case APPLY_VOLUME_SHAPER: {
260 CHECK_INTERFACE(IAudioTrack, data, reply);
261 sp<VolumeShaper::Configuration> configuration;
262 sp<VolumeShaper::Operation> operation;
263
264 int32_t present;
265 status_t status = data.readInt32(&present);
266 if (status == NO_ERROR && present != 0) {
267 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700268 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800269 }
270 status = status ?: data.readInt32(&present);
271 if (status == NO_ERROR && present != 0) {
272 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700273 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800274 }
275 if (status == NO_ERROR) {
276 status = (status_t)applyVolumeShaper(configuration, operation);
277 }
278 reply->writeInt32(status);
279 return NO_ERROR;
280 } break;
281 case GET_VOLUME_SHAPER_STATE: {
282 CHECK_INTERFACE(IAudioTrack, data, reply);
283 int id;
284 status_t status = data.readInt32(&id);
285 if (status == NO_ERROR) {
286 sp<VolumeShaper::State> state = getVolumeShaperState(id);
287 if (state.get() != nullptr) {
288 status = state->writeToParcel(reply);
289 }
290 }
291 return NO_ERROR;
292 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800293 default:
294 return BBinder::onTransact(code, data, reply, flags);
295 }
296}
297
Glenn Kasten40bc9062015-03-20 09:09:33 -0700298} // namespace android