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 #include <sys/types.h>
21
22 #include <android/IDataSource.h>
23 #include <binder/IPCThreadState.h>
24 #include <binder/Parcel.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <media/AudioResamplerPublic.h>
27 #include <media/AVSyncSettings.h>
28 #include <media/BufferingSettings.h>
29 #include <media/IMediaHTTPService.h>
30 #include <media/IMediaPlayer.h>
31 #include <media/IStreamSource.h>
32 #include <utils/String8.h>
33
34 namespace android {
35
36 using media::VolumeShaper;
37
38 // ModDrm helpers
readVector(const Parcel & reply,Vector<uint8_t> & vector)39 static status_t readVector(const Parcel& reply, Vector<uint8_t>& vector) {
40 uint32_t size = 0;
41 status_t status = reply.readUint32(&size);
42 if (status == OK) {
43 status = size <= reply.dataAvail() ? OK : BAD_VALUE;
44 }
45 if (status == OK) {
46 status = vector.insertAt((size_t) 0, size) >= 0 ? OK : NO_MEMORY;
47 }
48 if (status == OK) {
49 status = reply.read(vector.editArray(), size);
50 }
51 if (status != OK) {
52 char errorMsg[100];
53 char buganizerId[] = "173720767";
54 snprintf(errorMsg,
55 sizeof(errorMsg),
56 "%s: failed to read array. Size: %d, status: %d.",
57 __func__,
58 size,
59 status);
60 android_errorWriteWithInfoLog(
61 /* safetyNet tag= */ 0x534e4554,
62 buganizerId,
63 IPCThreadState::self()->getCallingUid(),
64 errorMsg,
65 strlen(errorMsg));
66 ALOGE("%s (b/%s)", errorMsg, buganizerId);
67 }
68 return status;
69 }
70
writeVector(Parcel & data,Vector<uint8_t> const & vector)71 static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
72 data.writeUint32(vector.size());
73 data.write(vector.array(), vector.size());
74 }
75
76 class BpMediaPlayer: public BpInterface<IMediaPlayer>
77 {
78 public:
BpMediaPlayer(const sp<IBinder> & impl)79 explicit BpMediaPlayer(const sp<IBinder>& impl)
80 : BpInterface<IMediaPlayer>(impl)
81 {
82 }
83
84 // disconnect from media player service
disconnect()85 void disconnect()
86 {
87 Parcel data, reply;
88 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
89 remote()->transact(DISCONNECT, data, &reply);
90 }
91
setDataSource(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)92 status_t setDataSource(
93 const sp<IMediaHTTPService> &httpService,
94 const char* url,
95 const KeyedVector<String8, String8>* headers)
96 {
97 Parcel data, reply;
98 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
99 data.writeInt32(httpService != NULL);
100 if (httpService != NULL) {
101 data.writeStrongBinder(IInterface::asBinder(httpService));
102 }
103 data.writeCString(url);
104 if (headers == NULL) {
105 data.writeInt32(0);
106 } else {
107 // serialize the headers
108 data.writeInt32(headers->size());
109 for (size_t i = 0; i < headers->size(); ++i) {
110 data.writeString8(headers->keyAt(i));
111 data.writeString8(headers->valueAt(i));
112 }
113 }
114 remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
115 return reply.readInt32();
116 }
117
setDataSource(int fd,int64_t offset,int64_t length)118 status_t setDataSource(int fd, int64_t offset, int64_t length) {
119 Parcel data, reply;
120 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
121 data.writeFileDescriptor(fd);
122 data.writeInt64(offset);
123 data.writeInt64(length);
124 remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
125 return reply.readInt32();
126 }
127
setDataSource(const sp<IStreamSource> & source)128 status_t setDataSource(const sp<IStreamSource> &source) {
129 Parcel data, reply;
130 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
131 data.writeStrongBinder(IInterface::asBinder(source));
132 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
133 return reply.readInt32();
134 }
135
setDataSource(const sp<IDataSource> & source)136 status_t setDataSource(const sp<IDataSource> &source) {
137 Parcel data, reply;
138 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
139 data.writeStrongBinder(IInterface::asBinder(source));
140 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
141 return reply.readInt32();
142 }
143
setDataSource(const String8 & rtpParams)144 status_t setDataSource(const String8& rtpParams) {
145 Parcel data, reply;
146 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
147 data.writeString8(rtpParams);
148 remote()->transact(SET_DATA_SOURCE_RTP, data, &reply);
149
150 return reply.readInt32();
151 }
152
153 // pass the buffered IGraphicBufferProducer to the media player service
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer)154 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
155 {
156 Parcel data, reply;
157 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
158 sp<IBinder> b(IInterface::asBinder(bufferProducer));
159 data.writeStrongBinder(b);
160 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
161 return reply.readInt32();
162 }
163
setBufferingSettings(const BufferingSettings & buffering)164 status_t setBufferingSettings(const BufferingSettings& buffering)
165 {
166 Parcel data, reply;
167 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
168 data.writeInt32(buffering.mInitialMarkMs);
169 data.writeInt32(buffering.mResumePlaybackMarkMs);
170 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply);
171 return reply.readInt32();
172 }
173
getBufferingSettings(BufferingSettings * buffering)174 status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */)
175 {
176 if (buffering == nullptr) {
177 return BAD_VALUE;
178 }
179 Parcel data, reply;
180 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
181 remote()->transact(GET_BUFFERING_SETTINGS, data, &reply);
182 status_t err = reply.readInt32();
183 if (err == OK) {
184 buffering->mInitialMarkMs = reply.readInt32();
185 buffering->mResumePlaybackMarkMs = reply.readInt32();
186 }
187 return err;
188 }
189
prepareAsync()190 status_t prepareAsync()
191 {
192 Parcel data, reply;
193 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
194 remote()->transact(PREPARE_ASYNC, data, &reply);
195 return reply.readInt32();
196 }
197
start()198 status_t start()
199 {
200 Parcel data, reply;
201 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
202 remote()->transact(START, data, &reply);
203 return reply.readInt32();
204 }
205
stop()206 status_t stop()
207 {
208 Parcel data, reply;
209 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
210 remote()->transact(STOP, data, &reply);
211 return reply.readInt32();
212 }
213
isPlaying(bool * state)214 status_t isPlaying(bool* state)
215 {
216 Parcel data, reply;
217 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
218 remote()->transact(IS_PLAYING, data, &reply);
219 *state = reply.readInt32();
220 return reply.readInt32();
221 }
222
setPlaybackSettings(const AudioPlaybackRate & rate)223 status_t setPlaybackSettings(const AudioPlaybackRate& rate)
224 {
225 Parcel data, reply;
226 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
227 data.writeFloat(rate.mSpeed);
228 data.writeFloat(rate.mPitch);
229 data.writeInt32((int32_t)rate.mFallbackMode);
230 data.writeInt32((int32_t)rate.mStretchMode);
231 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply);
232 return reply.readInt32();
233 }
234
getPlaybackSettings(AudioPlaybackRate * rate)235 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
236 {
237 Parcel data, reply;
238 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
239 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply);
240 status_t err = reply.readInt32();
241 if (err == OK) {
242 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
243 rate->mSpeed = reply.readFloat();
244 rate->mPitch = reply.readFloat();
245 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32();
246 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32();
247 }
248 return err;
249 }
250
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)251 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
252 {
253 Parcel data, reply;
254 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
255 data.writeInt32((int32_t)sync.mSource);
256 data.writeInt32((int32_t)sync.mAudioAdjustMode);
257 data.writeFloat(sync.mTolerance);
258 data.writeFloat(videoFpsHint);
259 remote()->transact(SET_SYNC_SETTINGS, data, &reply);
260 return reply.readInt32();
261 }
262
getSyncSettings(AVSyncSettings * sync,float * videoFps)263 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
264 {
265 Parcel data, reply;
266 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
267 remote()->transact(GET_SYNC_SETTINGS, data, &reply);
268 status_t err = reply.readInt32();
269 if (err == OK) {
270 AVSyncSettings settings;
271 settings.mSource = (AVSyncSource)reply.readInt32();
272 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32();
273 settings.mTolerance = reply.readFloat();
274 *sync = settings;
275 *videoFps = reply.readFloat();
276 }
277 return err;
278 }
279
pause()280 status_t pause()
281 {
282 Parcel data, reply;
283 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
284 remote()->transact(PAUSE, data, &reply);
285 return reply.readInt32();
286 }
287
seekTo(int msec,MediaPlayerSeekMode mode)288 status_t seekTo(int msec, MediaPlayerSeekMode mode)
289 {
290 Parcel data, reply;
291 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
292 data.writeInt32(msec);
293 data.writeInt32(mode);
294 remote()->transact(SEEK_TO, data, &reply);
295 return reply.readInt32();
296 }
297
getCurrentPosition(int * msec)298 status_t getCurrentPosition(int* msec)
299 {
300 Parcel data, reply;
301 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
302 remote()->transact(GET_CURRENT_POSITION, data, &reply);
303 *msec = reply.readInt32();
304 return reply.readInt32();
305 }
306
getDuration(int * msec)307 status_t getDuration(int* msec)
308 {
309 Parcel data, reply;
310 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
311 remote()->transact(GET_DURATION, data, &reply);
312 *msec = reply.readInt32();
313 return reply.readInt32();
314 }
315
reset()316 status_t reset()
317 {
318 Parcel data, reply;
319 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
320 remote()->transact(RESET, data, &reply);
321 return reply.readInt32();
322 }
323
notifyAt(int64_t mediaTimeUs)324 status_t notifyAt(int64_t mediaTimeUs)
325 {
326 Parcel data, reply;
327 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
328 data.writeInt64(mediaTimeUs);
329 remote()->transact(NOTIFY_AT, data, &reply);
330 return reply.readInt32();
331 }
332
setAudioStreamType(audio_stream_type_t stream)333 status_t setAudioStreamType(audio_stream_type_t stream)
334 {
335 Parcel data, reply;
336 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
337 data.writeInt32((int32_t) stream);
338 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
339 return reply.readInt32();
340 }
341
setLooping(int loop)342 status_t setLooping(int loop)
343 {
344 Parcel data, reply;
345 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
346 data.writeInt32(loop);
347 remote()->transact(SET_LOOPING, data, &reply);
348 return reply.readInt32();
349 }
350
setVolume(float leftVolume,float rightVolume)351 status_t setVolume(float leftVolume, float rightVolume)
352 {
353 Parcel data, reply;
354 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
355 data.writeFloat(leftVolume);
356 data.writeFloat(rightVolume);
357 remote()->transact(SET_VOLUME, data, &reply);
358 return reply.readInt32();
359 }
360
invoke(const Parcel & request,Parcel * reply)361 status_t invoke(const Parcel& request, Parcel *reply)
362 {
363 // Avoid doing any extra copy. The interface descriptor should
364 // have been set by MediaPlayer.java.
365 return remote()->transact(INVOKE, request, reply);
366 }
367
setMetadataFilter(const Parcel & request)368 status_t setMetadataFilter(const Parcel& request)
369 {
370 Parcel reply;
371 // Avoid doing any extra copy of the request. The interface
372 // descriptor should have been set by MediaPlayer.java.
373 remote()->transact(SET_METADATA_FILTER, request, &reply);
374 return reply.readInt32();
375 }
376
getMetadata(bool update_only,bool apply_filter,Parcel * reply)377 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
378 {
379 Parcel request;
380 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
381 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
382 request.writeInt32(update_only);
383 request.writeInt32(apply_filter);
384 remote()->transact(GET_METADATA, request, reply);
385 return reply->readInt32();
386 }
387
setAuxEffectSendLevel(float level)388 status_t setAuxEffectSendLevel(float level)
389 {
390 Parcel data, reply;
391 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
392 data.writeFloat(level);
393 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
394 return reply.readInt32();
395 }
396
attachAuxEffect(int effectId)397 status_t attachAuxEffect(int effectId)
398 {
399 Parcel data, reply;
400 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
401 data.writeInt32(effectId);
402 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
403 return reply.readInt32();
404 }
405
setParameter(int key,const Parcel & request)406 status_t setParameter(int key, const Parcel& request)
407 {
408 Parcel data, reply;
409 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
410 data.writeInt32(key);
411 if (request.dataSize() > 0) {
412 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
413 }
414 remote()->transact(SET_PARAMETER, data, &reply);
415 return reply.readInt32();
416 }
417
getParameter(int key,Parcel * reply)418 status_t getParameter(int key, Parcel *reply)
419 {
420 Parcel data;
421 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
422 data.writeInt32(key);
423 return remote()->transact(GET_PARAMETER, data, reply);
424 }
425
setRetransmitEndpoint(const struct sockaddr_in * endpoint)426 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint)
427 {
428 Parcel data, reply;
429 status_t err;
430
431 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
432 if (NULL != endpoint) {
433 data.writeInt32(sizeof(*endpoint));
434 data.write(endpoint, sizeof(*endpoint));
435 } else {
436 data.writeInt32(0);
437 }
438
439 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
440 if (OK != err) {
441 return err;
442 }
443 return reply.readInt32();
444 }
445
setNextPlayer(const sp<IMediaPlayer> & player)446 status_t setNextPlayer(const sp<IMediaPlayer>& player) {
447 Parcel data, reply;
448 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
449 sp<IBinder> b(IInterface::asBinder(player));
450 data.writeStrongBinder(b);
451 remote()->transact(SET_NEXT_PLAYER, data, &reply);
452 return reply.readInt32();
453 }
454
getRetransmitEndpoint(struct sockaddr_in * endpoint)455 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint)
456 {
457 Parcel data, reply;
458 status_t err;
459
460 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
461 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply);
462
463 if ((OK != err) || (OK != (err = reply.readInt32()))) {
464 return err;
465 }
466
467 data.read(endpoint, sizeof(*endpoint));
468
469 return err;
470 }
471
applyVolumeShaper(const sp<VolumeShaper::Configuration> & configuration,const sp<VolumeShaper::Operation> & operation)472 virtual VolumeShaper::Status applyVolumeShaper(
473 const sp<VolumeShaper::Configuration>& configuration,
474 const sp<VolumeShaper::Operation>& operation) {
475 Parcel data, reply;
476 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
477
478 status_t tmp;
479 status_t status = configuration.get() == nullptr
480 ? data.writeInt32(0)
481 : (tmp = data.writeInt32(1)) != NO_ERROR
482 ? tmp : configuration->writeToParcel(&data);
483 if (status != NO_ERROR) {
484 return VolumeShaper::Status(status);
485 }
486
487 status = operation.get() == nullptr
488 ? status = data.writeInt32(0)
489 : (tmp = data.writeInt32(1)) != NO_ERROR
490 ? tmp : operation->writeToParcel(&data);
491 if (status != NO_ERROR) {
492 return VolumeShaper::Status(status);
493 }
494
495 int32_t remoteVolumeShaperStatus;
496 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
497 if (status == NO_ERROR) {
498 status = reply.readInt32(&remoteVolumeShaperStatus);
499 }
500 if (status != NO_ERROR) {
501 return VolumeShaper::Status(status);
502 }
503 return VolumeShaper::Status(remoteVolumeShaperStatus);
504 }
505
getVolumeShaperState(int id)506 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
507 Parcel data, reply;
508 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
509
510 data.writeInt32(id);
511 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
512 if (status != NO_ERROR) {
513 return nullptr;
514 }
515 sp<VolumeShaper::State> state = new VolumeShaper::State();
516 status = state->readFromParcel(&reply);
517 if (status != NO_ERROR) {
518 return nullptr;
519 }
520 return state;
521 }
522
523 // Modular DRM
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)524 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
525 {
526 Parcel data, reply;
527 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
528
529 data.write(uuid, 16);
530 writeVector(data, drmSessionId);
531
532 status_t status = remote()->transact(PREPARE_DRM, data, &reply);
533 if (status != OK) {
534 ALOGE("prepareDrm: binder call failed: %d", status);
535 return status;
536 }
537
538 return reply.readInt32();
539 }
540
releaseDrm()541 status_t releaseDrm()
542 {
543 Parcel data, reply;
544 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
545
546 status_t status = remote()->transact(RELEASE_DRM, data, &reply);
547 if (status != OK) {
548 ALOGE("releaseDrm: binder call failed: %d", status);
549 return status;
550 }
551
552 return reply.readInt32();
553 }
554
setOutputDevice(audio_port_handle_t deviceId)555 status_t setOutputDevice(audio_port_handle_t deviceId)
556 {
557 Parcel data, reply;
558 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
559
560 data.writeInt32(deviceId);
561
562 status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
563 if (status != OK) {
564 ALOGE("setOutputDevice: binder call failed: %d", status);
565 return status;
566 }
567
568 return reply.readInt32();
569 }
570
getRoutedDeviceId(audio_port_handle_t * deviceId)571 status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
572 {
573 Parcel data, reply;
574 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
575
576 status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
577 if (status != OK) {
578 ALOGE("getRoutedDeviceid: binder call failed: %d", status);
579 *deviceId = AUDIO_PORT_HANDLE_NONE;
580 return status;
581 }
582
583 status = reply.readInt32();
584 if (status != NO_ERROR) {
585 *deviceId = AUDIO_PORT_HANDLE_NONE;
586 } else {
587 *deviceId = reply.readInt32();
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_ID: {
988 CHECK_INTERFACE(IMediaPlayer, data, reply);
989 audio_port_handle_t deviceId;
990 status_t ret = getRoutedDeviceId(&deviceId);
991 reply->writeInt32(ret);
992 if (ret == NO_ERROR) {
993 reply->writeInt32(deviceId);
994 }
995 return NO_ERROR;
996 } break;
997 case ENABLE_AUDIO_DEVICE_CALLBACK: {
998 CHECK_INTERFACE(IMediaPlayer, data, reply);
999 bool enabled;
1000 status_t status = data.readBool(&enabled);
1001 if (status == NO_ERROR) {
1002 reply->writeInt32(enableAudioDeviceCallback(enabled));
1003 } else {
1004 reply->writeInt32(BAD_VALUE);
1005 }
1006 return NO_ERROR;
1007 } break;
1008
1009 default:
1010 return BBinder::onTransact(code, data, reply, flags);
1011 }
1012 }
1013
1014 // ----------------------------------------------------------------------------
1015
1016 } // namespace android
1017