127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/*
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Copyright (C) 2010 The Android Open Source Project
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * you may not use this file except in compliance with the License.
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * You may obtain a copy of the License at
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Unless required by applicable law or agreed to in writing, software
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * See the License for the specific language governing permissions and
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * limitations under the License.
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
172272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi//#define LOG_NDEBUG 0
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#define LOG_TAG "DrmManager(Native)"
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "utils/Log.h"
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <utils/String8.h>
2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmInfo.h>
2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmInfoEvent.h>
2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmRights.h>
2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmConstraints.h>
263473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi#include <drm/DrmMetadata.h>
2727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmInfoStatus.h>
2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmInfoRequest.h>
2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmSupportInfo.h>
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <drm/DrmConvertedStatus.h>
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <IDrmEngine.h>
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "DrmManager.h"
3427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ReadWriteUtils.h"
3527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#define DECRYPT_FILE_ERROR -1
3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiusing namespace android;
3927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiconst String8 DrmManager::EMPTY_STRING("");
4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmManager::DrmManager() :
4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mDecryptSessionId(0),
4427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mConvertId(0) {
4513f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    srand(time(NULL));
4613f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    memset(mUniqueIdArray, 0, sizeof(bool) * kMaxNumUniqueIds);
4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
4827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmManager::~DrmManager() {
5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
538f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wangint DrmManager::addUniqueId(bool isNative) {
546b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
558f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
5613f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    int uniqueId = -1;
5713f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    int random = rand();
588f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
5913f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
6013f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson        int temp = (random + index) % kMaxNumUniqueIds;
6113f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson        if (!mUniqueIdArray[temp]) {
6213f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson            uniqueId = temp;
6313f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson            mUniqueIdArray[uniqueId] = true;
648f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
6513f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson            if (isNative) {
6613f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson                // set a flag to differentiate DrmManagerClient
6713f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson                // created from native side and java side
6813f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson                uniqueId |= 0x1000;
692272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            }
7013f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson            break;
712272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    }
738f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
7413f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    // -1 indicates that no unique id can be allocated.
7513f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    return uniqueId;
762272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
772272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
782272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimivoid DrmManager::removeUniqueId(int uniqueId) {
796b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
8013f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    if (uniqueId & 0x1000) {
8113f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson        // clear the flag for the native side.
8213f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson        uniqueId &= ~(0x1000);
8313f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    }
8413f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson
8513f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson    if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
8613f7fe763b9ad52fc27f21ed923c46b9555a321fHenrik B Andersson        mUniqueIdArray[uniqueId] = false;
872272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    }
882272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
892272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
90e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::loadPlugIns() {
915f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong
925f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong    String8 vendorPluginDirPath("/vendor/lib/drm");
935f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong    loadPlugIns(vendorPluginDirPath);
945f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong
95785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    String8 pluginDirPath("/system/lib/drm");
96785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    loadPlugIns(pluginDirPath);
975f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong    return DRM_NO_ERROR;
985f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong
9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
101e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
1025f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong    mPlugInManager.loadPlugIns(plugInDirPath);
1035f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
1043ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t i = 0; i < plugInPathList.size(); ++i) {
1055f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong        String8 plugInPath = plugInPathList[i];
1065f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong        DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
1075f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong        if (NULL != info) {
1085f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong            if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
109e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
110e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            }
1115f6f4e4e89bc9b234d89276aea3eae7f677e2ff7Edwin Wong            delete info;
112e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
11327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
114e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    return DRM_NO_ERROR;
115e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
11627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
117e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::unloadPlugIns() {
1186b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
119e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mConvertSessionMap.clear();
120e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mDecryptSessionMap.clear();
121e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mPlugInManager.unloadPlugIns();
122e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mSupportInfoToPlugInIdMap.clear();
12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
12427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
12527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
12627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t DrmManager::setDrmServiceListener(
12727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
1280e0a5f9e0b7a7ca618e8a1f7ccecc57a17e0d1e2Gloria Wang    Mutex::Autolock _l(mListenerLock);
129c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    if (NULL != drmServiceListener.get()) {
130c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi        mServiceListeners.add(uniqueId, drmServiceListener);
131c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    } else {
132c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi        mServiceListeners.removeItem(uniqueId);
133c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    }
13427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
13527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
13627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
137e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimivoid DrmManager::addClient(int uniqueId) {
1386b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
139e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
140e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
1413ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn        for (size_t index = 0; index < plugInIdList.size(); index++) {
142e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
143e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            rDrmEngine.initialize(uniqueId);
144e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            rDrmEngine.setOnInfoListener(uniqueId, this);
145e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
146e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
147e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
14827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
149e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimivoid DrmManager::removeClient(int uniqueId) {
1506b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
151e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
1523ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t index = 0; index < plugInIdList.size(); index++) {
15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
15427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        rDrmEngine.terminate(uniqueId);
15527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
15627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
15727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
15827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
1596b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
16027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
16227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
16327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.getConstraints(uniqueId, path, action);
16427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1683473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi AimiDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
1696b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
1703473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
1713473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    if (EMPTY_STRING != plugInId) {
1723473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
1733473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        return rDrmEngine.getMetadata(uniqueId, path);
1743473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    }
1753473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    return NULL;
1763473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi}
1773473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
17827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
1796b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
18027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
18127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    bool result = (EMPTY_STRING != plugInId) ? true : false;
18227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
183e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (0 < path.length()) {
18427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (result) {
18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
18627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            result = rDrmEngine.canHandle(uniqueId, path);
18727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        } else {
1887f89d09c0f4a47119834ba15789260b933123ea5Gloria Wang            String8 extension = path.getPathExtension();
1897f89d09c0f4a47119834ba15789260b933123ea5Gloria Wang            if (String8("") != extension) {
1907f89d09c0f4a47119834ba15789260b933123ea5Gloria Wang                result = canHandle(uniqueId, path);
1917f89d09c0f4a47119834ba15789260b933123ea5Gloria Wang            }
19227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
19327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
19427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
19527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
19627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
1986b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
20127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
20327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
20427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
20527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
20627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
20727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path) {
20827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    bool result = false;
20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2113ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t i = 0; i < plugInPathList.size(); ++i) {
21227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
21327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        result = rDrmEngine.canHandle(uniqueId, path);
21427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (result) {
21627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            break;
21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
21827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
21927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
22027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
22127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
2236b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
22427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
22527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
22627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
22927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
23127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2322272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
23327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            const String8& rightsPath, const String8& contentPath) {
2346b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
23527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
2362272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
23727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
23827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
2392272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
24027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2412272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
24227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
24327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
244bf5b3b29e31b293313788d7464cfb258ac0da803James DongString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
2456b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
24627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
24727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
24827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
249bf5b3b29e31b293313788d7464cfb258ac0da803James Dong        return rDrmEngine.getOriginalMimeType(uniqueId, path, fd);
25027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
25127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return EMPTY_STRING;
25227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
25327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
25427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
2556b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
25627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
25727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
25827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
25927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
26027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
26127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DrmObjectType::UNKNOWN;
26227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
26327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
26427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
2656b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
26627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
26727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
26827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
26927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
27027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
27127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return RightsStatus::RIGHTS_INVALID;
27227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
27327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::consumeRights(
27527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
2762272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
2776b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
27827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
27927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
2802272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
28127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2822272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
28327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
28427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2852272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::setPlaybackStatus(
286a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
2872272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
2886b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
28927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
29027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
2912272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
29227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2932272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
29427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
29527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
29627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::validateAction(
29727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, const String8& path, int action, const ActionDescription& description) {
2986b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
29927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
30027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
30127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
30227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.validateAction(uniqueId, path, action, description);
30327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
30427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
30527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
30627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3072272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::removeRights(int uniqueId, const String8& path) {
3086b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
30927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
3102272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
31127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
31227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
3132272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.removeRights(uniqueId, path);
31427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
3152272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
31627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
31727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3182272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::removeAllRights(int uniqueId) {
31927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
3202272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
3213ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t index = 0; index < plugInIdList.size(); index++) {
32227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
3232272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.removeAllRights(uniqueId);
3242272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR != result) {
3252272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            break;
3262272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
32727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
3282272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
32927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
33027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
33127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
3326b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mConvertLock);
33327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int convertId = -1;
33427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
33527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
33627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
33727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
33827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3392272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
3402272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            ++mConvertId;
3412272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            convertId = mConvertId;
3422272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            mConvertSessionMap.add(convertId, &rDrmEngine);
3432272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
34427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
34527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return convertId;
34627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
34727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
34827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConvertedStatus* DrmManager::convertData(
34927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, int convertId, const DrmBuffer* inputData) {
35027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
35127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3526b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mConvertLock);
35327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
35427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
35527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
35627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
35727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return drmConvertedStatus;
35827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
35927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
36027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
3616b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mConvertLock);
36227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
36327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
36427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
36527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
36627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
36727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        mConvertSessionMap.removeItem(convertId);
36827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
36927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return drmConvertedStatus;
37027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
37127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
37227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t DrmManager::getAllSupportInfo(
37327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
3746b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mLock);
37527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
37627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int size = plugInPathList.size();
37727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int validPlugins = 0;
37827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
37927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (0 < size) {
38027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        Vector<DrmSupportInfo> drmSupportInfoList;
38127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
38227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        for (int i = 0; i < size; ++i) {
38327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            String8 plugInPath = plugInPathList[i];
38427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            DrmSupportInfo* drmSupportInfo
385e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
38627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (NULL != drmSupportInfo) {
38727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                drmSupportInfoList.add(*drmSupportInfo);
38827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                delete drmSupportInfo; drmSupportInfo = NULL;
38927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
39027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
39127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
39227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        validPlugins = drmSupportInfoList.size();
39327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (0 < validPlugins) {
39427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
39527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            for (int i = 0; i < validPlugins; ++i) {
39627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
39727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
39827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
39927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
40027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    *length = validPlugins;
40127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
40227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
40327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4049d2f386dd2885eaffa11fd494ae258bb09fe6397James DongDecryptHandle* DrmManager::openDecryptSession(
4059d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
4069d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
407e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
40827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    status_t result = DRM_ERROR_CANNOT_HANDLE;
40927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
41027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
41127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DecryptHandle* handle = new DecryptHandle();
41227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (NULL != handle) {
41327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        handle->decryptId = mDecryptSessionId + 1;
41427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4153ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn        for (size_t index = 0; index < plugInIdList.size(); index++) {
41627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            String8 plugInId = plugInIdList.itemAt(index);
41727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
4189d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
41927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
42027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (DRM_NO_ERROR == result) {
42127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                ++mDecryptSessionId;
42227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
42327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                break;
42427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
42527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
42627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4272272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    if (DRM_NO_ERROR != result) {
42827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        delete handle; handle = NULL;
42927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
430e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    return handle;
431e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
432e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
4339d2f386dd2885eaffa11fd494ae258bb09fe6397James DongDecryptHandle* DrmManager::openDecryptSession(
4349d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        int uniqueId, const char* uri, const char* mime) {
435e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
436e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    status_t result = DRM_ERROR_CANNOT_HANDLE;
437e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
43827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
439e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    DecryptHandle* handle = new DecryptHandle();
440e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (NULL != handle) {
441e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        handle->decryptId = mDecryptSessionId + 1;
442e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
4433ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn        for (size_t index = 0; index < plugInIdList.size(); index++) {
444e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            String8 plugInId = plugInIdList.itemAt(index);
445e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
4469d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
44727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
448e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            if (DRM_NO_ERROR == result) {
449e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                ++mDecryptSessionId;
450e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
451e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                break;
452e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            }
453e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
454e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
455e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (DRM_NO_ERROR != result) {
456e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        delete handle; handle = NULL;
4573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
458e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
45927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return handle;
46027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
46127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
462cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei TakahashiDecryptHandle* DrmManager::openDecryptSession(
463cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
464cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    Mutex::Autolock _l(mDecryptLock);
465cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    status_t result = DRM_ERROR_CANNOT_HANDLE;
466cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
467cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi
468cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    DecryptHandle* handle = new DecryptHandle();
469cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    if (NULL != handle) {
470cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        handle->decryptId = mDecryptSessionId + 1;
471cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi
472cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        for (size_t index = 0; index < plugInIdList.size(); index++) {
473cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi            String8 plugInId = plugInIdList.itemAt(index);
474cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
475cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi            result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
476cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi
477cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi            if (DRM_NO_ERROR == result) {
478cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi                ++mDecryptSessionId;
479cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
480cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi                break;
481cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi            }
482cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        }
483cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    }
484cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    if (DRM_NO_ERROR != result) {
485cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        delete handle;
486cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        handle = NULL;
487cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi        ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
488cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    }
489cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi    return handle;
490cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi}
491cba7b32d8f2c47632313f54118ed3733b4b02cc8Kei Takahashi
4922272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
493e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
4942272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
49527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
49627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
4972272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
4982272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR == result) {
4992272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
5002272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
50127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
5022272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
50327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
50427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5052272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::initializeDecryptUnit(
50627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
5072272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5086b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
50927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
51027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
5112272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
51227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
5132272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
51427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
51527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5162272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
5172272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
5182272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5196b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang
5206b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
52127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
52227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
5232272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->decrypt(
5242272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
52527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
5262272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
52727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
52827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5292272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::finalizeDecryptUnit(
53027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
5312272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5326b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
53327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
53427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
5352272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
53627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
5372272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
53827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
53927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
54027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshissize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
541a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang            void* buffer, ssize_t numBytes, off64_t offset) {
54227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ssize_t result = DECRYPT_FILE_ERROR;
54327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5446b610a3d31a225adfc5867223df25dba16637bd9Gloria Wang    Mutex::Autolock _l(mDecryptLock);
54527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
54627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
54727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
54827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
54927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
55027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
55127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
55227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getSupportedPlugInId(
55327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, const String8& path, const String8& mimeType) {
55427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 plugInId("");
55527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
55627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != mimeType) {
55727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        plugInId = getSupportedPlugInId(mimeType);
55827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    } else {
55927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
56027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
56127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return plugInId;
56227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
56327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
56427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
56527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 plugInId("");
56627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
56727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != mimeType) {
5683ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn        for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
56927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
570