DrmManager.cpp revision c618b5af98dec06d49374a61a5a94016f9fec2d3
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
402272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi AimiVector<int> DrmManager::mUniqueIdVector;
4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiconst String8 DrmManager::EMPTY_STRING("");
4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmManager::DrmManager() :
4427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mDecryptSessionId(0),
4527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mConvertId(0) {
4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
4827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmManager::~DrmManager() {
5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
532272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimiint DrmManager::addUniqueId(int uniqueId) {
542272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    if (0 == uniqueId) {
552272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        int temp = 0;
562272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        bool foundUniqueId = false;
572272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        srand(time(NULL));
582272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
592272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        while (!foundUniqueId) {
602272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            const int size = mUniqueIdVector.size();
612272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            temp = rand() % 100;
622272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
632272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            int index = 0;
642272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            for (; index < size; ++index) {
652272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                if (mUniqueIdVector.itemAt(index) == temp) {
662272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                    foundUniqueId = false;
672272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                    break;
682272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                }
692272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            }
702272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            if (index == size) {
712272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                foundUniqueId = true;
722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            }
732272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        uniqueId = temp;
752272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    }
762272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    mUniqueIdVector.push(uniqueId);
772272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return uniqueId;
782272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
792272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
802272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimivoid DrmManager::removeUniqueId(int uniqueId) {
812272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
822272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (uniqueId == mUniqueIdVector.itemAt(i)) {
832272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            mUniqueIdVector.removeAt(i);
842272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            break;
852272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
862272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    }
872272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
882272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
89e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::loadPlugIns() {
9027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 pluginDirPath("/system/lib/drm/plugins/native");
91e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    return loadPlugIns(pluginDirPath);
9227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
94e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
9527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mSupportInfoToPlugInIdMap.isEmpty()) {
9627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        mPlugInManager.loadPlugIns(plugInDirPath);
97e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
98e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
99e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            String8 plugInPath = plugInPathList[i];
100e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
101e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            if (NULL != info) {
102e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
103e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            }
104e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
10527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
106e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    return DRM_NO_ERROR;
107e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
109e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatus_t DrmManager::unloadPlugIns() {
110e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mConvertSessionMap.clear();
111e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mDecryptSessionMap.clear();
112e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mPlugInManager.unloadPlugIns();
113e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    mSupportInfoToPlugInIdMap.clear();
11427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
11527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
11627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
11727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t DrmManager::setDrmServiceListener(
11827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
11927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Mutex::Autolock _l(mLock);
120c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    if (NULL != drmServiceListener.get()) {
121c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi        mServiceListeners.add(uniqueId, drmServiceListener);
122c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    } else {
123c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi        mServiceListeners.removeItem(uniqueId);
124c618b5af98dec06d49374a61a5a94016f9fec2d3Takeshi Aimi    }
12527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
12627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
12727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
128e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimivoid DrmManager::addClient(int uniqueId) {
129e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
130e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
131e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
132e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
133e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            rDrmEngine.initialize(uniqueId);
134e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            rDrmEngine.setOnInfoListener(uniqueId, this);
135e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
136e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
137e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
139e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimivoid DrmManager::removeClient(int uniqueId) {
140e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
14127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
14327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        rDrmEngine.terminate(uniqueId);
14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
14527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
14627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
14827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
14927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
15027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
15127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.getConstraints(uniqueId, path, action);
15227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
15427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
15527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1563473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi AimiDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
1573473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
1583473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    if (EMPTY_STRING != plugInId) {
1593473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
1603473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        return rDrmEngine.getMetadata(uniqueId, path);
1613473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    }
1623473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    return NULL;
1633473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi}
1643473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mPlugInManager.loadPlugIn(absolutePath);
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    rDrmEngine.initialize(uniqueId);
17027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    rDrmEngine.setOnInfoListener(uniqueId, this);
17127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
172e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
17327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
17427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
17627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
17727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
17927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
18027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    bool result = (EMPTY_STRING != plugInId) ? true : false;
18127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
182e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (0 < path.length()) {
18327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (result) {
18427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            result = rDrmEngine.canHandle(uniqueId, path);
18627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        } else {
18727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            result = canHandle(uniqueId, path);
18827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
18927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
19027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
19127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
19227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
19427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
19527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
19627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
19727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
19827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
20127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path) {
20327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    bool result = false;
20427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
20527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
20627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
20727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
20827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        result = rDrmEngine.canHandle(uniqueId, path);
20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (result) {
21127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            break;
21227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
21327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
21427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
21627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
21827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
21927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
22027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
22127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
22227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
22327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return NULL;
22427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
22527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2262272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            const String8& rightsPath, const String8& contentPath) {
22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
2292272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
23127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
2322272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
23327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2342272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
23527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
23627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
23727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
23827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
23927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
24027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
24127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.getOriginalMimeType(uniqueId, path);
24227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
24327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return EMPTY_STRING;
24427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
24527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
24627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
24727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
24827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
24927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
25027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
25127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
25227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DrmObjectType::UNKNOWN;
25327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
25427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
25527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
25627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
25727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
25827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
25927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
26027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
26127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return RightsStatus::RIGHTS_INVALID;
26227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
26327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2642272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::consumeRights(
26527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
2662272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
26727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
26827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
2692272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
27027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2712272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
27227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
27327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::setPlaybackStatus(
27527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
2762272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
27727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
27827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
2792272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
28027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
2812272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
28227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
28327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
28427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool DrmManager::validateAction(
28527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, const String8& path, int action, const ActionDescription& description) {
28627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
28727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
28827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
28927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return rDrmEngine.validateAction(uniqueId, path, action, description);
29027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
29127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
29227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
29327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2942272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::removeRights(int uniqueId, const String8& path) {
29527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
2962272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
29727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
29827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
2992272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.removeRights(uniqueId, path);
30027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
3012272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
30227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
30327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3042272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::removeAllRights(int uniqueId) {
30527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
3062272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
30727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
30827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
3092272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = rDrmEngine.removeAllRights(uniqueId);
3102272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR != result) {
3112272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            break;
3122272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
31327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
3142272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
31527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
31627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
31727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
31827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int convertId = -1;
31927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
32027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
32127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != plugInId) {
32227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
32327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3242272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
3252272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            Mutex::Autolock _l(mConvertLock);
3262272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            ++mConvertId;
3272272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            convertId = mConvertId;
3282272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            mConvertSessionMap.add(convertId, &rDrmEngine);
3292272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
33027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
33127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return convertId;
33227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
33327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
33427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConvertedStatus* DrmManager::convertData(
33527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, int convertId, const DrmBuffer* inputData) {
33627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
33727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
33827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
33927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
34027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
34127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
34227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return drmConvertedStatus;
34327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
34427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
34527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
34627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
34727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
34827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
34927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
35027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
35127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        mConvertSessionMap.removeItem(convertId);
35227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
35327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return drmConvertedStatus;
35427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
35527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
35627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatus_t DrmManager::getAllSupportInfo(
35727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
35827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
35927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int size = plugInPathList.size();
36027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int validPlugins = 0;
36127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
36227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (0 < size) {
36327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        Vector<DrmSupportInfo> drmSupportInfoList;
36427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
36527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        for (int i = 0; i < size; ++i) {
36627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            String8 plugInPath = plugInPathList[i];
36727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            DrmSupportInfo* drmSupportInfo
368e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
36927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (NULL != drmSupportInfo) {
37027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                drmSupportInfoList.add(*drmSupportInfo);
37127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                delete drmSupportInfo; drmSupportInfo = NULL;
37227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
37327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
37427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
37527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        validPlugins = drmSupportInfoList.size();
37627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (0 < validPlugins) {
37727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
37827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            for (int i = 0; i < validPlugins; ++i) {
37927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
38027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
38127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
38227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
38327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    *length = validPlugins;
38427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return DRM_NO_ERROR;
38527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
38627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
38727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiDecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, int offset, int length) {
388e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
38927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    status_t result = DRM_ERROR_CANNOT_HANDLE;
39027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
39127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
39227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    DecryptHandle* handle = new DecryptHandle();
39327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (NULL != handle) {
39427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        handle->decryptId = mDecryptSessionId + 1;
39527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
39627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
39727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            String8 plugInId = plugInIdList.itemAt(index);
39827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
39927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
40027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
40127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (DRM_NO_ERROR == result) {
40227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                ++mDecryptSessionId;
40327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
40427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                break;
40527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
40627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
40727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4082272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    if (DRM_NO_ERROR != result) {
40927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        delete handle; handle = NULL;
41027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
41127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
412e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    return handle;
413e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
414e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
415e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi AimiDecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
416e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
417e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    status_t result = DRM_ERROR_CANNOT_HANDLE;
418e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
419e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
420e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    DecryptHandle* handle = new DecryptHandle();
421e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (NULL != handle) {
422e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        handle->decryptId = mDecryptSessionId + 1;
423e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
424e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
425e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            String8 plugInId = plugInIdList.itemAt(index);
426e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
427e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
42827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
429e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            if (DRM_NO_ERROR == result) {
430e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                ++mDecryptSessionId;
431e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
432e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                break;
433e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi            }
434e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        }
435e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
436e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    if (DRM_NO_ERROR != result) {
437e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        delete handle; handle = NULL;
438e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
439e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    }
44027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return handle;
44127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
44227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4432272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
444e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
4452272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
44627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
44727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
4482272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
4492272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        if (DRM_NO_ERROR == result) {
4502272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
4512272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        }
45227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4532272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
45427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
45527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4562272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::initializeDecryptUnit(
45727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
4582272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
45927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
46027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
4612272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
46227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4632272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
46427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
46527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4662272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
4672272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
4682272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
46927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
47027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
4712272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->decrypt(
4722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
47327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
47527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
47627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4772272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimistatus_t DrmManager::finalizeDecryptUnit(
47827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
4792272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
48027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
48127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
4822272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
48327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
4842272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return result;
48527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
48627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
48727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshissize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
48827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            void* buffer, ssize_t numBytes, off_t offset) {
48927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    ssize_t result = DECRYPT_FILE_ERROR;
49027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
49127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
49227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
49327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
49427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
49527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return result;
49627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
49727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
49827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getSupportedPlugInId(
49927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            int uniqueId, const String8& path, const String8& mimeType) {
50027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 plugInId("");
50127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
50227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != mimeType) {
50327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        plugInId = getSupportedPlugInId(mimeType);
50427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    } else {
50527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
50627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
50727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return plugInId;
50827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
50927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
51027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
51127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 plugInId("");
51227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
51327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (EMPTY_STRING != mimeType) {
51427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
51527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
51627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
51727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (drmSupportInfo.isSupportedMimeType(mimeType)) {
51827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
51927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                break;
52027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
52127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
52227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
52327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return plugInId;
52427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
52527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
52627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiString8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
52727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    String8 plugInId("");
52827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    const String8 fileSuffix = path.getPathExtension();
52927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
53027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
53127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
53227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
53327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
53427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
53527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
53627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
53727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            if (drmEngine.canHandle(uniqueId, path)) {
53827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                plugInId = key;
53927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                break;
54027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            }
54127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
54227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
54327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return plugInId;
54427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
54527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
54627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshivoid DrmManager::onInfo(const DrmInfoEvent& event) {
54727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Mutex::Autolock _l(mLock);
54827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
54927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        int uniqueId = mServiceListeners.keyAt(index);
55027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
55127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        if (uniqueId == event.getUniqueId()) {
55227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
55327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi            serviceListener->notify(event);
55427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        }
55527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
55627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
55727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
558