DrmManager.cpp revision ac2652c25f5d2a38709131f7731651bc5819fed5
195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (C) 2010 The Android Open Source Project 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Licensed under the Apache License, Version 2.0 (the "License"); 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * you may not use this file except in compliance with the License. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * You may obtain a copy of the License at 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * http://www.apache.org/licenses/LICENSE-2.0 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Unless required by applicable law or agreed to in writing, software 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distributed under the License is distributed on an "AS IS" BASIS, 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * See the License for the specific language governing permissions and 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * limitations under the License. 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley//#define LOG_NDEBUG 0 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define LOG_TAG "DrmManager(Native)" 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "utils/Log.h" 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <utils/String8.h> 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfo.h> 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoEvent.h> 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmRights.h> 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmConstraints.h> 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmMetadata.h> 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoStatus.h> 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoRequest.h> 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmSupportInfo.h> 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmConvertedStatus.h> 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <IDrmEngine.h> 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "DrmManager.h" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "ReadWriteUtils.h" 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define DECRYPT_FILE_ERROR -1 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyusing namespace android; 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyVector<int> DrmManager::mUniqueIdVector; 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst String8 DrmManager::EMPTY_STRING(""); 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmManager::DrmManager() : 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mDecryptSessionId(0), 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mConvertId(0) { 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmManager::~DrmManager() { 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::addUniqueId(int uniqueId) { 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (0 == uniqueId) { 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int temp = 0; 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool foundUniqueId = false; 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley srand(time(NULL)); 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (!foundUniqueId) { 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const int size = mUniqueIdVector.size(); 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley temp = rand() % 100; 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int index = 0; 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (; index < size; ++index) { 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (mUniqueIdVector.itemAt(index) == temp) { 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley foundUniqueId = false; 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (index == size) { 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley foundUniqueId = true; 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uniqueId = temp; 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mUniqueIdVector.push(uniqueId); 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return uniqueId; 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::removeUniqueId(int uniqueId) { 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) { 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (uniqueId == mUniqueIdVector.itemAt(i)) { 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mUniqueIdVector.removeAt(i); 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::loadPlugIns() { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley String8 pluginDirPath("/system/lib/drm/plugins/native"); 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return loadPlugIns(pluginDirPath); 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) { 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (mSupportInfoToPlugInIdMap.isEmpty()) { 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mPlugInManager.loadPlugIns(plugInDirPath); 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (unsigned int i = 0; i < plugInPathList.size(); ++i) { 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley String8 plugInPath = plugInPathList[i]; 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (NULL != info) { 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mSupportInfoToPlugInIdMap.add(*info, plugInPath); 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return DRM_NO_ERROR; 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::unloadPlugIns() { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mConvertSessionMap.clear(); 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mDecryptSessionMap.clear(); 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mPlugInManager.unloadPlugIns(); 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mSupportInfoToPlugInIdMap.clear(); 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return DRM_NO_ERROR; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::setDrmServiceListener( 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) { 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Mutex::Autolock _l(mLock); 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (NULL != drmServiceListener.get()) { 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mServiceListeners.add(uniqueId, drmServiceListener); 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mServiceListeners.removeItem(uniqueId); 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return DRM_NO_ERROR; 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::addClient(int uniqueId) { 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!mSupportInfoToPlugInIdMap.isEmpty()) { 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (unsigned int index = 0; index < plugInIdList.size(); index++) { 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rDrmEngine.initialize(uniqueId); 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rDrmEngine.setOnInfoListener(uniqueId, this); 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::removeClient(int uniqueId) { 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (unsigned int index = 0; index < plugInIdList.size(); index++) { 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rDrmEngine.terminate(uniqueId); 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) { 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path); 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.getConstraints(uniqueId, path, action); 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) { 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path); 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.getMetadata(uniqueId, path); 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) { 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mPlugInManager.loadPlugIn(absolutePath); 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath); 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rDrmEngine.initialize(uniqueId); 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rDrmEngine.setOnInfoListener(uniqueId, this); 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DrmSupportInfo* info = rDrmEngine.getSupportInfo(0); 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley mSupportInfoToPlugInIdMap.add(*info, absolutePath); 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return DRM_NO_ERROR; 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleybool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) { 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInId(mimeType); 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool result = (EMPTY_STRING != plugInId) ? true : false; 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (0 < path.length()) { 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (result) { 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley result = rDrmEngine.canHandle(uniqueId, path); 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley result = canHandle(uniqueId, path); 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return result; 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) { 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType()); 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.processDrmInfo(uniqueId, drmInfo); 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleybool DrmManager::canHandle(int uniqueId, const String8& path) { 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool result = false; 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (unsigned int i = 0; i < plugInPathList.size(); ++i) { 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]); 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley result = rDrmEngine.canHandle(uniqueId, path); 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (result) { 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return result; 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) { 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType()); 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights, 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8& rightsPath, const String8& contentPath) { 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType()); 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley status_t result = DRM_ERROR_UNKNOWN; 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath); 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return result; 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) { 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.getOriginalMimeType(uniqueId, path); 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EMPTY_STRING; 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) { 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType); 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType); 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return DrmObjectType::UNKNOWN; 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) { 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (EMPTY_STRING != plugInId) { 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rDrmEngine.checkRightsStatus(uniqueId, path, action); 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return RightsStatus::RIGHTS_INVALID; 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::consumeRights( 265 int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) { 266 status_t result = DRM_ERROR_UNKNOWN; 267 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 268 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 269 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve); 270 } 271 return result; 272} 273 274status_t DrmManager::setPlaybackStatus( 275 int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) { 276 status_t result = DRM_ERROR_UNKNOWN; 277 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 278 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 279 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position); 280 } 281 return result; 282} 283 284bool DrmManager::validateAction( 285 int uniqueId, const String8& path, int action, const ActionDescription& description) { 286 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 287 if (EMPTY_STRING != plugInId) { 288 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 289 return rDrmEngine.validateAction(uniqueId, path, action, description); 290 } 291 return false; 292} 293 294status_t DrmManager::removeRights(int uniqueId, const String8& path) { 295 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 296 status_t result = DRM_ERROR_UNKNOWN; 297 if (EMPTY_STRING != plugInId) { 298 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 299 result = rDrmEngine.removeRights(uniqueId, path); 300 } 301 return result; 302} 303 304status_t DrmManager::removeAllRights(int uniqueId) { 305 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 306 status_t result = DRM_ERROR_UNKNOWN; 307 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 308 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 309 result = rDrmEngine.removeAllRights(uniqueId); 310 if (DRM_NO_ERROR != result) { 311 break; 312 } 313 } 314 return result; 315} 316 317int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) { 318 int convertId = -1; 319 320 const String8 plugInId = getSupportedPlugInId(mimeType); 321 if (EMPTY_STRING != plugInId) { 322 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 323 324 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) { 325 Mutex::Autolock _l(mConvertLock); 326 ++mConvertId; 327 convertId = mConvertId; 328 mConvertSessionMap.add(convertId, &rDrmEngine); 329 } 330 } 331 return convertId; 332} 333 334DrmConvertedStatus* DrmManager::convertData( 335 int uniqueId, int convertId, const DrmBuffer* inputData) { 336 DrmConvertedStatus *drmConvertedStatus = NULL; 337 338 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) { 339 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId); 340 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData); 341 } 342 return drmConvertedStatus; 343} 344 345DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) { 346 DrmConvertedStatus *drmConvertedStatus = NULL; 347 348 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) { 349 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId); 350 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId); 351 mConvertSessionMap.removeItem(convertId); 352 } 353 return drmConvertedStatus; 354} 355 356status_t DrmManager::getAllSupportInfo( 357 int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) { 358 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 359 int size = plugInPathList.size(); 360 int validPlugins = 0; 361 362 if (0 < size) { 363 Vector<DrmSupportInfo> drmSupportInfoList; 364 365 for (int i = 0; i < size; ++i) { 366 String8 plugInPath = plugInPathList[i]; 367 DrmSupportInfo* drmSupportInfo 368 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); 369 if (NULL != drmSupportInfo) { 370 drmSupportInfoList.add(*drmSupportInfo); 371 delete drmSupportInfo; drmSupportInfo = NULL; 372 } 373 } 374 375 validPlugins = drmSupportInfoList.size(); 376 if (0 < validPlugins) { 377 *drmSupportInfoArray = new DrmSupportInfo[validPlugins]; 378 for (int i = 0; i < validPlugins; ++i) { 379 (*drmSupportInfoArray)[i] = drmSupportInfoList[i]; 380 } 381 } 382 } 383 *length = validPlugins; 384 return DRM_NO_ERROR; 385} 386 387DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) { 388 Mutex::Autolock _l(mDecryptLock); 389 status_t result = DRM_ERROR_CANNOT_HANDLE; 390 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 391 392 DecryptHandle* handle = new DecryptHandle(); 393 if (NULL != handle) { 394 handle->decryptId = mDecryptSessionId + 1; 395 396 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 397 String8 plugInId = plugInIdList.itemAt(index); 398 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 399 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length); 400 401 if (DRM_NO_ERROR == result) { 402 ++mDecryptSessionId; 403 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine); 404 break; 405 } 406 } 407 } 408 if (DRM_NO_ERROR != result) { 409 delete handle; handle = NULL; 410 } 411 return handle; 412} 413 414DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) { 415 Mutex::Autolock _l(mDecryptLock); 416 status_t result = DRM_ERROR_CANNOT_HANDLE; 417 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 418 419 DecryptHandle* handle = new DecryptHandle(); 420 if (NULL != handle) { 421 handle->decryptId = mDecryptSessionId + 1; 422 423 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 424 String8 plugInId = plugInIdList.itemAt(index); 425 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 426 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri); 427 428 if (DRM_NO_ERROR == result) { 429 ++mDecryptSessionId; 430 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine); 431 break; 432 } 433 } 434 } 435 if (DRM_NO_ERROR != result) { 436 delete handle; handle = NULL; 437 LOGE("DrmManager::openDecryptSession: no capable plug-in found"); 438 } 439 return handle; 440} 441 442status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) { 443 Mutex::Autolock _l(mDecryptLock); 444 status_t result = DRM_ERROR_UNKNOWN; 445 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 446 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 447 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle); 448 if (DRM_NO_ERROR == result) { 449 mDecryptSessionMap.removeItem(decryptHandle->decryptId); 450 } 451 } 452 return result; 453} 454 455status_t DrmManager::initializeDecryptUnit( 456 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) { 457 status_t result = DRM_ERROR_UNKNOWN; 458 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 459 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 460 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo); 461 } 462 return result; 463} 464 465status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, 466 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) { 467 status_t result = DRM_ERROR_UNKNOWN; 468 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 469 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 470 result = drmEngine->decrypt( 471 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV); 472 } 473 return result; 474} 475 476status_t DrmManager::finalizeDecryptUnit( 477 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) { 478 status_t result = DRM_ERROR_UNKNOWN; 479 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 480 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 481 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId); 482 } 483 return result; 484} 485 486ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle, 487 void* buffer, ssize_t numBytes, off64_t offset) { 488 ssize_t result = DECRYPT_FILE_ERROR; 489 490 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 491 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 492 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset); 493 } 494 return result; 495} 496 497String8 DrmManager::getSupportedPlugInId( 498 int uniqueId, const String8& path, const String8& mimeType) { 499 String8 plugInId(""); 500 501 if (EMPTY_STRING != mimeType) { 502 plugInId = getSupportedPlugInId(mimeType); 503 } else { 504 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 505 } 506 return plugInId; 507} 508 509String8 DrmManager::getSupportedPlugInId(const String8& mimeType) { 510 String8 plugInId(""); 511 512 if (EMPTY_STRING != mimeType) { 513 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) { 514 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index); 515 516 if (drmSupportInfo.isSupportedMimeType(mimeType)) { 517 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo); 518 break; 519 } 520 } 521 } 522 return plugInId; 523} 524 525String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) { 526 String8 plugInId(""); 527 const String8 fileSuffix = path.getPathExtension(); 528 529 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) { 530 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index); 531 532 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) { 533 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo); 534 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key); 535 536 if (drmEngine.canHandle(uniqueId, path)) { 537 plugInId = key; 538 break; 539 } 540 } 541 } 542 return plugInId; 543} 544 545void DrmManager::onInfo(const DrmInfoEvent& event) { 546 Mutex::Autolock _l(mLock); 547 for (unsigned int index = 0; index < mServiceListeners.size(); index++) { 548 int uniqueId = mServiceListeners.keyAt(index); 549 550 if (uniqueId == event.getUniqueId()) { 551 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId); 552 serviceListener->notify(event); 553 } 554 } 555} 556 557