Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 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 "DrmPassthruPlugIn"
     19 #include <utils/Log.h>
     20 
     21 #include <drm/DrmRights.h>
     22 #include <drm/DrmConstraints.h>
     23 #include <drm/DrmMetadata.h>
     24 #include <drm/DrmInfo.h>
     25 #include <drm/DrmInfoEvent.h>
     26 #include <drm/DrmInfoStatus.h>
     27 #include <drm/DrmConvertedStatus.h>
     28 #include <drm/DrmInfoRequest.h>
     29 #include <drm/DrmSupportInfo.h>
     30 #include <DrmPassthruPlugIn.h>
     31 
     32 using namespace android;
     33 
     34 
     35 // This extern "C" is mandatory to be managed by TPlugInManager
     36 extern "C" IDrmEngine* create() {
     37     return new DrmPassthruPlugIn();
     38 }
     39 
     40 // This extern "C" is mandatory to be managed by TPlugInManager
     41 extern "C" void destroy(IDrmEngine* pPlugIn) {
     42     delete pPlugIn;
     43     pPlugIn = NULL;
     44 }
     45 
     46 DrmPassthruPlugIn::DrmPassthruPlugIn()
     47     : DrmEngineBase() {
     48 
     49 }
     50 
     51 DrmPassthruPlugIn::~DrmPassthruPlugIn() {
     52 
     53 }
     54 
     55 DrmMetadata* DrmPassthruPlugIn::onGetMetadata(int uniqueId, const String8* path) {
     56     return NULL;
     57 }
     58 
     59 DrmConstraints* DrmPassthruPlugIn::onGetConstraints(
     60         int uniqueId, const String8* path, int action) {
     61     ALOGV("DrmPassthruPlugIn::onGetConstraints From Path: %d", uniqueId);
     62     DrmConstraints* drmConstraints = new DrmConstraints();
     63 
     64     String8 value("dummy_available_time");
     65     char* charValue = NULL;
     66     charValue = new char[value.length() + 1];
     67     strncpy(charValue, value.string(), value.length());
     68 
     69     //Just add dummy available time for verification
     70     drmConstraints->put(&(DrmConstraints::LICENSE_AVAILABLE_TIME), charValue);
     71 
     72     return drmConstraints;
     73 }
     74 
     75 DrmInfoStatus* DrmPassthruPlugIn::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
     76     ALOGV("DrmPassthruPlugIn::onProcessDrmInfo - Enter : %d", uniqueId);
     77     DrmInfoStatus* drmInfoStatus = NULL;
     78     if (NULL != drmInfo) {
     79         switch (drmInfo->getInfoType()) {
     80         case DrmInfoRequest::TYPE_REGISTRATION_INFO: {
     81             const DrmBuffer* emptyBuffer = new DrmBuffer();
     82             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
     83                     DrmInfoRequest::TYPE_REGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
     84             break;
     85         }
     86         case DrmInfoRequest::TYPE_UNREGISTRATION_INFO: {
     87             const DrmBuffer* emptyBuffer = new DrmBuffer();
     88             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
     89                     DrmInfoRequest::TYPE_UNREGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
     90             break;
     91         }
     92         case DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO: {
     93             String8 licenseString("dummy_license_string");
     94             const int bufferSize = licenseString.size();
     95             char* data = NULL;
     96             data = new char[bufferSize];
     97             memcpy(data, licenseString.string(), bufferSize);
     98             const DrmBuffer* buffer = new DrmBuffer(data, bufferSize);
     99             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
    100                     DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, buffer, drmInfo->getMimeType());
    101             break;
    102         }
    103         }
    104     }
    105     ALOGV("DrmPassthruPlugIn::onProcessDrmInfo - Exit");
    106     return drmInfoStatus;
    107 }
    108 
    109 status_t DrmPassthruPlugIn::onSetOnInfoListener(
    110             int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
    111     ALOGV("DrmPassthruPlugIn::onSetOnInfoListener : %d", uniqueId);
    112     return DRM_NO_ERROR;
    113 }
    114 
    115 status_t DrmPassthruPlugIn::onInitialize(int uniqueId) {
    116     ALOGV("DrmPassthruPlugIn::onInitialize : %d", uniqueId);
    117     return DRM_NO_ERROR;
    118 }
    119 
    120 status_t DrmPassthruPlugIn::onTerminate(int uniqueId) {
    121     ALOGV("DrmPassthruPlugIn::onTerminate : %d", uniqueId);
    122     return DRM_NO_ERROR;
    123 }
    124 
    125 DrmSupportInfo* DrmPassthruPlugIn::onGetSupportInfo(int uniqueId) {
    126     ALOGV("DrmPassthruPlugIn::onGetSupportInfo : %d", uniqueId);
    127     DrmSupportInfo* drmSupportInfo = new DrmSupportInfo();
    128     // Add mimetype's
    129     drmSupportInfo->addMimeType(String8("application/vnd.passthru.drm"));
    130     // Add File Suffixes
    131     drmSupportInfo->addFileSuffix(String8(".passthru"));
    132     // Add plug-in description
    133     drmSupportInfo->setDescription(String8("Passthru plug-in"));
    134     return drmSupportInfo;
    135 }
    136 
    137 status_t DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& drmRights,
    138             const String8& rightsPath, const String8& contentPath) {
    139     ALOGV("DrmPassthruPlugIn::onSaveRights : %d", uniqueId);
    140     return DRM_NO_ERROR;
    141 }
    142 
    143 DrmInfo* DrmPassthruPlugIn::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
    144     ALOGV("DrmPassthruPlugIn::onAcquireDrmInfo : %d", uniqueId);
    145     DrmInfo* drmInfo = NULL;
    146 
    147     if (NULL != drmInfoRequest) {
    148         String8 dataString("dummy_acquistion_string");
    149         int length = dataString.length();
    150         char* data = NULL;
    151         data = new char[length];
    152         memcpy(data, dataString.string(), length);
    153         drmInfo = new DrmInfo(drmInfoRequest->getInfoType(),
    154             DrmBuffer(data, length), drmInfoRequest->getMimeType());
    155     }
    156     return drmInfo;
    157 }
    158 
    159 bool DrmPassthruPlugIn::onCanHandle(int uniqueId, const String8& path) {
    160     ALOGV("DrmPassthruPlugIn::canHandle: %s ", path.string());
    161     String8 extension = path.getPathExtension();
    162     extension.toLower();
    163     return (String8(".passthru") == extension);
    164 }
    165 
    166 String8 DrmPassthruPlugIn::onGetOriginalMimeType(int uniqueId, const String8& path) {
    167     ALOGV("DrmPassthruPlugIn::onGetOriginalMimeType() : %d", uniqueId);
    168     return String8("video/passthru");
    169 }
    170 
    171 int DrmPassthruPlugIn::onGetDrmObjectType(
    172             int uniqueId, const String8& path, const String8& mimeType) {
    173     ALOGV("DrmPassthruPlugIn::onGetDrmObjectType() : %d", uniqueId);
    174     return DrmObjectType::UNKNOWN;
    175 }
    176 
    177 int DrmPassthruPlugIn::onCheckRightsStatus(int uniqueId, const String8& path, int action) {
    178     ALOGV("DrmPassthruPlugIn::onCheckRightsStatus() : %d", uniqueId);
    179     int rightsStatus = RightsStatus::RIGHTS_VALID;
    180     return rightsStatus;
    181 }
    182 
    183 status_t DrmPassthruPlugIn::onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
    184             int action, bool reserve) {
    185     ALOGV("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
    186     return DRM_NO_ERROR;
    187 }
    188 
    189 status_t DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
    190             int playbackStatus, int64_t position) {
    191     ALOGV("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
    192     return DRM_NO_ERROR;
    193 }
    194 
    195 bool DrmPassthruPlugIn::onValidateAction(int uniqueId, const String8& path,
    196             int action, const ActionDescription& description) {
    197     ALOGV("DrmPassthruPlugIn::onValidateAction() : %d", uniqueId);
    198     return true;
    199 }
    200 
    201 status_t DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) {
    202     ALOGV("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId);
    203     return DRM_NO_ERROR;
    204 }
    205 
    206 status_t DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) {
    207     ALOGV("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId);
    208     return DRM_NO_ERROR;
    209 }
    210 
    211 status_t DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) {
    212     ALOGV("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId);
    213     return DRM_NO_ERROR;
    214 }
    215 
    216 DrmConvertedStatus* DrmPassthruPlugIn::onConvertData(
    217             int uniqueId, int convertId, const DrmBuffer* inputData) {
    218     ALOGV("DrmPassthruPlugIn::onConvertData() : %d", uniqueId);
    219     DrmBuffer* convertedData = NULL;
    220 
    221     if (NULL != inputData && 0 < inputData->length) {
    222         int length = inputData->length;
    223         char* data = NULL;
    224         data = new char[length];
    225         convertedData = new DrmBuffer(data, length);
    226         memcpy(convertedData->data, inputData->data, length);
    227     }
    228     return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, convertedData, 0 /*offset*/);
    229 }
    230 
    231 DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int convertId) {
    232     ALOGV("DrmPassthruPlugIn::onCloseConvertSession() : %d", uniqueId);
    233     return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, NULL, 0 /*offset*/);
    234 }
    235 
    236 status_t DrmPassthruPlugIn::onOpenDecryptSession(
    237             int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length) {
    238     ALOGV("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId);
    239 
    240 #ifdef ENABLE_PASSTHRU_DECRYPTION
    241     decryptHandle->mimeType = String8("video/passthru");
    242     decryptHandle->decryptApiType = DecryptApiType::ELEMENTARY_STREAM_BASED;
    243     decryptHandle->status = DRM_NO_ERROR;
    244     decryptHandle->decryptInfo = NULL;
    245     return DRM_NO_ERROR;
    246 #endif
    247 
    248     return DRM_ERROR_CANNOT_HANDLE;
    249 }
    250 
    251 status_t DrmPassthruPlugIn::onOpenDecryptSession(
    252             int uniqueId, DecryptHandle* decryptHandle, const char* uri) {
    253     return DRM_ERROR_CANNOT_HANDLE;
    254 }
    255 
    256 status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
    257     ALOGV("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
    258     if (NULL != decryptHandle) {
    259         if (NULL != decryptHandle->decryptInfo) {
    260             delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
    261         }
    262         delete decryptHandle; decryptHandle = NULL;
    263     }
    264     return DRM_NO_ERROR;
    265 }
    266 
    267 status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
    268             int decryptUnitId, const DrmBuffer* headerInfo) {
    269     ALOGV("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
    270     return DRM_NO_ERROR;
    271 }
    272 
    273 status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
    274             int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
    275     ALOGV("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
    276     /**
    277      * As a workaround implementation passthru would copy the given
    278      * encrypted buffer as it is to decrypted buffer. Note, decBuffer
    279      * memory has to be allocated by the caller.
    280      */
    281     if (NULL != (*decBuffer) && 0 < (*decBuffer)->length) {
    282         if ((*decBuffer)->length >= encBuffer->length) {
    283             memcpy((*decBuffer)->data, encBuffer->data, encBuffer->length);
    284             (*decBuffer)->length = encBuffer->length;
    285         } else {
    286             ALOGE("decBuffer size (%d) too small to hold %d bytes",
    287                 (*decBuffer)->length, encBuffer->length);
    288             return DRM_ERROR_UNKNOWN;
    289         }
    290     }
    291     return DRM_NO_ERROR;
    292 }
    293 
    294 status_t DrmPassthruPlugIn::onFinalizeDecryptUnit(
    295             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
    296     ALOGV("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
    297     return DRM_NO_ERROR;
    298 }
    299 
    300 ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* decryptHandle,
    301             void* buffer, ssize_t numBytes, off64_t offset) {
    302     ALOGV("DrmPassthruPlugIn::onPread() : %d", uniqueId);
    303     return 0;
    304 }
    305 
    306