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