xref: /aosp_15_r20/frameworks/av/media/libmedia/IMediaPlayer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 
getRoutedDeviceIds(DeviceIdVector & deviceIds)570     status_t getRoutedDeviceIds(DeviceIdVector& deviceIds)
571     {
572         Parcel data, reply;
573         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
574         deviceIds.clear();
575 
576         status_t status = remote()->transact(GET_ROUTED_DEVICE_IDS, data, &reply);
577         if (status != OK) {
578             ALOGE("getRoutedDeviceIds: binder call failed: %d", status);
579             return status;
580         }
581 
582         status = reply.readInt32();
583         if (status == NO_ERROR) {
584             int size = reply.readInt32();
585             for (int i = 0; i < size; i++) {
586                 deviceIds.push_back(reply.readInt32());
587             }
588         }
589         return status;
590     }
591 
enableAudioDeviceCallback(bool enabled)592     status_t enableAudioDeviceCallback(bool enabled)
593     {
594         Parcel data, reply;
595         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
596 
597         data.writeBool(enabled);
598 
599         status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
600         if (status != OK) {
601             ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
602             return status;
603         }
604 
605         return reply.readInt32();
606     }
607 };
608 
609 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
610 
611 // ----------------------------------------------------------------------
612 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)613 status_t BnMediaPlayer::onTransact(
614     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
615 {
616     switch (code) {
617         case DISCONNECT: {
618             CHECK_INTERFACE(IMediaPlayer, data, reply);
619             disconnect();
620             return NO_ERROR;
621         } break;
622         case SET_DATA_SOURCE_URL: {
623             CHECK_INTERFACE(IMediaPlayer, data, reply);
624 
625             sp<IMediaHTTPService> httpService;
626             if (data.readInt32()) {
627                 httpService =
628                     interface_cast<IMediaHTTPService>(data.readStrongBinder());
629             }
630 
631             const char* url = data.readCString();
632             if (url == NULL) {
633                 reply->writeInt32(BAD_VALUE);
634                 return NO_ERROR;
635             }
636             KeyedVector<String8, String8> headers;
637             int32_t numHeaders = data.readInt32();
638             for (int i = 0; i < numHeaders; ++i) {
639                 String8 key = data.readString8();
640                 String8 value = data.readString8();
641                 headers.add(key, value);
642             }
643             reply->writeInt32(setDataSource(
644                         httpService, url, numHeaders > 0 ? &headers : NULL));
645             return NO_ERROR;
646         } break;
647         case SET_DATA_SOURCE_FD: {
648             CHECK_INTERFACE(IMediaPlayer, data, reply);
649             int fd = data.readFileDescriptor();
650             int64_t offset = data.readInt64();
651             int64_t length = data.readInt64();
652             reply->writeInt32(setDataSource(fd, offset, length));
653             return NO_ERROR;
654         }
655         case SET_DATA_SOURCE_STREAM: {
656             CHECK_INTERFACE(IMediaPlayer, data, reply);
657             sp<IStreamSource> source =
658                 interface_cast<IStreamSource>(data.readStrongBinder());
659             if (source == NULL) {
660                 reply->writeInt32(BAD_VALUE);
661             } else {
662                 reply->writeInt32(setDataSource(source));
663             }
664             return NO_ERROR;
665         }
666         case SET_DATA_SOURCE_CALLBACK: {
667             CHECK_INTERFACE(IMediaPlayer, data, reply);
668             sp<IDataSource> source =
669                 interface_cast<IDataSource>(data.readStrongBinder());
670             if (source == NULL) {
671                 reply->writeInt32(BAD_VALUE);
672             } else {
673                 reply->writeInt32(setDataSource(source));
674             }
675             return NO_ERROR;
676         }
677         case SET_DATA_SOURCE_RTP: {
678             CHECK_INTERFACE(IMediaPlayer, data, reply);
679             String8 rtpParams = data.readString8();
680             reply->writeInt32(setDataSource(rtpParams));
681             return NO_ERROR;
682         }
683         case SET_VIDEO_SURFACETEXTURE: {
684             CHECK_INTERFACE(IMediaPlayer, data, reply);
685             sp<IGraphicBufferProducer> bufferProducer =
686                     interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
687             reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
688             return NO_ERROR;
689         } break;
690         case SET_BUFFERING_SETTINGS: {
691             CHECK_INTERFACE(IMediaPlayer, data, reply);
692             BufferingSettings buffering;
693             buffering.mInitialMarkMs = data.readInt32();
694             buffering.mResumePlaybackMarkMs = data.readInt32();
695             reply->writeInt32(setBufferingSettings(buffering));
696             return NO_ERROR;
697         } break;
698         case GET_BUFFERING_SETTINGS: {
699             CHECK_INTERFACE(IMediaPlayer, data, reply);
700             BufferingSettings buffering;
701             status_t err = getBufferingSettings(&buffering);
702             reply->writeInt32(err);
703             if (err == OK) {
704                 reply->writeInt32(buffering.mInitialMarkMs);
705                 reply->writeInt32(buffering.mResumePlaybackMarkMs);
706             }
707             return NO_ERROR;
708         } break;
709         case PREPARE_ASYNC: {
710             CHECK_INTERFACE(IMediaPlayer, data, reply);
711             reply->writeInt32(prepareAsync());
712             return NO_ERROR;
713         } break;
714         case START: {
715             CHECK_INTERFACE(IMediaPlayer, data, reply);
716             reply->writeInt32(start());
717             return NO_ERROR;
718         } break;
719         case STOP: {
720             CHECK_INTERFACE(IMediaPlayer, data, reply);
721             reply->writeInt32(stop());
722             return NO_ERROR;
723         } break;
724         case IS_PLAYING: {
725             CHECK_INTERFACE(IMediaPlayer, data, reply);
726             bool state;
727             status_t ret = isPlaying(&state);
728             reply->writeInt32(state);
729             reply->writeInt32(ret);
730             return NO_ERROR;
731         } break;
732         case SET_PLAYBACK_SETTINGS: {
733             CHECK_INTERFACE(IMediaPlayer, data, reply);
734             AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
735             rate.mSpeed = data.readFloat();
736             rate.mPitch = data.readFloat();
737             rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32();
738             rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32();
739             reply->writeInt32(setPlaybackSettings(rate));
740             return NO_ERROR;
741         } break;
742         case GET_PLAYBACK_SETTINGS: {
743             CHECK_INTERFACE(IMediaPlayer, data, reply);
744             AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
745             status_t err = getPlaybackSettings(&rate);
746             reply->writeInt32(err);
747             if (err == OK) {
748                 reply->writeFloat(rate.mSpeed);
749                 reply->writeFloat(rate.mPitch);
750                 reply->writeInt32((int32_t)rate.mFallbackMode);
751                 reply->writeInt32((int32_t)rate.mStretchMode);
752             }
753             return NO_ERROR;
754         } break;
755         case SET_SYNC_SETTINGS: {
756             CHECK_INTERFACE(IMediaPlayer, data, reply);
757             AVSyncSettings sync;
758             sync.mSource = (AVSyncSource)data.readInt32();
759             sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32();
760             sync.mTolerance = data.readFloat();
761             float videoFpsHint = data.readFloat();
762             reply->writeInt32(setSyncSettings(sync, videoFpsHint));
763             return NO_ERROR;
764         } break;
765         case GET_SYNC_SETTINGS: {
766             CHECK_INTERFACE(IMediaPlayer, data, reply);
767             AVSyncSettings sync;
768             float videoFps;
769             status_t err = getSyncSettings(&sync, &videoFps);
770             reply->writeInt32(err);
771             if (err == OK) {
772                 reply->writeInt32((int32_t)sync.mSource);
773                 reply->writeInt32((int32_t)sync.mAudioAdjustMode);
774                 reply->writeFloat(sync.mTolerance);
775                 reply->writeFloat(videoFps);
776             }
777             return NO_ERROR;
778         } break;
779         case PAUSE: {
780             CHECK_INTERFACE(IMediaPlayer, data, reply);
781             reply->writeInt32(pause());
782             return NO_ERROR;
783         } break;
784         case SEEK_TO: {
785             CHECK_INTERFACE(IMediaPlayer, data, reply);
786             int msec = data.readInt32();
787             MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32();
788             reply->writeInt32(seekTo(msec, mode));
789             return NO_ERROR;
790         } break;
791         case GET_CURRENT_POSITION: {
792             CHECK_INTERFACE(IMediaPlayer, data, reply);
793             int msec = 0;
794             status_t ret = getCurrentPosition(&msec);
795             reply->writeInt32(msec);
796             reply->writeInt32(ret);
797             return NO_ERROR;
798         } break;
799         case GET_DURATION: {
800             CHECK_INTERFACE(IMediaPlayer, data, reply);
801             int msec = 0;
802             status_t ret = getDuration(&msec);
803             reply->writeInt32(msec);
804             reply->writeInt32(ret);
805             return NO_ERROR;
806         } break;
807         case RESET: {
808             CHECK_INTERFACE(IMediaPlayer, data, reply);
809             reply->writeInt32(reset());
810             return NO_ERROR;
811         } break;
812         case NOTIFY_AT: {
813             CHECK_INTERFACE(IMediaPlayer, data, reply);
814             reply->writeInt32(notifyAt(data.readInt64()));
815             return NO_ERROR;
816         } break;
817         case SET_AUDIO_STREAM_TYPE: {
818             CHECK_INTERFACE(IMediaPlayer, data, reply);
819             reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
820             return NO_ERROR;
821         } break;
822         case SET_LOOPING: {
823             CHECK_INTERFACE(IMediaPlayer, data, reply);
824             reply->writeInt32(setLooping(data.readInt32()));
825             return NO_ERROR;
826         } break;
827         case SET_VOLUME: {
828             CHECK_INTERFACE(IMediaPlayer, data, reply);
829             float leftVolume = data.readFloat();
830             float rightVolume = data.readFloat();
831             reply->writeInt32(setVolume(leftVolume, rightVolume));
832             return NO_ERROR;
833         } break;
834         case INVOKE: {
835             CHECK_INTERFACE(IMediaPlayer, data, reply);
836             status_t result = invoke(data, reply);
837             return result;
838         } break;
839         case SET_METADATA_FILTER: {
840             CHECK_INTERFACE(IMediaPlayer, data, reply);
841             reply->writeInt32(setMetadataFilter(data));
842             return NO_ERROR;
843         } break;
844         case GET_METADATA: {
845             CHECK_INTERFACE(IMediaPlayer, data, reply);
846             bool update_only = static_cast<bool>(data.readInt32());
847             bool apply_filter = static_cast<bool>(data.readInt32());
848             const status_t retcode = getMetadata(update_only, apply_filter, reply);
849             reply->setDataPosition(0);
850             reply->writeInt32(retcode);
851             reply->setDataPosition(0);
852             return NO_ERROR;
853         } break;
854         case SET_AUX_EFFECT_SEND_LEVEL: {
855             CHECK_INTERFACE(IMediaPlayer, data, reply);
856             reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
857             return NO_ERROR;
858         } break;
859         case ATTACH_AUX_EFFECT: {
860             CHECK_INTERFACE(IMediaPlayer, data, reply);
861             reply->writeInt32(attachAuxEffect(data.readInt32()));
862             return NO_ERROR;
863         } break;
864         case SET_PARAMETER: {
865             CHECK_INTERFACE(IMediaPlayer, data, reply);
866             int key = data.readInt32();
867 
868             Parcel request;
869             if (data.dataAvail() > 0) {
870                 request.appendFrom(
871                         const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
872             }
873             request.setDataPosition(0);
874             reply->writeInt32(setParameter(key, request));
875             return NO_ERROR;
876         } break;
877         case GET_PARAMETER: {
878             CHECK_INTERFACE(IMediaPlayer, data, reply);
879             return getParameter(data.readInt32(), reply);
880         } break;
881         case SET_RETRANSMIT_ENDPOINT: {
882             CHECK_INTERFACE(IMediaPlayer, data, reply);
883 
884             struct sockaddr_in endpoint;
885             memset(&endpoint, 0, sizeof(endpoint));
886             int amt = data.readInt32();
887             if (amt == sizeof(endpoint)) {
888                 data.read(&endpoint, sizeof(struct sockaddr_in));
889                 reply->writeInt32(setRetransmitEndpoint(&endpoint));
890             } else {
891                 reply->writeInt32(setRetransmitEndpoint(NULL));
892             }
893 
894             return NO_ERROR;
895         } break;
896         case GET_RETRANSMIT_ENDPOINT: {
897             CHECK_INTERFACE(IMediaPlayer, data, reply);
898 
899             struct sockaddr_in endpoint;
900             memset(&endpoint, 0, sizeof(endpoint));
901             status_t res = getRetransmitEndpoint(&endpoint);
902 
903             reply->writeInt32(res);
904             reply->write(&endpoint, sizeof(endpoint));
905 
906             return NO_ERROR;
907         } break;
908         case SET_NEXT_PLAYER: {
909             CHECK_INTERFACE(IMediaPlayer, data, reply);
910             reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
911 
912             return NO_ERROR;
913         } break;
914 
915         case APPLY_VOLUME_SHAPER: {
916             CHECK_INTERFACE(IMediaPlayer, data, reply);
917             sp<VolumeShaper::Configuration> configuration;
918             sp<VolumeShaper::Operation> operation;
919 
920             int32_t present;
921             status_t status = data.readInt32(&present);
922             if (status == NO_ERROR && present != 0) {
923                 configuration = new VolumeShaper::Configuration();
924                 status = configuration->readFromParcel(&data);
925             }
926             if (status == NO_ERROR) {
927                 status = data.readInt32(&present);
928             }
929             if (status == NO_ERROR && present != 0) {
930                 operation = new VolumeShaper::Operation();
931                 status = operation->readFromParcel(&data);
932             }
933             if (status == NO_ERROR) {
934                 status = (status_t)applyVolumeShaper(configuration, operation);
935             }
936             reply->writeInt32(status);
937             return NO_ERROR;
938         } break;
939         case GET_VOLUME_SHAPER_STATE: {
940             CHECK_INTERFACE(IMediaPlayer, data, reply);
941             int id;
942             status_t status = data.readInt32(&id);
943             if (status == NO_ERROR) {
944                 sp<VolumeShaper::State> state = getVolumeShaperState(id);
945                 if (state.get() != nullptr) {
946                      status = state->writeToParcel(reply);
947                 }
948             }
949             return NO_ERROR;
950         } break;
951 
952         // Modular DRM
953         case PREPARE_DRM: {
954             CHECK_INTERFACE(IMediaPlayer, data, reply);
955 
956             uint8_t uuid[16] = {};
957             data.read(uuid, sizeof(uuid));
958             Vector<uint8_t> drmSessionId;
959             status_t status = readVector(data, drmSessionId);
960             if (status != OK) {
961               return status;
962             }
963             uint32_t result = prepareDrm(uuid, drmSessionId);
964             reply->writeInt32(result);
965             return OK;
966         }
967         case RELEASE_DRM: {
968             CHECK_INTERFACE(IMediaPlayer, data, reply);
969 
970             uint32_t result = releaseDrm();
971             reply->writeInt32(result);
972             return OK;
973         }
974 
975         // AudioRouting
976         case SET_OUTPUT_DEVICE: {
977             CHECK_INTERFACE(IMediaPlayer, data, reply);
978             int deviceId;
979             status_t status = data.readInt32(&deviceId);
980             if (status == NO_ERROR) {
981                 reply->writeInt32(setOutputDevice(deviceId));
982             } else {
983                 reply->writeInt32(BAD_VALUE);
984             }
985             return NO_ERROR;
986         }
987         case GET_ROUTED_DEVICE_IDS: {
988             CHECK_INTERFACE(IMediaPlayer, data, reply);
989             DeviceIdVector deviceIds;
990             status_t ret = getRoutedDeviceIds(deviceIds);
991             reply->writeInt32(ret);
992             if (ret == NO_ERROR) {
993                 reply->writeInt32(deviceIds.size());
994                 for (auto deviceId : deviceIds) {
995                     reply->writeInt32(deviceId);
996                 }
997             }
998             return NO_ERROR;
999         } break;
1000         case ENABLE_AUDIO_DEVICE_CALLBACK: {
1001             CHECK_INTERFACE(IMediaPlayer, data, reply);
1002             bool enabled;
1003             status_t status = data.readBool(&enabled);
1004             if (status == NO_ERROR) {
1005                 reply->writeInt32(enableAudioDeviceCallback(enabled));
1006             } else {
1007                 reply->writeInt32(BAD_VALUE);
1008             }
1009             return NO_ERROR;
1010         } break;
1011 
1012         default:
1013             return BBinder::onTransact(code, data, reply, flags);
1014     }
1015 }
1016 
1017 // ----------------------------------------------------------------------------
1018 
1019 } // namespace android
1020