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