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