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