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