blob: 189fef0fa4326c7703a089078cbfe4cf37020627 [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
Marco Nelissendab79b32019-11-18 08:25:47 -080022#include <android/IDataSource.h>
Santiago Seifert713642e2021-02-08 16:09:38 +000023#include <binder/IPCThreadState.h>
Mathias Agopian75624082009-05-19 19:08:10 -070024#include <binder/Parcel.h>
Marco Nelissendab79b32019-11-18 08:25:47 -080025#include <gui/IGraphicBufferProducer.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070026#include <media/AudioResamplerPublic.h>
27#include <media/AVSyncSettings.h>
Wei Jiad399e7e2016-10-26 15:49:11 -070028#include <media/BufferingSettings.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>
Dave Burked681bbb2011-08-30 14:39:17 +010032#include <utils/String8.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080033
34namespace android {
35
Ivan Lozano8cf3a072017-08-09 09:01:33 -070036using media::VolumeShaper;
37
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080038enum {
39 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
Dave Burked681bbb2011-08-30 14:39:17 +010040 SET_DATA_SOURCE_URL,
41 SET_DATA_SOURCE_FD,
42 SET_DATA_SOURCE_STREAM,
Chris Watkins99f31602015-03-20 13:06:33 -070043 SET_DATA_SOURCE_CALLBACK,
Byeongjo Park28225ab2019-01-24 20:31:19 +090044 SET_DATA_SOURCE_RTP,
Wei Jiad399e7e2016-10-26 15:49:11 -070045 SET_BUFFERING_SETTINGS,
Wei Jia9bb38032017-03-23 18:00:38 -070046 GET_BUFFERING_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080047 PREPARE_ASYNC,
48 START,
49 STOP,
50 IS_PLAYING,
Lajos Molnar3a474aa2015-04-24 17:10:07 -070051 SET_PLAYBACK_SETTINGS,
52 GET_PLAYBACK_SETTINGS,
53 SET_SYNC_SETTINGS,
54 GET_SYNC_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080055 PAUSE,
56 SEEK_TO,
57 GET_CURRENT_POSITION,
58 GET_DURATION,
59 RESET,
Wei Jia52c28512017-09-13 18:17:51 -070060 NOTIFY_AT,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080061 SET_AUDIO_STREAM_TYPE,
62 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070063 SET_VOLUME,
64 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070065 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070066 GET_METADATA,
Eric Laurent2beeb502010-07-16 07:43:46 -070067 SET_AUX_EFFECT_SEND_LEVEL,
Glenn Kasten11731182011-02-08 17:26:17 -080068 ATTACH_AUX_EFFECT,
69 SET_VIDEO_SURFACETEXTURE,
Gloria Wang4f9e47f2011-04-25 17:28:22 -070070 SET_PARAMETER,
71 GET_PARAMETER,
John Grossmanc795b642012-02-22 15:38:35 -080072 SET_RETRANSMIT_ENDPOINT,
John Grossman44a7e422012-06-21 17:29:24 -070073 GET_RETRANSMIT_ENDPOINT,
Marco Nelissen6b74d672012-02-28 16:07:44 -080074 SET_NEXT_PLAYER,
Andy Hung9fc8b5c2017-01-24 13:36:48 -080075 APPLY_VOLUME_SHAPER,
76 GET_VOLUME_SHAPER_STATE,
Hassan Shojaniacefac142017-02-06 21:02:02 -080077 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -080078 PREPARE_DRM,
79 RELEASE_DRM,
jiabin156c6872017-10-06 09:47:15 -070080 // AudioRouting
81 SET_OUTPUT_DEVICE,
82 GET_ROUTED_DEVICE_ID,
83 ENABLE_AUDIO_DEVICE_CALLBACK,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080084};
85
Hassan Shojania071437a2017-01-23 09:19:40 -080086// ModDrm helpers
Santiago Seifert713642e2021-02-08 16:09:38 +000087static status_t readVector(const Parcel& reply, Vector<uint8_t>& vector) {
88 uint32_t size = 0;
89 status_t status = reply.readUint32(&size);
90 if (status == OK) {
91 status = size <= reply.dataAvail() ? OK : BAD_VALUE;
92 }
93 if (status == OK) {
94 status = vector.insertAt((size_t) 0, size) >= 0 ? OK : NO_MEMORY;
95 }
96 if (status == OK) {
97 status = reply.read(vector.editArray(), size);
98 }
99 if (status != OK) {
100 char errorMsg[100];
101 char buganizerId[] = "173720767";
102 snprintf(errorMsg,
103 sizeof(errorMsg),
104 "%s: failed to read array. Size: %d, status: %d.",
105 __func__,
106 size,
107 status);
108 android_errorWriteWithInfoLog(
109 /* safetyNet tag= */ 0x534e4554,
110 buganizerId,
111 IPCThreadState::self()->getCallingUid(),
112 errorMsg,
113 strlen(errorMsg));
114 ALOGE("%s (b/%s)", errorMsg, buganizerId);
115 }
116 return status;
Hassan Shojania071437a2017-01-23 09:19:40 -0800117}
118
119static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
120 data.writeUint32(vector.size());
121 data.write(vector.array(), vector.size());
122}
123
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800124class BpMediaPlayer: public BpInterface<IMediaPlayer>
125{
126public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -0700127 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800128 : BpInterface<IMediaPlayer>(impl)
129 {
130 }
131
132 // disconnect from media player service
133 void disconnect()
134 {
135 Parcel data, reply;
136 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
137 remote()->transact(DISCONNECT, data, &reply);
138 }
139
Andreas Huber1b86fe02014-01-29 11:13:26 -0800140 status_t setDataSource(
141 const sp<IMediaHTTPService> &httpService,
142 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +0100143 const KeyedVector<String8, String8>* headers)
144 {
145 Parcel data, reply;
146 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800147 data.writeInt32(httpService != NULL);
148 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800149 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800150 }
Dave Burked681bbb2011-08-30 14:39:17 +0100151 data.writeCString(url);
152 if (headers == NULL) {
153 data.writeInt32(0);
154 } else {
155 // serialize the headers
156 data.writeInt32(headers->size());
157 for (size_t i = 0; i < headers->size(); ++i) {
158 data.writeString8(headers->keyAt(i));
159 data.writeString8(headers->valueAt(i));
160 }
161 }
162 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
163 return reply.readInt32();
164 }
165
166 status_t setDataSource(int fd, int64_t offset, int64_t length) {
167 Parcel data, reply;
168 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
169 data.writeFileDescriptor(fd);
170 data.writeInt64(offset);
171 data.writeInt64(length);
172 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
173 return reply.readInt32();
174 }
175
176 status_t setDataSource(const sp<IStreamSource> &source) {
177 Parcel data, reply;
178 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800179 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700180 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100181 return reply.readInt32();
182 }
183
Chris Watkins99f31602015-03-20 13:06:33 -0700184 status_t setDataSource(const sp<IDataSource> &source) {
185 Parcel data, reply;
186 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
187 data.writeStrongBinder(IInterface::asBinder(source));
188 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
189 return reply.readInt32();
190 }
191
Byeongjo Park28225ab2019-01-24 20:31:19 +0900192 status_t setDataSource(const String8& rtpParams) {
193 Parcel data, reply;
194 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
195 data.writeString8(rtpParams);
196 remote()->transact(SET_DATA_SOURCE_RTP, data, &reply);
197
198 return reply.readInt32();
199 }
200
Andy McFadden8ba01022012-12-18 09:46:54 -0800201 // pass the buffered IGraphicBufferProducer to the media player service
202 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800203 {
204 Parcel data, reply;
205 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800206 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800207 data.writeStrongBinder(b);
208 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
209 return reply.readInt32();
210 }
211
Wei Jiad399e7e2016-10-26 15:49:11 -0700212 status_t setBufferingSettings(const BufferingSettings& buffering)
213 {
214 Parcel data, reply;
215 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Dongwon Kang79e33732019-01-25 16:35:26 -0800216 data.writeInt32(buffering.mInitialMarkMs);
217 data.writeInt32(buffering.mResumePlaybackMarkMs);
Wei Jiad399e7e2016-10-26 15:49:11 -0700218 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
219 return reply.readInt32();
220 }
221
Wei Jia9bb38032017-03-23 18:00:38 -0700222 status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */)
Wei Jiad399e7e2016-10-26 15:49:11 -0700223 {
224 if (buffering == nullptr) {
225 return BAD_VALUE;
226 }
227 Parcel data, reply;
228 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Wei Jia9bb38032017-03-23 18:00:38 -0700229 remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
Wei Jiad399e7e2016-10-26 15:49:11 -0700230 status_t err = reply.readInt32();
231 if (err == OK) {
Dongwon Kang79e33732019-01-25 16:35:26 -0800232 buffering->mInitialMarkMs = reply.readInt32();
233 buffering->mResumePlaybackMarkMs = reply.readInt32();
Wei Jiad399e7e2016-10-26 15:49:11 -0700234 }
235 return err;
236 }
237
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800238 status_t prepareAsync()
239 {
240 Parcel data, reply;
241 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
242 remote()->transact(PREPARE_ASYNC, data, &reply);
243 return reply.readInt32();
244 }
245
246 status_t start()
247 {
248 Parcel data, reply;
249 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
250 remote()->transact(START, data, &reply);
251 return reply.readInt32();
252 }
253
254 status_t stop()
255 {
256 Parcel data, reply;
257 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
258 remote()->transact(STOP, data, &reply);
259 return reply.readInt32();
260 }
261
262 status_t isPlaying(bool* state)
263 {
264 Parcel data, reply;
265 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
266 remote()->transact(IS_PLAYING, data, &reply);
267 *state = reply.readInt32();
268 return reply.readInt32();
269 }
270
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700271 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800272 {
273 Parcel data, reply;
274 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700275 data.writeFloat(rate.mSpeed);
276 data.writeFloat(rate.mPitch);
277 data.writeInt32((int32_t)rate.mFallbackMode);
278 data.writeInt32((int32_t)rate.mStretchMode);
279 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800280 return reply.readInt32();
281 }
282
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700283 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
284 {
285 Parcel data, reply;
286 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
287 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
288 status_t err = reply.readInt32();
289 if (err == OK) {
290 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
291 rate->mSpeed = reply.readFloat();
292 rate->mPitch = reply.readFloat();
293 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
294 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
295 }
296 return err;
297 }
298
299 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
300 {
301 Parcel data, reply;
302 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
303 data.writeInt32((int32_t)sync.mSource);
304 data.writeInt32((int32_t)sync.mAudioAdjustMode);
305 data.writeFloat(sync.mTolerance);
306 data.writeFloat(videoFpsHint);
307 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
308 return reply.readInt32();
309 }
310
311 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
312 {
313 Parcel data, reply;
314 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
315 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
316 status_t err = reply.readInt32();
317 if (err == OK) {
318 AVSyncSettings settings;
319 settings.mSource = (AVSyncSource)reply.readInt32();
320 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
321 settings.mTolerance = reply.readFloat();
322 *sync = settings;
323 *videoFps = reply.readFloat();
324 }
325 return err;
326 }
327
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800328 status_t pause()
329 {
330 Parcel data, reply;
331 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
332 remote()->transact(PAUSE, data, &reply);
333 return reply.readInt32();
334 }
335
Wei Jiac5de0912016-11-18 10:22:14 -0800336 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800337 {
338 Parcel data, reply;
339 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
340 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800341 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800342 remote()->transact(SEEK_TO, data, &reply);
343 return reply.readInt32();
344 }
345
346 status_t getCurrentPosition(int* msec)
347 {
348 Parcel data, reply;
349 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
350 remote()->transact(GET_CURRENT_POSITION, data, &reply);
351 *msec = reply.readInt32();
352 return reply.readInt32();
353 }
354
355 status_t getDuration(int* msec)
356 {
357 Parcel data, reply;
358 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
359 remote()->transact(GET_DURATION, data, &reply);
360 *msec = reply.readInt32();
361 return reply.readInt32();
362 }
363
364 status_t reset()
365 {
366 Parcel data, reply;
367 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
368 remote()->transact(RESET, data, &reply);
369 return reply.readInt32();
370 }
371
Wei Jia52c28512017-09-13 18:17:51 -0700372 status_t notifyAt(int64_t mediaTimeUs)
373 {
374 Parcel data, reply;
375 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
376 data.writeInt64(mediaTimeUs);
377 remote()->transact(NOTIFY_AT, data, &reply);
378 return reply.readInt32();
379 }
380
Glenn Kastenfff6d712012-01-12 16:38:12 -0800381 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800382 {
383 Parcel data, reply;
384 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800385 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800386 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
387 return reply.readInt32();
388 }
389
390 status_t setLooping(int loop)
391 {
392 Parcel data, reply;
393 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
394 data.writeInt32(loop);
395 remote()->transact(SET_LOOPING, data, &reply);
396 return reply.readInt32();
397 }
398
399 status_t setVolume(float leftVolume, float rightVolume)
400 {
401 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700402 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800403 data.writeFloat(leftVolume);
404 data.writeFloat(rightVolume);
405 remote()->transact(SET_VOLUME, data, &reply);
406 return reply.readInt32();
407 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700408
409 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700410 {
411 // Avoid doing any extra copy. The interface descriptor should
412 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700413 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700414 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700415
416 status_t setMetadataFilter(const Parcel& request)
417 {
418 Parcel reply;
419 // Avoid doing any extra copy of the request. The interface
420 // descriptor should have been set by MediaPlayer.java.
421 remote()->transact(SET_METADATA_FILTER, request, &reply);
422 return reply.readInt32();
423 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700424
425 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
426 {
427 Parcel request;
428 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
429 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
430 request.writeInt32(update_only);
431 request.writeInt32(apply_filter);
432 remote()->transact(GET_METADATA, request, reply);
433 return reply->readInt32();
434 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800435
Eric Laurent2beeb502010-07-16 07:43:46 -0700436 status_t setAuxEffectSendLevel(float level)
437 {
438 Parcel data, reply;
439 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
440 data.writeFloat(level);
441 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
442 return reply.readInt32();
443 }
444
445 status_t attachAuxEffect(int effectId)
446 {
447 Parcel data, reply;
448 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
449 data.writeInt32(effectId);
450 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
451 return reply.readInt32();
452 }
Glenn Kasten11731182011-02-08 17:26:17 -0800453
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700454 status_t setParameter(int key, const Parcel& request)
455 {
456 Parcel data, reply;
457 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
458 data.writeInt32(key);
459 if (request.dataSize() > 0) {
460 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
461 }
462 remote()->transact(SET_PARAMETER, data, &reply);
463 return reply.readInt32();
464 }
465
466 status_t getParameter(int key, Parcel *reply)
467 {
468 Parcel data;
469 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
470 data.writeInt32(key);
471 return remote()->transact(GET_PARAMETER, data, reply);
472 }
473
John Grossman44a7e422012-06-21 17:29:24 -0700474 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
475 {
John Grossmanc795b642012-02-22 15:38:35 -0800476 Parcel data, reply;
477 status_t err;
478
479 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
480 if (NULL != endpoint) {
481 data.writeInt32(sizeof(*endpoint));
482 data.write(endpoint, sizeof(*endpoint));
483 } else {
484 data.writeInt32(0);
485 }
486
487 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
488 if (OK != err) {
489 return err;
490 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800491 return reply.readInt32();
492 }
John Grossmanc795b642012-02-22 15:38:35 -0800493
Marco Nelissen6b74d672012-02-28 16:07:44 -0800494 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
495 Parcel data, reply;
496 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800497 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800498 data.writeStrongBinder(b);
499 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800500 return reply.readInt32();
501 }
John Grossman44a7e422012-06-21 17:29:24 -0700502
503 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
504 {
505 Parcel data, reply;
506 status_t err;
507
508 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
509 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
510
511 if ((OK != err) || (OK != (err = reply.readInt32()))) {
512 return err;
513 }
514
515 data.read(endpoint, sizeof(*endpoint));
516
517 return err;
518 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800519
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800520 virtual VolumeShaper::Status applyVolumeShaper(
521 const sp<VolumeShaper::Configuration>& configuration,
522 const sp<VolumeShaper::Operation>& operation) {
523 Parcel data, reply;
524 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
525
526 status_t tmp;
527 status_t status = configuration.get() == nullptr
528 ? data.writeInt32(0)
529 : (tmp = data.writeInt32(1)) != NO_ERROR
530 ? tmp : configuration->writeToParcel(&data);
531 if (status != NO_ERROR) {
532 return VolumeShaper::Status(status);
533 }
534
535 status = operation.get() == nullptr
536 ? status = data.writeInt32(0)
537 : (tmp = data.writeInt32(1)) != NO_ERROR
538 ? tmp : operation->writeToParcel(&data);
539 if (status != NO_ERROR) {
540 return VolumeShaper::Status(status);
541 }
542
543 int32_t remoteVolumeShaperStatus;
544 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
545 if (status == NO_ERROR) {
546 status = reply.readInt32(&remoteVolumeShaperStatus);
547 }
548 if (status != NO_ERROR) {
549 return VolumeShaper::Status(status);
550 }
551 return VolumeShaper::Status(remoteVolumeShaperStatus);
552 }
553
554 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
555 Parcel data, reply;
556 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
557
558 data.writeInt32(id);
559 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
560 if (status != NO_ERROR) {
561 return nullptr;
562 }
563 sp<VolumeShaper::State> state = new VolumeShaper::State();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700564 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800565 if (status != NO_ERROR) {
566 return nullptr;
567 }
568 return state;
569 }
570
Hassan Shojaniacefac142017-02-06 21:02:02 -0800571 // Modular DRM
572 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800573 {
574 Parcel data, reply;
575 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
576
577 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800578 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800579
580 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
581 if (status != OK) {
582 ALOGE("prepareDrm: binder call failed: %d", status);
583 return status;
584 }
585
586 return reply.readInt32();
587 }
588
589 status_t releaseDrm()
590 {
591 Parcel data, reply;
592 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
593
594 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
595 if (status != OK) {
596 ALOGE("releaseDrm: binder call failed: %d", status);
597 return status;
598 }
599
600 return reply.readInt32();
601 }
jiabin156c6872017-10-06 09:47:15 -0700602
603 status_t setOutputDevice(audio_port_handle_t deviceId)
604 {
605 Parcel data, reply;
606 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
607
608 data.writeInt32(deviceId);
609
610 status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
611 if (status != OK) {
612 ALOGE("setOutputDevice: binder call failed: %d", status);
613 return status;
614 }
615
616 return reply.readInt32();
617 }
618
619 status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
620 {
621 Parcel data, reply;
622 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
623
624 status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
625 if (status != OK) {
626 ALOGE("getRoutedDeviceid: binder call failed: %d", status);
627 *deviceId = AUDIO_PORT_HANDLE_NONE;
628 return status;
629 }
630
631 status = reply.readInt32();
632 if (status != NO_ERROR) {
633 *deviceId = AUDIO_PORT_HANDLE_NONE;
634 } else {
635 *deviceId = reply.readInt32();
636 }
637 return status;
638 }
639
640 status_t enableAudioDeviceCallback(bool enabled)
641 {
642 Parcel data, reply;
643 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
644
645 data.writeBool(enabled);
646
647 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
648 if (status != OK) {
649 ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
650 return status;
651 }
652
653 return reply.readInt32();
654 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800655};
656
niko56f0cc52009-06-22 08:49:52 -0700657IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800658
659// ----------------------------------------------------------------------
660
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800661status_t BnMediaPlayer::onTransact(
662 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
663{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700664 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800665 case DISCONNECT: {
666 CHECK_INTERFACE(IMediaPlayer, data, reply);
667 disconnect();
668 return NO_ERROR;
669 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100670 case SET_DATA_SOURCE_URL: {
671 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800672
673 sp<IMediaHTTPService> httpService;
674 if (data.readInt32()) {
675 httpService =
676 interface_cast<IMediaHTTPService>(data.readStrongBinder());
677 }
678
Dave Burked681bbb2011-08-30 14:39:17 +0100679 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800680 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800681 reply->writeInt32(BAD_VALUE);
682 return NO_ERROR;
683 }
Dave Burked681bbb2011-08-30 14:39:17 +0100684 KeyedVector<String8, String8> headers;
685 int32_t numHeaders = data.readInt32();
686 for (int i = 0; i < numHeaders; ++i) {
687 String8 key = data.readString8();
688 String8 value = data.readString8();
689 headers.add(key, value);
690 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800691 reply->writeInt32(setDataSource(
692 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100693 return NO_ERROR;
694 } break;
695 case SET_DATA_SOURCE_FD: {
696 CHECK_INTERFACE(IMediaPlayer, data, reply);
697 int fd = data.readFileDescriptor();
698 int64_t offset = data.readInt64();
699 int64_t length = data.readInt64();
700 reply->writeInt32(setDataSource(fd, offset, length));
701 return NO_ERROR;
702 }
703 case SET_DATA_SOURCE_STREAM: {
704 CHECK_INTERFACE(IMediaPlayer, data, reply);
705 sp<IStreamSource> source =
706 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800707 if (source == NULL) {
708 reply->writeInt32(BAD_VALUE);
709 } else {
710 reply->writeInt32(setDataSource(source));
711 }
Dave Burked681bbb2011-08-30 14:39:17 +0100712 return NO_ERROR;
713 }
Chris Watkins99f31602015-03-20 13:06:33 -0700714 case SET_DATA_SOURCE_CALLBACK: {
715 CHECK_INTERFACE(IMediaPlayer, data, reply);
716 sp<IDataSource> source =
717 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800718 if (source == NULL) {
719 reply->writeInt32(BAD_VALUE);
720 } else {
721 reply->writeInt32(setDataSource(source));
722 }
Chris Watkins99f31602015-03-20 13:06:33 -0700723 return NO_ERROR;
724 }
Byeongjo Park28225ab2019-01-24 20:31:19 +0900725 case SET_DATA_SOURCE_RTP: {
726 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar19829332020-03-17 08:13:10 -0700727 String8 rtpParams = data.readString8();
Byeongjo Park28225ab2019-01-24 20:31:19 +0900728 reply->writeInt32(setDataSource(rtpParams));
729 return NO_ERROR;
730 }
Glenn Kasten11731182011-02-08 17:26:17 -0800731 case SET_VIDEO_SURFACETEXTURE: {
732 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800733 sp<IGraphicBufferProducer> bufferProducer =
734 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
735 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800736 return NO_ERROR;
737 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700738 case SET_BUFFERING_SETTINGS: {
739 CHECK_INTERFACE(IMediaPlayer, data, reply);
740 BufferingSettings buffering;
Dongwon Kang79e33732019-01-25 16:35:26 -0800741 buffering.mInitialMarkMs = data.readInt32();
742 buffering.mResumePlaybackMarkMs = data.readInt32();
Wei Jiad399e7e2016-10-26 15:49:11 -0700743 reply->writeInt32(setBufferingSettings(buffering));
744 return NO_ERROR;
745 } break;
Wei Jia9bb38032017-03-23 18:00:38 -0700746 case GET_BUFFERING_SETTINGS: {
Wei Jiad399e7e2016-10-26 15:49:11 -0700747 CHECK_INTERFACE(IMediaPlayer, data, reply);
748 BufferingSettings buffering;
Wei Jia9bb38032017-03-23 18:00:38 -0700749 status_t err = getBufferingSettings(&buffering);
Wei Jiad399e7e2016-10-26 15:49:11 -0700750 reply->writeInt32(err);
751 if (err == OK) {
Dongwon Kang79e33732019-01-25 16:35:26 -0800752 reply->writeInt32(buffering.mInitialMarkMs);
753 reply->writeInt32(buffering.mResumePlaybackMarkMs);
Wei Jiad399e7e2016-10-26 15:49:11 -0700754 }
755 return NO_ERROR;
756 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800757 case PREPARE_ASYNC: {
758 CHECK_INTERFACE(IMediaPlayer, data, reply);
759 reply->writeInt32(prepareAsync());
760 return NO_ERROR;
761 } break;
762 case START: {
763 CHECK_INTERFACE(IMediaPlayer, data, reply);
764 reply->writeInt32(start());
765 return NO_ERROR;
766 } break;
767 case STOP: {
768 CHECK_INTERFACE(IMediaPlayer, data, reply);
769 reply->writeInt32(stop());
770 return NO_ERROR;
771 } break;
772 case IS_PLAYING: {
773 CHECK_INTERFACE(IMediaPlayer, data, reply);
774 bool state;
775 status_t ret = isPlaying(&state);
776 reply->writeInt32(state);
777 reply->writeInt32(ret);
778 return NO_ERROR;
779 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700780 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800781 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700782 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
783 rate.mSpeed = data.readFloat();
784 rate.mPitch = data.readFloat();
785 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
786 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
787 reply->writeInt32(setPlaybackSettings(rate));
788 return NO_ERROR;
789 } break;
790 case GET_PLAYBACK_SETTINGS: {
791 CHECK_INTERFACE(IMediaPlayer, data, reply);
792 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
793 status_t err = getPlaybackSettings(&rate);
794 reply->writeInt32(err);
795 if (err == OK) {
796 reply->writeFloat(rate.mSpeed);
797 reply->writeFloat(rate.mPitch);
798 reply->writeInt32((int32_t)rate.mFallbackMode);
799 reply->writeInt32((int32_t)rate.mStretchMode);
800 }
801 return NO_ERROR;
802 } break;
803 case SET_SYNC_SETTINGS: {
804 CHECK_INTERFACE(IMediaPlayer, data, reply);
805 AVSyncSettings sync;
806 sync.mSource = (AVSyncSource)data.readInt32();
807 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
808 sync.mTolerance = data.readFloat();
809 float videoFpsHint = data.readFloat();
810 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
811 return NO_ERROR;
812 } break;
813 case GET_SYNC_SETTINGS: {
814 CHECK_INTERFACE(IMediaPlayer, data, reply);
815 AVSyncSettings sync;
816 float videoFps;
817 status_t err = getSyncSettings(&sync, &videoFps);
818 reply->writeInt32(err);
819 if (err == OK) {
820 reply->writeInt32((int32_t)sync.mSource);
821 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
822 reply->writeFloat(sync.mTolerance);
823 reply->writeFloat(videoFps);
824 }
Wei Jia98160162015-02-04 17:01:11 -0800825 return NO_ERROR;
826 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800827 case PAUSE: {
828 CHECK_INTERFACE(IMediaPlayer, data, reply);
829 reply->writeInt32(pause());
830 return NO_ERROR;
831 } break;
832 case SEEK_TO: {
833 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700834 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800835 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
836 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800837 return NO_ERROR;
838 } break;
839 case GET_CURRENT_POSITION: {
840 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700841 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800842 status_t ret = getCurrentPosition(&msec);
843 reply->writeInt32(msec);
844 reply->writeInt32(ret);
845 return NO_ERROR;
846 } break;
847 case GET_DURATION: {
848 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700849 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800850 status_t ret = getDuration(&msec);
851 reply->writeInt32(msec);
852 reply->writeInt32(ret);
853 return NO_ERROR;
854 } break;
855 case RESET: {
856 CHECK_INTERFACE(IMediaPlayer, data, reply);
857 reply->writeInt32(reset());
858 return NO_ERROR;
859 } break;
Wei Jia52c28512017-09-13 18:17:51 -0700860 case NOTIFY_AT: {
861 CHECK_INTERFACE(IMediaPlayer, data, reply);
862 reply->writeInt32(notifyAt(data.readInt64()));
863 return NO_ERROR;
864 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800865 case SET_AUDIO_STREAM_TYPE: {
866 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800867 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800868 return NO_ERROR;
869 } break;
870 case SET_LOOPING: {
871 CHECK_INTERFACE(IMediaPlayer, data, reply);
872 reply->writeInt32(setLooping(data.readInt32()));
873 return NO_ERROR;
874 } break;
875 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700876 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700877 float leftVolume = data.readFloat();
878 float rightVolume = data.readFloat();
879 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800880 return NO_ERROR;
881 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700882 case INVOKE: {
883 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700884 status_t result = invoke(data, reply);
885 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700886 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700887 case SET_METADATA_FILTER: {
888 CHECK_INTERFACE(IMediaPlayer, data, reply);
889 reply->writeInt32(setMetadataFilter(data));
890 return NO_ERROR;
891 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700892 case GET_METADATA: {
893 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700894 bool update_only = static_cast<bool>(data.readInt32());
895 bool apply_filter = static_cast<bool>(data.readInt32());
896 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700897 reply->setDataPosition(0);
898 reply->writeInt32(retcode);
899 reply->setDataPosition(0);
900 return NO_ERROR;
901 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700902 case SET_AUX_EFFECT_SEND_LEVEL: {
903 CHECK_INTERFACE(IMediaPlayer, data, reply);
904 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
905 return NO_ERROR;
906 } break;
907 case ATTACH_AUX_EFFECT: {
908 CHECK_INTERFACE(IMediaPlayer, data, reply);
909 reply->writeInt32(attachAuxEffect(data.readInt32()));
910 return NO_ERROR;
911 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700912 case SET_PARAMETER: {
913 CHECK_INTERFACE(IMediaPlayer, data, reply);
914 int key = data.readInt32();
915
916 Parcel request;
917 if (data.dataAvail() > 0) {
918 request.appendFrom(
919 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
920 }
921 request.setDataPosition(0);
922 reply->writeInt32(setParameter(key, request));
923 return NO_ERROR;
924 } break;
925 case GET_PARAMETER: {
926 CHECK_INTERFACE(IMediaPlayer, data, reply);
927 return getParameter(data.readInt32(), reply);
928 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800929 case SET_RETRANSMIT_ENDPOINT: {
930 CHECK_INTERFACE(IMediaPlayer, data, reply);
931
932 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700933 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800934 int amt = data.readInt32();
935 if (amt == sizeof(endpoint)) {
936 data.read(&endpoint, sizeof(struct sockaddr_in));
937 reply->writeInt32(setRetransmitEndpoint(&endpoint));
938 } else {
939 reply->writeInt32(setRetransmitEndpoint(NULL));
940 }
John Grossman44a7e422012-06-21 17:29:24 -0700941
942 return NO_ERROR;
943 } break;
944 case GET_RETRANSMIT_ENDPOINT: {
945 CHECK_INTERFACE(IMediaPlayer, data, reply);
946
947 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700948 memset(&endpoint, 0, sizeof(endpoint));
John Grossman44a7e422012-06-21 17:29:24 -0700949 status_t res = getRetransmitEndpoint(&endpoint);
950
951 reply->writeInt32(res);
952 reply->write(&endpoint, sizeof(endpoint));
953
Marco Nelissen6b74d672012-02-28 16:07:44 -0800954 return NO_ERROR;
955 } break;
956 case SET_NEXT_PLAYER: {
957 CHECK_INTERFACE(IMediaPlayer, data, reply);
958 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700959
John Grossmanc795b642012-02-22 15:38:35 -0800960 return NO_ERROR;
961 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800962
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800963 case APPLY_VOLUME_SHAPER: {
964 CHECK_INTERFACE(IMediaPlayer, data, reply);
965 sp<VolumeShaper::Configuration> configuration;
966 sp<VolumeShaper::Operation> operation;
967
968 int32_t present;
969 status_t status = data.readInt32(&present);
970 if (status == NO_ERROR && present != 0) {
971 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700972 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800973 }
974 if (status == NO_ERROR) {
975 status = data.readInt32(&present);
976 }
977 if (status == NO_ERROR && present != 0) {
978 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700979 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800980 }
981 if (status == NO_ERROR) {
982 status = (status_t)applyVolumeShaper(configuration, operation);
983 }
984 reply->writeInt32(status);
985 return NO_ERROR;
986 } break;
987 case GET_VOLUME_SHAPER_STATE: {
988 CHECK_INTERFACE(IMediaPlayer, data, reply);
989 int id;
990 status_t status = data.readInt32(&id);
991 if (status == NO_ERROR) {
992 sp<VolumeShaper::State> state = getVolumeShaperState(id);
993 if (state.get() != nullptr) {
994 status = state->writeToParcel(reply);
995 }
996 }
997 return NO_ERROR;
998 } break;
999
Hassan Shojaniacefac142017-02-06 21:02:02 -08001000 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -08001001 case PREPARE_DRM: {
1002 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -08001003
andrewlewis35c7db92020-08-14 10:41:13 +00001004 uint8_t uuid[16] = {};
Hassan Shojania071437a2017-01-23 09:19:40 -08001005 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -08001006 Vector<uint8_t> drmSessionId;
Santiago Seifert713642e2021-02-08 16:09:38 +00001007 status_t status = readVector(data, drmSessionId);
1008 if (status != OK) {
1009 return status;
1010 }
Hassan Shojaniacefac142017-02-06 21:02:02 -08001011 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -08001012 reply->writeInt32(result);
1013 return OK;
1014 }
1015 case RELEASE_DRM: {
1016 CHECK_INTERFACE(IMediaPlayer, data, reply);
1017
1018 uint32_t result = releaseDrm();
1019 reply->writeInt32(result);
1020 return OK;
1021 }
jiabin156c6872017-10-06 09:47:15 -07001022
1023 // AudioRouting
1024 case SET_OUTPUT_DEVICE: {
1025 CHECK_INTERFACE(IMediaPlayer, data, reply);
1026 int deviceId;
1027 status_t status = data.readInt32(&deviceId);
1028 if (status == NO_ERROR) {
1029 reply->writeInt32(setOutputDevice(deviceId));
1030 } else {
1031 reply->writeInt32(BAD_VALUE);
1032 }
1033 return NO_ERROR;
1034 }
1035 case GET_ROUTED_DEVICE_ID: {
1036 CHECK_INTERFACE(IMediaPlayer, data, reply);
1037 audio_port_handle_t deviceId;
1038 status_t ret = getRoutedDeviceId(&deviceId);
1039 reply->writeInt32(ret);
1040 if (ret == NO_ERROR) {
1041 reply->writeInt32(deviceId);
1042 }
1043 return NO_ERROR;
1044 } break;
1045 case ENABLE_AUDIO_DEVICE_CALLBACK: {
1046 CHECK_INTERFACE(IMediaPlayer, data, reply);
1047 bool enabled;
1048 status_t status = data.readBool(&enabled);
1049 if (status == NO_ERROR) {
1050 reply->writeInt32(enableAudioDeviceCallback(enabled));
1051 } else {
1052 reply->writeInt32(BAD_VALUE);
1053 }
1054 return NO_ERROR;
1055 } break;
1056
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001057 default:
1058 return BBinder::onTransact(code, data, reply, flags);
1059 }
1060}
1061
1062// ----------------------------------------------------------------------------
1063
Glenn Kasten40bc9062015-03-20 09:09:33 -07001064} // namespace android