1 /*
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
18 #include <arpa/inet.h>
19 #include <stdint.h>
20
21 #include <android/IDataSource.h>
22 #include <binder/IPCThreadState.h>
23 #include <binder/Parcel.h>
24 #include <gui/IGraphicBufferProducer.h>
25 #include <media/AudioResamplerPublic.h>
26 #include <media/AVSyncSettings.h>
27 #include <media/BufferingSettings.h>
28 #include <media/IMediaHTTPService.h>
29 #include <media/IMediaPlayer.h>
30 #include <media/IStreamSource.h>
31 #include <utils/String8.h>
32
33 namespace android {
34
35 using media::VolumeShaper;
36
37 // ModDrm helpers
readVector(const Parcel & reply,Vector<uint8_t> & vector)38 static status_t readVector(const Parcel& reply, Vector<uint8_t>& vector) {
39 uint32_t size = 0;
40 status_t status = reply.readUint32(&size);
41 if (status == OK) {
42 status = size <= reply.dataAvail() ? OK : BAD_VALUE;
43 }
44 if (status == OK) {
45 status = vector.insertAt((size_t) 0, size) >= 0 ? OK : NO_MEMORY;
46 }
47 if (status == OK) {
48 status = reply.read(vector.editArray(), size);
49 }
50 if (status != OK) {
51 char errorMsg[100];
52 char buganizerId[] = "173720767";
53 snprintf(errorMsg,
54 sizeof(errorMsg),
55 "%s: failed to read array. Size: %d, status: %d.",
56 __func__,
57 size,
58 status);
59 android_errorWriteWithInfoLog(
60 /* safetyNet tag= */ 0x534e4554,
61 buganizerId,
62 IPCThreadState::self()->getCallingUid(),
63 errorMsg,
64 strlen(errorMsg));
65 ALOGE("%s (b/%s)", errorMsg, buganizerId);
66 }
67 return status;
68 }
69
writeVector(Parcel & data,Vector<uint8_t> const & vector)70 static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
71 data.writeUint32(vector.size());
72 data.write(vector.array(), vector.size());
73 }
74
75 class BpMediaPlayer: public BpInterface<IMediaPlayer>
76 {
77 public:
BpMediaPlayer(const sp<IBinder> & impl)78 explicit BpMediaPlayer(const sp<IBinder>& impl)
79 : BpInterface<IMediaPlayer>(impl)
80 {
81 }
82
83 // disconnect from media player service
disconnect()84 void disconnect()
85 {
86 Parcel data, reply;
87 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
88 remote()->transact(DISCONNECT, data, &reply);
89 }
90
setDataSource(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)91 status_t setDataSource(
92 const sp<IMediaHTTPService> &httpService,
93 const char* url,
94 const KeyedVector<String8, String8>* headers)
95 {
96 Parcel data, reply;
97 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
98 data.writeInt32(httpService != NULL);
99 if (httpService != NULL) {
100 data.writeStrongBinder(IInterface::asBinder(httpService));
101 }
102 data.writeCString(url);
103 if (headers == NULL) {
104 data.writeInt32(0);
105 } else {
106 // serialize the headers
107 data.writeInt32(headers->size());
108 for (size_t i = 0; i < headers->size(); ++i) {
109 data.writeString8(headers->keyAt(i));
110 data.writeString8(headers->valueAt(i));
111 }
112 }
113 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
114 return reply.readInt32();
115 }
116
setDataSource(int fd,int64_t offset,int64_t length)117 status_t setDataSource(int fd, int64_t offset, int64_t length) {
118 Parcel data, reply;
119 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
120 data.writeFileDescriptor(fd);
121 data.writeInt64(offset);
122 data.writeInt64(length);
123 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
124 return reply.readInt32();
125 }
126
setDataSource(const sp<IStreamSource> & source)127 status_t setDataSource(const sp<IStreamSource> &source) {
128 Parcel data, reply;
129 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
130 data.writeStrongBinder(IInterface::asBinder(source));
131 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
132 return reply.readInt32();
133 }
134
setDataSource(const sp<IDataSource> & source)135 status_t setDataSource(const sp<IDataSource> &source) {
136 Parcel data, reply;
137 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
138 data.writeStrongBinder(IInterface::asBinder(source));
139 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
140 return reply.readInt32();
141 }
142
setDataSource(const String8 & rtpParams)143 status_t setDataSource(const String8& rtpParams) {
144 Parcel data, reply;
145 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
146 data.writeString8(rtpParams);
147 remote()->transact(SET_DATA_SOURCE_RTP, data, &reply);
148
149 return reply.readInt32();
150 }
151
152 // pass the buffered IGraphicBufferProducer to the media player service
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer)153 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
154 {
155 Parcel data, reply;
156 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
157 sp<IBinder> b(IInterface::asBinder(bufferProducer));
158 data.writeStrongBinder(b);
159 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
160 return reply.readInt32();
161 }
162
setBufferingSettings(const BufferingSettings & buffering)163 status_t setBufferingSettings(const BufferingSettings& buffering)
164 {
165 Parcel data, reply;
166 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
167 data.writeInt32(buffering.mInitialMarkMs);
168 data.writeInt32(buffering.mResumePlaybackMarkMs);
169 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
170 return reply.readInt32();
171 }
172
getBufferingSettings(BufferingSettings * buffering)173 status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */)
174 {
175 if (buffering == nullptr) {
176 return BAD_VALUE;
177 }
178 Parcel data, reply;
179 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
180 remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
181 status_t err = reply.readInt32();
182 if (err == OK) {
183 buffering->mInitialMarkMs = reply.readInt32();
184 buffering->mResumePlaybackMarkMs = reply.readInt32();
185 }
186 return err;
187 }
188
prepareAsync()189 status_t prepareAsync()
190 {
191 Parcel data, reply;
192 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
193 remote()->transact(PREPARE_ASYNC, data, &reply);
194 return reply.readInt32();
195 }
196
start()197 status_t start()
198 {
199 Parcel data, reply;
200 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
201 remote()->transact(START, data, &reply);
202 return reply.readInt32();
203 }
204
stop()205 status_t stop()
206 {
207 Parcel data, reply;
208 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
209 remote()->transact(STOP, data, &reply);
210 return reply.readInt32();
211 }
212
isPlaying(bool * state)213 status_t isPlaying(bool* state)
214 {
215 Parcel data, reply;
216 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
217 remote()->transact(IS_PLAYING, data, &reply);
218 *state = reply.readInt32();
219 return reply.readInt32();
220 }
221
setPlaybackSettings(const AudioPlaybackRate & rate)222 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
223 {
224 Parcel data, reply;
225 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
226 data.writeFloat(rate.mSpeed);
227 data.writeFloat(rate.mPitch);
228 data.writeInt32((int32_t)rate.mFallbackMode);
229 data.writeInt32((int32_t)rate.mStretchMode);
230 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
231 return reply.readInt32();
232 }
233
getPlaybackSettings(AudioPlaybackRate * rate)234 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
235 {
236 Parcel data, reply;
237 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
238 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
239 status_t err = reply.readInt32();
240 if (err == OK) {
241 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
242 rate->mSpeed = reply.readFloat();
243 rate->mPitch = reply.readFloat();
244 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
245 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
246 }
247 return err;
248 }
249
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)250 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
251 {
252 Parcel data, reply;
253 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
254 data.writeInt32((int32_t)sync.mSource);
255 data.writeInt32((int32_t)sync.mAudioAdjustMode);
256 data.writeFloat(sync.mTolerance);
257 data.writeFloat(videoFpsHint);
258 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
259 return reply.readInt32();
260 }
261
getSyncSettings(AVSyncSettings * sync,float * videoFps)262 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
263 {
264 Parcel data, reply;
265 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
266 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
267 status_t err = reply.readInt32();
268 if (err == OK) {
269 AVSyncSettings settings;
270 settings.mSource = (AVSyncSource)reply.readInt32();
271 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
272 settings.mTolerance = reply.readFloat();
273 *sync = settings;
274 *videoFps = reply.readFloat();
275 }
276 return err;
277 }
278
pause()279 status_t pause()
280 {
281 Parcel data, reply;
282 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
283 remote()->transact(PAUSE, data, &reply);
284 return reply.readInt32();
285 }
286
seekTo(int msec,MediaPlayerSeekMode mode)287 status_t seekTo(int msec, MediaPlayerSeekMode mode)
288 {
289 Parcel data, reply;
290 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
291 data.writeInt32(msec);
292 data.writeInt32(mode);
293 remote()->transact(SEEK_TO, data, &reply);
294 return reply.readInt32();
295 }
296
getCurrentPosition(int * msec)297 status_t getCurrentPosition(int* msec)
298 {
299 Parcel data, reply;
300 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
301 remote()->transact(GET_CURRENT_POSITION, data, &reply);
302 *msec = reply.readInt32();
303 return reply.readInt32();
304 }
305
getDuration(int * msec)306 status_t getDuration(int* msec)
307 {
308 Parcel data, reply;
309 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
310 remote()->transact(GET_DURATION, data, &reply);
311 *msec = reply.readInt32();
312 return reply.readInt32();
313 }
314
reset()315 status_t reset()
316 {
317 Parcel data, reply;
318 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
319 remote()->transact(RESET, data, &reply);
320 return reply.readInt32();
321 }
322
notifyAt(int64_t mediaTimeUs)323 status_t notifyAt(int64_t mediaTimeUs)
324 {
325 Parcel data, reply;
326 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
327 data.writeInt64(mediaTimeUs);
328 remote()->transact(NOTIFY_AT, data, &reply);
329 return reply.readInt32();
330 }
331
setAudioStreamType(audio_stream_type_t stream)332 status_t setAudioStreamType(audio_stream_type_t stream)
333 {
334 Parcel data, reply;
335 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
336 data.writeInt32((int32_t) stream);
337 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
338 return reply.readInt32();
339 }
340
setLooping(int loop)341 status_t setLooping(int loop)
342 {
343 Parcel data, reply;
344 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
345 data.writeInt32(loop);
346 remote()->transact(SET_LOOPING, data, &reply);
347 return reply.readInt32();
348 }
349
setVolume(float leftVolume,float rightVolume)350 status_t setVolume(float leftVolume, float rightVolume)
351 {
352 Parcel data, reply;
353 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
354 data.writeFloat(leftVolume);
355 data.writeFloat(rightVolume);
356 remote()->transact(SET_VOLUME, data, &reply);
357 return reply.readInt32();
358 }
359
invoke(const Parcel & request,Parcel * reply)360 status_t invoke(const Parcel& request, Parcel *reply)
361 {
362 // Avoid doing any extra copy. The interface descriptor should
363 // have been set by MediaPlayer.java.
364 return remote()->transact(INVOKE, request, reply);
365 }
366
setMetadataFilter(const Parcel & request)367 status_t setMetadataFilter(const Parcel& request)
368 {
369 Parcel reply;
370 // Avoid doing any extra copy of the request. The interface
371 // descriptor should have been set by MediaPlayer.java.
372 remote()->transact(SET_METADATA_FILTER, request, &reply);
373 return reply.readInt32();
374 }
375
getMetadata(bool update_only,bool apply_filter,Parcel * reply)376 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
377 {
378 Parcel request;
379 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
380 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
381 request.writeInt32(update_only);
382 request.writeInt32(apply_filter);
383 remote()->transact(GET_METADATA, request, reply);
384 return reply->readInt32();
385 }
386
setAuxEffectSendLevel(float level)387 status_t setAuxEffectSendLevel(float level)
388 {
389 Parcel data, reply;
390 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
391 data.writeFloat(level);
392 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
393 return reply.readInt32();
394 }
395
attachAuxEffect(int effectId)396 status_t attachAuxEffect(int effectId)
397 {
398 Parcel data, reply;
399 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
400 data.writeInt32(effectId);
401 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
402 return reply.readInt32();
403 }
404
setParameter(int key,const Parcel & request)405 status_t setParameter(int key, const Parcel& request)
406 {
407 Parcel data, reply;
408 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
409 data.writeInt32(key);
410 if (request.dataSize() > 0) {
411 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
412 }
413 remote()->transact(SET_PARAMETER, data, &reply);
414 return reply.readInt32();
415 }
416
getParameter(int key,Parcel * reply)417 status_t getParameter(int key, Parcel *reply)
418 {
419 Parcel data;
420 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
421 data.writeInt32(key);
422 return remote()->transact(GET_PARAMETER, data, reply);
423 }
424
setRetransmitEndpoint(const struct sockaddr_in * endpoint)425 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
426 {
427 Parcel data, reply;
428 status_t err;
429
430 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
431 if (NULL != endpoint) {
432 data.writeInt32(sizeof(*endpoint));
433 data.write(endpoint, sizeof(*endpoint));
434 } else {
435 data.writeInt32(0);
436 }
437
438 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
439 if (OK != err) {
440 return err;
441 }
442 return reply.readInt32();
443 }
444
setNextPlayer(const sp<IMediaPlayer> & player)445 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
446 Parcel data, reply;
447 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
448 sp<IBinder> b(IInterface::asBinder(player));
449 data.writeStrongBinder(b);
450 remote()->transact(SET_NEXT_PLAYER, data, &reply);
451 return reply.readInt32();
452 }
453
getRetransmitEndpoint(struct sockaddr_in * endpoint)454 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
455 {
456 Parcel data, reply;
457 status_t err;
458
459 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
460 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
461
462 if ((OK != err) || (OK != (err = reply.readInt32()))) {
463 return err;
464 }
465
466 data.read(endpoint, sizeof(*endpoint));
467
468 return err;
469 }
470
applyVolumeShaper(const sp<VolumeShaper::Configuration> & configuration,const sp<VolumeShaper::Operation> & operation)471 virtual VolumeShaper::Status applyVolumeShaper(
472 const sp<VolumeShaper::Configuration>& configuration,
473 const sp<VolumeShaper::Operation>& operation) {
474 Parcel data, reply;
475 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
476
477 status_t tmp;
478 status_t status = configuration.get() == nullptr
479 ? data.writeInt32(0)
480 : (tmp = data.writeInt32(1)) != NO_ERROR
481 ? tmp : configuration->writeToParcel(&data);
482 if (status != NO_ERROR) {
483 return VolumeShaper::Status(status);
484 }
485
486 status = operation.get() == nullptr
487 ? status = data.writeInt32(0)
488 : (tmp = data.writeInt32(1)) != NO_ERROR
489 ? tmp : operation->writeToParcel(&data);
490 if (status != NO_ERROR) {
491 return VolumeShaper::Status(status);
492 }
493
494 int32_t remoteVolumeShaperStatus;
495 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
496 if (status == NO_ERROR) {
497 status = reply.readInt32(&remoteVolumeShaperStatus);
498 }
499 if (status != NO_ERROR) {
500 return VolumeShaper::Status(status);
501 }
502 return VolumeShaper::Status(remoteVolumeShaperStatus);
503 }
504
getVolumeShaperState(int id)505 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
506 Parcel data, reply;
507 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
508
509 data.writeInt32(id);
510 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
511 if (status != NO_ERROR) {
512 return nullptr;
513 }
514 sp<VolumeShaper::State> state = new VolumeShaper::State();
515 status = state->readFromParcel(&reply);
516 if (status != NO_ERROR) {
517 return nullptr;
518 }
519 return state;
520 }
521
522 // Modular DRM
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)523 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
524 {
525 Parcel data, reply;
526 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
527
528 data.write(uuid, 16);
529 writeVector(data, drmSessionId);
530
531 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
532 if (status != OK) {
533 ALOGE("prepareDrm: binder call failed: %d", status);
534 return status;
535 }
536
537 return reply.readInt32();
538 }
539
releaseDrm()540 status_t releaseDrm()
541 {
542 Parcel data, reply;
543 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
544
545 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
546 if (status != OK) {
547 ALOGE("releaseDrm: binder call failed: %d", status);
548 return status;
549 }
550
551 return reply.readInt32();
552 }
553
setOutputDevice(audio_port_handle_t deviceId)554 status_t setOutputDevice(audio_port_handle_t deviceId)
555 {
556 Parcel data, reply;
557 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
558
559 data.writeInt32(deviceId);
560
561 status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
562 if (status != OK) {
563 ALOGE("setOutputDevice: binder call failed: %d", status);
564 return status;
565 }
566
567 return reply.readInt32();
568 }
569
getRoutedDeviceIds(DeviceIdVector & deviceIds)570 status_t getRoutedDeviceIds(DeviceIdVector& deviceIds)
571 {
572 Parcel data, reply;
573 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
574 deviceIds.clear();
575
576 status_t status = remote()->transact(GET_ROUTED_DEVICE_IDS, data, &reply);
577 if (status != OK) {
578 ALOGE("getRoutedDeviceIds: binder call failed: %d", status);
579 return status;
580 }
581
582 status = reply.readInt32();
583 if (status == NO_ERROR) {
584 int size = reply.readInt32();
585 for (int i = 0; i < size; i++) {
586 deviceIds.push_back(reply.readInt32());
587 }
588 }
589 return status;
590 }
591
enableAudioDeviceCallback(bool enabled)592 status_t enableAudioDeviceCallback(bool enabled)
593 {
594 Parcel data, reply;
595 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
596
597 data.writeBool(enabled);
598
599 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
600 if (status != OK) {
601 ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
602 return status;
603 }
604
605 return reply.readInt32();
606 }
607 };
608
609 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
610
611 // ----------------------------------------------------------------------
612
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)613 status_t BnMediaPlayer::onTransact(
614 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
615 {
616 switch (code) {
617 case DISCONNECT: {
618 CHECK_INTERFACE(IMediaPlayer, data, reply);
619 disconnect();
620 return NO_ERROR;
621 } break;
622 case SET_DATA_SOURCE_URL: {
623 CHECK_INTERFACE(IMediaPlayer, data, reply);
624
625 sp<IMediaHTTPService> httpService;
626 if (data.readInt32()) {
627 httpService =
628 interface_cast<IMediaHTTPService>(data.readStrongBinder());
629 }
630
631 const char* url = data.readCString();
632 if (url == NULL) {
633 reply->writeInt32(BAD_VALUE);
634 return NO_ERROR;
635 }
636 KeyedVector<String8, String8> headers;
637 int32_t numHeaders = data.readInt32();
638 for (int i = 0; i < numHeaders; ++i) {
639 String8 key = data.readString8();
640 String8 value = data.readString8();
641 headers.add(key, value);
642 }
643 reply->writeInt32(setDataSource(
644 httpService, url, numHeaders > 0 ? &headers : NULL));
645 return NO_ERROR;
646 } break;
647 case SET_DATA_SOURCE_FD: {
648 CHECK_INTERFACE(IMediaPlayer, data, reply);
649 int fd = data.readFileDescriptor();
650 int64_t offset = data.readInt64();
651 int64_t length = data.readInt64();
652 reply->writeInt32(setDataSource(fd, offset, length));
653 return NO_ERROR;
654 }
655 case SET_DATA_SOURCE_STREAM: {
656 CHECK_INTERFACE(IMediaPlayer, data, reply);
657 sp<IStreamSource> source =
658 interface_cast<IStreamSource>(data.readStrongBinder());
659 if (source == NULL) {
660 reply->writeInt32(BAD_VALUE);
661 } else {
662 reply->writeInt32(setDataSource(source));
663 }
664 return NO_ERROR;
665 }
666 case SET_DATA_SOURCE_CALLBACK: {
667 CHECK_INTERFACE(IMediaPlayer, data, reply);
668 sp<IDataSource> source =
669 interface_cast<IDataSource>(data.readStrongBinder());
670 if (source == NULL) {
671 reply->writeInt32(BAD_VALUE);
672 } else {
673 reply->writeInt32(setDataSource(source));
674 }
675 return NO_ERROR;
676 }
677 case SET_DATA_SOURCE_RTP: {
678 CHECK_INTERFACE(IMediaPlayer, data, reply);
679 String8 rtpParams = data.readString8();
680 reply->writeInt32(setDataSource(rtpParams));
681 return NO_ERROR;
682 }
683 case SET_VIDEO_SURFACETEXTURE: {
684 CHECK_INTERFACE(IMediaPlayer, data, reply);
685 sp<IGraphicBufferProducer> bufferProducer =
686 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
687 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
688 return NO_ERROR;
689 } break;
690 case SET_BUFFERING_SETTINGS: {
691 CHECK_INTERFACE(IMediaPlayer, data, reply);
692 BufferingSettings buffering;
693 buffering.mInitialMarkMs = data.readInt32();
694 buffering.mResumePlaybackMarkMs = data.readInt32();
695 reply->writeInt32(setBufferingSettings(buffering));
696 return NO_ERROR;
697 } break;
698 case GET_BUFFERING_SETTINGS: {
699 CHECK_INTERFACE(IMediaPlayer, data, reply);
700 BufferingSettings buffering;
701 status_t err = getBufferingSettings(&buffering);
702 reply->writeInt32(err);
703 if (err == OK) {
704 reply->writeInt32(buffering.mInitialMarkMs);
705 reply->writeInt32(buffering.mResumePlaybackMarkMs);
706 }
707 return NO_ERROR;
708 } break;
709 case PREPARE_ASYNC: {
710 CHECK_INTERFACE(IMediaPlayer, data, reply);
711 reply->writeInt32(prepareAsync());
712 return NO_ERROR;
713 } break;
714 case START: {
715 CHECK_INTERFACE(IMediaPlayer, data, reply);
716 reply->writeInt32(start());
717 return NO_ERROR;
718 } break;
719 case STOP: {
720 CHECK_INTERFACE(IMediaPlayer, data, reply);
721 reply->writeInt32(stop());
722 return NO_ERROR;
723 } break;
724 case IS_PLAYING: {
725 CHECK_INTERFACE(IMediaPlayer, data, reply);
726 bool state;
727 status_t ret = isPlaying(&state);
728 reply->writeInt32(state);
729 reply->writeInt32(ret);
730 return NO_ERROR;
731 } break;
732 case SET_PLAYBACK_SETTINGS: {
733 CHECK_INTERFACE(IMediaPlayer, data, reply);
734 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
735 rate.mSpeed = data.readFloat();
736 rate.mPitch = data.readFloat();
737 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
738 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
739 reply->writeInt32(setPlaybackSettings(rate));
740 return NO_ERROR;
741 } break;
742 case GET_PLAYBACK_SETTINGS: {
743 CHECK_INTERFACE(IMediaPlayer, data, reply);
744 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
745 status_t err = getPlaybackSettings(&rate);
746 reply->writeInt32(err);
747 if (err == OK) {
748 reply->writeFloat(rate.mSpeed);
749 reply->writeFloat(rate.mPitch);
750 reply->writeInt32((int32_t)rate.mFallbackMode);
751 reply->writeInt32((int32_t)rate.mStretchMode);
752 }
753 return NO_ERROR;
754 } break;
755 case SET_SYNC_SETTINGS: {
756 CHECK_INTERFACE(IMediaPlayer, data, reply);
757 AVSyncSettings sync;
758 sync.mSource = (AVSyncSource)data.readInt32();
759 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
760 sync.mTolerance = data.readFloat();
761 float videoFpsHint = data.readFloat();
762 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
763 return NO_ERROR;
764 } break;
765 case GET_SYNC_SETTINGS: {
766 CHECK_INTERFACE(IMediaPlayer, data, reply);
767 AVSyncSettings sync;
768 float videoFps;
769 status_t err = getSyncSettings(&sync, &videoFps);
770 reply->writeInt32(err);
771 if (err == OK) {
772 reply->writeInt32((int32_t)sync.mSource);
773 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
774 reply->writeFloat(sync.mTolerance);
775 reply->writeFloat(videoFps);
776 }
777 return NO_ERROR;
778 } break;
779 case PAUSE: {
780 CHECK_INTERFACE(IMediaPlayer, data, reply);
781 reply->writeInt32(pause());
782 return NO_ERROR;
783 } break;
784 case SEEK_TO: {
785 CHECK_INTERFACE(IMediaPlayer, data, reply);
786 int msec = data.readInt32();
787 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
788 reply->writeInt32(seekTo(msec, mode));
789 return NO_ERROR;
790 } break;
791 case GET_CURRENT_POSITION: {
792 CHECK_INTERFACE(IMediaPlayer, data, reply);
793 int msec = 0;
794 status_t ret = getCurrentPosition(&msec);
795 reply->writeInt32(msec);
796 reply->writeInt32(ret);
797 return NO_ERROR;
798 } break;
799 case GET_DURATION: {
800 CHECK_INTERFACE(IMediaPlayer, data, reply);
801 int msec = 0;
802 status_t ret = getDuration(&msec);
803 reply->writeInt32(msec);
804 reply->writeInt32(ret);
805 return NO_ERROR;
806 } break;
807 case RESET: {
808 CHECK_INTERFACE(IMediaPlayer, data, reply);
809 reply->writeInt32(reset());
810 return NO_ERROR;
811 } break;
812 case NOTIFY_AT: {
813 CHECK_INTERFACE(IMediaPlayer, data, reply);
814 reply->writeInt32(notifyAt(data.readInt64()));
815 return NO_ERROR;
816 } break;
817 case SET_AUDIO_STREAM_TYPE: {
818 CHECK_INTERFACE(IMediaPlayer, data, reply);
819 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
820 return NO_ERROR;
821 } break;
822 case SET_LOOPING: {
823 CHECK_INTERFACE(IMediaPlayer, data, reply);
824 reply->writeInt32(setLooping(data.readInt32()));
825 return NO_ERROR;
826 } break;
827 case SET_VOLUME: {
828 CHECK_INTERFACE(IMediaPlayer, data, reply);
829 float leftVolume = data.readFloat();
830 float rightVolume = data.readFloat();
831 reply->writeInt32(setVolume(leftVolume, rightVolume));
832 return NO_ERROR;
833 } break;
834 case INVOKE: {
835 CHECK_INTERFACE(IMediaPlayer, data, reply);
836 status_t result = invoke(data, reply);
837 return result;
838 } break;
839 case SET_METADATA_FILTER: {
840 CHECK_INTERFACE(IMediaPlayer, data, reply);
841 reply->writeInt32(setMetadataFilter(data));
842 return NO_ERROR;
843 } break;
844 case GET_METADATA: {
845 CHECK_INTERFACE(IMediaPlayer, data, reply);
846 bool update_only = static_cast<bool>(data.readInt32());
847 bool apply_filter = static_cast<bool>(data.readInt32());
848 const status_t retcode = getMetadata(update_only, apply_filter, reply);
849 reply->setDataPosition(0);
850 reply->writeInt32(retcode);
851 reply->setDataPosition(0);
852 return NO_ERROR;
853 } break;
854 case SET_AUX_EFFECT_SEND_LEVEL: {
855 CHECK_INTERFACE(IMediaPlayer, data, reply);
856 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
857 return NO_ERROR;
858 } break;
859 case ATTACH_AUX_EFFECT: {
860 CHECK_INTERFACE(IMediaPlayer, data, reply);
861 reply->writeInt32(attachAuxEffect(data.readInt32()));
862 return NO_ERROR;
863 } break;
864 case SET_PARAMETER: {
865 CHECK_INTERFACE(IMediaPlayer, data, reply);
866 int key = data.readInt32();
867
868 Parcel request;
869 if (data.dataAvail() > 0) {
870 request.appendFrom(
871 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
872 }
873 request.setDataPosition(0);
874 reply->writeInt32(setParameter(key, request));
875 return NO_ERROR;
876 } break;
877 case GET_PARAMETER: {
878 CHECK_INTERFACE(IMediaPlayer, data, reply);
879 return getParameter(data.readInt32(), reply);
880 } break;
881 case SET_RETRANSMIT_ENDPOINT: {
882 CHECK_INTERFACE(IMediaPlayer, data, reply);
883
884 struct sockaddr_in endpoint;
885 memset(&endpoint, 0, sizeof(endpoint));
886 int amt = data.readInt32();
887 if (amt == sizeof(endpoint)) {
888 data.read(&endpoint, sizeof(struct sockaddr_in));
889 reply->writeInt32(setRetransmitEndpoint(&endpoint));
890 } else {
891 reply->writeInt32(setRetransmitEndpoint(NULL));
892 }
893
894 return NO_ERROR;
895 } break;
896 case GET_RETRANSMIT_ENDPOINT: {
897 CHECK_INTERFACE(IMediaPlayer, data, reply);
898
899 struct sockaddr_in endpoint;
900 memset(&endpoint, 0, sizeof(endpoint));
901 status_t res = getRetransmitEndpoint(&endpoint);
902
903 reply->writeInt32(res);
904 reply->write(&endpoint, sizeof(endpoint));
905
906 return NO_ERROR;
907 } break;
908 case SET_NEXT_PLAYER: {
909 CHECK_INTERFACE(IMediaPlayer, data, reply);
910 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
911
912 return NO_ERROR;
913 } break;
914
915 case APPLY_VOLUME_SHAPER: {
916 CHECK_INTERFACE(IMediaPlayer, data, reply);
917 sp<VolumeShaper::Configuration> configuration;
918 sp<VolumeShaper::Operation> operation;
919
920 int32_t present;
921 status_t status = data.readInt32(&present);
922 if (status == NO_ERROR && present != 0) {
923 configuration = new VolumeShaper::Configuration();
924 status = configuration->readFromParcel(&data);
925 }
926 if (status == NO_ERROR) {
927 status = data.readInt32(&present);
928 }
929 if (status == NO_ERROR && present != 0) {
930 operation = new VolumeShaper::Operation();
931 status = operation->readFromParcel(&data);
932 }
933 if (status == NO_ERROR) {
934 status = (status_t)applyVolumeShaper(configuration, operation);
935 }
936 reply->writeInt32(status);
937 return NO_ERROR;
938 } break;
939 case GET_VOLUME_SHAPER_STATE: {
940 CHECK_INTERFACE(IMediaPlayer, data, reply);
941 int id;
942 status_t status = data.readInt32(&id);
943 if (status == NO_ERROR) {
944 sp<VolumeShaper::State> state = getVolumeShaperState(id);
945 if (state.get() != nullptr) {
946 status = state->writeToParcel(reply);
947 }
948 }
949 return NO_ERROR;
950 } break;
951
952 // Modular DRM
953 case PREPARE_DRM: {
954 CHECK_INTERFACE(IMediaPlayer, data, reply);
955
956 uint8_t uuid[16] = {};
957 data.read(uuid, sizeof(uuid));
958 Vector<uint8_t> drmSessionId;
959 status_t status = readVector(data, drmSessionId);
960 if (status != OK) {
961 return status;
962 }
963 uint32_t result = prepareDrm(uuid, drmSessionId);
964 reply->writeInt32(result);
965 return OK;
966 }
967 case RELEASE_DRM: {
968 CHECK_INTERFACE(IMediaPlayer, data, reply);
969
970 uint32_t result = releaseDrm();
971 reply->writeInt32(result);
972 return OK;
973 }
974
975 // AudioRouting
976 case SET_OUTPUT_DEVICE: {
977 CHECK_INTERFACE(IMediaPlayer, data, reply);
978 int deviceId;
979 status_t status = data.readInt32(&deviceId);
980 if (status == NO_ERROR) {
981 reply->writeInt32(setOutputDevice(deviceId));
982 } else {
983 reply->writeInt32(BAD_VALUE);
984 }
985 return NO_ERROR;
986 }
987 case GET_ROUTED_DEVICE_IDS: {
988 CHECK_INTERFACE(IMediaPlayer, data, reply);
989 DeviceIdVector deviceIds;
990 status_t ret = getRoutedDeviceIds(deviceIds);
991 reply->writeInt32(ret);
992 if (ret == NO_ERROR) {
993 reply->writeInt32(deviceIds.size());
994 for (auto deviceId : deviceIds) {
995 reply->writeInt32(deviceId);
996 }
997 }
998 return NO_ERROR;
999 } break;
1000 case ENABLE_AUDIO_DEVICE_CALLBACK: {
1001 CHECK_INTERFACE(IMediaPlayer, data, reply);
1002 bool enabled;
1003 status_t status = data.readBool(&enabled);
1004 if (status == NO_ERROR) {
1005 reply->writeInt32(enableAudioDeviceCallback(enabled));
1006 } else {
1007 reply->writeInt32(BAD_VALUE);
1008 }
1009 return NO_ERROR;
1010 } break;
1011
1012 default:
1013 return BBinder::onTransact(code, data, reply, flags);
1014 }
1015 }
1016
1017 // ----------------------------------------------------------------------------
1018
1019 } // namespace android
1020