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
getRoutedDeviceId(audio_port_handle_t * deviceId)570 status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
571 {
572 Parcel data, reply;
573 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
574
575 status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
576 if (status != OK) {
577 ALOGE("getRoutedDeviceid: binder call failed: %d", status);
578 *deviceId = AUDIO_PORT_HANDLE_NONE;
579 return status;
580 }
581
582 status = reply.readInt32();
583 if (status != NO_ERROR) {
584 *deviceId = AUDIO_PORT_HANDLE_NONE;
585 } else {
586 *deviceId = reply.readInt32();
587 }
588 return status;
589 }
590
enableAudioDeviceCallback(bool enabled)591 status_t enableAudioDeviceCallback(bool enabled)
592 {
593 Parcel data, reply;
594 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
595
596 data.writeBool(enabled);
597
598 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
599 if (status != OK) {
600 ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
601 return status;
602 }
603
604 return reply.readInt32();
605 }
606 };
607
608 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
609
610 // ----------------------------------------------------------------------
611
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)612 status_t BnMediaPlayer::onTransact(
613 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
614 {
615 switch (code) {
616 case DISCONNECT: {
617 CHECK_INTERFACE(IMediaPlayer, data, reply);
618 disconnect();
619 return NO_ERROR;
620 } break;
621 case SET_DATA_SOURCE_URL: {
622 CHECK_INTERFACE(IMediaPlayer, data, reply);
623
624 sp<IMediaHTTPService> httpService;
625 if (data.readInt32()) {
626 httpService =
627 interface_cast<IMediaHTTPService>(data.readStrongBinder());
628 }
629
630 const char* url = data.readCString();
631 if (url == NULL) {
632 reply->writeInt32(BAD_VALUE);
633 return NO_ERROR;
634 }
635 KeyedVector<String8, String8> headers;
636 int32_t numHeaders = data.readInt32();
637 for (int i = 0; i < numHeaders; ++i) {
638 String8 key = data.readString8();
639 String8 value = data.readString8();
640 headers.add(key, value);
641 }
642 reply->writeInt32(setDataSource(
643 httpService, url, numHeaders > 0 ? &headers : NULL));
644 return NO_ERROR;
645 } break;
646 case SET_DATA_SOURCE_FD: {
647 CHECK_INTERFACE(IMediaPlayer, data, reply);
648 int fd = data.readFileDescriptor();
649 int64_t offset = data.readInt64();
650 int64_t length = data.readInt64();
651 reply->writeInt32(setDataSource(fd, offset, length));
652 return NO_ERROR;
653 }
654 case SET_DATA_SOURCE_STREAM: {
655 CHECK_INTERFACE(IMediaPlayer, data, reply);
656 sp<IStreamSource> source =
657 interface_cast<IStreamSource>(data.readStrongBinder());
658 if (source == NULL) {
659 reply->writeInt32(BAD_VALUE);
660 } else {
661 reply->writeInt32(setDataSource(source));
662 }
663 return NO_ERROR;
664 }
665 case SET_DATA_SOURCE_CALLBACK: {
666 CHECK_INTERFACE(IMediaPlayer, data, reply);
667 sp<IDataSource> source =
668 interface_cast<IDataSource>(data.readStrongBinder());
669 if (source == NULL) {
670 reply->writeInt32(BAD_VALUE);
671 } else {
672 reply->writeInt32(setDataSource(source));
673 }
674 return NO_ERROR;
675 }
676 case SET_DATA_SOURCE_RTP: {
677 CHECK_INTERFACE(IMediaPlayer, data, reply);
678 String8 rtpParams = data.readString8();
679 reply->writeInt32(setDataSource(rtpParams));
680 return NO_ERROR;
681 }
682 case SET_VIDEO_SURFACETEXTURE: {
683 CHECK_INTERFACE(IMediaPlayer, data, reply);
684 sp<IGraphicBufferProducer> bufferProducer =
685 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
686 reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
687 return NO_ERROR;
688 } break;
689 case SET_BUFFERING_SETTINGS: {
690 CHECK_INTERFACE(IMediaPlayer, data, reply);
691 BufferingSettings buffering;
692 buffering.mInitialMarkMs = data.readInt32();
693 buffering.mResumePlaybackMarkMs = data.readInt32();
694 reply->writeInt32(setBufferingSettings(buffering));
695 return NO_ERROR;
696 } break;
697 case GET_BUFFERING_SETTINGS: {
698 CHECK_INTERFACE(IMediaPlayer, data, reply);
699 BufferingSettings buffering;
700 status_t err = getBufferingSettings(&buffering);
701 reply->writeInt32(err);
702 if (err == OK) {
703 reply->writeInt32(buffering.mInitialMarkMs);
704 reply->writeInt32(buffering.mResumePlaybackMarkMs);
705 }
706 return NO_ERROR;
707 } break;
708 case PREPARE_ASYNC: {
709 CHECK_INTERFACE(IMediaPlayer, data, reply);
710 reply->writeInt32(prepareAsync());
711 return NO_ERROR;
712 } break;
713 case START: {
714 CHECK_INTERFACE(IMediaPlayer, data, reply);
715 reply->writeInt32(start());
716 return NO_ERROR;
717 } break;
718 case STOP: {
719 CHECK_INTERFACE(IMediaPlayer, data, reply);
720 reply->writeInt32(stop());
721 return NO_ERROR;
722 } break;
723 case IS_PLAYING: {
724 CHECK_INTERFACE(IMediaPlayer, data, reply);
725 bool state;
726 status_t ret = isPlaying(&state);
727 reply->writeInt32(state);
728 reply->writeInt32(ret);
729 return NO_ERROR;
730 } break;
731 case SET_PLAYBACK_SETTINGS: {
732 CHECK_INTERFACE(IMediaPlayer, data, reply);
733 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
734 rate.mSpeed = data.readFloat();
735 rate.mPitch = data.readFloat();
736 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
737 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
738 reply->writeInt32(setPlaybackSettings(rate));
739 return NO_ERROR;
740 } break;
741 case GET_PLAYBACK_SETTINGS: {
742 CHECK_INTERFACE(IMediaPlayer, data, reply);
743 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
744 status_t err = getPlaybackSettings(&rate);
745 reply->writeInt32(err);
746 if (err == OK) {
747 reply->writeFloat(rate.mSpeed);
748 reply->writeFloat(rate.mPitch);
749 reply->writeInt32((int32_t)rate.mFallbackMode);
750 reply->writeInt32((int32_t)rate.mStretchMode);
751 }
752 return NO_ERROR;
753 } break;
754 case SET_SYNC_SETTINGS: {
755 CHECK_INTERFACE(IMediaPlayer, data, reply);
756 AVSyncSettings sync;
757 sync.mSource = (AVSyncSource)data.readInt32();
758 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
759 sync.mTolerance = data.readFloat();
760 float videoFpsHint = data.readFloat();
761 reply->writeInt32(setSyncSettings(sync, videoFpsHint));
762 return NO_ERROR;
763 } break;
764 case GET_SYNC_SETTINGS: {
765 CHECK_INTERFACE(IMediaPlayer, data, reply);
766 AVSyncSettings sync;
767 float videoFps;
768 status_t err = getSyncSettings(&sync, &videoFps);
769 reply->writeInt32(err);
770 if (err == OK) {
771 reply->writeInt32((int32_t)sync.mSource);
772 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
773 reply->writeFloat(sync.mTolerance);
774 reply->writeFloat(videoFps);
775 }
776 return NO_ERROR;
777 } break;
778 case PAUSE: {
779 CHECK_INTERFACE(IMediaPlayer, data, reply);
780 reply->writeInt32(pause());
781 return NO_ERROR;
782 } break;
783 case SEEK_TO: {
784 CHECK_INTERFACE(IMediaPlayer, data, reply);
785 int msec = data.readInt32();
786 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
787 reply->writeInt32(seekTo(msec, mode));
788 return NO_ERROR;
789 } break;
790 case GET_CURRENT_POSITION: {
791 CHECK_INTERFACE(IMediaPlayer, data, reply);
792 int msec = 0;
793 status_t ret = getCurrentPosition(&msec);
794 reply->writeInt32(msec);
795 reply->writeInt32(ret);
796 return NO_ERROR;
797 } break;
798 case GET_DURATION: {
799 CHECK_INTERFACE(IMediaPlayer, data, reply);
800 int msec = 0;
801 status_t ret = getDuration(&msec);
802 reply->writeInt32(msec);
803 reply->writeInt32(ret);
804 return NO_ERROR;
805 } break;
806 case RESET: {
807 CHECK_INTERFACE(IMediaPlayer, data, reply);
808 reply->writeInt32(reset());
809 return NO_ERROR;
810 } break;
811 case NOTIFY_AT: {
812 CHECK_INTERFACE(IMediaPlayer, data, reply);
813 reply->writeInt32(notifyAt(data.readInt64()));
814 return NO_ERROR;
815 } break;
816 case SET_AUDIO_STREAM_TYPE: {
817 CHECK_INTERFACE(IMediaPlayer, data, reply);
818 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
819 return NO_ERROR;
820 } break;
821 case SET_LOOPING: {
822 CHECK_INTERFACE(IMediaPlayer, data, reply);
823 reply->writeInt32(setLooping(data.readInt32()));
824 return NO_ERROR;
825 } break;
826 case SET_VOLUME: {
827 CHECK_INTERFACE(IMediaPlayer, data, reply);
828 float leftVolume = data.readFloat();
829 float rightVolume = data.readFloat();
830 reply->writeInt32(setVolume(leftVolume, rightVolume));
831 return NO_ERROR;
832 } break;
833 case INVOKE: {
834 CHECK_INTERFACE(IMediaPlayer, data, reply);
835 status_t result = invoke(data, reply);
836 return result;
837 } break;
838 case SET_METADATA_FILTER: {
839 CHECK_INTERFACE(IMediaPlayer, data, reply);
840 reply->writeInt32(setMetadataFilter(data));
841 return NO_ERROR;
842 } break;
843 case GET_METADATA: {
844 CHECK_INTERFACE(IMediaPlayer, data, reply);
845 bool update_only = static_cast<bool>(data.readInt32());
846 bool apply_filter = static_cast<bool>(data.readInt32());
847 const status_t retcode = getMetadata(update_only, apply_filter, reply);
848 reply->setDataPosition(0);
849 reply->writeInt32(retcode);
850 reply->setDataPosition(0);
851 return NO_ERROR;
852 } break;
853 case SET_AUX_EFFECT_SEND_LEVEL: {
854 CHECK_INTERFACE(IMediaPlayer, data, reply);
855 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
856 return NO_ERROR;
857 } break;
858 case ATTACH_AUX_EFFECT: {
859 CHECK_INTERFACE(IMediaPlayer, data, reply);
860 reply->writeInt32(attachAuxEffect(data.readInt32()));
861 return NO_ERROR;
862 } break;
863 case SET_PARAMETER: {
864 CHECK_INTERFACE(IMediaPlayer, data, reply);
865 int key = data.readInt32();
866
867 Parcel request;
868 if (data.dataAvail() > 0) {
869 request.appendFrom(
870 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
871 }
872 request.setDataPosition(0);
873 reply->writeInt32(setParameter(key, request));
874 return NO_ERROR;
875 } break;
876 case GET_PARAMETER: {
877 CHECK_INTERFACE(IMediaPlayer, data, reply);
878 return getParameter(data.readInt32(), reply);
879 } break;
880 case SET_RETRANSMIT_ENDPOINT: {
881 CHECK_INTERFACE(IMediaPlayer, data, reply);
882
883 struct sockaddr_in endpoint;
884 memset(&endpoint, 0, sizeof(endpoint));
885 int amt = data.readInt32();
886 if (amt == sizeof(endpoint)) {
887 data.read(&endpoint, sizeof(struct sockaddr_in));
888 reply->writeInt32(setRetransmitEndpoint(&endpoint));
889 } else {
890 reply->writeInt32(setRetransmitEndpoint(NULL));
891 }
892
893 return NO_ERROR;
894 } break;
895 case GET_RETRANSMIT_ENDPOINT: {
896 CHECK_INTERFACE(IMediaPlayer, data, reply);
897
898 struct sockaddr_in endpoint;
899 memset(&endpoint, 0, sizeof(endpoint));
900 status_t res = getRetransmitEndpoint(&endpoint);
901
902 reply->writeInt32(res);
903 reply->write(&endpoint, sizeof(endpoint));
904
905 return NO_ERROR;
906 } break;
907 case SET_NEXT_PLAYER: {
908 CHECK_INTERFACE(IMediaPlayer, data, reply);
909 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
910
911 return NO_ERROR;
912 } break;
913
914 case APPLY_VOLUME_SHAPER: {
915 CHECK_INTERFACE(IMediaPlayer, data, reply);
916 sp<VolumeShaper::Configuration> configuration;
917 sp<VolumeShaper::Operation> operation;
918
919 int32_t present;
920 status_t status = data.readInt32(&present);
921 if (status == NO_ERROR && present != 0) {
922 configuration = new VolumeShaper::Configuration();
923 status = configuration->readFromParcel(&data);
924 }
925 if (status == NO_ERROR) {
926 status = data.readInt32(&present);
927 }
928 if (status == NO_ERROR && present != 0) {
929 operation = new VolumeShaper::Operation();
930 status = operation->readFromParcel(&data);
931 }
932 if (status == NO_ERROR) {
933 status = (status_t)applyVolumeShaper(configuration, operation);
934 }
935 reply->writeInt32(status);
936 return NO_ERROR;
937 } break;
938 case GET_VOLUME_SHAPER_STATE: {
939 CHECK_INTERFACE(IMediaPlayer, data, reply);
940 int id;
941 status_t status = data.readInt32(&id);
942 if (status == NO_ERROR) {
943 sp<VolumeShaper::State> state = getVolumeShaperState(id);
944 if (state.get() != nullptr) {
945 status = state->writeToParcel(reply);
946 }
947 }
948 return NO_ERROR;
949 } break;
950
951 // Modular DRM
952 case PREPARE_DRM: {
953 CHECK_INTERFACE(IMediaPlayer, data, reply);
954
955 uint8_t uuid[16] = {};
956 data.read(uuid, sizeof(uuid));
957 Vector<uint8_t> drmSessionId;
958 status_t status = readVector(data, drmSessionId);
959 if (status != OK) {
960 return status;
961 }
962 uint32_t result = prepareDrm(uuid, drmSessionId);
963 reply->writeInt32(result);
964 return OK;
965 }
966 case RELEASE_DRM: {
967 CHECK_INTERFACE(IMediaPlayer, data, reply);
968
969 uint32_t result = releaseDrm();
970 reply->writeInt32(result);
971 return OK;
972 }
973
974 // AudioRouting
975 case SET_OUTPUT_DEVICE: {
976 CHECK_INTERFACE(IMediaPlayer, data, reply);
977 int deviceId;
978 status_t status = data.readInt32(&deviceId);
979 if (status == NO_ERROR) {
980 reply->writeInt32(setOutputDevice(deviceId));
981 } else {
982 reply->writeInt32(BAD_VALUE);
983 }
984 return NO_ERROR;
985 }
986 case GET_ROUTED_DEVICE_ID: {
987 CHECK_INTERFACE(IMediaPlayer, data, reply);
988 audio_port_handle_t deviceId;
989 status_t ret = getRoutedDeviceId(&deviceId);
990 reply->writeInt32(ret);
991 if (ret == NO_ERROR) {
992 reply->writeInt32(deviceId);
993 }
994 return NO_ERROR;
995 } break;
996 case ENABLE_AUDIO_DEVICE_CALLBACK: {
997 CHECK_INTERFACE(IMediaPlayer, data, reply);
998 bool enabled;
999 status_t status = data.readBool(&enabled);
1000 if (status == NO_ERROR) {
1001 reply->writeInt32(enableAudioDeviceCallback(enabled));
1002 } else {
1003 reply->writeInt32(BAD_VALUE);
1004 }
1005 return NO_ERROR;
1006 } break;
1007
1008 default:
1009 return BBinder::onTransact(code, data, reply, flags);
1010 }
1011 }
1012
1013 // ----------------------------------------------------------------------------
1014
1015 } // namespace android
1016