blob: 4967dda9bd4d0bb2145f5a75e99c54be455afca8 [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>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080020
Marco Nelissendab79b32019-11-18 08:25:47 -080021#include <android/IDataSource.h>
Santiago Seifert42a97f52021-02-08 16:09:38 +000022#include <binder/IPCThreadState.h>
Mathias Agopian75624082009-05-19 19:08:10 -070023#include <binder/Parcel.h>
Marco Nelissendab79b32019-11-18 08:25:47 -080024#include <gui/IGraphicBufferProducer.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070025#include <media/AudioResamplerPublic.h>
26#include <media/AVSyncSettings.h>
Wei Jiad399e7e2016-10-26 15:49:11 -070027#include <media/BufferingSettings.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080028#include <media/IMediaHTTPService.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080029#include <media/IMediaPlayer.h>
Dave Burked681bbb2011-08-30 14:39:17 +010030#include <media/IStreamSource.h>
Dave Burked681bbb2011-08-30 14:39:17 +010031#include <utils/String8.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080032
33namespace android {
34
Ivan Lozano8cf3a072017-08-09 09:01:33 -070035using media::VolumeShaper;
36
Hassan Shojania071437a2017-01-23 09:19:40 -080037// ModDrm helpers
Santiago Seifert42a97f52021-02-08 16:09:38 +000038static status_t readVector(const Parcel& reply, Vector<uint8_t>& vector) {
39 uint32_t size = 0;
40 status_t status = reply.readUint32(&size);
41 if (status == OK) {
42 status = size <= reply.dataAvail() ? OK : BAD_VALUE;
43 }
44 if (status == OK) {
45 status = vector.insertAt((size_t) 0, size) >= 0 ? OK : NO_MEMORY;
46 }
47 if (status == OK) {
48 status = reply.read(vector.editArray(), size);
49 }
50 if (status != OK) {
51 char errorMsg[100];
52 char buganizerId[] = "173720767";
53 snprintf(errorMsg,
54 sizeof(errorMsg),
55 "%s: failed to read array. Size: %d, status: %d.",
56 __func__,
57 size,
58 status);
59 android_errorWriteWithInfoLog(
60 /* safetyNet tag= */ 0x534e4554,
61 buganizerId,
62 IPCThreadState::self()->getCallingUid(),
63 errorMsg,
64 strlen(errorMsg));
65 ALOGE("%s (b/%s)", errorMsg, buganizerId);
66 }
67 return status;
Hassan Shojania071437a2017-01-23 09:19:40 -080068}
69
70static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
71 data.writeUint32(vector.size());
72 data.write(vector.array(), vector.size());
73}
74
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080075class BpMediaPlayer: public BpInterface<IMediaPlayer>
76{
77public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070078 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080079 : BpInterface<IMediaPlayer>(impl)
80 {
81 }
82
83 // disconnect from media player service
84 void disconnect()
85 {
86 Parcel data, reply;
87 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
88 remote()->transact(DISCONNECT, data, &reply);
89 }
90
Andreas Huber1b86fe02014-01-29 11:13:26 -080091 status_t setDataSource(
92 const sp<IMediaHTTPService> &httpService,
93 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +010094 const KeyedVector<String8, String8>* headers)
95 {
96 Parcel data, reply;
97 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -080098 data.writeInt32(httpService != NULL);
99 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800100 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800101 }
Dave Burked681bbb2011-08-30 14:39:17 +0100102 data.writeCString(url);
103 if (headers == NULL) {
104 data.writeInt32(0);
105 } else {
106 // serialize the headers
107 data.writeInt32(headers->size());
108 for (size_t i = 0; i < headers->size(); ++i) {
109 data.writeString8(headers->keyAt(i));
110 data.writeString8(headers->valueAt(i));
111 }
112 }
113 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
114 return reply.readInt32();
115 }
116
117 status_t setDataSource(int fd, int64_t offset, int64_t length) {
118 Parcel data, reply;
119 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
120 data.writeFileDescriptor(fd);
121 data.writeInt64(offset);
122 data.writeInt64(length);
123 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
124 return reply.readInt32();
125 }
126
127 status_t setDataSource(const sp<IStreamSource> &source) {
128 Parcel data, reply;
129 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800130 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700131 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100132 return reply.readInt32();
133 }
134
Chris Watkins99f31602015-03-20 13:06:33 -0700135 status_t setDataSource(const sp<IDataSource> &source) {
136 Parcel data, reply;
137 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
138 data.writeStrongBinder(IInterface::asBinder(source));
139 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
140 return reply.readInt32();
141 }
142
Byeongjo Park28225ab2019-01-24 20:31:19 +0900143 status_t setDataSource(const String8& rtpParams) {
144 Parcel data, reply;
145 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
146 data.writeString8(rtpParams);
147 remote()->transact(SET_DATA_SOURCE_RTP, data, &reply);
148
149 return reply.readInt32();
150 }
151
Andy McFadden8ba01022012-12-18 09:46:54 -0800152 // pass the buffered IGraphicBufferProducer to the media player service
153 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800154 {
155 Parcel data, reply;
156 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800157 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800158 data.writeStrongBinder(b);
159 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
160 return reply.readInt32();
161 }
162
Wei Jiad399e7e2016-10-26 15:49:11 -0700163 status_t setBufferingSettings(const BufferingSettings& buffering)
164 {
165 Parcel data, reply;
166 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Dongwon Kang79e33732019-01-25 16:35:26 -0800167 data.writeInt32(buffering.mInitialMarkMs);
168 data.writeInt32(buffering.mResumePlaybackMarkMs);
Wei Jiad399e7e2016-10-26 15:49:11 -0700169 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
170 return reply.readInt32();
171 }
172
Wei Jia9bb38032017-03-23 18:00:38 -0700173 status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */)
Wei Jiad399e7e2016-10-26 15:49:11 -0700174 {
175 if (buffering == nullptr) {
176 return BAD_VALUE;
177 }
178 Parcel data, reply;
179 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Wei Jia9bb38032017-03-23 18:00:38 -0700180 remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
Wei Jiad399e7e2016-10-26 15:49:11 -0700181 status_t err = reply.readInt32();
182 if (err == OK) {
Dongwon Kang79e33732019-01-25 16:35:26 -0800183 buffering->mInitialMarkMs = reply.readInt32();
184 buffering->mResumePlaybackMarkMs = reply.readInt32();
Wei Jiad399e7e2016-10-26 15:49:11 -0700185 }
186 return err;
187 }
188
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800189 status_t prepareAsync()
190 {
191 Parcel data, reply;
192 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
193 remote()->transact(PREPARE_ASYNC, data, &reply);
194 return reply.readInt32();
195 }
196
197 status_t start()
198 {
199 Parcel data, reply;
200 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
201 remote()->transact(START, data, &reply);
202 return reply.readInt32();
203 }
204
205 status_t stop()
206 {
207 Parcel data, reply;
208 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
209 remote()->transact(STOP, data, &reply);
210 return reply.readInt32();
211 }
212
213 status_t isPlaying(bool* state)
214 {
215 Parcel data, reply;
216 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
217 remote()->transact(IS_PLAYING, data, &reply);
218 *state = reply.readInt32();
219 return reply.readInt32();
220 }
221
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700222 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800223 {
224 Parcel data, reply;
225 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700226 data.writeFloat(rate.mSpeed);
227 data.writeFloat(rate.mPitch);
228 data.writeInt32((int32_t)rate.mFallbackMode);
229 data.writeInt32((int32_t)rate.mStretchMode);
230 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800231 return reply.readInt32();
232 }
233
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700234 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
235 {
236 Parcel data, reply;
237 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
238 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
239 status_t err = reply.readInt32();
240 if (err == OK) {
241 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
242 rate->mSpeed = reply.readFloat();
243 rate->mPitch = reply.readFloat();
244 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
245 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
246 }
247 return err;
248 }
249
250 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
251 {
252 Parcel data, reply;
253 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
254 data.writeInt32((int32_t)sync.mSource);
255 data.writeInt32((int32_t)sync.mAudioAdjustMode);
256 data.writeFloat(sync.mTolerance);
257 data.writeFloat(videoFpsHint);
258 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
259 return reply.readInt32();
260 }
261
262 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
263 {
264 Parcel data, reply;
265 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
266 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
267 status_t err = reply.readInt32();
268 if (err == OK) {
269 AVSyncSettings settings;
270 settings.mSource = (AVSyncSource)reply.readInt32();
271 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
272 settings.mTolerance = reply.readFloat();
273 *sync = settings;
274 *videoFps = reply.readFloat();
275 }
276 return err;
277 }
278
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800279 status_t pause()
280 {
281 Parcel data, reply;
282 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
283 remote()->transact(PAUSE, data, &reply);
284 return reply.readInt32();
285 }
286
Wei Jiac5de0912016-11-18 10:22:14 -0800287 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800288 {
289 Parcel data, reply;
290 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
291 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800292 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800293 remote()->transact(SEEK_TO, data, &reply);
294 return reply.readInt32();
295 }
296
297 status_t getCurrentPosition(int* msec)
298 {
299 Parcel data, reply;
300 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
301 remote()->transact(GET_CURRENT_POSITION, data, &reply);
302 *msec = reply.readInt32();
303 return reply.readInt32();
304 }
305
306 status_t getDuration(int* msec)
307 {
308 Parcel data, reply;
309 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
310 remote()->transact(GET_DURATION, data, &reply);
311 *msec = reply.readInt32();
312 return reply.readInt32();
313 }
314
315 status_t reset()
316 {
317 Parcel data, reply;
318 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
319 remote()->transact(RESET, data, &reply);
320 return reply.readInt32();
321 }
322
Wei Jia52c28512017-09-13 18:17:51 -0700323 status_t notifyAt(int64_t mediaTimeUs)
324 {
325 Parcel data, reply;
326 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
327 data.writeInt64(mediaTimeUs);
328 remote()->transact(NOTIFY_AT, data, &reply);
329 return reply.readInt32();
330 }
331
Glenn Kastenfff6d712012-01-12 16:38:12 -0800332 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800333 {
334 Parcel data, reply;
335 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800336 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800337 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
338 return reply.readInt32();
339 }
340
341 status_t setLooping(int loop)
342 {
343 Parcel data, reply;
344 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
345 data.writeInt32(loop);
346 remote()->transact(SET_LOOPING, data, &reply);
347 return reply.readInt32();
348 }
349
350 status_t setVolume(float leftVolume, float rightVolume)
351 {
352 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700353 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800354 data.writeFloat(leftVolume);
355 data.writeFloat(rightVolume);
356 remote()->transact(SET_VOLUME, data, &reply);
357 return reply.readInt32();
358 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700359
360 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700361 {
362 // Avoid doing any extra copy. The interface descriptor should
363 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700364 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700365 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700366
367 status_t setMetadataFilter(const Parcel& request)
368 {
369 Parcel reply;
370 // Avoid doing any extra copy of the request. The interface
371 // descriptor should have been set by MediaPlayer.java.
372 remote()->transact(SET_METADATA_FILTER, request, &reply);
373 return reply.readInt32();
374 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700375
376 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
377 {
378 Parcel request;
379 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
380 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
381 request.writeInt32(update_only);
382 request.writeInt32(apply_filter);
383 remote()->transact(GET_METADATA, request, reply);
384 return reply->readInt32();
385 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800386
Eric Laurent2beeb502010-07-16 07:43:46 -0700387 status_t setAuxEffectSendLevel(float level)
388 {
389 Parcel data, reply;
390 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
391 data.writeFloat(level);
392 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
393 return reply.readInt32();
394 }
395
396 status_t attachAuxEffect(int effectId)
397 {
398 Parcel data, reply;
399 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
400 data.writeInt32(effectId);
401 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
402 return reply.readInt32();
403 }
Glenn Kasten11731182011-02-08 17:26:17 -0800404
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700405 status_t setParameter(int key, const Parcel& request)
406 {
407 Parcel data, reply;
408 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
409 data.writeInt32(key);
410 if (request.dataSize() > 0) {
411 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
412 }
413 remote()->transact(SET_PARAMETER, data, &reply);
414 return reply.readInt32();
415 }
416
417 status_t getParameter(int key, Parcel *reply)
418 {
419 Parcel data;
420 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
421 data.writeInt32(key);
422 return remote()->transact(GET_PARAMETER, data, reply);
423 }
424
John Grossman44a7e422012-06-21 17:29:24 -0700425 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
426 {
John Grossmanc795b642012-02-22 15:38:35 -0800427 Parcel data, reply;
428 status_t err;
429
430 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
431 if (NULL != endpoint) {
432 data.writeInt32(sizeof(*endpoint));
433 data.write(endpoint, sizeof(*endpoint));
434 } else {
435 data.writeInt32(0);
436 }
437
438 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
439 if (OK != err) {
440 return err;
441 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800442 return reply.readInt32();
443 }
John Grossmanc795b642012-02-22 15:38:35 -0800444
Marco Nelissen6b74d672012-02-28 16:07:44 -0800445 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
446 Parcel data, reply;
447 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800448 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800449 data.writeStrongBinder(b);
450 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800451 return reply.readInt32();
452 }
John Grossman44a7e422012-06-21 17:29:24 -0700453
454 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
455 {
456 Parcel data, reply;
457 status_t err;
458
459 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
460 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
461
462 if ((OK != err) || (OK != (err = reply.readInt32()))) {
463 return err;
464 }
465
466 data.read(endpoint, sizeof(*endpoint));
467
468 return err;
469 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800470
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800471 virtual VolumeShaper::Status applyVolumeShaper(
472 const sp<VolumeShaper::Configuration>& configuration,
473 const sp<VolumeShaper::Operation>& operation) {
474 Parcel data, reply;
475 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
476
477 status_t tmp;
478 status_t status = configuration.get() == nullptr
479 ? data.writeInt32(0)
480 : (tmp = data.writeInt32(1)) != NO_ERROR
481 ? tmp : configuration->writeToParcel(&data);
482 if (status != NO_ERROR) {
483 return VolumeShaper::Status(status);
484 }
485
486 status = operation.get() == nullptr
487 ? status = data.writeInt32(0)
488 : (tmp = data.writeInt32(1)) != NO_ERROR
489 ? tmp : operation->writeToParcel(&data);
490 if (status != NO_ERROR) {
491 return VolumeShaper::Status(status);
492 }
493
494 int32_t remoteVolumeShaperStatus;
495 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
496 if (status == NO_ERROR) {
497 status = reply.readInt32(&remoteVolumeShaperStatus);
498 }
499 if (status != NO_ERROR) {
500 return VolumeShaper::Status(status);
501 }
502 return VolumeShaper::Status(remoteVolumeShaperStatus);
503 }
504
505 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
506 Parcel data, reply;
507 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
508
509 data.writeInt32(id);
510 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
511 if (status != NO_ERROR) {
512 return nullptr;
513 }
514 sp<VolumeShaper::State> state = new VolumeShaper::State();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700515 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800516 if (status != NO_ERROR) {
517 return nullptr;
518 }
519 return state;
520 }
521
Hassan Shojaniacefac142017-02-06 21:02:02 -0800522 // Modular DRM
523 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800524 {
525 Parcel data, reply;
526 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
527
528 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800529 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800530
531 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
532 if (status != OK) {
533 ALOGE("prepareDrm: binder call failed: %d", status);
534 return status;
535 }
536
537 return reply.readInt32();
538 }
539
540 status_t releaseDrm()
541 {
542 Parcel data, reply;
543 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
544
545 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
546 if (status != OK) {
547 ALOGE("releaseDrm: binder call failed: %d", status);
548 return status;
549 }
550
551 return reply.readInt32();
552 }
jiabin156c6872017-10-06 09:47:15 -0700553
554 status_t setOutputDevice(audio_port_handle_t deviceId)
555 {
556 Parcel data, reply;
557 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
558
559 data.writeInt32(deviceId);
560
561 status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
562 if (status != OK) {
563 ALOGE("setOutputDevice: binder call failed: %d", status);
564 return status;
565 }
566
567 return reply.readInt32();
568 }
569
Robert Wub7f8edc2024-11-04 19:54:38 +0000570 status_t getRoutedDeviceIds(DeviceIdVector& deviceIds)
jiabin156c6872017-10-06 09:47:15 -0700571 {
572 Parcel data, reply;
573 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Robert Wub7f8edc2024-11-04 19:54:38 +0000574 deviceIds.clear();
jiabin156c6872017-10-06 09:47:15 -0700575
Robert Wub7f8edc2024-11-04 19:54:38 +0000576 status_t status = remote()->transact(GET_ROUTED_DEVICE_IDS, data, &reply);
jiabin156c6872017-10-06 09:47:15 -0700577 if (status != OK) {
Robert Wub7f8edc2024-11-04 19:54:38 +0000578 ALOGE("getRoutedDeviceIds: binder call failed: %d", status);
jiabin156c6872017-10-06 09:47:15 -0700579 return status;
580 }
581
582 status = reply.readInt32();
Robert Wub7f8edc2024-11-04 19:54:38 +0000583 if (status == NO_ERROR) {
584 int size = reply.readInt32();
585 for (int i = 0; i < size; i++) {
586 deviceIds.push_back(reply.readInt32());
587 }
jiabin156c6872017-10-06 09:47:15 -0700588 }
589 return status;
590 }
591
592 status_t enableAudioDeviceCallback(bool enabled)
593 {
594 Parcel data, reply;
595 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
596
597 data.writeBool(enabled);
598
599 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
600 if (status != OK) {
601 ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
602 return status;
603 }
604
605 return reply.readInt32();
606 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800607};
608
niko56f0cc52009-06-22 08:49:52 -0700609IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800610
611// ----------------------------------------------------------------------
612
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800613status_t BnMediaPlayer::onTransact(
614 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
615{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700616 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800617 case DISCONNECT: {
618 CHECK_INTERFACE(IMediaPlayer, data, reply);
619 disconnect();
620 return NO_ERROR;
621 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100622 case SET_DATA_SOURCE_URL: {
623 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800624
625 sp<IMediaHTTPService> httpService;
626 if (data.readInt32()) {
627 httpService =
628 interface_cast<IMediaHTTPService>(data.readStrongBinder());
629 }
630
Dave Burked681bbb2011-08-30 14:39:17 +0100631 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800632 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800633 reply->writeInt32(BAD_VALUE);
634 return NO_ERROR;
635 }
Dave Burked681bbb2011-08-30 14:39:17 +0100636 KeyedVector<String8, String8> headers;
637 int32_t numHeaders = data.readInt32();
638 for (int i = 0; i < numHeaders; ++i) {
639 String8 key = data.readString8();
640 String8 value = data.readString8();
641 headers.add(key, value);
642 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800643 reply->writeInt32(setDataSource(
644 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100645 return NO_ERROR;
646 } break;
647 case SET_DATA_SOURCE_FD: {
648 CHECK_INTERFACE(IMediaPlayer, data, reply);
649 int fd = data.readFileDescriptor();
650 int64_t offset = data.readInt64();
651 int64_t length = data.readInt64();
652 reply->writeInt32(setDataSource(fd, offset, length));
653 return NO_ERROR;
654 }
655 case SET_DATA_SOURCE_STREAM: {
656 CHECK_INTERFACE(IMediaPlayer, data, reply);
657 sp<IStreamSource> source =
658 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800659 if (source == NULL) {
660 reply->writeInt32(BAD_VALUE);
661 } else {
662 reply->writeInt32(setDataSource(source));
663 }
Dave Burked681bbb2011-08-30 14:39:17 +0100664 return NO_ERROR;
665 }
Chris Watkins99f31602015-03-20 13:06:33 -0700666 case SET_DATA_SOURCE_CALLBACK: {
667 CHECK_INTERFACE(IMediaPlayer, data, reply);
668 sp<IDataSource> source =
669 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800670 if (source == NULL) {
671 reply->writeInt32(BAD_VALUE);
672 } else {
673 reply->writeInt32(setDataSource(source));
674 }
Chris Watkins99f31602015-03-20 13:06:33 -0700675 return NO_ERROR;
676 }
Byeongjo Park28225ab2019-01-24 20:31:19 +0900677 case SET_DATA_SOURCE_RTP: {
678 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar19829332020-03-17 08:13:10 -0700679 String8 rtpParams = data.readString8();
Byeongjo Park28225ab2019-01-24 20:31:19 +0900680 reply->writeInt32(setDataSource(rtpParams));
681 return NO_ERROR;
682 }
Glenn Kasten11731182011-02-08 17:26:17 -0800683 case SET_VIDEO_SURFACETEXTURE: {
684 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800685 sp<IGraphicBufferProducer> bufferProducer =
686 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
687 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800688 return NO_ERROR;
689 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700690 case SET_BUFFERING_SETTINGS: {
691 CHECK_INTERFACE(IMediaPlayer, data, reply);
692 BufferingSettings buffering;
Dongwon Kang79e33732019-01-25 16:35:26 -0800693 buffering.mInitialMarkMs = data.readInt32();
694 buffering.mResumePlaybackMarkMs = data.readInt32();
Wei Jiad399e7e2016-10-26 15:49:11 -0700695 reply->writeInt32(setBufferingSettings(buffering));
696 return NO_ERROR;
697 } break;
Wei Jia9bb38032017-03-23 18:00:38 -0700698 case GET_BUFFERING_SETTINGS: {
Wei Jiad399e7e2016-10-26 15:49:11 -0700699 CHECK_INTERFACE(IMediaPlayer, data, reply);
700 BufferingSettings buffering;
Wei Jia9bb38032017-03-23 18:00:38 -0700701 status_t err = getBufferingSettings(&buffering);
Wei Jiad399e7e2016-10-26 15:49:11 -0700702 reply->writeInt32(err);
703 if (err == OK) {
Dongwon Kang79e33732019-01-25 16:35:26 -0800704 reply->writeInt32(buffering.mInitialMarkMs);
705 reply->writeInt32(buffering.mResumePlaybackMarkMs);
Wei Jiad399e7e2016-10-26 15:49:11 -0700706 }
707 return NO_ERROR;
708 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800709 case PREPARE_ASYNC: {
710 CHECK_INTERFACE(IMediaPlayer, data, reply);
711 reply->writeInt32(prepareAsync());
712 return NO_ERROR;
713 } break;
714 case START: {
715 CHECK_INTERFACE(IMediaPlayer, data, reply);
716 reply->writeInt32(start());
717 return NO_ERROR;
718 } break;
719 case STOP: {
720 CHECK_INTERFACE(IMediaPlayer, data, reply);
721 reply->writeInt32(stop());
722 return NO_ERROR;
723 } break;
724 case IS_PLAYING: {
725 CHECK_INTERFACE(IMediaPlayer, data, reply);
726 bool state;
727 status_t ret = isPlaying(&state);
728 reply->writeInt32(state);
729 reply->writeInt32(ret);
730 return NO_ERROR;
731 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700732 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800733 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700734 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
735 rate.mSpeed = data.readFloat();
736 rate.mPitch = data.readFloat();
737 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
738 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
739 reply->writeInt32(setPlaybackSettings(rate));
740 return NO_ERROR;
741 } break;
742 case GET_PLAYBACK_SETTINGS: {
743 CHECK_INTERFACE(IMediaPlayer, data, reply);
744 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
745 status_t err = getPlaybackSettings(&rate);
746 reply->writeInt32(err);
747 if (err == OK) {
748 reply->writeFloat(rate.mSpeed);
749 reply->writeFloat(rate.mPitch);
750 reply->writeInt32((int32_t)rate.mFallbackMode);
751 reply->writeInt32((int32_t)rate.mStretchMode);
752 }
753 return NO_ERROR;
754 } break;
755 case SET_SYNC_SETTINGS: {
756 CHECK_INTERFACE(IMediaPlayer, data, reply);
757 AVSyncSettings sync;
758 sync.mSource = (AVSyncSource)data.readInt32();
759 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
760 sync.mTolerance = data.readFloat();
761 float videoFpsHint = data.readFloat();
762 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
763 return NO_ERROR;
764 } break;
765 case GET_SYNC_SETTINGS: {
766 CHECK_INTERFACE(IMediaPlayer, data, reply);
767 AVSyncSettings sync;
768 float videoFps;
769 status_t err = getSyncSettings(&sync, &videoFps);
770 reply->writeInt32(err);
771 if (err == OK) {
772 reply->writeInt32((int32_t)sync.mSource);
773 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
774 reply->writeFloat(sync.mTolerance);
775 reply->writeFloat(videoFps);
776 }
Wei Jia98160162015-02-04 17:01:11 -0800777 return NO_ERROR;
778 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800779 case PAUSE: {
780 CHECK_INTERFACE(IMediaPlayer, data, reply);
781 reply->writeInt32(pause());
782 return NO_ERROR;
783 } break;
784 case SEEK_TO: {
785 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700786 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800787 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
788 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800789 return NO_ERROR;
790 } break;
791 case GET_CURRENT_POSITION: {
792 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700793 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800794 status_t ret = getCurrentPosition(&msec);
795 reply->writeInt32(msec);
796 reply->writeInt32(ret);
797 return NO_ERROR;
798 } break;
799 case GET_DURATION: {
800 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700801 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800802 status_t ret = getDuration(&msec);
803 reply->writeInt32(msec);
804 reply->writeInt32(ret);
805 return NO_ERROR;
806 } break;
807 case RESET: {
808 CHECK_INTERFACE(IMediaPlayer, data, reply);
809 reply->writeInt32(reset());
810 return NO_ERROR;
811 } break;
Wei Jia52c28512017-09-13 18:17:51 -0700812 case NOTIFY_AT: {
813 CHECK_INTERFACE(IMediaPlayer, data, reply);
814 reply->writeInt32(notifyAt(data.readInt64()));
815 return NO_ERROR;
816 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800817 case SET_AUDIO_STREAM_TYPE: {
818 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800819 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800820 return NO_ERROR;
821 } break;
822 case SET_LOOPING: {
823 CHECK_INTERFACE(IMediaPlayer, data, reply);
824 reply->writeInt32(setLooping(data.readInt32()));
825 return NO_ERROR;
826 } break;
827 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700828 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700829 float leftVolume = data.readFloat();
830 float rightVolume = data.readFloat();
831 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800832 return NO_ERROR;
833 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700834 case INVOKE: {
835 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700836 status_t result = invoke(data, reply);
837 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700838 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700839 case SET_METADATA_FILTER: {
840 CHECK_INTERFACE(IMediaPlayer, data, reply);
841 reply->writeInt32(setMetadataFilter(data));
842 return NO_ERROR;
843 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700844 case GET_METADATA: {
845 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700846 bool update_only = static_cast<bool>(data.readInt32());
847 bool apply_filter = static_cast<bool>(data.readInt32());
848 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700849 reply->setDataPosition(0);
850 reply->writeInt32(retcode);
851 reply->setDataPosition(0);
852 return NO_ERROR;
853 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700854 case SET_AUX_EFFECT_SEND_LEVEL: {
855 CHECK_INTERFACE(IMediaPlayer, data, reply);
856 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
857 return NO_ERROR;
858 } break;
859 case ATTACH_AUX_EFFECT: {
860 CHECK_INTERFACE(IMediaPlayer, data, reply);
861 reply->writeInt32(attachAuxEffect(data.readInt32()));
862 return NO_ERROR;
863 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700864 case SET_PARAMETER: {
865 CHECK_INTERFACE(IMediaPlayer, data, reply);
866 int key = data.readInt32();
867
868 Parcel request;
869 if (data.dataAvail() > 0) {
870 request.appendFrom(
871 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
872 }
873 request.setDataPosition(0);
874 reply->writeInt32(setParameter(key, request));
875 return NO_ERROR;
876 } break;
877 case GET_PARAMETER: {
878 CHECK_INTERFACE(IMediaPlayer, data, reply);
879 return getParameter(data.readInt32(), reply);
880 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800881 case SET_RETRANSMIT_ENDPOINT: {
882 CHECK_INTERFACE(IMediaPlayer, data, reply);
883
884 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700885 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800886 int amt = data.readInt32();
887 if (amt == sizeof(endpoint)) {
888 data.read(&endpoint, sizeof(struct sockaddr_in));
889 reply->writeInt32(setRetransmitEndpoint(&endpoint));
890 } else {
891 reply->writeInt32(setRetransmitEndpoint(NULL));
892 }
John Grossman44a7e422012-06-21 17:29:24 -0700893
894 return NO_ERROR;
895 } break;
896 case GET_RETRANSMIT_ENDPOINT: {
897 CHECK_INTERFACE(IMediaPlayer, data, reply);
898
899 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700900 memset(&endpoint, 0, sizeof(endpoint));
John Grossman44a7e422012-06-21 17:29:24 -0700901 status_t res = getRetransmitEndpoint(&endpoint);
902
903 reply->writeInt32(res);
904 reply->write(&endpoint, sizeof(endpoint));
905
Marco Nelissen6b74d672012-02-28 16:07:44 -0800906 return NO_ERROR;
907 } break;
908 case SET_NEXT_PLAYER: {
909 CHECK_INTERFACE(IMediaPlayer, data, reply);
910 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700911
John Grossmanc795b642012-02-22 15:38:35 -0800912 return NO_ERROR;
913 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800914
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800915 case APPLY_VOLUME_SHAPER: {
916 CHECK_INTERFACE(IMediaPlayer, data, reply);
917 sp<VolumeShaper::Configuration> configuration;
918 sp<VolumeShaper::Operation> operation;
919
920 int32_t present;
921 status_t status = data.readInt32(&present);
922 if (status == NO_ERROR && present != 0) {
923 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700924 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800925 }
926 if (status == NO_ERROR) {
927 status = data.readInt32(&present);
928 }
929 if (status == NO_ERROR && present != 0) {
930 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700931 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800932 }
933 if (status == NO_ERROR) {
934 status = (status_t)applyVolumeShaper(configuration, operation);
935 }
936 reply->writeInt32(status);
937 return NO_ERROR;
938 } break;
939 case GET_VOLUME_SHAPER_STATE: {
940 CHECK_INTERFACE(IMediaPlayer, data, reply);
941 int id;
942 status_t status = data.readInt32(&id);
943 if (status == NO_ERROR) {
944 sp<VolumeShaper::State> state = getVolumeShaperState(id);
945 if (state.get() != nullptr) {
946 status = state->writeToParcel(reply);
947 }
948 }
949 return NO_ERROR;
950 } break;
951
Hassan Shojaniacefac142017-02-06 21:02:02 -0800952 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -0800953 case PREPARE_DRM: {
954 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800955
andrewlewis35c7db92020-08-14 10:41:13 +0000956 uint8_t uuid[16] = {};
Hassan Shojania071437a2017-01-23 09:19:40 -0800957 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -0800958 Vector<uint8_t> drmSessionId;
Santiago Seifert42a97f52021-02-08 16:09:38 +0000959 status_t status = readVector(data, drmSessionId);
960 if (status != OK) {
961 return status;
962 }
Hassan Shojaniacefac142017-02-06 21:02:02 -0800963 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800964 reply->writeInt32(result);
965 return OK;
966 }
967 case RELEASE_DRM: {
968 CHECK_INTERFACE(IMediaPlayer, data, reply);
969
970 uint32_t result = releaseDrm();
971 reply->writeInt32(result);
972 return OK;
973 }
jiabin156c6872017-10-06 09:47:15 -0700974
975 // AudioRouting
976 case SET_OUTPUT_DEVICE: {
977 CHECK_INTERFACE(IMediaPlayer, data, reply);
978 int deviceId;
979 status_t status = data.readInt32(&deviceId);
980 if (status == NO_ERROR) {
981 reply->writeInt32(setOutputDevice(deviceId));
982 } else {
983 reply->writeInt32(BAD_VALUE);
984 }
985 return NO_ERROR;
986 }
Robert Wub7f8edc2024-11-04 19:54:38 +0000987 case GET_ROUTED_DEVICE_IDS: {
jiabin156c6872017-10-06 09:47:15 -0700988 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Wub7f8edc2024-11-04 19:54:38 +0000989 DeviceIdVector deviceIds;
990 status_t ret = getRoutedDeviceIds(deviceIds);
jiabin156c6872017-10-06 09:47:15 -0700991 reply->writeInt32(ret);
992 if (ret == NO_ERROR) {
Robert Wub7f8edc2024-11-04 19:54:38 +0000993 reply->writeInt32(deviceIds.size());
994 for (auto deviceId : deviceIds) {
995 reply->writeInt32(deviceId);
996 }
jiabin156c6872017-10-06 09:47:15 -0700997 }
998 return NO_ERROR;
999 } break;
1000 case ENABLE_AUDIO_DEVICE_CALLBACK: {
1001 CHECK_INTERFACE(IMediaPlayer, data, reply);
1002 bool enabled;
1003 status_t status = data.readBool(&enabled);
1004 if (status == NO_ERROR) {
1005 reply->writeInt32(enableAudioDeviceCallback(enabled));
1006 } else {
1007 reply->writeInt32(BAD_VALUE);
1008 }
1009 return NO_ERROR;
1010 } break;
1011
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001012 default:
1013 return BBinder::onTransact(code, data, reply, flags);
1014 }
1015}
1016
1017// ----------------------------------------------------------------------------
1018
Glenn Kasten40bc9062015-03-20 09:09:33 -07001019} // namespace android