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 <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <binder/Parcel.h>
     22 #include <binder/IMemory.h>
     23 #include <media/ICrypto.h>
     24 #include <media/IDrm.h>
     25 #include <media/IHDCP.h>
     26 #include <media/IMediaCodecList.h>
     27 #include <media/IMediaHTTPService.h>
     28 #include <media/IMediaPlayerService.h>
     29 #include <media/IMediaRecorder.h>
     30 #include <media/IOMX.h>
     31 #include <media/IRemoteDisplay.h>
     32 #include <media/IRemoteDisplayClient.h>
     33 #include <media/IStreamSource.h>
     34 
     35 #include <utils/Errors.h>  // for status_t
     36 #include <utils/String8.h>
     37 
     38 namespace android {
     39 
     40 enum {
     41     CREATE = IBinder::FIRST_CALL_TRANSACTION,
     42     DECODE_URL,
     43     DECODE_FD,
     44     CREATE_MEDIA_RECORDER,
     45     CREATE_METADATA_RETRIEVER,
     46     GET_OMX,
     47     MAKE_CRYPTO,
     48     MAKE_DRM,
     49     MAKE_HDCP,
     50     ADD_BATTERY_DATA,
     51     PULL_BATTERY_DATA,
     52     LISTEN_FOR_REMOTE_DISPLAY,
     53     GET_CODEC_LIST,
     54 };
     55 
     56 class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
     57 {
     58 public:
     59     BpMediaPlayerService(const sp<IBinder>& impl)
     60         : BpInterface<IMediaPlayerService>(impl)
     61     {
     62     }
     63 
     64     virtual sp<IMediaMetadataRetriever> createMetadataRetriever()
     65     {
     66         Parcel data, reply;
     67         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     68         remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
     69         return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
     70     }
     71 
     72     virtual sp<IMediaPlayer> create(
     73             const sp<IMediaPlayerClient>& client, int audioSessionId) {
     74         Parcel data, reply;
     75         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     76         data.writeStrongBinder(client->asBinder());
     77         data.writeInt32(audioSessionId);
     78 
     79         remote()->transact(CREATE, data, &reply);
     80         return interface_cast<IMediaPlayer>(reply.readStrongBinder());
     81     }
     82 
     83     virtual sp<IMediaRecorder> createMediaRecorder()
     84     {
     85         Parcel data, reply;
     86         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     87         remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
     88         return interface_cast<IMediaRecorder>(reply.readStrongBinder());
     89     }
     90 
     91     virtual status_t decode(
     92             const sp<IMediaHTTPService> &httpService,
     93             const char* url,
     94             uint32_t *pSampleRate,
     95             int* pNumChannels,
     96             audio_format_t* pFormat,
     97             const sp<IMemoryHeap>& heap,
     98             size_t *pSize)
     99     {
    100         Parcel data, reply;
    101         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    102         data.writeInt32(httpService != NULL);
    103         if (httpService != NULL) {
    104             data.writeStrongBinder(httpService->asBinder());
    105         }
    106         data.writeCString(url);
    107         data.writeStrongBinder(heap->asBinder());
    108         status_t status = remote()->transact(DECODE_URL, data, &reply);
    109         if (status == NO_ERROR) {
    110             status = (status_t)reply.readInt32();
    111             if (status == NO_ERROR) {
    112                 *pSampleRate = uint32_t(reply.readInt32());
    113                 *pNumChannels = reply.readInt32();
    114                 *pFormat = (audio_format_t)reply.readInt32();
    115                 *pSize = (size_t)reply.readInt32();
    116             }
    117         }
    118         return status;
    119     }
    120 
    121     virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate,
    122                                int* pNumChannels, audio_format_t* pFormat,
    123                                const sp<IMemoryHeap>& heap, size_t *pSize)
    124     {
    125         Parcel data, reply;
    126         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    127         data.writeFileDescriptor(fd);
    128         data.writeInt64(offset);
    129         data.writeInt64(length);
    130         data.writeStrongBinder(heap->asBinder());
    131         status_t status = remote()->transact(DECODE_FD, data, &reply);
    132         if (status == NO_ERROR) {
    133             status = (status_t)reply.readInt32();
    134             if (status == NO_ERROR) {
    135                 *pSampleRate = uint32_t(reply.readInt32());
    136                 *pNumChannels = reply.readInt32();
    137                 *pFormat = (audio_format_t)reply.readInt32();
    138                 *pSize = (size_t)reply.readInt32();
    139             }
    140         }
    141         return status;
    142     }
    143 
    144     virtual sp<IOMX> getOMX() {
    145         Parcel data, reply;
    146         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    147         remote()->transact(GET_OMX, data, &reply);
    148         return interface_cast<IOMX>(reply.readStrongBinder());
    149     }
    150 
    151     virtual sp<ICrypto> makeCrypto() {
    152         Parcel data, reply;
    153         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    154         remote()->transact(MAKE_CRYPTO, data, &reply);
    155         return interface_cast<ICrypto>(reply.readStrongBinder());
    156     }
    157 
    158     virtual sp<IDrm> makeDrm() {
    159         Parcel data, reply;
    160         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    161         remote()->transact(MAKE_DRM, data, &reply);
    162         return interface_cast<IDrm>(reply.readStrongBinder());
    163     }
    164 
    165     virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
    166         Parcel data, reply;
    167         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    168         data.writeInt32(createEncryptionModule);
    169         remote()->transact(MAKE_HDCP, data, &reply);
    170         return interface_cast<IHDCP>(reply.readStrongBinder());
    171     }
    172 
    173     virtual void addBatteryData(uint32_t params) {
    174         Parcel data, reply;
    175         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    176         data.writeInt32(params);
    177         remote()->transact(ADD_BATTERY_DATA, data, &reply);
    178     }
    179 
    180     virtual status_t pullBatteryData(Parcel* reply) {
    181         Parcel data;
    182         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    183         return remote()->transact(PULL_BATTERY_DATA, data, reply);
    184     }
    185 
    186     virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
    187             const String8& iface)
    188     {
    189         Parcel data, reply;
    190         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    191         data.writeStrongBinder(client->asBinder());
    192         data.writeString8(iface);
    193         remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply);
    194         return interface_cast<IRemoteDisplay>(reply.readStrongBinder());
    195     }
    196 
    197     virtual sp<IMediaCodecList> getCodecList() const {
    198         Parcel data, reply;
    199         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    200         remote()->transact(GET_CODEC_LIST, data, &reply);
    201         return interface_cast<IMediaCodecList>(reply.readStrongBinder());
    202     }
    203 };
    204 
    205 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
    206 
    207 // ----------------------------------------------------------------------
    208 
    209 status_t BnMediaPlayerService::onTransact(
    210     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    211 {
    212     switch (code) {
    213         case CREATE: {
    214             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    215             sp<IMediaPlayerClient> client =
    216                 interface_cast<IMediaPlayerClient>(data.readStrongBinder());
    217             int audioSessionId = data.readInt32();
    218             sp<IMediaPlayer> player = create(client, audioSessionId);
    219             reply->writeStrongBinder(player->asBinder());
    220             return NO_ERROR;
    221         } break;
    222         case DECODE_URL: {
    223             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    224             sp<IMediaHTTPService> httpService;
    225             if (data.readInt32()) {
    226                 httpService =
    227                     interface_cast<IMediaHTTPService>(data.readStrongBinder());
    228             }
    229             const char* url = data.readCString();
    230             sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
    231             uint32_t sampleRate;
    232             int numChannels;
    233             audio_format_t format;
    234             size_t size;
    235             status_t status =
    236                 decode(httpService,
    237                        url,
    238                        &sampleRate,
    239                        &numChannels,
    240                        &format,
    241                        heap,
    242                        &size);
    243             reply->writeInt32(status);
    244             if (status == NO_ERROR) {
    245                 reply->writeInt32(sampleRate);
    246                 reply->writeInt32(numChannels);
    247                 reply->writeInt32((int32_t)format);
    248                 reply->writeInt32((int32_t)size);
    249             }
    250             return NO_ERROR;
    251         } break;
    252         case DECODE_FD: {
    253             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    254             int fd = dup(data.readFileDescriptor());
    255             int64_t offset = data.readInt64();
    256             int64_t length = data.readInt64();
    257             sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
    258             uint32_t sampleRate;
    259             int numChannels;
    260             audio_format_t format;
    261             size_t size;
    262             status_t status = decode(fd, offset, length, &sampleRate, &numChannels, &format,
    263                                      heap, &size);
    264             reply->writeInt32(status);
    265             if (status == NO_ERROR) {
    266                 reply->writeInt32(sampleRate);
    267                 reply->writeInt32(numChannels);
    268                 reply->writeInt32((int32_t)format);
    269                 reply->writeInt32((int32_t)size);
    270             }
    271             return NO_ERROR;
    272         } break;
    273         case CREATE_MEDIA_RECORDER: {
    274             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    275             sp<IMediaRecorder> recorder = createMediaRecorder();
    276             reply->writeStrongBinder(recorder->asBinder());
    277             return NO_ERROR;
    278         } break;
    279         case CREATE_METADATA_RETRIEVER: {
    280             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    281             sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
    282             reply->writeStrongBinder(retriever->asBinder());
    283             return NO_ERROR;
    284         } break;
    285         case GET_OMX: {
    286             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    287             sp<IOMX> omx = getOMX();
    288             reply->writeStrongBinder(omx->asBinder());
    289             return NO_ERROR;
    290         } break;
    291         case MAKE_CRYPTO: {
    292             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    293             sp<ICrypto> crypto = makeCrypto();
    294             reply->writeStrongBinder(crypto->asBinder());
    295             return NO_ERROR;
    296         } break;
    297         case MAKE_DRM: {
    298             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    299             sp<IDrm> drm = makeDrm();
    300             reply->writeStrongBinder(drm->asBinder());
    301             return NO_ERROR;
    302         } break;
    303         case MAKE_HDCP: {
    304             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    305             bool createEncryptionModule = data.readInt32();
    306             sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);
    307             reply->writeStrongBinder(hdcp->asBinder());
    308             return NO_ERROR;
    309         } break;
    310         case ADD_BATTERY_DATA: {
    311             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    312             uint32_t params = data.readInt32();
    313             addBatteryData(params);
    314             return NO_ERROR;
    315         } break;
    316         case PULL_BATTERY_DATA: {
    317             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    318             pullBatteryData(reply);
    319             return NO_ERROR;
    320         } break;
    321         case LISTEN_FOR_REMOTE_DISPLAY: {
    322             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    323             sp<IRemoteDisplayClient> client(
    324                     interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
    325             String8 iface(data.readString8());
    326             sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface));
    327             reply->writeStrongBinder(display->asBinder());
    328             return NO_ERROR;
    329         } break;
    330         case GET_CODEC_LIST: {
    331             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    332             sp<IMediaCodecList> mcl = getCodecList();
    333             reply->writeStrongBinder(mcl->asBinder());
    334             return NO_ERROR;
    335         } break;
    336         default:
    337             return BBinder::onTransact(code, data, reply, flags);
    338     }
    339 }
    340 
    341 // ----------------------------------------------------------------------------
    342 
    343 }; // namespace android
    344