blob: 3996227ae3919938b0b3fa1578c2c922c5d99a91 [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
38enum {
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,
Wei Jiad399e7e2016-10-26 15:49:11 -070044 SET_BUFFERING_SETTINGS,
45 GET_DEFAULT_BUFFERING_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080046 PREPARE_ASYNC,
47 START,
48 STOP,
49 IS_PLAYING,
Lajos Molnar3a474aa2015-04-24 17:10:07 -070050 SET_PLAYBACK_SETTINGS,
51 GET_PLAYBACK_SETTINGS,
52 SET_SYNC_SETTINGS,
53 GET_SYNC_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080054 PAUSE,
55 SEEK_TO,
56 GET_CURRENT_POSITION,
57 GET_DURATION,
58 RESET,
59 SET_AUDIO_STREAM_TYPE,
60 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070061 SET_VOLUME,
62 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070063 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070064 GET_METADATA,
Eric Laurent2beeb502010-07-16 07:43:46 -070065 SET_AUX_EFFECT_SEND_LEVEL,
Glenn Kasten11731182011-02-08 17:26:17 -080066 ATTACH_AUX_EFFECT,
67 SET_VIDEO_SURFACETEXTURE,
Gloria Wang4f9e47f2011-04-25 17:28:22 -070068 SET_PARAMETER,
69 GET_PARAMETER,
John Grossmanc795b642012-02-22 15:38:35 -080070 SET_RETRANSMIT_ENDPOINT,
John Grossman44a7e422012-06-21 17:29:24 -070071 GET_RETRANSMIT_ENDPOINT,
Marco Nelissen6b74d672012-02-28 16:07:44 -080072 SET_NEXT_PLAYER,
Andy Hung9fc8b5c2017-01-24 13:36:48 -080073 APPLY_VOLUME_SHAPER,
74 GET_VOLUME_SHAPER_STATE,
Hassan Shojaniacefac142017-02-06 21:02:02 -080075 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -080076 PREPARE_DRM,
77 RELEASE_DRM,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080078};
79
Hassan Shojania071437a2017-01-23 09:19:40 -080080// ModDrm helpers
81static void readVector(const Parcel& reply, Vector<uint8_t>& vector) {
82 uint32_t size = reply.readUint32();
83 vector.insertAt((size_t)0, size);
84 reply.read(vector.editArray(), size);
85}
86
87static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
88 data.writeUint32(vector.size());
89 data.write(vector.array(), vector.size());
90}
91
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080092class BpMediaPlayer: public BpInterface<IMediaPlayer>
93{
94public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070095 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080096 : BpInterface<IMediaPlayer>(impl)
97 {
98 }
99
100 // disconnect from media player service
101 void disconnect()
102 {
103 Parcel data, reply;
104 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
105 remote()->transact(DISCONNECT, data, &reply);
106 }
107
Andreas Huber1b86fe02014-01-29 11:13:26 -0800108 status_t setDataSource(
109 const sp<IMediaHTTPService> &httpService,
110 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +0100111 const KeyedVector<String8, String8>* headers)
112 {
113 Parcel data, reply;
114 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800115 data.writeInt32(httpService != NULL);
116 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800117 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800118 }
Dave Burked681bbb2011-08-30 14:39:17 +0100119 data.writeCString(url);
120 if (headers == NULL) {
121 data.writeInt32(0);
122 } else {
123 // serialize the headers
124 data.writeInt32(headers->size());
125 for (size_t i = 0; i < headers->size(); ++i) {
126 data.writeString8(headers->keyAt(i));
127 data.writeString8(headers->valueAt(i));
128 }
129 }
130 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
131 return reply.readInt32();
132 }
133
134 status_t setDataSource(int fd, int64_t offset, int64_t length) {
135 Parcel data, reply;
136 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
137 data.writeFileDescriptor(fd);
138 data.writeInt64(offset);
139 data.writeInt64(length);
140 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
141 return reply.readInt32();
142 }
143
144 status_t setDataSource(const sp<IStreamSource> &source) {
145 Parcel data, reply;
146 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800147 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700148 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100149 return reply.readInt32();
150 }
151
Chris Watkins99f31602015-03-20 13:06:33 -0700152 status_t setDataSource(const sp<IDataSource> &source) {
153 Parcel data, reply;
154 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
155 data.writeStrongBinder(IInterface::asBinder(source));
156 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
157 return reply.readInt32();
158 }
159
Andy McFadden8ba01022012-12-18 09:46:54 -0800160 // pass the buffered IGraphicBufferProducer to the media player service
161 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800162 {
163 Parcel data, reply;
164 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800165 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800166 data.writeStrongBinder(b);
167 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
168 return reply.readInt32();
169 }
170
Wei Jiad399e7e2016-10-26 15:49:11 -0700171 status_t setBufferingSettings(const BufferingSettings& buffering)
172 {
173 Parcel data, reply;
174 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
175 buffering.writeToParcel(&data);
176 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
177 return reply.readInt32();
178 }
179
180 status_t getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */)
181 {
182 if (buffering == nullptr) {
183 return BAD_VALUE;
184 }
185 Parcel data, reply;
186 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
187 remote()->transact(GET_DEFAULT_BUFFERING_SETTINGS, data, &reply);
188 status_t err = reply.readInt32();
189 if (err == OK) {
190 err = buffering->readFromParcel(&reply);
191 }
192 return err;
193 }
194
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800195 status_t prepareAsync()
196 {
197 Parcel data, reply;
198 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
199 remote()->transact(PREPARE_ASYNC, data, &reply);
200 return reply.readInt32();
201 }
202
203 status_t start()
204 {
205 Parcel data, reply;
206 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
207 remote()->transact(START, data, &reply);
208 return reply.readInt32();
209 }
210
211 status_t stop()
212 {
213 Parcel data, reply;
214 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
215 remote()->transact(STOP, data, &reply);
216 return reply.readInt32();
217 }
218
219 status_t isPlaying(bool* state)
220 {
221 Parcel data, reply;
222 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
223 remote()->transact(IS_PLAYING, data, &reply);
224 *state = reply.readInt32();
225 return reply.readInt32();
226 }
227
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700228 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800229 {
230 Parcel data, reply;
231 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700232 data.writeFloat(rate.mSpeed);
233 data.writeFloat(rate.mPitch);
234 data.writeInt32((int32_t)rate.mFallbackMode);
235 data.writeInt32((int32_t)rate.mStretchMode);
236 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800237 return reply.readInt32();
238 }
239
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700240 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
241 {
242 Parcel data, reply;
243 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
244 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
245 status_t err = reply.readInt32();
246 if (err == OK) {
247 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
248 rate->mSpeed = reply.readFloat();
249 rate->mPitch = reply.readFloat();
250 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
251 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
252 }
253 return err;
254 }
255
256 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
257 {
258 Parcel data, reply;
259 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
260 data.writeInt32((int32_t)sync.mSource);
261 data.writeInt32((int32_t)sync.mAudioAdjustMode);
262 data.writeFloat(sync.mTolerance);
263 data.writeFloat(videoFpsHint);
264 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
265 return reply.readInt32();
266 }
267
268 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
269 {
270 Parcel data, reply;
271 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
272 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
273 status_t err = reply.readInt32();
274 if (err == OK) {
275 AVSyncSettings settings;
276 settings.mSource = (AVSyncSource)reply.readInt32();
277 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
278 settings.mTolerance = reply.readFloat();
279 *sync = settings;
280 *videoFps = reply.readFloat();
281 }
282 return err;
283 }
284
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800285 status_t pause()
286 {
287 Parcel data, reply;
288 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
289 remote()->transact(PAUSE, data, &reply);
290 return reply.readInt32();
291 }
292
Wei Jiac5de0912016-11-18 10:22:14 -0800293 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800294 {
295 Parcel data, reply;
296 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
297 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800298 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800299 remote()->transact(SEEK_TO, data, &reply);
300 return reply.readInt32();
301 }
302
303 status_t getCurrentPosition(int* msec)
304 {
305 Parcel data, reply;
306 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
307 remote()->transact(GET_CURRENT_POSITION, data, &reply);
308 *msec = reply.readInt32();
309 return reply.readInt32();
310 }
311
312 status_t getDuration(int* msec)
313 {
314 Parcel data, reply;
315 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
316 remote()->transact(GET_DURATION, data, &reply);
317 *msec = reply.readInt32();
318 return reply.readInt32();
319 }
320
321 status_t reset()
322 {
323 Parcel data, reply;
324 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
325 remote()->transact(RESET, data, &reply);
326 return reply.readInt32();
327 }
328
Glenn Kastenfff6d712012-01-12 16:38:12 -0800329 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800330 {
331 Parcel data, reply;
332 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800333 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800334 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
335 return reply.readInt32();
336 }
337
338 status_t setLooping(int loop)
339 {
340 Parcel data, reply;
341 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
342 data.writeInt32(loop);
343 remote()->transact(SET_LOOPING, data, &reply);
344 return reply.readInt32();
345 }
346
347 status_t setVolume(float leftVolume, float rightVolume)
348 {
349 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700350 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800351 data.writeFloat(leftVolume);
352 data.writeFloat(rightVolume);
353 remote()->transact(SET_VOLUME, data, &reply);
354 return reply.readInt32();
355 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700356
357 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700358 {
359 // Avoid doing any extra copy. The interface descriptor should
360 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700361 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700362 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700363
364 status_t setMetadataFilter(const Parcel& request)
365 {
366 Parcel reply;
367 // Avoid doing any extra copy of the request. The interface
368 // descriptor should have been set by MediaPlayer.java.
369 remote()->transact(SET_METADATA_FILTER, request, &reply);
370 return reply.readInt32();
371 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700372
373 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
374 {
375 Parcel request;
376 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
377 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
378 request.writeInt32(update_only);
379 request.writeInt32(apply_filter);
380 remote()->transact(GET_METADATA, request, reply);
381 return reply->readInt32();
382 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800383
Eric Laurent2beeb502010-07-16 07:43:46 -0700384 status_t setAuxEffectSendLevel(float level)
385 {
386 Parcel data, reply;
387 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
388 data.writeFloat(level);
389 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
390 return reply.readInt32();
391 }
392
393 status_t attachAuxEffect(int effectId)
394 {
395 Parcel data, reply;
396 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
397 data.writeInt32(effectId);
398 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
399 return reply.readInt32();
400 }
Glenn Kasten11731182011-02-08 17:26:17 -0800401
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700402 status_t setParameter(int key, const Parcel& request)
403 {
404 Parcel data, reply;
405 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
406 data.writeInt32(key);
407 if (request.dataSize() > 0) {
408 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
409 }
410 remote()->transact(SET_PARAMETER, data, &reply);
411 return reply.readInt32();
412 }
413
414 status_t getParameter(int key, Parcel *reply)
415 {
416 Parcel data;
417 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
418 data.writeInt32(key);
419 return remote()->transact(GET_PARAMETER, data, reply);
420 }
421
John Grossman44a7e422012-06-21 17:29:24 -0700422 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
423 {
John Grossmanc795b642012-02-22 15:38:35 -0800424 Parcel data, reply;
425 status_t err;
426
427 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
428 if (NULL != endpoint) {
429 data.writeInt32(sizeof(*endpoint));
430 data.write(endpoint, sizeof(*endpoint));
431 } else {
432 data.writeInt32(0);
433 }
434
435 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
436 if (OK != err) {
437 return err;
438 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800439 return reply.readInt32();
440 }
John Grossmanc795b642012-02-22 15:38:35 -0800441
Marco Nelissen6b74d672012-02-28 16:07:44 -0800442 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
443 Parcel data, reply;
444 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800445 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800446 data.writeStrongBinder(b);
447 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800448 return reply.readInt32();
449 }
John Grossman44a7e422012-06-21 17:29:24 -0700450
451 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
452 {
453 Parcel data, reply;
454 status_t err;
455
456 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
457 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
458
459 if ((OK != err) || (OK != (err = reply.readInt32()))) {
460 return err;
461 }
462
463 data.read(endpoint, sizeof(*endpoint));
464
465 return err;
466 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800467
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800468 virtual VolumeShaper::Status applyVolumeShaper(
469 const sp<VolumeShaper::Configuration>& configuration,
470 const sp<VolumeShaper::Operation>& operation) {
471 Parcel data, reply;
472 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
473
474 status_t tmp;
475 status_t status = configuration.get() == nullptr
476 ? data.writeInt32(0)
477 : (tmp = data.writeInt32(1)) != NO_ERROR
478 ? tmp : configuration->writeToParcel(&data);
479 if (status != NO_ERROR) {
480 return VolumeShaper::Status(status);
481 }
482
483 status = operation.get() == nullptr
484 ? status = data.writeInt32(0)
485 : (tmp = data.writeInt32(1)) != NO_ERROR
486 ? tmp : operation->writeToParcel(&data);
487 if (status != NO_ERROR) {
488 return VolumeShaper::Status(status);
489 }
490
491 int32_t remoteVolumeShaperStatus;
492 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
493 if (status == NO_ERROR) {
494 status = reply.readInt32(&remoteVolumeShaperStatus);
495 }
496 if (status != NO_ERROR) {
497 return VolumeShaper::Status(status);
498 }
499 return VolumeShaper::Status(remoteVolumeShaperStatus);
500 }
501
502 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
503 Parcel data, reply;
504 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
505
506 data.writeInt32(id);
507 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
508 if (status != NO_ERROR) {
509 return nullptr;
510 }
511 sp<VolumeShaper::State> state = new VolumeShaper::State();
512 status = state->readFromParcel(reply);
513 if (status != NO_ERROR) {
514 return nullptr;
515 }
516 return state;
517 }
518
Hassan Shojaniacefac142017-02-06 21:02:02 -0800519 // Modular DRM
520 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800521 {
522 Parcel data, reply;
523 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
524
525 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800526 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800527
528 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
529 if (status != OK) {
530 ALOGE("prepareDrm: binder call failed: %d", status);
531 return status;
532 }
533
534 return reply.readInt32();
535 }
536
537 status_t releaseDrm()
538 {
539 Parcel data, reply;
540 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
541
542 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
543 if (status != OK) {
544 ALOGE("releaseDrm: binder call failed: %d", status);
545 return status;
546 }
547
548 return reply.readInt32();
549 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800550};
551
niko56f0cc52009-06-22 08:49:52 -0700552IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800553
554// ----------------------------------------------------------------------
555
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800556status_t BnMediaPlayer::onTransact(
557 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
558{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700559 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800560 case DISCONNECT: {
561 CHECK_INTERFACE(IMediaPlayer, data, reply);
562 disconnect();
563 return NO_ERROR;
564 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100565 case SET_DATA_SOURCE_URL: {
566 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800567
568 sp<IMediaHTTPService> httpService;
569 if (data.readInt32()) {
570 httpService =
571 interface_cast<IMediaHTTPService>(data.readStrongBinder());
572 }
573
Dave Burked681bbb2011-08-30 14:39:17 +0100574 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800575 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800576 reply->writeInt32(BAD_VALUE);
577 return NO_ERROR;
578 }
Dave Burked681bbb2011-08-30 14:39:17 +0100579 KeyedVector<String8, String8> headers;
580 int32_t numHeaders = data.readInt32();
581 for (int i = 0; i < numHeaders; ++i) {
582 String8 key = data.readString8();
583 String8 value = data.readString8();
584 headers.add(key, value);
585 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800586 reply->writeInt32(setDataSource(
587 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100588 return NO_ERROR;
589 } break;
590 case SET_DATA_SOURCE_FD: {
591 CHECK_INTERFACE(IMediaPlayer, data, reply);
592 int fd = data.readFileDescriptor();
593 int64_t offset = data.readInt64();
594 int64_t length = data.readInt64();
595 reply->writeInt32(setDataSource(fd, offset, length));
596 return NO_ERROR;
597 }
598 case SET_DATA_SOURCE_STREAM: {
599 CHECK_INTERFACE(IMediaPlayer, data, reply);
600 sp<IStreamSource> source =
601 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800602 if (source == NULL) {
603 reply->writeInt32(BAD_VALUE);
604 } else {
605 reply->writeInt32(setDataSource(source));
606 }
Dave Burked681bbb2011-08-30 14:39:17 +0100607 return NO_ERROR;
608 }
Chris Watkins99f31602015-03-20 13:06:33 -0700609 case SET_DATA_SOURCE_CALLBACK: {
610 CHECK_INTERFACE(IMediaPlayer, data, reply);
611 sp<IDataSource> source =
612 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800613 if (source == NULL) {
614 reply->writeInt32(BAD_VALUE);
615 } else {
616 reply->writeInt32(setDataSource(source));
617 }
Chris Watkins99f31602015-03-20 13:06:33 -0700618 return NO_ERROR;
619 }
Glenn Kasten11731182011-02-08 17:26:17 -0800620 case SET_VIDEO_SURFACETEXTURE: {
621 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800622 sp<IGraphicBufferProducer> bufferProducer =
623 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
624 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800625 return NO_ERROR;
626 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700627 case SET_BUFFERING_SETTINGS: {
628 CHECK_INTERFACE(IMediaPlayer, data, reply);
629 BufferingSettings buffering;
630 buffering.readFromParcel(&data);
631 reply->writeInt32(setBufferingSettings(buffering));
632 return NO_ERROR;
633 } break;
634 case GET_DEFAULT_BUFFERING_SETTINGS: {
635 CHECK_INTERFACE(IMediaPlayer, data, reply);
636 BufferingSettings buffering;
637 status_t err = getDefaultBufferingSettings(&buffering);
638 reply->writeInt32(err);
639 if (err == OK) {
640 buffering.writeToParcel(reply);
641 }
642 return NO_ERROR;
643 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800644 case PREPARE_ASYNC: {
645 CHECK_INTERFACE(IMediaPlayer, data, reply);
646 reply->writeInt32(prepareAsync());
647 return NO_ERROR;
648 } break;
649 case START: {
650 CHECK_INTERFACE(IMediaPlayer, data, reply);
651 reply->writeInt32(start());
652 return NO_ERROR;
653 } break;
654 case STOP: {
655 CHECK_INTERFACE(IMediaPlayer, data, reply);
656 reply->writeInt32(stop());
657 return NO_ERROR;
658 } break;
659 case IS_PLAYING: {
660 CHECK_INTERFACE(IMediaPlayer, data, reply);
661 bool state;
662 status_t ret = isPlaying(&state);
663 reply->writeInt32(state);
664 reply->writeInt32(ret);
665 return NO_ERROR;
666 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700667 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800668 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700669 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
670 rate.mSpeed = data.readFloat();
671 rate.mPitch = data.readFloat();
672 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
673 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
674 reply->writeInt32(setPlaybackSettings(rate));
675 return NO_ERROR;
676 } break;
677 case GET_PLAYBACK_SETTINGS: {
678 CHECK_INTERFACE(IMediaPlayer, data, reply);
679 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
680 status_t err = getPlaybackSettings(&rate);
681 reply->writeInt32(err);
682 if (err == OK) {
683 reply->writeFloat(rate.mSpeed);
684 reply->writeFloat(rate.mPitch);
685 reply->writeInt32((int32_t)rate.mFallbackMode);
686 reply->writeInt32((int32_t)rate.mStretchMode);
687 }
688 return NO_ERROR;
689 } break;
690 case SET_SYNC_SETTINGS: {
691 CHECK_INTERFACE(IMediaPlayer, data, reply);
692 AVSyncSettings sync;
693 sync.mSource = (AVSyncSource)data.readInt32();
694 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
695 sync.mTolerance = data.readFloat();
696 float videoFpsHint = data.readFloat();
697 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
698 return NO_ERROR;
699 } break;
700 case GET_SYNC_SETTINGS: {
701 CHECK_INTERFACE(IMediaPlayer, data, reply);
702 AVSyncSettings sync;
703 float videoFps;
704 status_t err = getSyncSettings(&sync, &videoFps);
705 reply->writeInt32(err);
706 if (err == OK) {
707 reply->writeInt32((int32_t)sync.mSource);
708 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
709 reply->writeFloat(sync.mTolerance);
710 reply->writeFloat(videoFps);
711 }
Wei Jia98160162015-02-04 17:01:11 -0800712 return NO_ERROR;
713 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800714 case PAUSE: {
715 CHECK_INTERFACE(IMediaPlayer, data, reply);
716 reply->writeInt32(pause());
717 return NO_ERROR;
718 } break;
719 case SEEK_TO: {
720 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700721 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800722 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
723 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800724 return NO_ERROR;
725 } break;
726 case GET_CURRENT_POSITION: {
727 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700728 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800729 status_t ret = getCurrentPosition(&msec);
730 reply->writeInt32(msec);
731 reply->writeInt32(ret);
732 return NO_ERROR;
733 } break;
734 case GET_DURATION: {
735 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700736 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800737 status_t ret = getDuration(&msec);
738 reply->writeInt32(msec);
739 reply->writeInt32(ret);
740 return NO_ERROR;
741 } break;
742 case RESET: {
743 CHECK_INTERFACE(IMediaPlayer, data, reply);
744 reply->writeInt32(reset());
745 return NO_ERROR;
746 } break;
747 case SET_AUDIO_STREAM_TYPE: {
748 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800749 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800750 return NO_ERROR;
751 } break;
752 case SET_LOOPING: {
753 CHECK_INTERFACE(IMediaPlayer, data, reply);
754 reply->writeInt32(setLooping(data.readInt32()));
755 return NO_ERROR;
756 } break;
757 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700758 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700759 float leftVolume = data.readFloat();
760 float rightVolume = data.readFloat();
761 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800762 return NO_ERROR;
763 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700764 case INVOKE: {
765 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700766 status_t result = invoke(data, reply);
767 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700768 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700769 case SET_METADATA_FILTER: {
770 CHECK_INTERFACE(IMediaPlayer, data, reply);
771 reply->writeInt32(setMetadataFilter(data));
772 return NO_ERROR;
773 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700774 case GET_METADATA: {
775 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700776 bool update_only = static_cast<bool>(data.readInt32());
777 bool apply_filter = static_cast<bool>(data.readInt32());
778 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700779 reply->setDataPosition(0);
780 reply->writeInt32(retcode);
781 reply->setDataPosition(0);
782 return NO_ERROR;
783 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700784 case SET_AUX_EFFECT_SEND_LEVEL: {
785 CHECK_INTERFACE(IMediaPlayer, data, reply);
786 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
787 return NO_ERROR;
788 } break;
789 case ATTACH_AUX_EFFECT: {
790 CHECK_INTERFACE(IMediaPlayer, data, reply);
791 reply->writeInt32(attachAuxEffect(data.readInt32()));
792 return NO_ERROR;
793 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700794 case SET_PARAMETER: {
795 CHECK_INTERFACE(IMediaPlayer, data, reply);
796 int key = data.readInt32();
797
798 Parcel request;
799 if (data.dataAvail() > 0) {
800 request.appendFrom(
801 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
802 }
803 request.setDataPosition(0);
804 reply->writeInt32(setParameter(key, request));
805 return NO_ERROR;
806 } break;
807 case GET_PARAMETER: {
808 CHECK_INTERFACE(IMediaPlayer, data, reply);
809 return getParameter(data.readInt32(), reply);
810 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800811 case SET_RETRANSMIT_ENDPOINT: {
812 CHECK_INTERFACE(IMediaPlayer, data, reply);
813
814 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700815 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800816 int amt = data.readInt32();
817 if (amt == sizeof(endpoint)) {
818 data.read(&endpoint, sizeof(struct sockaddr_in));
819 reply->writeInt32(setRetransmitEndpoint(&endpoint));
820 } else {
821 reply->writeInt32(setRetransmitEndpoint(NULL));
822 }
John Grossman44a7e422012-06-21 17:29:24 -0700823
824 return NO_ERROR;
825 } break;
826 case GET_RETRANSMIT_ENDPOINT: {
827 CHECK_INTERFACE(IMediaPlayer, data, reply);
828
829 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700830 memset(&endpoint, 0, sizeof(endpoint));
John Grossman44a7e422012-06-21 17:29:24 -0700831 status_t res = getRetransmitEndpoint(&endpoint);
832
833 reply->writeInt32(res);
834 reply->write(&endpoint, sizeof(endpoint));
835
Marco Nelissen6b74d672012-02-28 16:07:44 -0800836 return NO_ERROR;
837 } break;
838 case SET_NEXT_PLAYER: {
839 CHECK_INTERFACE(IMediaPlayer, data, reply);
840 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700841
John Grossmanc795b642012-02-22 15:38:35 -0800842 return NO_ERROR;
843 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800844
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800845 case APPLY_VOLUME_SHAPER: {
846 CHECK_INTERFACE(IMediaPlayer, data, reply);
847 sp<VolumeShaper::Configuration> configuration;
848 sp<VolumeShaper::Operation> operation;
849
850 int32_t present;
851 status_t status = data.readInt32(&present);
852 if (status == NO_ERROR && present != 0) {
853 configuration = new VolumeShaper::Configuration();
854 status = configuration->readFromParcel(data);
855 }
856 if (status == NO_ERROR) {
857 status = data.readInt32(&present);
858 }
859 if (status == NO_ERROR && present != 0) {
860 operation = new VolumeShaper::Operation();
861 status = operation->readFromParcel(data);
862 }
863 if (status == NO_ERROR) {
864 status = (status_t)applyVolumeShaper(configuration, operation);
865 }
866 reply->writeInt32(status);
867 return NO_ERROR;
868 } break;
869 case GET_VOLUME_SHAPER_STATE: {
870 CHECK_INTERFACE(IMediaPlayer, data, reply);
871 int id;
872 status_t status = data.readInt32(&id);
873 if (status == NO_ERROR) {
874 sp<VolumeShaper::State> state = getVolumeShaperState(id);
875 if (state.get() != nullptr) {
876 status = state->writeToParcel(reply);
877 }
878 }
879 return NO_ERROR;
880 } break;
881
Hassan Shojaniacefac142017-02-06 21:02:02 -0800882 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -0800883 case PREPARE_DRM: {
884 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800885
Hassan Shojania071437a2017-01-23 09:19:40 -0800886 uint8_t uuid[16];
887 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -0800888 Vector<uint8_t> drmSessionId;
889 readVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800890
Hassan Shojaniacefac142017-02-06 21:02:02 -0800891 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800892 reply->writeInt32(result);
893 return OK;
894 }
895 case RELEASE_DRM: {
896 CHECK_INTERFACE(IMediaPlayer, data, reply);
897
898 uint32_t result = releaseDrm();
899 reply->writeInt32(result);
900 return OK;
901 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800902 default:
903 return BBinder::onTransact(code, data, reply, flags);
904 }
905}
906
907// ----------------------------------------------------------------------------
908
Glenn Kasten40bc9062015-03-20 09:09:33 -0700909} // namespace android