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/IMediaPlayerService.h>
     24 #include <media/IMediaRecorder.h>
     25 #include <media/IOMX.h>
     26 
     27 #include <utils/Errors.h>  // for status_t
     28 
     29 namespace android {
     30 
     31 enum {
     32     CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
     33     CREATE_FD,
     34     DECODE_URL,
     35     DECODE_FD,
     36     CREATE_MEDIA_RECORDER,
     37     CREATE_METADATA_RETRIEVER,
     38     GET_OMX,
     39     SNOOP
     40 };
     41 
     42 class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
     43 {
     44 public:
     45     BpMediaPlayerService(const sp<IBinder>& impl)
     46         : BpInterface<IMediaPlayerService>(impl)
     47     {
     48     }
     49 
     50     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid)
     51     {
     52         Parcel data, reply;
     53         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     54         data.writeInt32(pid);
     55         remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
     56         return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
     57     }
     58 
     59     virtual sp<IMediaPlayer> create(
     60             pid_t pid, const sp<IMediaPlayerClient>& client,
     61             const char* url, const KeyedVector<String8, String8> *headers) {
     62         Parcel data, reply;
     63         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     64         data.writeInt32(pid);
     65         data.writeStrongBinder(client->asBinder());
     66         data.writeCString(url);
     67 
     68         if (headers == NULL) {
     69             data.writeInt32(0);
     70         } else {
     71             // serialize the headers
     72             data.writeInt32(headers->size());
     73             for (size_t i = 0; i < headers->size(); ++i) {
     74                 data.writeString8(headers->keyAt(i));
     75                 data.writeString8(headers->valueAt(i));
     76             }
     77         }
     78 
     79         remote()->transact(CREATE_URL, data, &reply);
     80         return interface_cast<IMediaPlayer>(reply.readStrongBinder());
     81     }
     82 
     83     virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid)
     84     {
     85         Parcel data, reply;
     86         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     87         data.writeInt32(pid);
     88         remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
     89         return interface_cast<IMediaRecorder>(reply.readStrongBinder());
     90     }
     91 
     92     virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length)
     93     {
     94         Parcel data, reply;
     95         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
     96         data.writeInt32(pid);
     97         data.writeStrongBinder(client->asBinder());
     98         data.writeFileDescriptor(fd);
     99         data.writeInt64(offset);
    100         data.writeInt64(length);
    101         remote()->transact(CREATE_FD, data, &reply);
    102         return interface_cast<IMediaPlayer>(reply.readStrongBinder());
    103     }
    104 
    105     virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
    106     {
    107         Parcel data, reply;
    108         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    109         data.writeCString(url);
    110         remote()->transact(DECODE_URL, data, &reply);
    111         *pSampleRate = uint32_t(reply.readInt32());
    112         *pNumChannels = reply.readInt32();
    113         *pFormat = reply.readInt32();
    114         return interface_cast<IMemory>(reply.readStrongBinder());
    115     }
    116 
    117     virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
    118     {
    119         Parcel data, reply;
    120         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    121         data.writeFileDescriptor(fd);
    122         data.writeInt64(offset);
    123         data.writeInt64(length);
    124         remote()->transact(DECODE_FD, data, &reply);
    125         *pSampleRate = uint32_t(reply.readInt32());
    126         *pNumChannels = reply.readInt32();
    127         *pFormat = reply.readInt32();
    128         return interface_cast<IMemory>(reply.readStrongBinder());
    129     }
    130 
    131     virtual sp<IMemory> snoop()
    132     {
    133         Parcel data, reply;
    134         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    135         remote()->transact(SNOOP, data, &reply);
    136         return interface_cast<IMemory>(reply.readStrongBinder());
    137     }
    138 
    139     virtual sp<IOMX> getOMX() {
    140         Parcel data, reply;
    141         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    142         remote()->transact(GET_OMX, data, &reply);
    143         return interface_cast<IOMX>(reply.readStrongBinder());
    144     }
    145 };
    146 
    147 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
    148 
    149 // ----------------------------------------------------------------------
    150 
    151 status_t BnMediaPlayerService::onTransact(
    152     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    153 {
    154     switch(code) {
    155         case CREATE_URL: {
    156             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    157             pid_t pid = data.readInt32();
    158             sp<IMediaPlayerClient> client =
    159                 interface_cast<IMediaPlayerClient>(data.readStrongBinder());
    160             const char* url = data.readCString();
    161 
    162             KeyedVector<String8, String8> headers;
    163             int32_t numHeaders = data.readInt32();
    164             for (int i = 0; i < numHeaders; ++i) {
    165                 String8 key = data.readString8();
    166                 String8 value = data.readString8();
    167                 headers.add(key, value);
    168             }
    169 
    170             sp<IMediaPlayer> player = create(
    171                     pid, client, url, numHeaders > 0 ? &headers : NULL);
    172 
    173             reply->writeStrongBinder(player->asBinder());
    174             return NO_ERROR;
    175         } break;
    176         case CREATE_FD: {
    177             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    178             pid_t pid = data.readInt32();
    179             sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
    180             int fd = dup(data.readFileDescriptor());
    181             int64_t offset = data.readInt64();
    182             int64_t length = data.readInt64();
    183             sp<IMediaPlayer> player = create(pid, client, fd, offset, length);
    184             reply->writeStrongBinder(player->asBinder());
    185             return NO_ERROR;
    186         } break;
    187         case DECODE_URL: {
    188             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    189             const char* url = data.readCString();
    190             uint32_t sampleRate;
    191             int numChannels;
    192             int format;
    193             sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
    194             reply->writeInt32(sampleRate);
    195             reply->writeInt32(numChannels);
    196             reply->writeInt32(format);
    197             reply->writeStrongBinder(player->asBinder());
    198             return NO_ERROR;
    199         } break;
    200         case DECODE_FD: {
    201             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    202             int fd = dup(data.readFileDescriptor());
    203             int64_t offset = data.readInt64();
    204             int64_t length = data.readInt64();
    205             uint32_t sampleRate;
    206             int numChannels;
    207             int format;
    208             sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
    209             reply->writeInt32(sampleRate);
    210             reply->writeInt32(numChannels);
    211             reply->writeInt32(format);
    212             reply->writeStrongBinder(player->asBinder());
    213             return NO_ERROR;
    214         } break;
    215         case SNOOP: {
    216             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    217             sp<IMemory> snooped_audio = snoop();
    218             reply->writeStrongBinder(snooped_audio->asBinder());
    219             return NO_ERROR;
    220         } break;
    221         case CREATE_MEDIA_RECORDER: {
    222             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    223             pid_t pid = data.readInt32();
    224             sp<IMediaRecorder> recorder = createMediaRecorder(pid);
    225             reply->writeStrongBinder(recorder->asBinder());
    226             return NO_ERROR;
    227         } break;
    228         case CREATE_METADATA_RETRIEVER: {
    229             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    230             pid_t pid = data.readInt32();
    231             sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
    232             reply->writeStrongBinder(retriever->asBinder());
    233             return NO_ERROR;
    234         } break;
    235         case GET_OMX: {
    236             CHECK_INTERFACE(IMediaPlayerService, data, reply);
    237             sp<IOMX> omx = getOMX();
    238             reply->writeStrongBinder(omx->asBinder());
    239             return NO_ERROR;
    240         } break;
    241         default:
    242             return BBinder::onTransact(code, data, reply, flags);
    243     }
    244 }
    245 
    246 // ----------------------------------------------------------------------------
    247 
    248 }; // namespace android
    249