• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
36 namespace android {
37 
38 enum {
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
readVector(const Parcel & reply,Vector<uint8_t> & vector)81 static 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 
writeVector(Parcel & data,Vector<uint8_t> const & vector)87 static void writeVector(Parcel& data, Vector<uint8_t> const& vector) {
88     data.writeUint32(vector.size());
89     data.write(vector.array(), vector.size());
90 }
91 
92 class BpMediaPlayer: public BpInterface<IMediaPlayer>
93 {
94 public:
BpMediaPlayer(const sp<IBinder> & impl)95     explicit BpMediaPlayer(const sp<IBinder>& impl)
96         : BpInterface<IMediaPlayer>(impl)
97     {
98     }
99 
100     // disconnect from media player service
disconnect()101     void disconnect()
102     {
103         Parcel data, reply;
104         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
105         remote()->transact(DISCONNECT, data, &reply);
106     }
107 
setDataSource(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)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 
setDataSource(int fd,int64_t offset,int64_t length)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 
setDataSource(const sp<IStreamSource> & source)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 
setDataSource(const sp<IDataSource> & source)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
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer)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 
setBufferingSettings(const BufferingSettings & buffering)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 
getDefaultBufferingSettings(BufferingSettings * buffering)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 
prepareAsync()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 
start()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 
stop()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 
isPlaying(bool * state)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 
setPlaybackSettings(const AudioPlaybackRate & rate)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 
getPlaybackSettings(AudioPlaybackRate * rate)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 
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)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 
getSyncSettings(AVSyncSettings * sync,float * videoFps)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 
pause()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 
seekTo(int msec,MediaPlayerSeekMode mode)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 
getCurrentPosition(int * msec)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 
getDuration(int * msec)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 
reset()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 
setAudioStreamType(audio_stream_type_t stream)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 
setLooping(int loop)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 
setVolume(float leftVolume,float rightVolume)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 
invoke(const Parcel & request,Parcel * reply)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 
setMetadataFilter(const Parcel & request)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 
getMetadata(bool update_only,bool apply_filter,Parcel * reply)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 
setAuxEffectSendLevel(float level)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 
attachAuxEffect(int effectId)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 
setParameter(int key,const Parcel & request)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 
getParameter(int key,Parcel * reply)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 
setRetransmitEndpoint(const struct sockaddr_in * endpoint)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 
setNextPlayer(const sp<IMediaPlayer> & player)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 
getRetransmitEndpoint(struct sockaddr_in * endpoint)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 
applyVolumeShaper(const sp<VolumeShaper::Configuration> & configuration,const sp<VolumeShaper::Operation> & operation)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 
getVolumeShaperState(int id)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
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)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 
releaseDrm()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 
552 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
553 
554 // ----------------------------------------------------------------------
555 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)556 status_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