blob: 903e503e0f21822a609efef2c904522f386acef9 [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
John Grossmanc795b642012-02-22 15:38:35 -080018#include <arpa/inet.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080019#include <stdint.h>
20#include <sys/types.h>
21
Mathias Agopian75624082009-05-19 19:08:10 -070022#include <binder/Parcel.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080023
Lajos Molnar3a474aa2015-04-24 17:10:07 -070024#include <media/AudioResamplerPublic.h>
25#include <media/AVSyncSettings.h>
Wei Jiad399e7e2016-10-26 15:49:11 -070026#include <media/BufferingSettings.h>
Lajos Molnar3a474aa2015-04-24 17:10:07 -070027
Chris Watkins99f31602015-03-20 13:06:33 -070028#include <media/IDataSource.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080029#include <media/IMediaHTTPService.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080030#include <media/IMediaPlayer.h>
Dave Burked681bbb2011-08-30 14:39:17 +010031#include <media/IStreamSource.h>
32
Andy McFadden8ba01022012-12-18 09:46:54 -080033#include <gui/IGraphicBufferProducer.h>
Dave Burked681bbb2011-08-30 14:39:17 +010034#include <utils/String8.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080035
36namespace android {
37
Ivan Lozano8cf3a072017-08-09 09:01:33 -070038using media::VolumeShaper;
39
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080040enum {
41 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
Dave Burked681bbb2011-08-30 14:39:17 +010042 SET_DATA_SOURCE_URL,
43 SET_DATA_SOURCE_FD,
44 SET_DATA_SOURCE_STREAM,
Chris Watkins99f31602015-03-20 13:06:33 -070045 SET_DATA_SOURCE_CALLBACK,
Wei Jiad399e7e2016-10-26 15:49:11 -070046 SET_BUFFERING_SETTINGS,
47 GET_DEFAULT_BUFFERING_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080048 PREPARE_ASYNC,
49 START,
50 STOP,
51 IS_PLAYING,
Lajos Molnar3a474aa2015-04-24 17:10:07 -070052 SET_PLAYBACK_SETTINGS,
53 GET_PLAYBACK_SETTINGS,
54 SET_SYNC_SETTINGS,
55 GET_SYNC_SETTINGS,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080056 PAUSE,
57 SEEK_TO,
58 GET_CURRENT_POSITION,
59 GET_DURATION,
60 RESET,
Wei Jia52c28512017-09-13 18:17:51 -070061 NOTIFY_AT,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080062 SET_AUDIO_STREAM_TYPE,
63 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070064 SET_VOLUME,
65 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070066 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070067 GET_METADATA,
Eric Laurent2beeb502010-07-16 07:43:46 -070068 SET_AUX_EFFECT_SEND_LEVEL,
Glenn Kasten11731182011-02-08 17:26:17 -080069 ATTACH_AUX_EFFECT,
70 SET_VIDEO_SURFACETEXTURE,
Gloria Wang4f9e47f2011-04-25 17:28:22 -070071 SET_PARAMETER,
72 GET_PARAMETER,
John Grossmanc795b642012-02-22 15:38:35 -080073 SET_RETRANSMIT_ENDPOINT,
John Grossman44a7e422012-06-21 17:29:24 -070074 GET_RETRANSMIT_ENDPOINT,
Marco Nelissen6b74d672012-02-28 16:07:44 -080075 SET_NEXT_PLAYER,
Andy Hung9fc8b5c2017-01-24 13:36:48 -080076 APPLY_VOLUME_SHAPER,
77 GET_VOLUME_SHAPER_STATE,
Hassan Shojaniacefac142017-02-06 21:02:02 -080078 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -080079 PREPARE_DRM,
80 RELEASE_DRM,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080081};
82
Hassan Shojania071437a2017-01-23 09:19:40 -080083// ModDrm helpers
84static void readVector(const Parcel& reply, Vector<uint8_t>& vector) {
85 uint32_t size = reply.readUint32();
86 vector.insertAt((size_t)0, size);
87 reply.read(vector.editArray(), size);
88}
89
90static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
91 data.writeUint32(vector.size());
92 data.write(vector.array(), vector.size());
93}
94
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080095class BpMediaPlayer: public BpInterface<IMediaPlayer>
96{
97public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070098 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080099 : BpInterface<IMediaPlayer>(impl)
100 {
101 }
102
103 // disconnect from media player service
104 void disconnect()
105 {
106 Parcel data, reply;
107 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
108 remote()->transact(DISCONNECT, data, &reply);
109 }
110
Andreas Huber1b86fe02014-01-29 11:13:26 -0800111 status_t setDataSource(
112 const sp<IMediaHTTPService> &httpService,
113 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +0100114 const KeyedVector<String8, String8>* headers)
115 {
116 Parcel data, reply;
117 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800118 data.writeInt32(httpService != NULL);
119 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800120 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800121 }
Dave Burked681bbb2011-08-30 14:39:17 +0100122 data.writeCString(url);
123 if (headers == NULL) {
124 data.writeInt32(0);
125 } else {
126 // serialize the headers
127 data.writeInt32(headers->size());
128 for (size_t i = 0; i < headers->size(); ++i) {
129 data.writeString8(headers->keyAt(i));
130 data.writeString8(headers->valueAt(i));
131 }
132 }
133 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
134 return reply.readInt32();
135 }
136
137 status_t setDataSource(int fd, int64_t offset, int64_t length) {
138 Parcel data, reply;
139 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
140 data.writeFileDescriptor(fd);
141 data.writeInt64(offset);
142 data.writeInt64(length);
143 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
144 return reply.readInt32();
145 }
146
147 status_t setDataSource(const sp<IStreamSource> &source) {
148 Parcel data, reply;
149 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800150 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700151 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100152 return reply.readInt32();
153 }
154
Chris Watkins99f31602015-03-20 13:06:33 -0700155 status_t setDataSource(const sp<IDataSource> &source) {
156 Parcel data, reply;
157 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
158 data.writeStrongBinder(IInterface::asBinder(source));
159 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
160 return reply.readInt32();
161 }
162
Andy McFadden8ba01022012-12-18 09:46:54 -0800163 // pass the buffered IGraphicBufferProducer to the media player service
164 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800165 {
166 Parcel data, reply;
167 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800168 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800169 data.writeStrongBinder(b);
170 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
171 return reply.readInt32();
172 }
173
Wei Jiad399e7e2016-10-26 15:49:11 -0700174 status_t setBufferingSettings(const BufferingSettings& buffering)
175 {
176 Parcel data, reply;
177 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
178 buffering.writeToParcel(&data);
179 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
180 return reply.readInt32();
181 }
182
183 status_t getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */)
184 {
185 if (buffering == nullptr) {
186 return BAD_VALUE;
187 }
188 Parcel data, reply;
189 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
190 remote()->transact(GET_DEFAULT_BUFFERING_SETTINGS, data, &reply);
191 status_t err = reply.readInt32();
192 if (err == OK) {
193 err = buffering->readFromParcel(&reply);
194 }
195 return err;
196 }
197
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800198 status_t prepareAsync()
199 {
200 Parcel data, reply;
201 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
202 remote()->transact(PREPARE_ASYNC, data, &reply);
203 return reply.readInt32();
204 }
205
206 status_t start()
207 {
208 Parcel data, reply;
209 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
210 remote()->transact(START, data, &reply);
211 return reply.readInt32();
212 }
213
214 status_t stop()
215 {
216 Parcel data, reply;
217 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
218 remote()->transact(STOP, data, &reply);
219 return reply.readInt32();
220 }
221
222 status_t isPlaying(bool* state)
223 {
224 Parcel data, reply;
225 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
226 remote()->transact(IS_PLAYING, data, &reply);
227 *state = reply.readInt32();
228 return reply.readInt32();
229 }
230
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700231 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800232 {
233 Parcel data, reply;
234 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700235 data.writeFloat(rate.mSpeed);
236 data.writeFloat(rate.mPitch);
237 data.writeInt32((int32_t)rate.mFallbackMode);
238 data.writeInt32((int32_t)rate.mStretchMode);
239 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800240 return reply.readInt32();
241 }
242
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700243 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
244 {
245 Parcel data, reply;
246 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
247 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
248 status_t err = reply.readInt32();
249 if (err == OK) {
250 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
251 rate->mSpeed = reply.readFloat();
252 rate->mPitch = reply.readFloat();
253 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
254 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
255 }
256 return err;
257 }
258
259 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
260 {
261 Parcel data, reply;
262 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
263 data.writeInt32((int32_t)sync.mSource);
264 data.writeInt32((int32_t)sync.mAudioAdjustMode);
265 data.writeFloat(sync.mTolerance);
266 data.writeFloat(videoFpsHint);
267 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
268 return reply.readInt32();
269 }
270
271 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
272 {
273 Parcel data, reply;
274 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
275 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
276 status_t err = reply.readInt32();
277 if (err == OK) {
278 AVSyncSettings settings;
279 settings.mSource = (AVSyncSource)reply.readInt32();
280 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
281 settings.mTolerance = reply.readFloat();
282 *sync = settings;
283 *videoFps = reply.readFloat();
284 }
285 return err;
286 }
287
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800288 status_t pause()
289 {
290 Parcel data, reply;
291 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
292 remote()->transact(PAUSE, data, &reply);
293 return reply.readInt32();
294 }
295
Wei Jiac5de0912016-11-18 10:22:14 -0800296 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800297 {
298 Parcel data, reply;
299 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
300 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800301 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800302 remote()->transact(SEEK_TO, data, &reply);
303 return reply.readInt32();
304 }
305
306 status_t getCurrentPosition(int* msec)
307 {
308 Parcel data, reply;
309 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
310 remote()->transact(GET_CURRENT_POSITION, data, &reply);
311 *msec = reply.readInt32();
312 return reply.readInt32();
313 }
314
315 status_t getDuration(int* msec)
316 {
317 Parcel data, reply;
318 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
319 remote()->transact(GET_DURATION, data, &reply);
320 *msec = reply.readInt32();
321 return reply.readInt32();
322 }
323
324 status_t reset()
325 {
326 Parcel data, reply;
327 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
328 remote()->transact(RESET, data, &reply);
329 return reply.readInt32();
330 }
331
Wei Jia52c28512017-09-13 18:17:51 -0700332 status_t notifyAt(int64_t mediaTimeUs)
333 {
334 Parcel data, reply;
335 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
336 data.writeInt64(mediaTimeUs);
337 remote()->transact(NOTIFY_AT, data, &reply);
338 return reply.readInt32();
339 }
340
Glenn Kastenfff6d712012-01-12 16:38:12 -0800341 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800342 {
343 Parcel data, reply;
344 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800345 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800346 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
347 return reply.readInt32();
348 }
349
350 status_t setLooping(int loop)
351 {
352 Parcel data, reply;
353 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
354 data.writeInt32(loop);
355 remote()->transact(SET_LOOPING, data, &reply);
356 return reply.readInt32();
357 }
358
359 status_t setVolume(float leftVolume, float rightVolume)
360 {
361 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700362 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800363 data.writeFloat(leftVolume);
364 data.writeFloat(rightVolume);
365 remote()->transact(SET_VOLUME, data, &reply);
366 return reply.readInt32();
367 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700368
369 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700370 {
371 // Avoid doing any extra copy. The interface descriptor should
372 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700373 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700374 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700375
376 status_t setMetadataFilter(const Parcel& request)
377 {
378 Parcel reply;
379 // Avoid doing any extra copy of the request. The interface
380 // descriptor should have been set by MediaPlayer.java.
381 remote()->transact(SET_METADATA_FILTER, request, &reply);
382 return reply.readInt32();
383 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700384
385 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
386 {
387 Parcel request;
388 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
389 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
390 request.writeInt32(update_only);
391 request.writeInt32(apply_filter);
392 remote()->transact(GET_METADATA, request, reply);
393 return reply->readInt32();
394 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800395
Eric Laurent2beeb502010-07-16 07:43:46 -0700396 status_t setAuxEffectSendLevel(float level)
397 {
398 Parcel data, reply;
399 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
400 data.writeFloat(level);
401 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
402 return reply.readInt32();
403 }
404
405 status_t attachAuxEffect(int effectId)
406 {
407 Parcel data, reply;
408 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
409 data.writeInt32(effectId);
410 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
411 return reply.readInt32();
412 }
Glenn Kasten11731182011-02-08 17:26:17 -0800413
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700414 status_t setParameter(int key, const Parcel& request)
415 {
416 Parcel data, reply;
417 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
418 data.writeInt32(key);
419 if (request.dataSize() > 0) {
420 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
421 }
422 remote()->transact(SET_PARAMETER, data, &reply);
423 return reply.readInt32();
424 }
425
426 status_t getParameter(int key, Parcel *reply)
427 {
428 Parcel data;
429 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
430 data.writeInt32(key);
431 return remote()->transact(GET_PARAMETER, data, reply);
432 }
433
John Grossman44a7e422012-06-21 17:29:24 -0700434 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
435 {
John Grossmanc795b642012-02-22 15:38:35 -0800436 Parcel data, reply;
437 status_t err;
438
439 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
440 if (NULL != endpoint) {
441 data.writeInt32(sizeof(*endpoint));
442 data.write(endpoint, sizeof(*endpoint));
443 } else {
444 data.writeInt32(0);
445 }
446
447 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
448 if (OK != err) {
449 return err;
450 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800451 return reply.readInt32();
452 }
John Grossmanc795b642012-02-22 15:38:35 -0800453
Marco Nelissen6b74d672012-02-28 16:07:44 -0800454 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
455 Parcel data, reply;
456 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800457 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800458 data.writeStrongBinder(b);
459 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800460 return reply.readInt32();
461 }
John Grossman44a7e422012-06-21 17:29:24 -0700462
463 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
464 {
465 Parcel data, reply;
466 status_t err;
467
468 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
469 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
470
471 if ((OK != err) || (OK != (err = reply.readInt32()))) {
472 return err;
473 }
474
475 data.read(endpoint, sizeof(*endpoint));
476
477 return err;
478 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800479
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800480 virtual VolumeShaper::Status applyVolumeShaper(
481 const sp<VolumeShaper::Configuration>& configuration,
482 const sp<VolumeShaper::Operation>& operation) {
483 Parcel data, reply;
484 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
485
486 status_t tmp;
487 status_t status = configuration.get() == nullptr
488 ? data.writeInt32(0)
489 : (tmp = data.writeInt32(1)) != NO_ERROR
490 ? tmp : configuration->writeToParcel(&data);
491 if (status != NO_ERROR) {
492 return VolumeShaper::Status(status);
493 }
494
495 status = operation.get() == nullptr
496 ? status = data.writeInt32(0)
497 : (tmp = data.writeInt32(1)) != NO_ERROR
498 ? tmp : operation->writeToParcel(&data);
499 if (status != NO_ERROR) {
500 return VolumeShaper::Status(status);
501 }
502
503 int32_t remoteVolumeShaperStatus;
504 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
505 if (status == NO_ERROR) {
506 status = reply.readInt32(&remoteVolumeShaperStatus);
507 }
508 if (status != NO_ERROR) {
509 return VolumeShaper::Status(status);
510 }
511 return VolumeShaper::Status(remoteVolumeShaperStatus);
512 }
513
514 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
515 Parcel data, reply;
516 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
517
518 data.writeInt32(id);
519 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
520 if (status != NO_ERROR) {
521 return nullptr;
522 }
523 sp<VolumeShaper::State> state = new VolumeShaper::State();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700524 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800525 if (status != NO_ERROR) {
526 return nullptr;
527 }
528 return state;
529 }
530
Hassan Shojaniacefac142017-02-06 21:02:02 -0800531 // Modular DRM
532 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800533 {
534 Parcel data, reply;
535 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
536
537 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800538 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800539
540 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
541 if (status != OK) {
542 ALOGE("prepareDrm: binder call failed: %d", status);
543 return status;
544 }
545
546 return reply.readInt32();
547 }
548
549 status_t releaseDrm()
550 {
551 Parcel data, reply;
552 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
553
554 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
555 if (status != OK) {
556 ALOGE("releaseDrm: binder call failed: %d", status);
557 return status;
558 }
559
560 return reply.readInt32();
561 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800562};
563
niko56f0cc52009-06-22 08:49:52 -0700564IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800565
566// ----------------------------------------------------------------------
567
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800568status_t BnMediaPlayer::onTransact(
569 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
570{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700571 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800572 case DISCONNECT: {
573 CHECK_INTERFACE(IMediaPlayer, data, reply);
574 disconnect();
575 return NO_ERROR;
576 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100577 case SET_DATA_SOURCE_URL: {
578 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800579
580 sp<IMediaHTTPService> httpService;
581 if (data.readInt32()) {
582 httpService =
583 interface_cast<IMediaHTTPService>(data.readStrongBinder());
584 }
585
Dave Burked681bbb2011-08-30 14:39:17 +0100586 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800587 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800588 reply->writeInt32(BAD_VALUE);
589 return NO_ERROR;
590 }
Dave Burked681bbb2011-08-30 14:39:17 +0100591 KeyedVector<String8, String8> headers;
592 int32_t numHeaders = data.readInt32();
593 for (int i = 0; i < numHeaders; ++i) {
594 String8 key = data.readString8();
595 String8 value = data.readString8();
596 headers.add(key, value);
597 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800598 reply->writeInt32(setDataSource(
599 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100600 return NO_ERROR;
601 } break;
602 case SET_DATA_SOURCE_FD: {
603 CHECK_INTERFACE(IMediaPlayer, data, reply);
604 int fd = data.readFileDescriptor();
605 int64_t offset = data.readInt64();
606 int64_t length = data.readInt64();
607 reply->writeInt32(setDataSource(fd, offset, length));
608 return NO_ERROR;
609 }
610 case SET_DATA_SOURCE_STREAM: {
611 CHECK_INTERFACE(IMediaPlayer, data, reply);
612 sp<IStreamSource> source =
613 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800614 if (source == NULL) {
615 reply->writeInt32(BAD_VALUE);
616 } else {
617 reply->writeInt32(setDataSource(source));
618 }
Dave Burked681bbb2011-08-30 14:39:17 +0100619 return NO_ERROR;
620 }
Chris Watkins99f31602015-03-20 13:06:33 -0700621 case SET_DATA_SOURCE_CALLBACK: {
622 CHECK_INTERFACE(IMediaPlayer, data, reply);
623 sp<IDataSource> source =
624 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800625 if (source == NULL) {
626 reply->writeInt32(BAD_VALUE);
627 } else {
628 reply->writeInt32(setDataSource(source));
629 }
Chris Watkins99f31602015-03-20 13:06:33 -0700630 return NO_ERROR;
631 }
Glenn Kasten11731182011-02-08 17:26:17 -0800632 case SET_VIDEO_SURFACETEXTURE: {
633 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800634 sp<IGraphicBufferProducer> bufferProducer =
635 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
636 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800637 return NO_ERROR;
638 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700639 case SET_BUFFERING_SETTINGS: {
640 CHECK_INTERFACE(IMediaPlayer, data, reply);
641 BufferingSettings buffering;
642 buffering.readFromParcel(&data);
643 reply->writeInt32(setBufferingSettings(buffering));
644 return NO_ERROR;
645 } break;
646 case GET_DEFAULT_BUFFERING_SETTINGS: {
647 CHECK_INTERFACE(IMediaPlayer, data, reply);
648 BufferingSettings buffering;
649 status_t err = getDefaultBufferingSettings(&buffering);
650 reply->writeInt32(err);
651 if (err == OK) {
652 buffering.writeToParcel(reply);
653 }
654 return NO_ERROR;
655 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800656 case PREPARE_ASYNC: {
657 CHECK_INTERFACE(IMediaPlayer, data, reply);
658 reply->writeInt32(prepareAsync());
659 return NO_ERROR;
660 } break;
661 case START: {
662 CHECK_INTERFACE(IMediaPlayer, data, reply);
663 reply->writeInt32(start());
664 return NO_ERROR;
665 } break;
666 case STOP: {
667 CHECK_INTERFACE(IMediaPlayer, data, reply);
668 reply->writeInt32(stop());
669 return NO_ERROR;
670 } break;
671 case IS_PLAYING: {
672 CHECK_INTERFACE(IMediaPlayer, data, reply);
673 bool state;
674 status_t ret = isPlaying(&state);
675 reply->writeInt32(state);
676 reply->writeInt32(ret);
677 return NO_ERROR;
678 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700679 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800680 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700681 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
682 rate.mSpeed = data.readFloat();
683 rate.mPitch = data.readFloat();
684 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
685 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
686 reply->writeInt32(setPlaybackSettings(rate));
687 return NO_ERROR;
688 } break;
689 case GET_PLAYBACK_SETTINGS: {
690 CHECK_INTERFACE(IMediaPlayer, data, reply);
691 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
692 status_t err = getPlaybackSettings(&rate);
693 reply->writeInt32(err);
694 if (err == OK) {
695 reply->writeFloat(rate.mSpeed);
696 reply->writeFloat(rate.mPitch);
697 reply->writeInt32((int32_t)rate.mFallbackMode);
698 reply->writeInt32((int32_t)rate.mStretchMode);
699 }
700 return NO_ERROR;
701 } break;
702 case SET_SYNC_SETTINGS: {
703 CHECK_INTERFACE(IMediaPlayer, data, reply);
704 AVSyncSettings sync;
705 sync.mSource = (AVSyncSource)data.readInt32();
706 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
707 sync.mTolerance = data.readFloat();
708 float videoFpsHint = data.readFloat();
709 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
710 return NO_ERROR;
711 } break;
712 case GET_SYNC_SETTINGS: {
713 CHECK_INTERFACE(IMediaPlayer, data, reply);
714 AVSyncSettings sync;
715 float videoFps;
716 status_t err = getSyncSettings(&sync, &videoFps);
717 reply->writeInt32(err);
718 if (err == OK) {
719 reply->writeInt32((int32_t)sync.mSource);
720 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
721 reply->writeFloat(sync.mTolerance);
722 reply->writeFloat(videoFps);
723 }
Wei Jia98160162015-02-04 17:01:11 -0800724 return NO_ERROR;
725 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800726 case PAUSE: {
727 CHECK_INTERFACE(IMediaPlayer, data, reply);
728 reply->writeInt32(pause());
729 return NO_ERROR;
730 } break;
731 case SEEK_TO: {
732 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700733 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800734 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
735 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800736 return NO_ERROR;
737 } break;
738 case GET_CURRENT_POSITION: {
739 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700740 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800741 status_t ret = getCurrentPosition(&msec);
742 reply->writeInt32(msec);
743 reply->writeInt32(ret);
744 return NO_ERROR;
745 } break;
746 case GET_DURATION: {
747 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700748 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800749 status_t ret = getDuration(&msec);
750 reply->writeInt32(msec);
751 reply->writeInt32(ret);
752 return NO_ERROR;
753 } break;
754 case RESET: {
755 CHECK_INTERFACE(IMediaPlayer, data, reply);
756 reply->writeInt32(reset());
757 return NO_ERROR;
758 } break;
Wei Jia52c28512017-09-13 18:17:51 -0700759 case NOTIFY_AT: {
760 CHECK_INTERFACE(IMediaPlayer, data, reply);
761 reply->writeInt32(notifyAt(data.readInt64()));
762 return NO_ERROR;
763 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800764 case SET_AUDIO_STREAM_TYPE: {
765 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800766 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800767 return NO_ERROR;
768 } break;
769 case SET_LOOPING: {
770 CHECK_INTERFACE(IMediaPlayer, data, reply);
771 reply->writeInt32(setLooping(data.readInt32()));
772 return NO_ERROR;
773 } break;
774 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700775 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700776 float leftVolume = data.readFloat();
777 float rightVolume = data.readFloat();
778 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800779 return NO_ERROR;
780 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700781 case INVOKE: {
782 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700783 status_t result = invoke(data, reply);
784 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700785 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700786 case SET_METADATA_FILTER: {
787 CHECK_INTERFACE(IMediaPlayer, data, reply);
788 reply->writeInt32(setMetadataFilter(data));
789 return NO_ERROR;
790 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700791 case GET_METADATA: {
792 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700793 bool update_only = static_cast<bool>(data.readInt32());
794 bool apply_filter = static_cast<bool>(data.readInt32());
795 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700796 reply->setDataPosition(0);
797 reply->writeInt32(retcode);
798 reply->setDataPosition(0);
799 return NO_ERROR;
800 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700801 case SET_AUX_EFFECT_SEND_LEVEL: {
802 CHECK_INTERFACE(IMediaPlayer, data, reply);
803 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
804 return NO_ERROR;
805 } break;
806 case ATTACH_AUX_EFFECT: {
807 CHECK_INTERFACE(IMediaPlayer, data, reply);
808 reply->writeInt32(attachAuxEffect(data.readInt32()));
809 return NO_ERROR;
810 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700811 case SET_PARAMETER: {
812 CHECK_INTERFACE(IMediaPlayer, data, reply);
813 int key = data.readInt32();
814
815 Parcel request;
816 if (data.dataAvail() > 0) {
817 request.appendFrom(
818 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
819 }
820 request.setDataPosition(0);
821 reply->writeInt32(setParameter(key, request));
822 return NO_ERROR;
823 } break;
824 case GET_PARAMETER: {
825 CHECK_INTERFACE(IMediaPlayer, data, reply);
826 return getParameter(data.readInt32(), reply);
827 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800828 case SET_RETRANSMIT_ENDPOINT: {
829 CHECK_INTERFACE(IMediaPlayer, data, reply);
830
831 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700832 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800833 int amt = data.readInt32();
834 if (amt == sizeof(endpoint)) {
835 data.read(&endpoint, sizeof(struct sockaddr_in));
836 reply->writeInt32(setRetransmitEndpoint(&endpoint));
837 } else {
838 reply->writeInt32(setRetransmitEndpoint(NULL));
839 }
John Grossman44a7e422012-06-21 17:29:24 -0700840
841 return NO_ERROR;
842 } break;
843 case GET_RETRANSMIT_ENDPOINT: {
844 CHECK_INTERFACE(IMediaPlayer, data, reply);
845
846 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700847 memset(&endpoint, 0, sizeof(endpoint));
John Grossman44a7e422012-06-21 17:29:24 -0700848 status_t res = getRetransmitEndpoint(&endpoint);
849
850 reply->writeInt32(res);
851 reply->write(&endpoint, sizeof(endpoint));
852
Marco Nelissen6b74d672012-02-28 16:07:44 -0800853 return NO_ERROR;
854 } break;
855 case SET_NEXT_PLAYER: {
856 CHECK_INTERFACE(IMediaPlayer, data, reply);
857 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700858
John Grossmanc795b642012-02-22 15:38:35 -0800859 return NO_ERROR;
860 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800861
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800862 case APPLY_VOLUME_SHAPER: {
863 CHECK_INTERFACE(IMediaPlayer, data, reply);
864 sp<VolumeShaper::Configuration> configuration;
865 sp<VolumeShaper::Operation> operation;
866
867 int32_t present;
868 status_t status = data.readInt32(&present);
869 if (status == NO_ERROR && present != 0) {
870 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700871 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800872 }
873 if (status == NO_ERROR) {
874 status = data.readInt32(&present);
875 }
876 if (status == NO_ERROR && present != 0) {
877 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700878 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800879 }
880 if (status == NO_ERROR) {
881 status = (status_t)applyVolumeShaper(configuration, operation);
882 }
883 reply->writeInt32(status);
884 return NO_ERROR;
885 } break;
886 case GET_VOLUME_SHAPER_STATE: {
887 CHECK_INTERFACE(IMediaPlayer, data, reply);
888 int id;
889 status_t status = data.readInt32(&id);
890 if (status == NO_ERROR) {
891 sp<VolumeShaper::State> state = getVolumeShaperState(id);
892 if (state.get() != nullptr) {
893 status = state->writeToParcel(reply);
894 }
895 }
896 return NO_ERROR;
897 } break;
898
Hassan Shojaniacefac142017-02-06 21:02:02 -0800899 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -0800900 case PREPARE_DRM: {
901 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800902
Hassan Shojania071437a2017-01-23 09:19:40 -0800903 uint8_t uuid[16];
904 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -0800905 Vector<uint8_t> drmSessionId;
906 readVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800907
Hassan Shojaniacefac142017-02-06 21:02:02 -0800908 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800909 reply->writeInt32(result);
910 return OK;
911 }
912 case RELEASE_DRM: {
913 CHECK_INTERFACE(IMediaPlayer, data, reply);
914
915 uint32_t result = releaseDrm();
916 reply->writeInt32(result);
917 return OK;
918 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800919 default:
920 return BBinder::onTransact(code, data, reply, flags);
921 }
922}
923
924// ----------------------------------------------------------------------------
925
Glenn Kasten40bc9062015-03-20 09:09:33 -0700926} // namespace android