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