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