blob: cda3b3a1cad074621f8587a94956f63ae5c08d92 [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,
61 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,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080080};
81
Hassan Shojania071437a2017-01-23 09:19:40 -080082// ModDrm helpers
83static void readVector(const Parcel& reply, Vector<uint8_t>& vector) {
84 uint32_t size = reply.readUint32();
85 vector.insertAt((size_t)0, size);
86 reply.read(vector.editArray(), size);
87}
88
89static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
90 data.writeUint32(vector.size());
91 data.write(vector.array(), vector.size());
92}
93
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080094class BpMediaPlayer: public BpInterface<IMediaPlayer>
95{
96public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070097 explicit BpMediaPlayer(const sp<IBinder>& impl)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080098 : BpInterface<IMediaPlayer>(impl)
99 {
100 }
101
102 // disconnect from media player service
103 void disconnect()
104 {
105 Parcel data, reply;
106 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
107 remote()->transact(DISCONNECT, data, &reply);
108 }
109
Andreas Huber1b86fe02014-01-29 11:13:26 -0800110 status_t setDataSource(
111 const sp<IMediaHTTPService> &httpService,
112 const char* url,
Dave Burked681bbb2011-08-30 14:39:17 +0100113 const KeyedVector<String8, String8>* headers)
114 {
115 Parcel data, reply;
116 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Andreas Huber1b86fe02014-01-29 11:13:26 -0800117 data.writeInt32(httpService != NULL);
118 if (httpService != NULL) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800119 data.writeStrongBinder(IInterface::asBinder(httpService));
Andreas Huber1b86fe02014-01-29 11:13:26 -0800120 }
Dave Burked681bbb2011-08-30 14:39:17 +0100121 data.writeCString(url);
122 if (headers == NULL) {
123 data.writeInt32(0);
124 } else {
125 // serialize the headers
126 data.writeInt32(headers->size());
127 for (size_t i = 0; i < headers->size(); ++i) {
128 data.writeString8(headers->keyAt(i));
129 data.writeString8(headers->valueAt(i));
130 }
131 }
132 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
133 return reply.readInt32();
134 }
135
136 status_t setDataSource(int fd, int64_t offset, int64_t length) {
137 Parcel data, reply;
138 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
139 data.writeFileDescriptor(fd);
140 data.writeInt64(offset);
141 data.writeInt64(length);
142 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
143 return reply.readInt32();
144 }
145
146 status_t setDataSource(const sp<IStreamSource> &source) {
147 Parcel data, reply;
148 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800149 data.writeStrongBinder(IInterface::asBinder(source));
Glenn Kasten8d655102011-09-07 14:40:23 -0700150 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
Dave Burked681bbb2011-08-30 14:39:17 +0100151 return reply.readInt32();
152 }
153
Chris Watkins99f31602015-03-20 13:06:33 -0700154 status_t setDataSource(const sp<IDataSource> &source) {
155 Parcel data, reply;
156 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
157 data.writeStrongBinder(IInterface::asBinder(source));
158 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
159 return reply.readInt32();
160 }
161
Andy McFadden8ba01022012-12-18 09:46:54 -0800162 // pass the buffered IGraphicBufferProducer to the media player service
163 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Glenn Kasten11731182011-02-08 17:26:17 -0800164 {
165 Parcel data, reply;
166 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800167 sp<IBinder> b(IInterface::asBinder(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800168 data.writeStrongBinder(b);
169 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
170 return reply.readInt32();
171 }
172
Wei Jiad399e7e2016-10-26 15:49:11 -0700173 status_t setBufferingSettings(const BufferingSettings& buffering)
174 {
175 Parcel data, reply;
176 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
177 buffering.writeToParcel(&data);
178 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
179 return reply.readInt32();
180 }
181
182 status_t getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */)
183 {
184 if (buffering == nullptr) {
185 return BAD_VALUE;
186 }
187 Parcel data, reply;
188 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
189 remote()->transact(GET_DEFAULT_BUFFERING_SETTINGS, data, &reply);
190 status_t err = reply.readInt32();
191 if (err == OK) {
192 err = buffering->readFromParcel(&reply);
193 }
194 return err;
195 }
196
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800197 status_t prepareAsync()
198 {
199 Parcel data, reply;
200 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
201 remote()->transact(PREPARE_ASYNC, data, &reply);
202 return reply.readInt32();
203 }
204
205 status_t start()
206 {
207 Parcel data, reply;
208 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
209 remote()->transact(START, data, &reply);
210 return reply.readInt32();
211 }
212
213 status_t stop()
214 {
215 Parcel data, reply;
216 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
217 remote()->transact(STOP, data, &reply);
218 return reply.readInt32();
219 }
220
221 status_t isPlaying(bool* state)
222 {
223 Parcel data, reply;
224 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
225 remote()->transact(IS_PLAYING, data, &reply);
226 *state = reply.readInt32();
227 return reply.readInt32();
228 }
229
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700230 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
Wei Jia98160162015-02-04 17:01:11 -0800231 {
232 Parcel data, reply;
233 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700234 data.writeFloat(rate.mSpeed);
235 data.writeFloat(rate.mPitch);
236 data.writeInt32((int32_t)rate.mFallbackMode);
237 data.writeInt32((int32_t)rate.mStretchMode);
238 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
Wei Jia98160162015-02-04 17:01:11 -0800239 return reply.readInt32();
240 }
241
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700242 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
243 {
244 Parcel data, reply;
245 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
246 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
247 status_t err = reply.readInt32();
248 if (err == OK) {
249 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
250 rate->mSpeed = reply.readFloat();
251 rate->mPitch = reply.readFloat();
252 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
253 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
254 }
255 return err;
256 }
257
258 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
259 {
260 Parcel data, reply;
261 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
262 data.writeInt32((int32_t)sync.mSource);
263 data.writeInt32((int32_t)sync.mAudioAdjustMode);
264 data.writeFloat(sync.mTolerance);
265 data.writeFloat(videoFpsHint);
266 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
267 return reply.readInt32();
268 }
269
270 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
271 {
272 Parcel data, reply;
273 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
274 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
275 status_t err = reply.readInt32();
276 if (err == OK) {
277 AVSyncSettings settings;
278 settings.mSource = (AVSyncSource)reply.readInt32();
279 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
280 settings.mTolerance = reply.readFloat();
281 *sync = settings;
282 *videoFps = reply.readFloat();
283 }
284 return err;
285 }
286
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800287 status_t pause()
288 {
289 Parcel data, reply;
290 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
291 remote()->transact(PAUSE, data, &reply);
292 return reply.readInt32();
293 }
294
Wei Jiac5de0912016-11-18 10:22:14 -0800295 status_t seekTo(int msec, MediaPlayerSeekMode mode)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800296 {
297 Parcel data, reply;
298 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
299 data.writeInt32(msec);
Wei Jiac5de0912016-11-18 10:22:14 -0800300 data.writeInt32(mode);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800301 remote()->transact(SEEK_TO, data, &reply);
302 return reply.readInt32();
303 }
304
305 status_t getCurrentPosition(int* msec)
306 {
307 Parcel data, reply;
308 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
309 remote()->transact(GET_CURRENT_POSITION, data, &reply);
310 *msec = reply.readInt32();
311 return reply.readInt32();
312 }
313
314 status_t getDuration(int* msec)
315 {
316 Parcel data, reply;
317 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
318 remote()->transact(GET_DURATION, data, &reply);
319 *msec = reply.readInt32();
320 return reply.readInt32();
321 }
322
323 status_t reset()
324 {
325 Parcel data, reply;
326 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
327 remote()->transact(RESET, data, &reply);
328 return reply.readInt32();
329 }
330
Glenn Kastenfff6d712012-01-12 16:38:12 -0800331 status_t setAudioStreamType(audio_stream_type_t stream)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800332 {
333 Parcel data, reply;
334 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Glenn Kastenfff6d712012-01-12 16:38:12 -0800335 data.writeInt32((int32_t) stream);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800336 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
337 return reply.readInt32();
338 }
339
340 status_t setLooping(int loop)
341 {
342 Parcel data, reply;
343 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
344 data.writeInt32(loop);
345 remote()->transact(SET_LOOPING, data, &reply);
346 return reply.readInt32();
347 }
348
349 status_t setVolume(float leftVolume, float rightVolume)
350 {
351 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700352 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800353 data.writeFloat(leftVolume);
354 data.writeFloat(rightVolume);
355 remote()->transact(SET_VOLUME, data, &reply);
356 return reply.readInt32();
357 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700358
359 status_t invoke(const Parcel& request, Parcel *reply)
James Dong040e4a12011-04-06 18:29:01 -0700360 {
361 // Avoid doing any extra copy. The interface descriptor should
362 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700363 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700364 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700365
366 status_t setMetadataFilter(const Parcel& request)
367 {
368 Parcel reply;
369 // Avoid doing any extra copy of the request. The interface
370 // descriptor should have been set by MediaPlayer.java.
371 remote()->transact(SET_METADATA_FILTER, request, &reply);
372 return reply.readInt32();
373 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700374
375 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
376 {
377 Parcel request;
378 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
379 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
380 request.writeInt32(update_only);
381 request.writeInt32(apply_filter);
382 remote()->transact(GET_METADATA, request, reply);
383 return reply->readInt32();
384 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800385
Eric Laurent2beeb502010-07-16 07:43:46 -0700386 status_t setAuxEffectSendLevel(float level)
387 {
388 Parcel data, reply;
389 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
390 data.writeFloat(level);
391 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
392 return reply.readInt32();
393 }
394
395 status_t attachAuxEffect(int effectId)
396 {
397 Parcel data, reply;
398 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
399 data.writeInt32(effectId);
400 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
401 return reply.readInt32();
402 }
Glenn Kasten11731182011-02-08 17:26:17 -0800403
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700404 status_t setParameter(int key, const Parcel& request)
405 {
406 Parcel data, reply;
407 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
408 data.writeInt32(key);
409 if (request.dataSize() > 0) {
410 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
411 }
412 remote()->transact(SET_PARAMETER, data, &reply);
413 return reply.readInt32();
414 }
415
416 status_t getParameter(int key, Parcel *reply)
417 {
418 Parcel data;
419 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
420 data.writeInt32(key);
421 return remote()->transact(GET_PARAMETER, data, reply);
422 }
423
John Grossman44a7e422012-06-21 17:29:24 -0700424 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
425 {
John Grossmanc795b642012-02-22 15:38:35 -0800426 Parcel data, reply;
427 status_t err;
428
429 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
430 if (NULL != endpoint) {
431 data.writeInt32(sizeof(*endpoint));
432 data.write(endpoint, sizeof(*endpoint));
433 } else {
434 data.writeInt32(0);
435 }
436
437 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
438 if (OK != err) {
439 return err;
440 }
Marco Nelissen6b74d672012-02-28 16:07:44 -0800441 return reply.readInt32();
442 }
John Grossmanc795b642012-02-22 15:38:35 -0800443
Marco Nelissen6b74d672012-02-28 16:07:44 -0800444 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
445 Parcel data, reply;
446 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800447 sp<IBinder> b(IInterface::asBinder(player));
Marco Nelissen6b74d672012-02-28 16:07:44 -0800448 data.writeStrongBinder(b);
449 remote()->transact(SET_NEXT_PLAYER, data, &reply);
John Grossmanc795b642012-02-22 15:38:35 -0800450 return reply.readInt32();
451 }
John Grossman44a7e422012-06-21 17:29:24 -0700452
453 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
454 {
455 Parcel data, reply;
456 status_t err;
457
458 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
459 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
460
461 if ((OK != err) || (OK != (err = reply.readInt32()))) {
462 return err;
463 }
464
465 data.read(endpoint, sizeof(*endpoint));
466
467 return err;
468 }
Hassan Shojania071437a2017-01-23 09:19:40 -0800469
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800470 virtual VolumeShaper::Status applyVolumeShaper(
471 const sp<VolumeShaper::Configuration>& configuration,
472 const sp<VolumeShaper::Operation>& operation) {
473 Parcel data, reply;
474 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
475
476 status_t tmp;
477 status_t status = configuration.get() == nullptr
478 ? data.writeInt32(0)
479 : (tmp = data.writeInt32(1)) != NO_ERROR
480 ? tmp : configuration->writeToParcel(&data);
481 if (status != NO_ERROR) {
482 return VolumeShaper::Status(status);
483 }
484
485 status = operation.get() == nullptr
486 ? status = data.writeInt32(0)
487 : (tmp = data.writeInt32(1)) != NO_ERROR
488 ? tmp : operation->writeToParcel(&data);
489 if (status != NO_ERROR) {
490 return VolumeShaper::Status(status);
491 }
492
493 int32_t remoteVolumeShaperStatus;
494 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
495 if (status == NO_ERROR) {
496 status = reply.readInt32(&remoteVolumeShaperStatus);
497 }
498 if (status != NO_ERROR) {
499 return VolumeShaper::Status(status);
500 }
501 return VolumeShaper::Status(remoteVolumeShaperStatus);
502 }
503
504 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
505 Parcel data, reply;
506 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
507
508 data.writeInt32(id);
509 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
510 if (status != NO_ERROR) {
511 return nullptr;
512 }
513 sp<VolumeShaper::State> state = new VolumeShaper::State();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700514 status = state->readFromParcel(&reply);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800515 if (status != NO_ERROR) {
516 return nullptr;
517 }
518 return state;
519 }
520
Hassan Shojaniacefac142017-02-06 21:02:02 -0800521 // Modular DRM
522 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
Hassan Shojania071437a2017-01-23 09:19:40 -0800523 {
524 Parcel data, reply;
525 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
526
527 data.write(uuid, 16);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800528 writeVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800529
530 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
531 if (status != OK) {
532 ALOGE("prepareDrm: binder call failed: %d", status);
533 return status;
534 }
535
536 return reply.readInt32();
537 }
538
539 status_t releaseDrm()
540 {
541 Parcel data, reply;
542 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
543
544 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
545 if (status != OK) {
546 ALOGE("releaseDrm: binder call failed: %d", status);
547 return status;
548 }
549
550 return reply.readInt32();
551 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800552};
553
niko56f0cc52009-06-22 08:49:52 -0700554IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800555
556// ----------------------------------------------------------------------
557
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800558status_t BnMediaPlayer::onTransact(
559 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
560{
Glenn Kastene53b9ea2012-03-12 16:29:55 -0700561 switch (code) {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800562 case DISCONNECT: {
563 CHECK_INTERFACE(IMediaPlayer, data, reply);
564 disconnect();
565 return NO_ERROR;
566 } break;
Dave Burked681bbb2011-08-30 14:39:17 +0100567 case SET_DATA_SOURCE_URL: {
568 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800569
570 sp<IMediaHTTPService> httpService;
571 if (data.readInt32()) {
572 httpService =
573 interface_cast<IMediaHTTPService>(data.readStrongBinder());
574 }
575
Dave Burked681bbb2011-08-30 14:39:17 +0100576 const char* url = data.readCString();
Wei Jia0ca02a02016-01-14 13:14:31 -0800577 if (url == NULL) {
Wei Jia2afac0c2016-01-07 12:13:07 -0800578 reply->writeInt32(BAD_VALUE);
579 return NO_ERROR;
580 }
Dave Burked681bbb2011-08-30 14:39:17 +0100581 KeyedVector<String8, String8> headers;
582 int32_t numHeaders = data.readInt32();
583 for (int i = 0; i < numHeaders; ++i) {
584 String8 key = data.readString8();
585 String8 value = data.readString8();
586 headers.add(key, value);
587 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800588 reply->writeInt32(setDataSource(
589 httpService, url, numHeaders > 0 ? &headers : NULL));
Dave Burked681bbb2011-08-30 14:39:17 +0100590 return NO_ERROR;
591 } break;
592 case SET_DATA_SOURCE_FD: {
593 CHECK_INTERFACE(IMediaPlayer, data, reply);
594 int fd = data.readFileDescriptor();
595 int64_t offset = data.readInt64();
596 int64_t length = data.readInt64();
597 reply->writeInt32(setDataSource(fd, offset, length));
598 return NO_ERROR;
599 }
600 case SET_DATA_SOURCE_STREAM: {
601 CHECK_INTERFACE(IMediaPlayer, data, reply);
602 sp<IStreamSource> source =
603 interface_cast<IStreamSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800604 if (source == NULL) {
605 reply->writeInt32(BAD_VALUE);
606 } else {
607 reply->writeInt32(setDataSource(source));
608 }
Dave Burked681bbb2011-08-30 14:39:17 +0100609 return NO_ERROR;
610 }
Chris Watkins99f31602015-03-20 13:06:33 -0700611 case SET_DATA_SOURCE_CALLBACK: {
612 CHECK_INTERFACE(IMediaPlayer, data, reply);
613 sp<IDataSource> source =
614 interface_cast<IDataSource>(data.readStrongBinder());
Wei Jia2afac0c2016-01-07 12:13:07 -0800615 if (source == NULL) {
616 reply->writeInt32(BAD_VALUE);
617 } else {
618 reply->writeInt32(setDataSource(source));
619 }
Chris Watkins99f31602015-03-20 13:06:33 -0700620 return NO_ERROR;
621 }
Glenn Kasten11731182011-02-08 17:26:17 -0800622 case SET_VIDEO_SURFACETEXTURE: {
623 CHECK_INTERFACE(IMediaPlayer, data, reply);
Andy McFadden8ba01022012-12-18 09:46:54 -0800624 sp<IGraphicBufferProducer> bufferProducer =
625 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
626 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
Glenn Kasten11731182011-02-08 17:26:17 -0800627 return NO_ERROR;
628 } break;
Wei Jiad399e7e2016-10-26 15:49:11 -0700629 case SET_BUFFERING_SETTINGS: {
630 CHECK_INTERFACE(IMediaPlayer, data, reply);
631 BufferingSettings buffering;
632 buffering.readFromParcel(&data);
633 reply->writeInt32(setBufferingSettings(buffering));
634 return NO_ERROR;
635 } break;
636 case GET_DEFAULT_BUFFERING_SETTINGS: {
637 CHECK_INTERFACE(IMediaPlayer, data, reply);
638 BufferingSettings buffering;
639 status_t err = getDefaultBufferingSettings(&buffering);
640 reply->writeInt32(err);
641 if (err == OK) {
642 buffering.writeToParcel(reply);
643 }
644 return NO_ERROR;
645 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800646 case PREPARE_ASYNC: {
647 CHECK_INTERFACE(IMediaPlayer, data, reply);
648 reply->writeInt32(prepareAsync());
649 return NO_ERROR;
650 } break;
651 case START: {
652 CHECK_INTERFACE(IMediaPlayer, data, reply);
653 reply->writeInt32(start());
654 return NO_ERROR;
655 } break;
656 case STOP: {
657 CHECK_INTERFACE(IMediaPlayer, data, reply);
658 reply->writeInt32(stop());
659 return NO_ERROR;
660 } break;
661 case IS_PLAYING: {
662 CHECK_INTERFACE(IMediaPlayer, data, reply);
663 bool state;
664 status_t ret = isPlaying(&state);
665 reply->writeInt32(state);
666 reply->writeInt32(ret);
667 return NO_ERROR;
668 } break;
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700669 case SET_PLAYBACK_SETTINGS: {
Wei Jia98160162015-02-04 17:01:11 -0800670 CHECK_INTERFACE(IMediaPlayer, data, reply);
Lajos Molnar3a474aa2015-04-24 17:10:07 -0700671 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
672 rate.mSpeed = data.readFloat();
673 rate.mPitch = data.readFloat();
674 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
675 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
676 reply->writeInt32(setPlaybackSettings(rate));
677 return NO_ERROR;
678 } break;
679 case GET_PLAYBACK_SETTINGS: {
680 CHECK_INTERFACE(IMediaPlayer, data, reply);
681 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
682 status_t err = getPlaybackSettings(&rate);
683 reply->writeInt32(err);
684 if (err == OK) {
685 reply->writeFloat(rate.mSpeed);
686 reply->writeFloat(rate.mPitch);
687 reply->writeInt32((int32_t)rate.mFallbackMode);
688 reply->writeInt32((int32_t)rate.mStretchMode);
689 }
690 return NO_ERROR;
691 } break;
692 case SET_SYNC_SETTINGS: {
693 CHECK_INTERFACE(IMediaPlayer, data, reply);
694 AVSyncSettings sync;
695 sync.mSource = (AVSyncSource)data.readInt32();
696 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
697 sync.mTolerance = data.readFloat();
698 float videoFpsHint = data.readFloat();
699 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
700 return NO_ERROR;
701 } break;
702 case GET_SYNC_SETTINGS: {
703 CHECK_INTERFACE(IMediaPlayer, data, reply);
704 AVSyncSettings sync;
705 float videoFps;
706 status_t err = getSyncSettings(&sync, &videoFps);
707 reply->writeInt32(err);
708 if (err == OK) {
709 reply->writeInt32((int32_t)sync.mSource);
710 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
711 reply->writeFloat(sync.mTolerance);
712 reply->writeFloat(videoFps);
713 }
Wei Jia98160162015-02-04 17:01:11 -0800714 return NO_ERROR;
715 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800716 case PAUSE: {
717 CHECK_INTERFACE(IMediaPlayer, data, reply);
718 reply->writeInt32(pause());
719 return NO_ERROR;
720 } break;
721 case SEEK_TO: {
722 CHECK_INTERFACE(IMediaPlayer, data, reply);
Wei Jia67b6dcc2016-10-31 17:01:37 -0700723 int msec = data.readInt32();
Wei Jiac5de0912016-11-18 10:22:14 -0800724 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
725 reply->writeInt32(seekTo(msec, mode));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800726 return NO_ERROR;
727 } break;
728 case GET_CURRENT_POSITION: {
729 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700730 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800731 status_t ret = getCurrentPosition(&msec);
732 reply->writeInt32(msec);
733 reply->writeInt32(ret);
734 return NO_ERROR;
735 } break;
736 case GET_DURATION: {
737 CHECK_INTERFACE(IMediaPlayer, data, reply);
Robert Shih89235432015-09-02 16:46:59 -0700738 int msec = 0;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800739 status_t ret = getDuration(&msec);
740 reply->writeInt32(msec);
741 reply->writeInt32(ret);
742 return NO_ERROR;
743 } break;
744 case RESET: {
745 CHECK_INTERFACE(IMediaPlayer, data, reply);
746 reply->writeInt32(reset());
747 return NO_ERROR;
748 } break;
749 case SET_AUDIO_STREAM_TYPE: {
750 CHECK_INTERFACE(IMediaPlayer, data, reply);
Glenn Kastenfff6d712012-01-12 16:38:12 -0800751 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800752 return NO_ERROR;
753 } break;
754 case SET_LOOPING: {
755 CHECK_INTERFACE(IMediaPlayer, data, reply);
756 reply->writeInt32(setLooping(data.readInt32()));
757 return NO_ERROR;
758 } break;
759 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700760 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700761 float leftVolume = data.readFloat();
762 float rightVolume = data.readFloat();
763 reply->writeInt32(setVolume(leftVolume, rightVolume));
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800764 return NO_ERROR;
765 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700766 case INVOKE: {
767 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong040e4a12011-04-06 18:29:01 -0700768 status_t result = invoke(data, reply);
769 return result;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700770 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700771 case SET_METADATA_FILTER: {
772 CHECK_INTERFACE(IMediaPlayer, data, reply);
773 reply->writeInt32(setMetadataFilter(data));
774 return NO_ERROR;
775 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700776 case GET_METADATA: {
777 CHECK_INTERFACE(IMediaPlayer, data, reply);
Gloria Wangde162ff2011-08-01 14:01:29 -0700778 bool update_only = static_cast<bool>(data.readInt32());
779 bool apply_filter = static_cast<bool>(data.readInt32());
780 const status_t retcode = getMetadata(update_only, apply_filter, reply);
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700781 reply->setDataPosition(0);
782 reply->writeInt32(retcode);
783 reply->setDataPosition(0);
784 return NO_ERROR;
785 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700786 case SET_AUX_EFFECT_SEND_LEVEL: {
787 CHECK_INTERFACE(IMediaPlayer, data, reply);
788 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
789 return NO_ERROR;
790 } break;
791 case ATTACH_AUX_EFFECT: {
792 CHECK_INTERFACE(IMediaPlayer, data, reply);
793 reply->writeInt32(attachAuxEffect(data.readInt32()));
794 return NO_ERROR;
795 } break;
Gloria Wang4f9e47f2011-04-25 17:28:22 -0700796 case SET_PARAMETER: {
797 CHECK_INTERFACE(IMediaPlayer, data, reply);
798 int key = data.readInt32();
799
800 Parcel request;
801 if (data.dataAvail() > 0) {
802 request.appendFrom(
803 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
804 }
805 request.setDataPosition(0);
806 reply->writeInt32(setParameter(key, request));
807 return NO_ERROR;
808 } break;
809 case GET_PARAMETER: {
810 CHECK_INTERFACE(IMediaPlayer, data, reply);
811 return getParameter(data.readInt32(), reply);
812 } break;
John Grossmanc795b642012-02-22 15:38:35 -0800813 case SET_RETRANSMIT_ENDPOINT: {
814 CHECK_INTERFACE(IMediaPlayer, data, reply);
815
816 struct sockaddr_in endpoint;
Nick Kralevich0981df62015-08-20 09:56:39 -0700817 memset(&endpoint, 0, sizeof(endpoint));
John Grossmanc795b642012-02-22 15:38:35 -0800818 int amt = data.readInt32();
819 if (amt == sizeof(endpoint)) {
820 data.read(&endpoint, sizeof(struct sockaddr_in));
821 reply->writeInt32(setRetransmitEndpoint(&endpoint));
822 } else {
823 reply->writeInt32(setRetransmitEndpoint(NULL));
824 }
John Grossman44a7e422012-06-21 17:29:24 -0700825
826 return NO_ERROR;
827 } break;
828 case GET_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 Grossman44a7e422012-06-21 17:29:24 -0700833 status_t res = getRetransmitEndpoint(&endpoint);
834
835 reply->writeInt32(res);
836 reply->write(&endpoint, sizeof(endpoint));
837
Marco Nelissen6b74d672012-02-28 16:07:44 -0800838 return NO_ERROR;
839 } break;
840 case SET_NEXT_PLAYER: {
841 CHECK_INTERFACE(IMediaPlayer, data, reply);
842 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
John Grossman44a7e422012-06-21 17:29:24 -0700843
John Grossmanc795b642012-02-22 15:38:35 -0800844 return NO_ERROR;
845 } break;
Hassan Shojania071437a2017-01-23 09:19:40 -0800846
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800847 case APPLY_VOLUME_SHAPER: {
848 CHECK_INTERFACE(IMediaPlayer, data, reply);
849 sp<VolumeShaper::Configuration> configuration;
850 sp<VolumeShaper::Operation> operation;
851
852 int32_t present;
853 status_t status = data.readInt32(&present);
854 if (status == NO_ERROR && present != 0) {
855 configuration = new VolumeShaper::Configuration();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700856 status = configuration->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800857 }
858 if (status == NO_ERROR) {
859 status = data.readInt32(&present);
860 }
861 if (status == NO_ERROR && present != 0) {
862 operation = new VolumeShaper::Operation();
Ivan Lozano8cf3a072017-08-09 09:01:33 -0700863 status = operation->readFromParcel(&data);
Andy Hung9fc8b5c2017-01-24 13:36:48 -0800864 }
865 if (status == NO_ERROR) {
866 status = (status_t)applyVolumeShaper(configuration, operation);
867 }
868 reply->writeInt32(status);
869 return NO_ERROR;
870 } break;
871 case GET_VOLUME_SHAPER_STATE: {
872 CHECK_INTERFACE(IMediaPlayer, data, reply);
873 int id;
874 status_t status = data.readInt32(&id);
875 if (status == NO_ERROR) {
876 sp<VolumeShaper::State> state = getVolumeShaperState(id);
877 if (state.get() != nullptr) {
878 status = state->writeToParcel(reply);
879 }
880 }
881 return NO_ERROR;
882 } break;
883
Hassan Shojaniacefac142017-02-06 21:02:02 -0800884 // Modular DRM
Hassan Shojania071437a2017-01-23 09:19:40 -0800885 case PREPARE_DRM: {
886 CHECK_INTERFACE(IMediaPlayer, data, reply);
Hassan Shojaniacefac142017-02-06 21:02:02 -0800887
Hassan Shojania071437a2017-01-23 09:19:40 -0800888 uint8_t uuid[16];
889 data.read(uuid, sizeof(uuid));
Hassan Shojaniacefac142017-02-06 21:02:02 -0800890 Vector<uint8_t> drmSessionId;
891 readVector(data, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800892
Hassan Shojaniacefac142017-02-06 21:02:02 -0800893 uint32_t result = prepareDrm(uuid, drmSessionId);
Hassan Shojania071437a2017-01-23 09:19:40 -0800894 reply->writeInt32(result);
895 return OK;
896 }
897 case RELEASE_DRM: {
898 CHECK_INTERFACE(IMediaPlayer, data, reply);
899
900 uint32_t result = releaseDrm();
901 reply->writeInt32(result);
902 return OK;
903 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800904 default:
905 return BBinder::onTransact(code, data, reply, flags);
906 }
907}
908
909// ----------------------------------------------------------------------------
910
Glenn Kasten40bc9062015-03-20 09:09:33 -0700911} // namespace android