blob: e2eccddd907941da1dcc091dcf38eefb9b7502b0 [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** 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
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** 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
15** limitations under the License.
16*/
17
John Grossmanc795b642012-02-22 15:38:35 -080018#include <arpa/inet.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080019#include <stdint.h>
20#include <sys/types.h>
21
Mathias Agopian75624082009-05-19 19:08:10 -070022#include <binder/Parcel.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080023
Lajos Molnar3a474aa2015-04-24 17:10:07 -070024#include <media/AudioResamplerPublic.h>
25#include <media/AVSyncSettings.h>
Wei Jiad399e7e2016-10-26 15:49:11 -070026#include <media/BufferingSettings.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070027
Chris Watkins99f31602015-03-20 13:06:33 -070028#include <media/IDataSource.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080029#include <media/IMediaHTTPService.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080030#include <media/IMediaPlayer.h>
Dave Burked681bbb2011-08-30 14:39:17 +010031#include <media/IStreamSource.h>
32
Andy McFadden8ba01022012-12-18 09:46:54 -080033#include <gui/IGraphicBufferProducer.h>
Dave Burked681bbb2011-08-30 14:39:17 +010034#include <utils/String8.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080035
36namespace android {
37
Ivan Lozano8cf3a072017-08-09 09:01:33 -070038using media::VolumeShaper;
39
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080040enum {
41 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
Dave Burked681bbb2011-08-30 14:39:17 +010042 SET_DATA_SOURCE_URL,
43 SET_DATA_SOURCE_FD,
44 SET_DATA_SOURCE_STREAM,
Chris Watkins99f31602015-03-20 13:06:33 -070045 SET_DATA_SOURCE_CALLBACK,
Wei Jiad399e7e2016-10-26 15:49:11 -070046 SET_BUFFERING_SETTINGS,
Wei Jia9bb38032017-03-23 18:00:38 -070047 GET_BUFFERING_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080048 PREPARE_ASYNC,
49 START,
50 STOP,
51 IS_PLAYING,
Lajos Molnar3a474aa2015-04-24 17:10:07 -070052 SET_PLAYBACK_SETTINGS,
53 GET_PLAYBACK_SETTINGS,
54 SET_SYNC_SETTINGS,
55 GET_SYNC_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080056 PAUSE,
57 SEEK_TO,
58 GET_CURRENT_POSITION,
59 GET_DURATION,
60 RESET,
Wei Jia52c28512017-09-13 18:17:51 -070061 NOTIFY_AT,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080062 SET_AUDIO_STREAM_TYPE,
63 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070064 SET_VOLUME,
65 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070066 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070067 GET_METADATA,
Eric Laurent2beeb502010-07-16 07:43:46 -070068 SET_AUX_EFFECT_SEND_LEVEL,
Glenn Kasten11731182011-02-08 17:26:17 -080069 ATTACH_AUX_EFFECT,
70 SET_VIDEO_SURFACETEXTURE,
Gloria Wang4f9e47f2011-04-25 17:28:22 -070071 SET_PARAMETER,
72 GET_PARAMETER,
John Grossmanc795b642012-02-22 15:38:35 -080073 SET_RETRANSMIT_ENDPOINT,
John Grossman44a7e422012-06-21 17:29:24 -070074 GET_RETRANSMIT_ENDPOINT,
Marco Nelissen6b74d672012-02-28 16:07:44 -080075 SET_NEXT_PLAYER,
Andy Hung9fc8b5c2017-01-24 13:36:48 -080076 APPLY_VOLUME_SHAPER,
77 GET_VOLUME_SHAPER_STATE,
Hassan Shojaniacefac142017-02-06 21:02:02 -080078 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -080079 PREPARE_DRM,
80 RELEASE_DRM,
jiabin156c6872017-10-06 09:47:15 -070081 // AudioRouting
82 SET_OUTPUT_DEVICE,
83 GET_ROUTED_DEVICE_ID,
84 ENABLE_AUDIO_DEVICE_CALLBACK,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080085};
86
Hassan Shojania071437a2017-01-23 09:19:40 -080087// ModDrm helpers
88static void readVector(const Parcel& reply, Vector<uint8_t>& vector) {
89 uint32_t size = reply.readUint32();
90 vector.insertAt((size_t)0, size);
91 reply.read(vector.editArray(), size);
92}
93
94static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
95 data.writeUint32(vector.size());
96 data.write(vector.array(), vector.size());
97}
98
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080099class BpMediaPlayer: public BpInterface<IMediaPlayer>
100{
101public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700102 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800103 : BpInterface<IMediaPlayer>(impl)
104 {
105 }
106
107 // disconnect from media player service
108 void disconnect()
109 {
110 Parcel data, reply;
111 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
112 remote()->transact(DISCONNECT, data, &reply);
113 }
114
Andreas Huber1b86fe02014-01-29 11:13:26 -0800115 status_t setDataSource(
116 const sp<IMediaHTTPService> &httpService,
117 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +0100118 const KeyedVector<String8, String8>* headers)
119 {
120 Parcel data, reply;
121 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800122 data.writeInt32(httpService != NULL);
123 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800124 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800125 }
Dave Burked681bbb2011-08-30 14:39:17 +0100126 data.writeCString(url);
127 if (headers == NULL) {
128 data.writeInt32(0);
129 } else {
130 // serialize the headers
131 data.writeInt32(headers->size());
132 for (size_t i = 0; i < headers->size(); ++i) {
133 data.writeString8(headers->keyAt(i));
134 data.writeString8(headers->valueAt(i));
135 }
136 }
137 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
138 return reply.readInt32();
139 }
140
141 status_t setDataSource(int fd, int64_t offset, int64_t length) {
142 Parcel data, reply;
143 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
144 data.writeFileDescriptor(fd);
145 data.writeInt64(offset);
146 data.writeInt64(length);
147 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
148 return reply.readInt32();
149 }
150
151 status_t setDataSource(const sp<IStreamSource> &source) {
152 Parcel data, reply;
153 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800154 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700155 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100156 return reply.readInt32();
157 }
158
Chris Watkins99f31602015-03-20 13:06:33 -0700159 status_t setDataSource(const sp<IDataSource> &source) {
160 Parcel data, reply;
161 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
162 data.writeStrongBinder(IInterface::asBinder(source));
163 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
164 return reply.readInt32();
165 }
166
Andy McFadden8ba01022012-12-18 09:46:54 -0800167 // pass the buffered IGraphicBufferProducer to the media player service
168 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800169 {
170 Parcel data, reply;
171 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800172 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800173 data.writeStrongBinder(b);
174 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
175 return reply.readInt32();
176 }
177
Wei Jiad399e7e2016-10-26 15:49:11 -0700178 status_t setBufferingSettings(const BufferingSettings& buffering)
179 {
180 Parcel data, reply;
181 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
182 buffering.writeToParcel(&data);
183 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
184 return reply.readInt32();
185 }
186
Wei Jia9bb38032017-03-23 18:00:38 -0700187 status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */)
Wei Jiad399e7e2016-10-26 15:49:11 -0700188 {
189 if (buffering == nullptr) {
190 return BAD_VALUE;
191 }
192 Parcel data, reply;
193 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Wei Jia9bb38032017-03-23 18:00:38 -0700194 remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
Wei Jiad399e7e2016-10-26 15:49:11 -0700195 status_t err = reply.readInt32();
196 if (err == OK) {
197 err = buffering->readFromParcel(&reply);
198 }
199 return err;
200 }
201
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800202 status_t prepareAsync()
203 {
204 Parcel data, reply;
205 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
206 remote()->transact(PREPARE_ASYNC, data, &reply);
207 return reply.readInt32();
208 }
209
210 status_t start()
211 {
212 Parcel data, reply;
213 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
214 remote()->transact(START, data, &reply);
215 return reply.readInt32();
216 }
217
218 status_t stop()
219 {
220 Parcel data, reply;
221 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
222 remote()->transact(STOP, data, &reply);
223 return reply.readInt32();
224 }
225
226 status_t isPlaying(bool* state)
227 {
228 Parcel data, reply;
229 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
230 remote()->transact(IS_PLAYING, data, &reply);
231 *state = reply.readInt32();
232 return reply.readInt32();
233 }
234
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700235 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800236 {
237 Parcel data, reply;
238 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700239 data.writeFloat(rate.mSpeed);
240 data.writeFloat(rate.mPitch);
241 data.writeInt32((int32_t)rate.mFallbackMode);
242 data.writeInt32((int32_t)rate.mStretchMode);
243 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800244 return reply.readInt32();
245 }
246
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700247 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
248 {
249 Parcel data, reply;
250 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
251 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
252 status_t err = reply.readInt32();
253 if (err == OK) {
254 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
255 rate->mSpeed = reply.readFloat();
256 rate->mPitch = reply.readFloat();
257 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
258 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
259 }
260 return err;
261 }
262
263 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
264 {
265 Parcel data, reply;
266 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
267 data.writeInt32((int32_t)sync.mSource);
268 data.writeInt32((int32_t)sync.mAudioAdjustMode);
269 data.writeFloat(sync.mTolerance);
270 data.writeFloat(videoFpsHint);
271 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
272 return reply.readInt32();
273 }
274
275 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
276 {
277 Parcel data, reply;
278 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
279 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
280 status_t err = reply.readInt32();
281 if (err == OK) {
282 AVSyncSettings settings;
283 settings.mSource = (AVSyncSource)reply.readInt32();
284 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
285 settings.mTolerance = reply.readFloat();
286 *sync = settings;
287 *videoFps = reply.readFloat();
288 }
289 return err;
290 }
291
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800292 status_t pause()
293 {
294 Parcel data, reply;
295 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
296 remote()->transact(PAUSE, data, &reply);
297 return reply.readInt32();
298 }
299
Wei Jiac5de0912016-11-18 10:22:14 -0800300 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800301 {
302 Parcel data, reply;
303 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
304 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800305 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800306 remote()->transact(SEEK_TO, data, &reply);
307 return reply.readInt32();
308 }
309
310 status_t getCurrentPosition(int* msec)
311 {
312 Parcel data, reply;
313 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
314 remote()->transact(GET_CURRENT_POSITION, data, &reply);
315 *msec = reply.readInt32();
316 return reply.readInt32();
317 }
318
319 status_t getDuration(int* msec)
320 {
321 Parcel data, reply;
322 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
323 remote()->transact(GET_DURATION, data, &reply);
324 *msec = reply.readInt32();
325 return reply.readInt32();
326 }
327
328 status_t reset()
329 {
330 Parcel data, reply;
331 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
332 remote()->transact(RESET, data, &reply);
333 return reply.readInt32();
334 }
335
Wei Jia52c28512017-09-13 18:17:51 -0700336 status_t notifyAt(int64_t mediaTimeUs)
337 {
338 Parcel data, reply;
339 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
340 data.writeInt64(mediaTimeUs);
341 remote()->transact(NOTIFY_AT, data, &reply);
342 return reply.readInt32();
343 }
344
Glenn Kastenfff6d712012-01-12 16:38:12 -0800345 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800346 {
347 Parcel data, reply;
348 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800349 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800350 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
351 return reply.readInt32();
352 }
353
354 status_t setLooping(int loop)
355 {
356 Parcel data, reply;
357 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
358 data.writeInt32(loop);
359 remote()->transact(SET_LOOPING, data, &reply);
360 return reply.readInt32();
361 }
362
363 status_t setVolume(float leftVolume, float rightVolume)
364 {
365 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700366 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800367 data.writeFloat(leftVolume);
368 data.writeFloat(rightVolume);
369 remote()->transact(SET_VOLUME, data, &reply);
370 return reply.readInt32();
371 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700372
373 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700374 {
375 // Avoid doing any extra copy. The interface descriptor should
376 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700377 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700378 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700379
380 status_t setMetadataFilter(const Parcel& request)
381 {
382 Parcel reply;
383 // Avoid doing any extra copy of the request. The interface
384 // descriptor should have been set by MediaPlayer.java.
385 remote()->transact(SET_METADATA_FILTER, request, &reply);
386 return reply.readInt32();
387 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700388
389 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
390 {
391 Parcel request;
392 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
393 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
394 request.writeInt32(update_only);
395 request.writeInt32(apply_filter);
396 remote()->transact(GET_METADATA, request, reply);
397 return reply->readInt32();
398 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800399
Eric Laurent2beeb502010-07-16 07:43:46 -0700400 status_t setAuxEffectSendLevel(float level)
401 {
402 Parcel data, reply;
403 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
404 data.writeFloat(level);
405 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
406 return reply.readInt32();
407 }
408
409 status_t attachAuxEffect(int effectId)
410 {
411 Parcel data, reply;
412 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
413 data.writeInt32(effectId);
414 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
415 return reply.readInt32();
416 }
Glenn Kasten11731182011-02-08 17:26:17 -0800417
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700418 status_t setParameter(int key, const Parcel& request)
419 {
420 Parcel data, reply;
421 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
422 data.writeInt32(key);
423 if (request.dataSize() > 0) {
424 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
425 }
426 remote()->transact(SET_PARAMETER, data, &reply);
427 return reply.readInt32();
428 }
429
430 status_t getParameter(int key, Parcel *reply)
431 {
432 Parcel data;
433 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
434 data.writeInt32(key);
435 return remote()->transact(GET_PARAMETER, data, reply);
436 }
437
John Grossman44a7e422012-06-21 17:29:24 -0700438 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
439 {
John Grossmanc795b642012-02-22 15:38:35 -0800440 Parcel data, reply;
441 status_t err;
442
443 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
444 if (NULL != endpoint) {
445 data.writeInt32(sizeof(*endpoint));
446 data.write(endpoint, sizeof(*endpoint));
447 } else {
448 data.writeInt32(0);
449 }
450
451 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
452 if (OK != err) {
453 return err;
454 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800455 return reply.readInt32();
456 }
John Grossmanc795b642012-02-22 15:38:35 -0800457
Marco Nelissen6b74d672012-02-28 16:07:44 -0800458 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
459 Parcel data, reply;
460 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800461 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800462 data.writeStrongBinder(b);
463 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800464 return reply.readInt32();
465 }
John Grossman44a7e422012-06-21 17:29:24 -0700466
467 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
468 {
469 Parcel data, reply;
470 status_t err;
471
472 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
473 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
474
475 if ((OK != err) || (OK != (err = reply.readInt32()))) {
476 return err;
477 }
478
479 data.read(endpoint, sizeof(*endpoint));
480
481 return err;
482 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800483
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800484 virtual VolumeShaper::Status applyVolumeShaper(
485 const sp<VolumeShaper::Configuration>& configuration,
486 const sp<VolumeShaper::Operation>& operation) {
487 Parcel data, reply;
488 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
489
490 status_t tmp;
491 status_t status = configuration.get() == nullptr
492 ? data.writeInt32(0)
493 : (tmp = data.writeInt32(1)) != NO_ERROR
494 ? tmp : configuration->writeToParcel(&data);
495 if (status != NO_ERROR) {
496 return VolumeShaper::Status(status);
497 }
498
499 status = operation.get() == nullptr
500 ? status = data.writeInt32(0)
501 : (tmp = data.writeInt32(1)) != NO_ERROR
502 ? tmp : operation->writeToParcel(&data);
503 if (status != NO_ERROR) {
504 return VolumeShaper::Status(status);
505 }
506
507 int32_t remoteVolumeShaperStatus;
508 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
509 if (status == NO_ERROR) {
510 status = reply.readInt32(&remoteVolumeShaperStatus);
511 }
512 if (status != NO_ERROR) {
513 return VolumeShaper::Status(status);
514 }
515 return VolumeShaper::Status(remoteVolumeShaperStatus);
516 }
517
518 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
519 Parcel data, reply;
520 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
521
522 data.writeInt32(id);
523 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
524 if (status != NO_ERROR) {
525 return nullptr;
526 }
527 sp<VolumeShaper::State> state = new VolumeShaper::State();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700528 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800529 if (status != NO_ERROR) {
530 return nullptr;
531 }
532 return state;
533 }
534
Hassan Shojaniacefac142017-02-06 21:02:02 -0800535 // Modular DRM
536 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800537 {
538 Parcel data, reply;
539 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
540
541 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800542 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800543
544 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
545 if (status != OK) {
546 ALOGE("prepareDrm: binder call failed: %d", status);
547 return status;
548 }
549
550 return reply.readInt32();
551 }
552
553 status_t releaseDrm()
554 {
555 Parcel data, reply;
556 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
557
558 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
559 if (status != OK) {
560 ALOGE("releaseDrm: binder call failed: %d", status);
561 return status;
562 }
563
564 return reply.readInt32();
565 }
jiabin156c6872017-10-06 09:47:15 -0700566
567 status_t setOutputDevice(audio_port_handle_t deviceId)
568 {
569 Parcel data, reply;
570 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
571
572 data.writeInt32(deviceId);
573
574 status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
575 if (status != OK) {
576 ALOGE("setOutputDevice: binder call failed: %d", status);
577 return status;
578 }
579
580 return reply.readInt32();
581 }
582
583 status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
584 {
585 Parcel data, reply;
586 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
587
588 status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
589 if (status != OK) {
590 ALOGE("getRoutedDeviceid: binder call failed: %d", status);
591 *deviceId = AUDIO_PORT_HANDLE_NONE;
592 return status;
593 }
594
595 status = reply.readInt32();
596 if (status != NO_ERROR) {
597 *deviceId = AUDIO_PORT_HANDLE_NONE;
598 } else {
599 *deviceId = reply.readInt32();
600 }
601 return status;
602 }
603
604 status_t enableAudioDeviceCallback(bool enabled)
605 {
606 Parcel data, reply;
607 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
608
609 data.writeBool(enabled);
610
611 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
612 if (status != OK) {
613 ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
614 return status;
615 }
616
617 return reply.readInt32();
618 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800619};
620
niko56f0cc52009-06-22 08:49:52 -0700621IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800622
623// ----------------------------------------------------------------------
624
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800625status_t BnMediaPlayer::onTransact(
626 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
627{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700628 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800629 case DISCONNECT: {
630 CHECK_INTERFACE(IMediaPlayer, data, reply);
631 disconnect();
632 return NO_ERROR;
633 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100634 case SET_DATA_SOURCE_URL: {
635 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800636
637 sp<IMediaHTTPService> httpService;
638 if (data.readInt32()) {
639 httpService =
640 interface_cast<IMediaHTTPService>(data.readStrongBinder());
641 }
642
Dave Burked681bbb2011-08-30 14:39:17 +0100643 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800644 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800645 reply->writeInt32(BAD_VALUE);
646 return NO_ERROR;
647 }
Dave Burked681bbb2011-08-30 14:39:17 +0100648 KeyedVector<String8, String8> headers;
649 int32_t numHeaders = data.readInt32();
650 for (int i = 0; i < numHeaders; ++i) {
651 String8 key = data.readString8();
652 String8 value = data.readString8();
653 headers.add(key, value);
654 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800655 reply->writeInt32(setDataSource(
656 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100657 return NO_ERROR;
658 } break;
659 case SET_DATA_SOURCE_FD: {
660 CHECK_INTERFACE(IMediaPlayer, data, reply);
661 int fd = data.readFileDescriptor();
662 int64_t offset = data.readInt64();
663 int64_t length = data.readInt64();
664 reply->writeInt32(setDataSource(fd, offset, length));
665 return NO_ERROR;
666 }
667 case SET_DATA_SOURCE_STREAM: {
668 CHECK_INTERFACE(IMediaPlayer, data, reply);
669 sp<IStreamSource> source =
670 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800671 if (source == NULL) {
672 reply->writeInt32(BAD_VALUE);
673 } else {
674 reply->writeInt32(setDataSource(source));
675 }
Dave Burked681bbb2011-08-30 14:39:17 +0100676 return NO_ERROR;
677 }
Chris Watkins99f31602015-03-20 13:06:33 -0700678 case SET_DATA_SOURCE_CALLBACK: {
679 CHECK_INTERFACE(IMediaPlayer, data, reply);
680 sp<IDataSource> source =
681 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800682 if (source == NULL) {
683 reply->writeInt32(BAD_VALUE);
684 } else {
685 reply->writeInt32(setDataSource(source));
686 }
Chris Watkins99f31602015-03-20 13:06:33 -0700687 return NO_ERROR;
688 }
Glenn Kasten11731182011-02-08 17:26:17 -0800689 case SET_VIDEO_SURFACETEXTURE: {
690 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800691 sp<IGraphicBufferProducer> bufferProducer =
692 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
693 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800694 return NO_ERROR;
695 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700696 case SET_BUFFERING_SETTINGS: {
697 CHECK_INTERFACE(IMediaPlayer, data, reply);
698 BufferingSettings buffering;
699 buffering.readFromParcel(&data);
700 reply->writeInt32(setBufferingSettings(buffering));
701 return NO_ERROR;
702 } break;
Wei Jia9bb38032017-03-23 18:00:38 -0700703 case GET_BUFFERING_SETTINGS: {
Wei Jiad399e7e2016-10-26 15:49:11 -0700704 CHECK_INTERFACE(IMediaPlayer, data, reply);
705 BufferingSettings buffering;
Wei Jia9bb38032017-03-23 18:00:38 -0700706 status_t err = getBufferingSettings(&buffering);
Wei Jiad399e7e2016-10-26 15:49:11 -0700707 reply->writeInt32(err);
708 if (err == OK) {
709 buffering.writeToParcel(reply);
710 }
711 return NO_ERROR;
712 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800713 case PREPARE_ASYNC: {
714 CHECK_INTERFACE(IMediaPlayer, data, reply);
715 reply->writeInt32(prepareAsync());
716 return NO_ERROR;
717 } break;
718 case START: {
719 CHECK_INTERFACE(IMediaPlayer, data, reply);
720 reply->writeInt32(start());
721 return NO_ERROR;
722 } break;
723 case STOP: {
724 CHECK_INTERFACE(IMediaPlayer, data, reply);
725 reply->writeInt32(stop());
726 return NO_ERROR;
727 } break;
728 case IS_PLAYING: {
729 CHECK_INTERFACE(IMediaPlayer, data, reply);
730 bool state;
731 status_t ret = isPlaying(&state);
732 reply->writeInt32(state);
733 reply->writeInt32(ret);
734 return NO_ERROR;
735 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700736 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800737 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700738 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
739 rate.mSpeed = data.readFloat();
740 rate.mPitch = data.readFloat();
741 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
742 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
743 reply->writeInt32(setPlaybackSettings(rate));
744 return NO_ERROR;
745 } break;
746 case GET_PLAYBACK_SETTINGS: {
747 CHECK_INTERFACE(IMediaPlayer, data, reply);
748 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
749 status_t err = getPlaybackSettings(&rate);
750 reply->writeInt32(err);
751 if (err == OK) {
752 reply->writeFloat(rate.mSpeed);
753 reply->writeFloat(rate.mPitch);
754 reply->writeInt32((int32_t)rate.mFallbackMode);
755 reply->writeInt32((int32_t)rate.mStretchMode);
756 }
757 return NO_ERROR;
758 } break;
759 case SET_SYNC_SETTINGS: {
760 CHECK_INTERFACE(IMediaPlayer, data, reply);
761 AVSyncSettings sync;
762 sync.mSource = (AVSyncSource)data.readInt32();
763 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
764 sync.mTolerance = data.readFloat();
765 float videoFpsHint = data.readFloat();
766 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
767 return NO_ERROR;
768 } break;
769 case GET_SYNC_SETTINGS: {
770 CHECK_INTERFACE(IMediaPlayer, data, reply);
771 AVSyncSettings sync;
772 float videoFps;
773 status_t err = getSyncSettings(&sync, &videoFps);
774 reply->writeInt32(err);
775 if (err == OK) {
776 reply->writeInt32((int32_t)sync.mSource);
777 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
778 reply->writeFloat(sync.mTolerance);
779 reply->writeFloat(videoFps);
780 }
Wei Jia98160162015-02-04 17:01:11 -0800781 return NO_ERROR;
782 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800783 case PAUSE: {
784 CHECK_INTERFACE(IMediaPlayer, data, reply);
785 reply->writeInt32(pause());
786 return NO_ERROR;
787 } break;
788 case SEEK_TO: {
789 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700790 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800791 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
792 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800793 return NO_ERROR;
794 } break;
795 case GET_CURRENT_POSITION: {
796 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700797 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800798 status_t ret = getCurrentPosition(&msec);
799 reply->writeInt32(msec);
800 reply->writeInt32(ret);
801 return NO_ERROR;
802 } break;
803 case GET_DURATION: {
804 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700805 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800806 status_t ret = getDuration(&msec);
807 reply->writeInt32(msec);
808 reply->writeInt32(ret);
809 return NO_ERROR;
810 } break;
811 case RESET: {
812 CHECK_INTERFACE(IMediaPlayer, data, reply);
813 reply->writeInt32(reset());
814 return NO_ERROR;
815 } break;
Wei Jia52c28512017-09-13 18:17:51 -0700816 case NOTIFY_AT: {
817 CHECK_INTERFACE(IMediaPlayer, data, reply);
818 reply->writeInt32(notifyAt(data.readInt64()));
819 return NO_ERROR;
820 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800821 case SET_AUDIO_STREAM_TYPE: {
822 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800823 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800824 return NO_ERROR;
825 } break;
826 case SET_LOOPING: {
827 CHECK_INTERFACE(IMediaPlayer, data, reply);
828 reply->writeInt32(setLooping(data.readInt32()));
829 return NO_ERROR;
830 } break;
831 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700832 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700833 float leftVolume = data.readFloat();
834 float rightVolume = data.readFloat();
835 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800836 return NO_ERROR;
837 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700838 case INVOKE: {
839 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700840 status_t result = invoke(data, reply);
841 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700842 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700843 case SET_METADATA_FILTER: {
844 CHECK_INTERFACE(IMediaPlayer, data, reply);
845 reply->writeInt32(setMetadataFilter(data));
846 return NO_ERROR;
847 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700848 case GET_METADATA: {
849 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700850 bool update_only = static_cast<bool>(data.readInt32());
851 bool apply_filter = static_cast<bool>(data.readInt32());
852 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700853 reply->setDataPosition(0);
854 reply->writeInt32(retcode);
855 reply->setDataPosition(0);
856 return NO_ERROR;
857 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700858 case SET_AUX_EFFECT_SEND_LEVEL: {
859 CHECK_INTERFACE(IMediaPlayer, data, reply);
860 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
861 return NO_ERROR;
862 } break;
863 case ATTACH_AUX_EFFECT: {
864 CHECK_INTERFACE(IMediaPlayer, data, reply);
865 reply->writeInt32(attachAuxEffect(data.readInt32()));
866 return NO_ERROR;
867 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700868 case SET_PARAMETER: {
869 CHECK_INTERFACE(IMediaPlayer, data, reply);
870 int key = data.readInt32();
871
872 Parcel request;
873 if (data.dataAvail() > 0) {
874 request.appendFrom(
875 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
876 }
877 request.setDataPosition(0);
878 reply->writeInt32(setParameter(key, request));
879 return NO_ERROR;
880 } break;
881 case GET_PARAMETER: {
882 CHECK_INTERFACE(IMediaPlayer, data, reply);
883 return getParameter(data.readInt32(), reply);
884 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800885 case SET_RETRANSMIT_ENDPOINT: {
886 CHECK_INTERFACE(IMediaPlayer, data, reply);
887
888 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700889 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800890 int amt = data.readInt32();
891 if (amt == sizeof(endpoint)) {
892 data.read(&endpoint, sizeof(struct sockaddr_in));
893 reply->writeInt32(setRetransmitEndpoint(&endpoint));
894 } else {
895 reply->writeInt32(setRetransmitEndpoint(NULL));
896 }
John Grossman44a7e422012-06-21 17:29:24 -0700897
898 return NO_ERROR;
899 } break;
900 case GET_RETRANSMIT_ENDPOINT: {
901 CHECK_INTERFACE(IMediaPlayer, data, reply);
902
903 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700904 memset(&endpoint, 0, sizeof(endpoint));
John Grossman44a7e422012-06-21 17:29:24 -0700905 status_t res = getRetransmitEndpoint(&endpoint);
906
907 reply->writeInt32(res);
908 reply->write(&endpoint, sizeof(endpoint));
909
Marco Nelissen6b74d672012-02-28 16:07:44 -0800910 return NO_ERROR;
911 } break;
912 case SET_NEXT_PLAYER: {
913 CHECK_INTERFACE(IMediaPlayer, data, reply);
914 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700915
John Grossmanc795b642012-02-22 15:38:35 -0800916 return NO_ERROR;
917 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800918
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800919 case APPLY_VOLUME_SHAPER: {
920 CHECK_INTERFACE(IMediaPlayer, data, reply);
921 sp<VolumeShaper::Configuration> configuration;
922 sp<VolumeShaper::Operation> operation;
923
924 int32_t present;
925 status_t status = data.readInt32(&present);
926 if (status == NO_ERROR && present != 0) {
927 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700928 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800929 }
930 if (status == NO_ERROR) {
931 status = data.readInt32(&present);
932 }
933 if (status == NO_ERROR && present != 0) {
934 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700935 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800936 }
937 if (status == NO_ERROR) {
938 status = (status_t)applyVolumeShaper(configuration, operation);
939 }
940 reply->writeInt32(status);
941 return NO_ERROR;
942 } break;
943 case GET_VOLUME_SHAPER_STATE: {
944 CHECK_INTERFACE(IMediaPlayer, data, reply);
945 int id;
946 status_t status = data.readInt32(&id);
947 if (status == NO_ERROR) {
948 sp<VolumeShaper::State> state = getVolumeShaperState(id);
949 if (state.get() != nullptr) {
950 status = state->writeToParcel(reply);
951 }
952 }
953 return NO_ERROR;
954 } break;
955
Hassan Shojaniacefac142017-02-06 21:02:02 -0800956 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -0800957 case PREPARE_DRM: {
958 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800959
Hassan Shojania071437a2017-01-23 09:19:40 -0800960 uint8_t uuid[16];
961 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -0800962 Vector<uint8_t> drmSessionId;
963 readVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800964
Hassan Shojaniacefac142017-02-06 21:02:02 -0800965 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800966 reply->writeInt32(result);
967 return OK;
968 }
969 case RELEASE_DRM: {
970 CHECK_INTERFACE(IMediaPlayer, data, reply);
971
972 uint32_t result = releaseDrm();
973 reply->writeInt32(result);
974 return OK;
975 }
jiabin156c6872017-10-06 09:47:15 -0700976
977 // AudioRouting
978 case SET_OUTPUT_DEVICE: {
979 CHECK_INTERFACE(IMediaPlayer, data, reply);
980 int deviceId;
981 status_t status = data.readInt32(&deviceId);
982 if (status == NO_ERROR) {
983 reply->writeInt32(setOutputDevice(deviceId));
984 } else {
985 reply->writeInt32(BAD_VALUE);
986 }
987 return NO_ERROR;
988 }
989 case GET_ROUTED_DEVICE_ID: {
990 CHECK_INTERFACE(IMediaPlayer, data, reply);
991 audio_port_handle_t deviceId;
992 status_t ret = getRoutedDeviceId(&deviceId);
993 reply->writeInt32(ret);
994 if (ret == NO_ERROR) {
995 reply->writeInt32(deviceId);
996 }
997 return NO_ERROR;
998 } break;
999 case ENABLE_AUDIO_DEVICE_CALLBACK: {
1000 CHECK_INTERFACE(IMediaPlayer, data, reply);
1001 bool enabled;
1002 status_t status = data.readBool(&enabled);
1003 if (status == NO_ERROR) {
1004 reply->writeInt32(enableAudioDeviceCallback(enabled));
1005 } else {
1006 reply->writeInt32(BAD_VALUE);
1007 }
1008 return NO_ERROR;
1009 } break;
1010
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001011 default:
1012 return BBinder::onTransact(code, data, reply, flags);
1013 }
1014}
1015
1016// ----------------------------------------------------------------------------
1017
Glenn Kasten40bc9062015-03-20 09:09:33 -07001018} // namespace android