DrmPassthruPlugIn.cpp revision 75979dc147c4d2f832730da2e9b68d93ce892ba3
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * Copyright (C) 2010 The Android Open Source Project 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * you may not use this file except in compliance with the License. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You may obtain a copy of the License at 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * See the License for the specific language governing permissions and 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * limitations under the License. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//#define LOG_NDEBUG 0 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define LOG_TAG "DrmPassthruPlugIn" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <utils/Log.h> 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmRights.h> 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmConstraints.h> 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmMetadata.h> 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmInfo.h> 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmInfoEvent.h> 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmInfoStatus.h> 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmConvertedStatus.h> 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmInfoRequest.h> 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <drm/DrmSupportInfo.h> 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <DrmPassthruPlugIn.h> 3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using namespace android; 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 3583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch// This extern "C" is mandatory to be managed by TPlugInManager 3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)extern "C" IDrmEngine* create() { 3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return new DrmPassthruPlugIn(); 38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// This extern "C" is mandatory to be managed by TPlugInManager 4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)extern "C" void destroy(IDrmEngine* pPlugIn) { 4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) delete pPlugIn; 4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) pPlugIn = NULL; 44f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 4683750176c3ee2cea66c8a9751271026a5901be3aBen MurdochDrmPassthruPlugIn::DrmPassthruPlugIn() 4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) : DrmEngineBase() { 4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)DrmPassthruPlugIn::~DrmPassthruPlugIn() { 52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 5483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DrmMetadata* DrmPassthruPlugIn::onGetMetadata(int uniqueId, const String8* path) { 56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return NULL; 5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 5983750176c3ee2cea66c8a9751271026a5901be3aBen MurdochDrmConstraints* DrmPassthruPlugIn::onGetConstraints( 6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 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 75DrmInfoStatus* 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 109status_t DrmPassthruPlugIn::onSetOnInfoListener( 110 int uniqueId, const IDrmEngine::OnInfoListener* infoListener) { 111 ALOGV("DrmPassthruPlugIn::onSetOnInfoListener : %d", uniqueId); 112 return DRM_NO_ERROR; 113} 114 115status_t DrmPassthruPlugIn::onInitialize(int uniqueId) { 116 ALOGV("DrmPassthruPlugIn::onInitialize : %d", uniqueId); 117 return DRM_NO_ERROR; 118} 119 120status_t DrmPassthruPlugIn::onTerminate(int uniqueId) { 121 ALOGV("DrmPassthruPlugIn::onTerminate : %d", uniqueId); 122 return DRM_NO_ERROR; 123} 124 125DrmSupportInfo* 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 137status_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 143DrmInfo* 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 159bool 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 166String8 DrmPassthruPlugIn::onGetOriginalMimeType(int uniqueId, const String8& path) { 167 ALOGV("DrmPassthruPlugIn::onGetOriginalMimeType() : %d", uniqueId); 168 return String8("video/passthru"); 169} 170 171int DrmPassthruPlugIn::onGetDrmObjectType( 172 int uniqueId, const String8& path, const String8& mimeType) { 173 ALOGV("DrmPassthruPlugIn::onGetDrmObjectType() : %d", uniqueId); 174 return DrmObjectType::UNKNOWN; 175} 176 177int 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 183status_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 189status_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 195bool DrmPassthruPlugIn::onValidateAction(int uniqueId, const String8& path, 196 int action, const ActionDescription& description) { 197 ALOGV("DrmPassthruPlugIn::onValidateAction() : %d", uniqueId); 198 return true; 199} 200 201status_t DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) { 202 ALOGV("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId); 203 return DRM_NO_ERROR; 204} 205 206status_t DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) { 207 ALOGV("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId); 208 return DRM_NO_ERROR; 209} 210 211status_t DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) { 212 ALOGV("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId); 213 return DRM_NO_ERROR; 214} 215 216DrmConvertedStatus* 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 231DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int convertId) { 232 ALOGV("DrmPassthruPlugIn::onCloseConvertSession() : %d", uniqueId); 233 return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, NULL, 0 /*offset*/); 234} 235 236status_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 251status_t DrmPassthruPlugIn::onOpenDecryptSession( 252 int uniqueId, DecryptHandle* decryptHandle, const char* uri) { 253 return DRM_ERROR_CANNOT_HANDLE; 254} 255 256status_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 267status_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 273status_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 294status_t DrmPassthruPlugIn::onFinalizeDecryptUnit( 295 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) { 296 ALOGV("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId); 297 return DRM_NO_ERROR; 298} 299 300ssize_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