FwdLockEngine.cpp revision fdd65a0fc7df2c878cc601e4c0f4021cb264f051
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/* 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Copyright (C) 2010 The Android Open Source Project 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Licensed under the Apache License, Version 2.0 (the "License"); 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * you may not use this file except in compliance with the License. 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * You may obtain a copy of the License at 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * http://www.apache.org/licenses/LICENSE-2.0 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Unless required by applicable law or agreed to in writing, software 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * distributed under the License is distributed on an "AS IS" BASIS, 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * See the License for the specific language governing permissions and 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * limitations under the License. 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */ 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "SessionMap.h" 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "FwdLockEngine.h" 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <utils/Log.h> 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <errno.h> 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <stdio.h> 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <unistd.h> 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "drm_framework_common.h" 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <fcntl.h> 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <limits.h> 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <DrmRights.h> 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <DrmConstraints.h> 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <DrmMetadata.h> 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <DrmInfo.h> 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <DrmInfoStatus.h> 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <DrmInfoRequest.h> 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <DrmSupportInfo.h> 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <DrmConvertedStatus.h> 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <utils/String8.h> 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "FwdLockConv.h" 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "FwdLockFile.h" 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "FwdLockGlue.h" 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "FwdLockEngineConst.h" 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "MimeTypeUtil.h" 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#undef LOG_TAG 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define LOG_TAG "FwdLockEngine" 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing namespace android; 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This extern "C" is mandatory to be managed by TPlugInManager 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdochextern "C" IDrmEngine* create() { 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return new FwdLockEngine(); 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This extern "C" is mandatory to be managed by TPlugInManager 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuextern "C" void destroy(IDrmEngine* plugIn) { 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delete plugIn; 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuFwdLockEngine::FwdLockEngine() { 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOGD("FwdLockEngine Construction"); 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 59116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFwdLockEngine::~FwdLockEngine() { 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOGD("FwdLockEngine Destruction"); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch convertSessionMap.destroyMap(); 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decodeSessionMap.destroyMap(); 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) { 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int retStatus = DrmConvertedStatus::STATUS_ERROR; 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu switch(status) { 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case FwdLockConv_Status_OK: 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu retStatus = DrmConvertedStatus::STATUS_OK; 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case FwdLockConv_Status_SyntaxError: 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case FwdLockConv_Status_InvalidArgument: 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case FwdLockConv_Status_UnsupportedFileFormat: 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case FwdLockConv_Status_UnsupportedContentTransferEncoding: 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \ 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "Returning STATUS_INPUTDATA_ERROR", status); 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR; 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu default: 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \ 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "Returning STATUS_ERROR", status); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) retStatus = DrmConvertedStatus::STATUS_ERROR; 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return retStatus; 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuDrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) { 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DrmConstraints* drmConstraints = NULL; 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOGD("FwdLockEngine::onGetConstraints"); 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (NULL != path && 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) { 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Return the empty constraints to show no error condition. 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu drmConstraints = new DrmConstraints(); 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return drmConstraints; 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) { 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DrmMetadata* drmMetadata = NULL; 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOGD("FwdLockEngine::onGetMetadata"); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (NULL != path) { 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Returns empty metadata to show no error condition. 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) drmMetadata = new DrmMetadata(); 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return drmMetadata; 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)android::status_t FwdLockEngine::onInitialize(int uniqueId) { 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOGD("FwdLockEngine::onInitialize"); 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (FwdLockGlue_InitializeKeyEncryption()) { 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded"); 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:" 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "errno = %d", errno); 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return DRM_NO_ERROR; 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuandroid::status_t 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuFwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) { 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Not used 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOGD("FwdLockEngine::onSetOnInfoListener"); 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return DRM_NO_ERROR; 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdochandroid::status_t FwdLockEngine::onTerminate(int uniqueId) { 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOGD("FwdLockEngine::onTerminate"); 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return DRM_NO_ERROR; 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) { 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DrmSupportInfo* pSupportInfo = new DrmSupportInfo(); 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOGD("FwdLockEngine::onGetSupportInfo"); 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // fill all Forward Lock mimetypes and extensions 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (NULL != pSupportInfo) { 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_FL)); 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_FL)); 1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_DM)); 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_DM)); 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pSupportInfo->setDescription(String8(FWDLOCK_DESCRIPTION)); 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pSupportInfo; 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool FwdLockEngine::onCanHandle(int uniqueId, const String8& path) { 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool result = false; 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) String8 extString = path.getPathExtension(); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extString.toLower(); 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((extString == String8(FWDLOCK_DOTEXTENSION_FL)) || 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (extString == String8(FWDLOCK_DOTEXTENSION_DM))) { 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = true; 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return result; 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) { 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DrmInfoStatus *drmInfoStatus = NULL; 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Nothing to process 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8("")); 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOGD("FwdLockEngine::onProcessDrmInfo"); 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return drmInfoStatus; 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatus_t FwdLockEngine::onSaveRights( 1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int uniqueId, 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const DrmRights& drmRights, 1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const String8& rightsPath, 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const String8& contentPath) { 195 // No rights to save. Return 196 LOGD("FwdLockEngine::onSaveRights"); 197 return DRM_ERROR_UNKNOWN; 198} 199 200DrmInfo* FwdLockEngine::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) { 201 DrmInfo* drmInfo = NULL; 202 203 // Nothing to be done for Forward Lock file 204 LOGD("FwdLockEngine::onAcquireDrmInfo"); 205 206 return drmInfo; 207} 208 209int FwdLockEngine::onCheckRightsStatus(int uniqueId, 210 const String8& path, 211 int action) { 212 int result = RightsStatus::RIGHTS_INVALID; 213 214 LOGD("FwdLockEngine::onCheckRightsStatus"); 215 216 // Only Transfer action is not allowed for forward Lock files. 217 if (onCanHandle(uniqueId, path)) { 218 switch(action) { 219 case Action::DEFAULT: 220 case Action::PLAY: 221 case Action::RINGTONE: 222 case Action::OUTPUT: 223 case Action::PREVIEW: 224 case Action::EXECUTE: 225 case Action::DISPLAY: 226 result = RightsStatus::RIGHTS_VALID; 227 break; 228 229 case Action::TRANSFER: 230 default: 231 result = RightsStatus::RIGHTS_INVALID; 232 break; 233 } 234 } 235 236 return result; 237} 238 239status_t FwdLockEngine::onConsumeRights(int uniqueId, 240 DecryptHandle* decryptHandle, 241 int action, 242 bool reserve) { 243 // No rights consumption 244 LOGD("FwdLockEngine::onConsumeRights"); 245 return DRM_NO_ERROR; 246} 247 248bool FwdLockEngine::onValidateAction(int uniqueId, 249 const String8& path, 250 int action, 251 const ActionDescription& description) { 252 LOGD("FwdLockEngine::onValidateAction"); 253 254 // For the forwardlock engine checkRights and ValidateAction are the same. 255 return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID); 256} 257 258String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) { 259 LOGD("FwdLockEngine::onGetOriginalMimeType"); 260 String8 mimeString = String8(""); 261 int fileDesc = FwdLockFile_open(path.string()); 262 263 if (-1 < fileDesc) { 264 const char* pMimeType = FwdLockFile_GetContentType(fileDesc); 265 266 if (NULL != pMimeType) { 267 String8 contentType = String8(pMimeType); 268 contentType.toLower(); 269 mimeString = MimeTypeUtil::convertMimeType(contentType); 270 } 271 272 FwdLockFile_close(fileDesc); 273 } 274 275 return mimeString; 276} 277 278int FwdLockEngine::onGetDrmObjectType(int uniqueId, 279 const String8& path, 280 const String8& mimeType) { 281 String8 mimeStr = String8(mimeType); 282 283 LOGD("FwdLockEngine::onGetDrmObjectType"); 284 285 mimeStr.toLower(); 286 287 /* Checks whether 288 * 1. path and mime type both are not empty strings (meaning unavailable) else content is unknown 289 * 2. if one of them is empty string and if other is known then its a DRM Content Object. 290 * 3. if both of them are available, then both may be of known type 291 * (regardless of the relation between them to make it compatible with other DRM Engines) 292 */ 293 if (((0 == path.length()) || onCanHandle(uniqueId, path)) && 294 ((0 == mimeType.length()) || ((mimeStr == String8(FWDLOCK_MIMETYPE_FL)) || 295 (mimeStr == String8(FWDLOCK_MIMETYPE_DM)))) && (mimeType != path) ) { 296 return DrmObjectType::CONTENT; 297 } 298 299 return DrmObjectType::UNKNOWN; 300} 301 302status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) { 303 // No Rights to remove 304 LOGD("FwdLockEngine::onRemoveRights"); 305 return DRM_NO_ERROR; 306} 307 308status_t FwdLockEngine::onRemoveAllRights(int uniqueId) { 309 // No rights to remove 310 LOGD("FwdLockEngine::onRemoveAllRights"); 311 return DRM_NO_ERROR; 312} 313 314#ifdef USE_64BIT_DRM_API 315status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle, 316 int playbackStatus, int64_t position) { 317#else 318status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle, 319 int playbackStatus, int position) { 320#endif 321 // Not used 322 LOGD("FwdLockEngine::onSetPlaybackStatus"); 323 return DRM_NO_ERROR; 324} 325 326status_t FwdLockEngine::onOpenConvertSession(int uniqueId, 327 int convertId) { 328 status_t result = DRM_ERROR_UNKNOWN; 329 LOGD("FwdLockEngine::onOpenConvertSession"); 330 if (!convertSessionMap.isCreated(convertId)) { 331 ConvertSession *newSession = new ConvertSession(); 332 if (FwdLockConv_Status_OK == 333 FwdLockConv_OpenSession(&(newSession->uniqueId), &(newSession->output))) { 334 convertSessionMap.addValue(convertId, newSession); 335 result = DRM_NO_ERROR; 336 } else { 337 LOGD("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed."); 338 delete newSession; 339 } 340 } 341 return result; 342} 343 344DrmConvertedStatus* FwdLockEngine::onConvertData(int uniqueId, 345 int convertId, 346 const DrmBuffer* inputData) { 347 FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument; 348 DrmBuffer *convResult = new DrmBuffer(NULL, 0); 349 int offset = -1; 350 351 if (NULL != inputData && convertSessionMap.isCreated(convertId)) { 352 ConvertSession *convSession = convertSessionMap.getValue(convertId); 353 354 if (NULL != convSession) { 355 retStatus = FwdLockConv_ConvertData(convSession->uniqueId, 356 inputData->data, 357 inputData->length, 358 &(convSession->output)); 359 360 if (FwdLockConv_Status_OK == retStatus) { 361 // return bytes from conversion if available 362 if (convSession->output.fromConvertData.numBytes > 0) { 363 convResult->data = new char[convSession->output.fromConvertData.numBytes]; 364 365 if (NULL != convResult->data) { 366 convResult->length = convSession->output.fromConvertData.numBytes; 367 memcpy(convResult->data, 368 (char *)convSession->output.fromConvertData.pBuffer, 369 convResult->length); 370 } 371 } 372 } else { 373 offset = convSession->output.fromConvertData.errorPos; 374 } 375 } 376 } 377 return new DrmConvertedStatus(getConvertedStatus(retStatus), convResult, offset); 378} 379 380DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int uniqueId, 381 int convertId) { 382 FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument; 383 DrmBuffer *convResult = new DrmBuffer(NULL, 0); 384 int offset = -1; 385 386 LOGD("FwdLockEngine::onCloseConvertSession"); 387 388 if (convertSessionMap.isCreated(convertId)) { 389 ConvertSession *convSession = convertSessionMap.getValue(convertId); 390 391 if (NULL != convSession) { 392 retStatus = FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output)); 393 394 if (FwdLockConv_Status_OK == retStatus) { 395 offset = convSession->output.fromCloseSession.fileOffset; 396 convResult->data = new char[FWD_LOCK_SIGNATURES_SIZE]; 397 398 if (NULL != convResult->data) { 399 convResult->length = FWD_LOCK_SIGNATURES_SIZE; 400 memcpy(convResult->data, 401 (char *)convSession->output.fromCloseSession.signatures, 402 convResult->length); 403 } 404 } 405 } 406 convertSessionMap.removeValue(convertId); 407 } 408 return new DrmConvertedStatus(getConvertedStatus(retStatus), convResult, offset); 409} 410 411#ifdef USE_64BIT_DRM_API 412status_t FwdLockEngine::onOpenDecryptSession(int uniqueId, 413 DecryptHandle* decryptHandle, 414 int fd, 415 off64_t offset, 416 off64_t length) { 417#else 418status_t FwdLockEngine::onOpenDecryptSession(int uniqueId, 419 DecryptHandle* decryptHandle, 420 int fd, 421 int offset, 422 int length) { 423#endif 424 status_t result = DRM_ERROR_CANNOT_HANDLE; 425 int fileDesc = -1; 426 427 LOGD("FwdLockEngine::onOpenDecryptSession"); 428 429 if ((-1 < fd) && 430 (NULL != decryptHandle) && 431 (!decodeSessionMap.isCreated(decryptHandle->decryptId))) { 432 fileDesc = dup(fd); 433 } else { 434 LOGD("FwdLockEngine::onOpenDecryptSession parameter error"); 435 return result; 436 } 437 438 if (-1 < fileDesc && 439 -1 < ::lseek(fileDesc, offset, SEEK_SET) && 440 -1 < FwdLockFile_attach(fileDesc)) { 441 // check for file integrity. This must be done to protect the content mangling. 442 int retVal = FwdLockFile_CheckHeaderIntegrity(fileDesc); 443 DecodeSession* decodeSession = new DecodeSession(fileDesc); 444 445 if (retVal && NULL != decodeSession) { 446 decodeSessionMap.addValue(decryptHandle->decryptId, decodeSession); 447 const char *pmime= FwdLockFile_GetContentType(fileDesc); 448 String8 contentType = String8(pmime == NULL ? "" : pmime); 449 contentType.toLower(); 450 decryptHandle->mimeType = MimeTypeUtil::convertMimeType(contentType); 451 decryptHandle->decryptApiType = DecryptApiType::CONTAINER_BASED; 452 decryptHandle->status = RightsStatus::RIGHTS_VALID; 453 decryptHandle->decryptInfo = NULL; 454 result = DRM_NO_ERROR; 455 } else { 456 LOGD("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd"); 457 FwdLockFile_detach(fileDesc); 458 ::close(fileDesc); 459 delete decodeSession; 460 } 461 } 462 463 LOGD("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result); 464 465 return result; 466} 467 468status_t FwdLockEngine::onOpenDecryptSession(int uniqueId, 469 DecryptHandle* decryptHandle, 470 const char* uri) { 471 status_t result = DRM_ERROR_CANNOT_HANDLE; 472 const char fileTag [] = "file://"; 473 474 if (NULL != decryptHandle && NULL != uri && strlen(uri) > sizeof(fileTag)) { 475 String8 uriTag = String8(uri); 476 uriTag.toLower(); 477 478 if (0 == strncmp(uriTag.string(), fileTag, sizeof(fileTag) - 1)) { 479 const char *filePath = strchr(uri + sizeof(fileTag) - 1, '/'); 480 if (NULL != filePath && onCanHandle(uniqueId, String8(filePath))) { 481 int fd = open(filePath, O_RDONLY); 482 483 if (-1 < fd) { 484 // offset is always 0 and length is not used. so any positive size. 485 result = onOpenDecryptSession(uniqueId, decryptHandle, fd, 0, 1); 486 487 // fd is duplicated already if success. closing the file 488 close(fd); 489 } 490 } 491 } 492 } 493 494 return result; 495} 496 497status_t FwdLockEngine::onCloseDecryptSession(int uniqueId, 498 DecryptHandle* decryptHandle) { 499 status_t result = DRM_ERROR_UNKNOWN; 500 LOGD("FwdLockEngine::onCloseDecryptSession"); 501 502 if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) { 503 DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId); 504 if (NULL != session && session->fileDesc > -1) { 505 FwdLockFile_detach(session->fileDesc); 506 ::close(session->fileDesc); 507 decodeSessionMap.removeValue(decryptHandle->decryptId); 508 result = DRM_NO_ERROR; 509 } 510 } 511 512 LOGD("FwdLockEngine::onCloseDecryptSession Exit"); 513 return result; 514} 515 516status_t FwdLockEngine::onInitializeDecryptUnit(int uniqueId, 517 DecryptHandle* decryptHandle, 518 int decryptUnitId, 519 const DrmBuffer* headerInfo) { 520 LOGD("FwdLockEngine::onInitializeDecryptUnit"); 521 return DRM_ERROR_UNKNOWN; 522} 523 524status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, 525 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) { 526 LOGD("FwdLockEngine::onDecrypt"); 527 return DRM_ERROR_UNKNOWN; 528} 529 530status_t FwdLockEngine::onDecrypt(int uniqueId, 531 DecryptHandle* decryptHandle, 532 int decryptUnitId, 533 const DrmBuffer* encBuffer, 534 DrmBuffer** decBuffer) { 535 LOGD("FwdLockEngine::onDecrypt"); 536 return DRM_ERROR_UNKNOWN; 537} 538 539status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId, 540 DecryptHandle* decryptHandle, 541 int decryptUnitId) { 542 LOGD("FwdLockEngine::onFinalizeDecryptUnit"); 543 return DRM_ERROR_UNKNOWN; 544} 545 546ssize_t FwdLockEngine::onRead(int uniqueId, 547 DecryptHandle* decryptHandle, 548 void* buffer, 549 int numBytes) { 550 ssize_t size = -1; 551 552 if (NULL != decryptHandle && 553 decodeSessionMap.isCreated(decryptHandle->decryptId) && 554 NULL != buffer && 555 numBytes > -1) { 556 DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId); 557 if (NULL != session && session->fileDesc > -1) { 558 size = FwdLockFile_read(session->fileDesc, buffer, numBytes); 559 560 if (0 > size) { 561 session->offset = ((off_t)-1); 562 } else { 563 session->offset += size; 564 } 565 } 566 } 567 568 return size; 569} 570 571#ifdef USE_64BIT_DRM_API 572off64_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle, 573 off64_t offset, int whence) { 574#else 575off_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle, 576 off_t offset, int whence) { 577#endif 578 off_t offval = -1; 579 580 if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) { 581 DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId); 582 if (NULL != session && session->fileDesc > -1) { 583 offval = FwdLockFile_lseek(session->fileDesc, offset, whence); 584 session->offset = offval; 585 } 586 } 587 588 return offval; 589} 590 591#ifdef USE_64BIT_DRM_API 592ssize_t FwdLockEngine::onPread(int uniqueId, 593 DecryptHandle* decryptHandle, 594 void* buffer, 595 ssize_t numBytes, 596 off64_t offset) { 597#else 598ssize_t FwdLockEngine::onPread(int uniqueId, 599 DecryptHandle* decryptHandle, 600 void* buffer, 601 ssize_t numBytes, 602 off_t offset) { 603#endif 604 ssize_t bytesRead = -1; 605 606 DecodeSession* decoderSession = NULL; 607 608 if ((NULL != decryptHandle) && 609 (NULL != (decoderSession = decodeSessionMap.getValue(decryptHandle->decryptId))) && 610 (NULL != buffer) && 611 (numBytes > -1) && 612 (offset > -1)) { 613 if (offset != decoderSession->offset) { 614 decoderSession->offset = onLseek(uniqueId, decryptHandle, offset, SEEK_SET); 615 } 616 617 if (((off_t)-1) != decoderSession->offset) { 618 bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes); 619 if (bytesRead < 0) { 620 LOGD("FwdLockEngine::onPread error reading"); 621 } 622 } 623 } else { 624 LOGD("FwdLockEngine::onPread decryptId not found"); 625 } 626 627 return bytesRead; 628} 629