DrmManager.cpp revision 289401b7566384570de86e9ad6ab3c572e358675
1d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/*
2d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Copyright (C) 2010 The Android Open Source Project
3d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
4d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
5d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * you may not use this file except in compliance with the License.
6d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * You may obtain a copy of the License at
7d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
8d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
9d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
10d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Unless required by applicable law or agreed to in writing, software
11d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
12d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * See the License for the specific language governing permissions and
14d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * limitations under the License.
15d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
16d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
17dc549d60f98d809f626c99de614960409a847054Takeshi Aimi//#define LOG_NDEBUG 0
18d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#define LOG_TAG "DrmManager(Native)"
19d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include "utils/Log.h"
20d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
21d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <utils/String8.h>
22d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfo.h>
23d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoEvent.h>
24d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmRights.h>
25d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmConstraints.h>
26dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi#include <drm/DrmMetadata.h>
27d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoStatus.h>
28d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoRequest.h>
29d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmSupportInfo.h>
30d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmConvertedStatus.h>
31d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <IDrmEngine.h>
32d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
33d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include "DrmManager.h"
34d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include "ReadWriteUtils.h"
35d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
36d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#define DECRYPT_FILE_ERROR -1
37d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
38d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiusing namespace android;
39d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
40dc549d60f98d809f626c99de614960409a847054Takeshi AimiVector<int> DrmManager::mUniqueIdVector;
41d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiconst String8 DrmManager::EMPTY_STRING("");
42d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
43d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmManager::DrmManager() :
44d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mDecryptSessionId(0),
45d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mConvertId(0) {
46d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
47d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
48d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
49d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmManager::~DrmManager() {
50d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
51d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
52d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
53dc549d60f98d809f626c99de614960409a847054Takeshi Aimiint DrmManager::addUniqueId(int uniqueId) {
54dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    if (0 == uniqueId) {
55dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int temp = 0;
56dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        bool foundUniqueId = false;
57dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        srand(time(NULL));
58dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
59dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        while (!foundUniqueId) {
60dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            const int size = mUniqueIdVector.size();
61dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            temp = rand() % 100;
62dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
63dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            int index = 0;
64dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            for (; index < size; ++index) {
65dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (mUniqueIdVector.itemAt(index) == temp) {
66dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    foundUniqueId = false;
67dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
68dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
69dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
70dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            if (index == size) {
71dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                foundUniqueId = true;
72dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
73dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
74dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        uniqueId = temp;
75dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
76dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    mUniqueIdVector.push(uniqueId);
77dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return uniqueId;
78dc549d60f98d809f626c99de614960409a847054Takeshi Aimi}
79dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
80dc549d60f98d809f626c99de614960409a847054Takeshi Aimivoid DrmManager::removeUniqueId(int uniqueId) {
81dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
82dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (uniqueId == mUniqueIdVector.itemAt(i)) {
83dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mUniqueIdVector.removeAt(i);
84dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
85dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
86dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
87dc549d60f98d809f626c99de614960409a847054Takeshi Aimi}
88dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
89c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::loadPlugIns() {
90cbba720a460f49a9d16afcc7e85c4564d7d945a1Glenn Kasten    String8 pluginDirPath("/system/lib/drm");
91c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    return loadPlugIns(pluginDirPath);
92d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
93d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
94c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
95d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mSupportInfoToPlugInIdMap.isEmpty()) {
96d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        mPlugInManager.loadPlugIns(plugInDirPath);
97c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
98c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
99c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            String8 plugInPath = plugInPathList[i];
100c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
101c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            if (NULL != info) {
102c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
103c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
104c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
105d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
106c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    return DRM_NO_ERROR;
107c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
108d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
109c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::unloadPlugIns() {
110c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mConvertSessionMap.clear();
111c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mDecryptSessionMap.clear();
112c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mPlugInManager.unloadPlugIns();
113c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mSupportInfoToPlugInIdMap.clear();
114d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
115d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
116d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
117d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::setDrmServiceListener(
118d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
119d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Mutex::Autolock _l(mLock);
120f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    if (NULL != drmServiceListener.get()) {
121f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        mServiceListeners.add(uniqueId, drmServiceListener);
122f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    } else {
123f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        mServiceListeners.removeItem(uniqueId);
124f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    }
125d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
126d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
127d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
128c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimivoid DrmManager::addClient(int uniqueId) {
129c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
130c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
131c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
132c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
133c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            rDrmEngine.initialize(uniqueId);
134c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            rDrmEngine.setOnInfoListener(uniqueId, this);
135c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
136c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
137c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
138d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
139c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimivoid DrmManager::removeClient(int uniqueId) {
140c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
141d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
142d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
143d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        rDrmEngine.terminate(uniqueId);
144d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
145d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
146d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
147d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
148d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
149d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
150d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
151d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getConstraints(uniqueId, path, action);
152d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
153d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
154d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
155d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
156dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi AimiDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
157dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
158dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    if (EMPTY_STRING != plugInId) {
159dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
160dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return rDrmEngine.getMetadata(uniqueId, path);
161dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
162dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    return NULL;
163dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi}
164dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
165d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
166d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mPlugInManager.loadPlugIn(absolutePath);
167d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
168d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
169d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    rDrmEngine.initialize(uniqueId);
170d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    rDrmEngine.setOnInfoListener(uniqueId, this);
171d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
172c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
173d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
174d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
175d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
176d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
177d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
178d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
179d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
180d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    bool result = (EMPTY_STRING != plugInId) ? true : false;
181d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
182c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (0 < path.length()) {
183d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (result) {
184d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
185d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            result = rDrmEngine.canHandle(uniqueId, path);
186d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        } else {
187289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            String8 extension = path.getPathExtension();
188289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            if (String8("") != extension) {
189289401b7566384570de86e9ad6ab3c572e358675Gloria Wang                result = canHandle(uniqueId, path);
190289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            }
191d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
192d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
193d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
194d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
195d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
196d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
197d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
198d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
199d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
200d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
201d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
202d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
203d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
204d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
205d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path) {
206d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    bool result = false;
207d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
208d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
209d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
210d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
211d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        result = rDrmEngine.canHandle(uniqueId, path);
212d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
213d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (result) {
214d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            break;
215d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
216d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
217d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
218d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
219d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
220d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
221d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
222d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
223d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
224d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
225d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
226d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
227d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
228d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
229dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
230d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            const String8& rightsPath, const String8& contentPath) {
231d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
232dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
233d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
234d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
235dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
236d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
237dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
238d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
239d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
240d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
241d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
242d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
243d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
244d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getOriginalMimeType(uniqueId, path);
245d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
246d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return EMPTY_STRING;
247d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
248d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
249d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
250d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
251d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
252d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
253d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
254d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
255d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DrmObjectType::UNKNOWN;
256d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
257d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
258d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
259d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
260d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
261d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
262d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
263d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
264d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return RightsStatus::RIGHTS_INVALID;
265d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
266d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
267dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::consumeRights(
268d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
269dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
270d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
271d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
272dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
273d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
274dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
275d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
276d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
277dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::setPlaybackStatus(
2785fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria Wang    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
279dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
280d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
281d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
282dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
283d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
284dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
285d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
286d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
287d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::validateAction(
288d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, const String8& path, int action, const ActionDescription& description) {
289d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
290d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
291d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
292d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.validateAction(uniqueId, path, action, description);
293d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
294d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return false;
295d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
296d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
297dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::removeRights(int uniqueId, const String8& path) {
298d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
299dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
300d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
301d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
302dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.removeRights(uniqueId, path);
303d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
304dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
305d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
306d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
307dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::removeAllRights(int uniqueId) {
308d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
309dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
310d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
311d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
312dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.removeAllRights(uniqueId);
313dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR != result) {
314dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
315dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
316d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
317dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
318d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
319d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
320d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
321d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int convertId = -1;
322d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
323d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
324d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
325d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
326d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
327dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
328dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Mutex::Autolock _l(mConvertLock);
329dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            ++mConvertId;
330dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            convertId = mConvertId;
331dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mConvertSessionMap.add(convertId, &rDrmEngine);
332dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
333d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
334d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return convertId;
335d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
336d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
337d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConvertedStatus* DrmManager::convertData(
338d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, int convertId, const DrmBuffer* inputData) {
339d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
340d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
341d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
342d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
343d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
344d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
345d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return drmConvertedStatus;
346d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
347d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
348d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
349d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
350d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
351d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
352d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
353d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
354d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        mConvertSessionMap.removeItem(convertId);
355d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
356d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return drmConvertedStatus;
357d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
358d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
359d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::getAllSupportInfo(
360d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
361d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
362d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int size = plugInPathList.size();
363d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int validPlugins = 0;
364d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
365d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (0 < size) {
366d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        Vector<DrmSupportInfo> drmSupportInfoList;
367d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
368d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (int i = 0; i < size; ++i) {
369d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 plugInPath = plugInPathList[i];
370d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmSupportInfo* drmSupportInfo
371c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
372d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (NULL != drmSupportInfo) {
373d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                drmSupportInfoList.add(*drmSupportInfo);
374d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                delete drmSupportInfo; drmSupportInfo = NULL;
375d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
376d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
377d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
378d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        validPlugins = drmSupportInfoList.size();
379d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (0 < validPlugins) {
380d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
381d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            for (int i = 0; i < validPlugins; ++i) {
382d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
383d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
384d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
385d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
386d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    *length = validPlugins;
387d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
388d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
389d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
3905fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria WangDecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) {
391c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
392d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    status_t result = DRM_ERROR_CANNOT_HANDLE;
393d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
394d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
395d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DecryptHandle* handle = new DecryptHandle();
396d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != handle) {
397d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        handle->decryptId = mDecryptSessionId + 1;
398d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
399d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
400d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 plugInId = plugInIdList.itemAt(index);
401d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
402d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
403d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
404d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (DRM_NO_ERROR == result) {
405d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                ++mDecryptSessionId;
406d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
407d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
408d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
409d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
410d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
411dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    if (DRM_NO_ERROR != result) {
412d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        delete handle; handle = NULL;
413d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
414c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    return handle;
415c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
416c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
417c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi AimiDecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
418c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
419c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    status_t result = DRM_ERROR_CANNOT_HANDLE;
420c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
421d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
422c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    DecryptHandle* handle = new DecryptHandle();
423c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (NULL != handle) {
424c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        handle->decryptId = mDecryptSessionId + 1;
425c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
426c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
427c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            String8 plugInId = plugInIdList.itemAt(index);
428c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
429c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
430d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
431c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            if (DRM_NO_ERROR == result) {
432c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                ++mDecryptSessionId;
433c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
434c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                break;
435c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
436c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
437c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
438c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (DRM_NO_ERROR != result) {
439c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        delete handle; handle = NULL;
440c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
441c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
442d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return handle;
443d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
444d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
445dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
446c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
447dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
448d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
449d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
450dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
451dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR == result) {
452dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
453dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
454d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
455dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
456d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
457d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
458dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::initializeDecryptUnit(
459d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
460dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
461d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
462d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
463dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
464d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
465dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
466d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
467d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
468dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
469dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
470dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
471d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
472d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
473dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->decrypt(
474dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
475d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
476dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
477d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
478d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
479dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::finalizeDecryptUnit(
480d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
481dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
482d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
483d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
484dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
485d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
486dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
487d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
488d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
489d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshissize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
4905fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria Wang            void* buffer, ssize_t numBytes, off64_t offset) {
491d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    ssize_t result = DECRYPT_FILE_ERROR;
492d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
493d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
494d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
495d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
496d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
497d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
498d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
499d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
500d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInId(
501d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, const String8& path, const String8& mimeType) {
502d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
503d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
504d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != mimeType) {
505d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        plugInId = getSupportedPlugInId(mimeType);
506d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    } else {
507d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
508d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
509d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
510d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
511d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
512d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
513d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
514d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
515d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != mimeType) {
516d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
517d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
518d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
519d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (drmSupportInfo.isSupportedMimeType(mimeType)) {
520d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
521d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
522d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
523d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
524d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
525d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
526d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
527d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
528d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
529d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
530d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 fileSuffix = path.getPathExtension();
531d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
532d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
533d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
534d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
535d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
536d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
537d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
538d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
539d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (drmEngine.canHandle(uniqueId, path)) {
540d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                plugInId = key;
541d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
542d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
543d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
544d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
545d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
546d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
547d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
548d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshivoid DrmManager::onInfo(const DrmInfoEvent& event) {
549d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Mutex::Autolock _l(mLock);
550d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
551d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        int uniqueId = mServiceListeners.keyAt(index);
552d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
553d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (uniqueId == event.getUniqueId()) {
554d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
555d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            serviceListener->notify(event);
556d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
557d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
558d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
559d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
560