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
40d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiconst String8 DrmManager::EMPTY_STRING("");
41d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
42d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmManager::DrmManager() :
43d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mDecryptSessionId(0),
44d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mConvertId(0) {
45d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
46d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
47d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
48d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmManager::~DrmManager() {
49d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
50d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
51d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
52a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wangint DrmManager::addUniqueId(bool isNative) {
532ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
54a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
55a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    int temp = 0;
56a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    bool foundUniqueId = false;
57a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    const int size = mUniqueIdVector.size();
58a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    const int uniqueIdRange = 0xfff;
59a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    int maxLoopTimes = (uniqueIdRange - 1) / 2;
60a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    srand(time(NULL));
61a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
62a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    while (!foundUniqueId) {
63a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        temp = rand() & uniqueIdRange;
64a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
65a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        if (isNative) {
66a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang            // set a flag to differentiate DrmManagerClient
67a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang            // created from native side and java side
68a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang            temp |= 0x1000;
69a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        }
70a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
71a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        int index = 0;
72a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        for (; index < size; ++index) {
73a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang            if (mUniqueIdVector.itemAt(index) == temp) {
74a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang                foundUniqueId = false;
75a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang                break;
76dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
77dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
78a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        if (index == size) {
79a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang            foundUniqueId = true;
80a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        }
81a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
82a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        maxLoopTimes --;
83a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang        LOG_FATAL_IF(maxLoopTimes <= 0, "cannot find an unique ID for this session");
84dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
85a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang
86a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    mUniqueIdVector.push(temp);
87a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    return temp;
88dc549d60f98d809f626c99de614960409a847054Takeshi Aimi}
89dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
90dc549d60f98d809f626c99de614960409a847054Takeshi Aimivoid DrmManager::removeUniqueId(int uniqueId) {
912ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
92dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
93dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (uniqueId == mUniqueIdVector.itemAt(i)) {
94dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mUniqueIdVector.removeAt(i);
95dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
96dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
97dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
98dc549d60f98d809f626c99de614960409a847054Takeshi Aimi}
99dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
100c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::loadPlugIns() {
101aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong
102aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    String8 vendorPluginDirPath("/vendor/lib/drm");
103aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    loadPlugIns(vendorPluginDirPath);
104aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong
1054a30052beacebd99b37f3a4db248d718d9f98820James Dong    String8 pluginDirPath("/system/lib/drm");
1064a30052beacebd99b37f3a4db248d718d9f98820James Dong    loadPlugIns(pluginDirPath);
107aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    return DRM_NO_ERROR;
108aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong
109d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
110d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
111c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
112aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    mPlugInManager.loadPlugIns(plugInDirPath);
113aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
114aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
115aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong        String8 plugInPath = plugInPathList[i];
116aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong        DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
117aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong        if (NULL != info) {
118aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong            if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
119c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
120c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
121aab6fe21df535171006063edf8367b59c6e525e0Edwin Wong            delete info;
122c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
123d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
124c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    return DRM_NO_ERROR;
125c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
126d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
127c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimistatus_t DrmManager::unloadPlugIns() {
1282ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
129c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mConvertSessionMap.clear();
130c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mDecryptSessionMap.clear();
131c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mPlugInManager.unloadPlugIns();
132c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    mSupportInfoToPlugInIdMap.clear();
133d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
134d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
135d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
136d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::setDrmServiceListener(
137d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
138192b591cdca78f258dd3260e41d7217f6fc6e36cGloria Wang    Mutex::Autolock _l(mListenerLock);
139f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    if (NULL != drmServiceListener.get()) {
140f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        mServiceListeners.add(uniqueId, drmServiceListener);
141f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    } else {
142f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        mServiceListeners.removeItem(uniqueId);
143f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi    }
144d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
145d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
146d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
147c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimivoid DrmManager::addClient(int uniqueId) {
1482ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
149c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
150c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
151c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
152c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
153c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            rDrmEngine.initialize(uniqueId);
154c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            rDrmEngine.setOnInfoListener(uniqueId, this);
155c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
156c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
157c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
158d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
159c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimivoid DrmManager::removeClient(int uniqueId) {
1602ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
161c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
162d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
163d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
164d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        rDrmEngine.terminate(uniqueId);
165d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
166d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
167d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
168d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
1692ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
170d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
171d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
172d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
173d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getConstraints(uniqueId, path, action);
174d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
175d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
176d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
177d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
178dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi AimiDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
1792ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
180dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
181dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    if (EMPTY_STRING != plugInId) {
182dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
183dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return rDrmEngine.getMetadata(uniqueId, path);
184dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
185dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    return NULL;
186dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi}
187dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
188d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
1892ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
190d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mPlugInManager.loadPlugIn(absolutePath);
191d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
192d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
193d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    rDrmEngine.initialize(uniqueId);
194d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    rDrmEngine.setOnInfoListener(uniqueId, this);
195d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
196c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
197d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
1983f0341cbbdeee248e71814f7071233c823b44f74James Dong    delete info;
199d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
200d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
201d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
202d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
203d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
2042ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
205d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
206d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    bool result = (EMPTY_STRING != plugInId) ? true : false;
207d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
208c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (0 < path.length()) {
209d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (result) {
210d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
211d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            result = rDrmEngine.canHandle(uniqueId, path);
212d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        } else {
213289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            String8 extension = path.getPathExtension();
214289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            if (String8("") != extension) {
215289401b7566384570de86e9ad6ab3c572e358675Gloria Wang                result = canHandle(uniqueId, path);
216289401b7566384570de86e9ad6ab3c572e358675Gloria Wang            }
217d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
218d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
219d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
220d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
221d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
222d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
2232ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
224d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
225d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
226d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
227d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
228d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
229d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
230d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
231d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
232d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::canHandle(int uniqueId, const String8& path) {
233d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    bool result = false;
234d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
235d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
236d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
237d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
238d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        result = rDrmEngine.canHandle(uniqueId, path);
239d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
240d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (result) {
241d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            break;
242d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
243d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
244d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
245d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
246d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
247d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
2482ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
249d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
250d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
251d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
252d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
253d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
254d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return NULL;
255d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
256d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
257dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
258d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            const String8& rightsPath, const String8& contentPath) {
2592ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
260d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
261dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
262d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
263d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
264dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
265d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
266dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
267d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
268d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
269d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
2702ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
271d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
272d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
273d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
274d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getOriginalMimeType(uniqueId, path);
275d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
276d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return EMPTY_STRING;
277d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
278d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
279d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
2802ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
281d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
282d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
283d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
284d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
285d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
286d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DrmObjectType::UNKNOWN;
287d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
288d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
289d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
2902ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
291d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
292d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
293d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
294d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
295d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
296d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return RightsStatus::RIGHTS_INVALID;
297d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
298d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
299dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::consumeRights(
300d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
301dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
3022ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
303d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
304d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
305dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
306d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
307dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
308d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
309d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
310dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::setPlaybackStatus(
3115fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria Wang    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
312dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
3132ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
314d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
315d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
316dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
317d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
318dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
319d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
320d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
321d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshibool DrmManager::validateAction(
322d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, const String8& path, int action, const ActionDescription& description) {
3232ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
324d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
325d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
326d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
327d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return rDrmEngine.validateAction(uniqueId, path, action, description);
328d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
329d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return false;
330d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
331d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
332dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::removeRights(int uniqueId, const String8& path) {
3332ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
334d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
335dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
336d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
337d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
338dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.removeRights(uniqueId, path);
339d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
340dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
341d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
342d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
343dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::removeAllRights(int uniqueId) {
344d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
345dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
346d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
347d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
348dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = rDrmEngine.removeAllRights(uniqueId);
349dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR != result) {
350dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
351dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
352d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
353dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
354d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
355d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
356d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
3572ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mConvertLock);
358d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int convertId = -1;
359d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
360d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 plugInId = getSupportedPlugInId(mimeType);
361d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != plugInId) {
362d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
363d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
364dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
365dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            ++mConvertId;
366dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            convertId = mConvertId;
367dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mConvertSessionMap.add(convertId, &rDrmEngine);
368dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
369d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
370d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return convertId;
371d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
372d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
373d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConvertedStatus* DrmManager::convertData(
374d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, int convertId, const DrmBuffer* inputData) {
375d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
376d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
3772ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mConvertLock);
378d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
379d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
380d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
381d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
382d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return drmConvertedStatus;
383d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
384d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
385d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiDrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
3862ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mConvertLock);
387d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmConvertedStatus *drmConvertedStatus = NULL;
388d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
389d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
390d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
391d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
392d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        mConvertSessionMap.removeItem(convertId);
393d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
394d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return drmConvertedStatus;
395d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
396d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
397d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatus_t DrmManager::getAllSupportInfo(
398d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
3992ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mLock);
400d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
401d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int size = plugInPathList.size();
402d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int validPlugins = 0;
403d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
404d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (0 < size) {
405d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        Vector<DrmSupportInfo> drmSupportInfoList;
406d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
407d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (int i = 0; i < size; ++i) {
408d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 plugInPath = plugInPathList[i];
409d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmSupportInfo* drmSupportInfo
410c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
411d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (NULL != drmSupportInfo) {
412d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                drmSupportInfoList.add(*drmSupportInfo);
413d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                delete drmSupportInfo; drmSupportInfo = NULL;
414d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
415d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
416d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
417d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        validPlugins = drmSupportInfoList.size();
418d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (0 < validPlugins) {
419d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
420d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            for (int i = 0; i < validPlugins; ++i) {
421d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
422d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
423d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
424d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
425d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    *length = validPlugins;
426d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return DRM_NO_ERROR;
427d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
428d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
4295fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria WangDecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) {
430c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
431d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    status_t result = DRM_ERROR_CANNOT_HANDLE;
432d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
433d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
434d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DecryptHandle* handle = new DecryptHandle();
435d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != handle) {
436d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        handle->decryptId = mDecryptSessionId + 1;
437d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
438d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
439d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 plugInId = plugInIdList.itemAt(index);
440d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
441d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
442d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
443d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (DRM_NO_ERROR == result) {
444d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                ++mDecryptSessionId;
445d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
446d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
447d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
448d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
449d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
450dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    if (DRM_NO_ERROR != result) {
451d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        delete handle; handle = NULL;
452d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
453c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    return handle;
454c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi}
455c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
456c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi AimiDecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
457c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
458c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    status_t result = DRM_ERROR_CANNOT_HANDLE;
459c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
460d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
461c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    DecryptHandle* handle = new DecryptHandle();
462c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (NULL != handle) {
463c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        handle->decryptId = mDecryptSessionId + 1;
464c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
465c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
466c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            String8 plugInId = plugInIdList.itemAt(index);
467c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
468c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
469d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
470c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            if (DRM_NO_ERROR == result) {
471c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                ++mDecryptSessionId;
472c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
473c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                break;
474c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
475c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
476c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
477c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (DRM_NO_ERROR != result) {
478c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        delete handle; handle = NULL;
4792ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang        LOGV("DrmManager::openDecryptSession: no capable plug-in found");
480c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
481d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return handle;
482d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
483d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
484dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
485c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    Mutex::Autolock _l(mDecryptLock);
486dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
487d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
488d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
489dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
490dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (DRM_NO_ERROR == result) {
491dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
492dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
493d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
494dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
495d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
496d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
497dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::initializeDecryptUnit(
498d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
499dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5002ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
501d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
502d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
503dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
504d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
505dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
506d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
507d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
508dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
509dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
510dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5112ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang
5122ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
513d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
514d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
515dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->decrypt(
516dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
517d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
518dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
519d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
520d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
521dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatus_t DrmManager::finalizeDecryptUnit(
522d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
523dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    status_t result = DRM_ERROR_UNKNOWN;
5242ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
525d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
526d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
527dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
528d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
529dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
530d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
531d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
532d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshissize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
5335fc3edb13edb058f14e6550d295ce3e50e5ebf8cGloria Wang            void* buffer, ssize_t numBytes, off64_t offset) {
534d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    ssize_t result = DECRYPT_FILE_ERROR;
535d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
5362ef2d49aa3c19e99e2a753dac2dfb51fc87b5328Gloria Wang    Mutex::Autolock _l(mDecryptLock);
537d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
538d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
539d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
540d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
541d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
542d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
543d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
544d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInId(
545d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, const String8& path, const String8& mimeType) {
546d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
547d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
548d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != mimeType) {
549d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        plugInId = getSupportedPlugInId(mimeType);
550d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    } else {
551d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
552d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
553d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
554d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
555d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
556d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
557d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
558d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
559d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (EMPTY_STRING != mimeType) {
560d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
561d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
562d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
563d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (drmSupportInfo.isSupportedMimeType(mimeType)) {
564d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
565d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
566d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
567d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
568d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
569d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
570d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
571d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
572d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
573d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 plugInId("");
574d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 fileSuffix = path.getPathExtension();
575d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
576d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
577d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
578d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
579d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
580d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
581d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
582d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
583d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (drmEngine.canHandle(uniqueId, path)) {
584d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                plugInId = key;
585d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                break;
586d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
587d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
588d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
589d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return plugInId;
590d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
591d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
592d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshivoid DrmManager::onInfo(const DrmInfoEvent& event) {
593192b591cdca78f258dd3260e41d7217f6fc6e36cGloria Wang    Mutex::Autolock _l(mListenerLock);
594d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
595d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        int uniqueId = mServiceListeners.keyAt(index);
596d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
597d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (uniqueId == event.getUniqueId()) {
598d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
599d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            serviceListener->notify(event);
600d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
601d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
602d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
603d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
604