Home | History | Annotate | Download | only in libmedia
      1 /*
      2  * Copyright 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "IDataSource"
     19 #include <utils/Log.h>
     20 #include <utils/Timers.h>
     21 
     22 #include <media/IDataSource.h>
     23 
     24 #include <binder/IMemory.h>
     25 #include <binder/Parcel.h>
     26 #include <drm/drm_framework_common.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 
     29 namespace android {
     30 
     31 enum {
     32     GET_IMEMORY = IBinder::FIRST_CALL_TRANSACTION,
     33     READ_AT,
     34     GET_SIZE,
     35     CLOSE,
     36     GET_FLAGS,
     37     TO_STRING,
     38     DRM_INITIALIZATION,
     39 };
     40 
     41 struct BpDataSource : public BpInterface<IDataSource> {
     42     explicit BpDataSource(const sp<IBinder>& impl)
     43         : BpInterface<IDataSource>(impl) {}
     44 
     45     virtual sp<IMemory> getIMemory() {
     46         Parcel data, reply;
     47         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     48         remote()->transact(GET_IMEMORY, data, &reply);
     49         sp<IBinder> binder = reply.readStrongBinder();
     50         return interface_cast<IMemory>(binder);
     51     }
     52 
     53     virtual ssize_t readAt(off64_t offset, size_t size) {
     54         Parcel data, reply;
     55         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     56         data.writeInt64(offset);
     57         data.writeInt64(size);
     58         status_t err = remote()->transact(READ_AT, data, &reply);
     59         if (err != OK) {
     60             return err;
     61         }
     62         int64_t value = 0;
     63         err = reply.readInt64(&value);
     64         if (err != OK) {
     65             return err;
     66         }
     67         return (ssize_t)value;
     68     }
     69 
     70     virtual status_t getSize(off64_t* size) {
     71         Parcel data, reply;
     72         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     73         remote()->transact(GET_SIZE, data, &reply);
     74         status_t err = reply.readInt32();
     75         *size = reply.readInt64();
     76         return err;
     77     }
     78 
     79     virtual void close() {
     80         Parcel data, reply;
     81         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     82         remote()->transact(CLOSE, data, &reply);
     83     }
     84 
     85     virtual uint32_t getFlags() {
     86         Parcel data, reply;
     87         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     88         remote()->transact(GET_FLAGS, data, &reply);
     89         return reply.readUint32();
     90     }
     91 
     92     virtual String8 toString() {
     93         Parcel data, reply;
     94         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
     95         remote()->transact(TO_STRING, data, &reply);
     96         return reply.readString8();
     97     }
     98 
     99     virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
    100         Parcel data, reply;
    101         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
    102         if (mime == NULL) {
    103             data.writeInt32(0);
    104         } else {
    105             data.writeInt32(1);
    106             data.writeCString(mime);
    107         }
    108         remote()->transact(DRM_INITIALIZATION, data, &reply);
    109         sp<DecryptHandle> handle;
    110         if (reply.dataAvail() != 0) {
    111             handle = new DecryptHandle();
    112             handle->decryptId = reply.readInt32();
    113             handle->mimeType = reply.readString8();
    114             handle->decryptApiType = reply.readInt32();
    115             handle->status = reply.readInt32();
    116 
    117             const int bufferLength = data.readInt32();
    118             if (bufferLength != -1) {
    119                 handle->decryptInfo = new DecryptInfo();
    120                 handle->decryptInfo->decryptBufferLength = bufferLength;
    121             }
    122 
    123             size_t size = data.readInt32();
    124             for (size_t i = 0; i < size; ++i) {
    125                 DrmCopyControl key = (DrmCopyControl)data.readInt32();
    126                 int value = data.readInt32();
    127                 handle->copyControlVector.add(key, value);
    128             }
    129 
    130             size = data.readInt32();
    131             for (size_t i = 0; i < size; ++i) {
    132                 String8 key = data.readString8();
    133                 String8 value = data.readString8();
    134                 handle->extendedData.add(key, value);
    135             }
    136         }
    137         return handle;
    138     }
    139 };
    140 
    141 IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
    142 
    143 status_t BnDataSource::onTransact(
    144     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    145     switch (code) {
    146         case GET_IMEMORY: {
    147             CHECK_INTERFACE(IDataSource, data, reply);
    148             reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
    149             return NO_ERROR;
    150         } break;
    151         case READ_AT: {
    152             CHECK_INTERFACE(IDataSource, data, reply);
    153             off64_t offset = (off64_t) data.readInt64();
    154             size_t size = (size_t) data.readInt64();
    155             reply->writeInt64(readAt(offset, size));
    156             return NO_ERROR;
    157         } break;
    158         case GET_SIZE: {
    159             CHECK_INTERFACE(IDataSource, data, reply);
    160             off64_t size;
    161             status_t err = getSize(&size);
    162             reply->writeInt32(err);
    163             reply->writeInt64(size);
    164             return NO_ERROR;
    165         } break;
    166         case CLOSE: {
    167             CHECK_INTERFACE(IDataSource, data, reply);
    168             close();
    169             return NO_ERROR;
    170         } break;
    171         case GET_FLAGS: {
    172             CHECK_INTERFACE(IDataSource, data, reply);
    173             reply->writeUint32(getFlags());
    174             return NO_ERROR;
    175         } break;
    176         case TO_STRING: {
    177             CHECK_INTERFACE(IDataSource, data, reply);
    178             reply->writeString8(toString());
    179             return NO_ERROR;
    180         } break;
    181         case DRM_INITIALIZATION: {
    182             CHECK_INTERFACE(IDataSource, data, reply);
    183             const char *mime = NULL;
    184             const int32_t flag = data.readInt32();
    185             if (flag != 0) {
    186                 mime = data.readCString();
    187             }
    188             sp<DecryptHandle> handle = DrmInitialization(mime);
    189             if (handle != NULL) {
    190                 reply->writeInt32(handle->decryptId);
    191                 reply->writeString8(handle->mimeType);
    192                 reply->writeInt32(handle->decryptApiType);
    193                 reply->writeInt32(handle->status);
    194 
    195                 if (handle->decryptInfo != NULL) {
    196                     reply->writeInt32(handle->decryptInfo->decryptBufferLength);
    197                 } else {
    198                     reply->writeInt32(-1);
    199                 }
    200 
    201                 size_t size = handle->copyControlVector.size();
    202                 reply->writeInt32(size);
    203                 for (size_t i = 0; i < size; ++i) {
    204                     reply->writeInt32(handle->copyControlVector.keyAt(i));
    205                     reply->writeInt32(handle->copyControlVector.valueAt(i));
    206                 }
    207 
    208                 size = handle->extendedData.size();
    209                 reply->writeInt32(size);
    210                 for (size_t i = 0; i < size; ++i) {
    211                     reply->writeString8(handle->extendedData.keyAt(i));
    212                     reply->writeString8(handle->extendedData.valueAt(i));
    213                 }
    214             }
    215             return NO_ERROR;
    216         } break;
    217 
    218         default:
    219             return BBinder::onTransact(code, data, reply, flags);
    220     }
    221 }
    222 
    223 }  // namespace android
    224