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 status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels,
     90                                audio_format_t* pFormat,
     91                                const sp<IMemoryHeap>& heap, size_t *pSize)
     92     {
     93         Parcel data, reply;
     94         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     95         data.writeCString(url);
     96         data.writeStrongBinder(heap->asBinder());
     97         status_t status = remote()->transact(DECODE_URL, data, &reply);
     98         if (status == NO_ERROR) {
     99             status = (status_t)reply.readInt32();
    100             if (status == NO_ERROR) {
    101                 *pSampleRate = uint32_t(reply.readInt32());
    102                 *pNumChannels = reply.readInt32();
    103                 *pFormat = (audio_format_t)reply.readInt32();
    104                 *pSize = (size_t)reply.readInt32();
    105             }
    106         }
    107         return status;
    108     }
    109 
    110     virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate,
    111                                int* pNumChannels, audio_format_t* pFormat,
    112                                const sp<IMemoryHeap>& heap, size_t *pSize)
    113     {
    114         Parcel data, reply;
    115         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    116         data.writeFileDescriptor(fd);
    117         data.writeInt64(offset);
    118         data.writeInt64(length);
    119         data.writeStrongBinder(heap->asBinder());
    120         status_t status = remote()->transact(DECODE_FD, data, &reply);
    121         if (status == NO_ERROR) {
    122             status = (status_t)reply.readInt32();
    123             if (status == NO_ERROR) {
    124                 *pSampleRate = uint32_t(reply.readInt32());
    125                 *pNumChannels = reply.readInt32();
    126                 *pFormat = (audio_format_t)reply.readInt32();
    127                 *pSize = (size_t)reply.readInt32();
    128             }
    129         }
    130         return status;
    131     }
    132 
    133     virtual sp<IOMX> getOMX() {
    134         Parcel data, reply;
    135         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    136         remote()->transact(GET_OMX, data, &reply);
    137         return interface_cast<IOMX>(reply.readStrongBinder());
    138     }
    139 
    140     virtual sp<ICrypto> makeCrypto() {
    141         Parcel data, reply;
    142         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    143         remote()->transact(MAKE_CRYPTO, data, &reply);
    144         return interface_cast<ICrypto>(reply.readStrongBinder());
    145     }
    146 
    147     virtual sp<IDrm> makeDrm() {
    148         Parcel data, reply;
    149         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    150         remote()->transact(MAKE_DRM, data, &reply);
    151         return interface_cast<IDrm>(reply.readStrongBinder());
    152     }
    153 
    154     virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
    155         Parcel data, reply;
    156         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    157         data.writeInt32(createEncryptionModule);
    158         remote()->transact(MAKE_HDCP, data, &reply);
    159         return interface_cast<IHDCP>(reply.readStrongBinder());
    160     }
    161 
    162     virtual void addBatteryData(uint32_t params) {
    163         Parcel data, reply;
    164         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    165         data.writeInt32(params);
    166         remote()->transact(ADD_BATTERY_DATA, data, &reply);
    167     }
    168 
    169     virtual status_t pullBatteryData(Parcel* reply) {
    170         Parcel data;
    171         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    172         return remote()->transact(PULL_BATTERY_DATA, data, reply);
    173     }
    174 
    175     virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
    176             const String8& iface)
    177     {
    178         Parcel data, reply;
    179         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    180         data.writeStrongBinder(client->asBinder());
    181         data.writeString8(iface);
    182         remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply);
    183         return interface_cast<IRemoteDisplay>(reply.readStrongBinder());
    184     }
    185 
    186     virtual status_t updateProxyConfig(
    187             const char *host, int32_t port, const char *exclusionList) {
    188         Parcel data, reply;
    189 
    190         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    191         if (host == NULL) {
    192             data.writeInt32(0);
    193         } else {
    194             data.writeInt32(1);
    195             data.writeCString(host);
    196             data.writeInt32(port);
    197             data.writeCString(exclusionList);
    198         }
    199 
    200         remote()->transact(UPDATE_PROXY_CONFIG, data, &reply);
    201 
    202         return reply.readInt32();
    203     }
    204 };
    205 
    206 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
    207 
    208 // ----------------------------------------------------------------------
    209 
    210 status_t BnMediaPlayerService::onTransact(
    211     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    212 {
    213     switch (code) {
    214         case CREATE: {
    215             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    216             sp<IMediaPlayerClient> client =
    217                 interface_cast<IMediaPlayerClient>(data.readStrongBinder());
    218             int audioSessionId = data.readInt32();
    219             sp<IMediaPlayer> player = create(client, audioSessionId);
    220             reply->writeStrongBinder(player->asBinder());
    221             return NO_ERROR;
    222         } break;
    223         case DECODE_URL: {
    224             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    225             const char* url = data.readCString();
    226             sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
    227             uint32_t sampleRate;
    228             int numChannels;
    229             audio_format_t format;
    230             size_t size;
    231             status_t status = decode(url, &sampleRate, &numChannels, &format, heap, &size);
    232             reply->writeInt32(status);
    233             if (status == NO_ERROR) {
    234                 reply->writeInt32(sampleRate);
    235                 reply->writeInt32(numChannels);
    236                 reply->writeInt32((int32_t)format);
    237                 reply->writeInt32((int32_t)size);
    238             }
    239             return NO_ERROR;
    240         } break;
    241         case DECODE_FD: {
    242             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    243             int fd = dup(data.readFileDescriptor());
    244             int64_t offset = data.readInt64();
    245             int64_t length = data.readInt64();
    246             sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
    247             uint32_t sampleRate;
    248             int numChannels;
    249             audio_format_t format;
    250             size_t size;
    251             status_t status = decode(fd, offset, length, &sampleRate, &numChannels, &format,
    252                                      heap, &size);
    253             reply->writeInt32(status);
    254             if (status == NO_ERROR) {
    255                 reply->writeInt32(sampleRate);
    256                 reply->writeInt32(numChannels);
    257                 reply->writeInt32((int32_t)format);
    258                 reply->writeInt32((int32_t)size);
    259             }
    260             return NO_ERROR;
    261         } break;
    262         case CREATE_MEDIA_RECORDER: {
    263             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    264             sp<IMediaRecorder> recorder = createMediaRecorder();
    265             reply->writeStrongBinder(recorder->asBinder());
    266             return NO_ERROR;
    267         } break;
    268         case CREATE_METADATA_RETRIEVER: {
    269             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    270             sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
    271             reply->writeStrongBinder(retriever->asBinder());
    272             return NO_ERROR;
    273         } break;
    274         case GET_OMX: {
    275             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    276             sp<IOMX> omx = getOMX();
    277             reply->writeStrongBinder(omx->asBinder());
    278             return NO_ERROR;
    279         } break;
    280         case MAKE_CRYPTO: {
    281             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    282             sp<ICrypto> crypto = makeCrypto();
    283             reply->writeStrongBinder(crypto->asBinder());
    284             return NO_ERROR;
    285         } break;
    286         case MAKE_DRM: {
    287             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    288             sp<IDrm> drm = makeDrm();
    289             reply->writeStrongBinder(drm->asBinder());
    290             return NO_ERROR;
    291         } break;
    292         case MAKE_HDCP: {
    293             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    294             bool createEncryptionModule = data.readInt32();
    295             sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);
    296             reply->writeStrongBinder(hdcp->asBinder());
    297             return NO_ERROR;
    298         } break;
    299         case ADD_BATTERY_DATA: {
    300             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    301             uint32_t params = data.readInt32();
    302             addBatteryData(params);
    303             return NO_ERROR;
    304         } break;
    305         case PULL_BATTERY_DATA: {
    306             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    307             pullBatteryData(reply);
    308             return NO_ERROR;
    309         } break;
    310         case LISTEN_FOR_REMOTE_DISPLAY: {
    311             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    312             sp<IRemoteDisplayClient> client(
    313                     interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
    314             String8 iface(data.readString8());
    315             sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface));
    316             reply->writeStrongBinder(display->asBinder());
    317             return NO_ERROR;
    318         } break;
    319         case UPDATE_PROXY_CONFIG:
    320         {
    321             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    322 
    323             const char *host = NULL;
    324             int32_t port = 0;
    325             const char *exclusionList = NULL;
    326 
    327             if (data.readInt32()) {
    328                 host = data.readCString();
    329                 port = data.readInt32();
    330                 exclusionList = data.readCString();
    331             }
    332 
    333             reply->writeInt32(updateProxyConfig(host, port, exclusionList));
    334 
    335             return OK;
    336         }
    337         default:
    338             return BBinder::onTransact(code, data, reply, flags);
    339     }
    340 }
    341 
    342 // ----------------------------------------------------------------------------
    343 
    344 }; // namespace android
    345