blob: 3e4fe8c07d23cf29a6b4cd17bc91e2bdb4a89831 [file] [log] [blame]
aimitakeshid074e302010-07-29 10:12:27 +09001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Takeshi Aimidc549d62010-09-20 23:40:41 +090017//#define LOG_NDEBUG 0
aimitakeshid074e302010-07-29 10:12:27 +090018#define LOG_TAG "DrmManager(Native)"
19#include "utils/Log.h"
20
21#include <utils/String8.h>
22#include <drm/DrmInfo.h>
23#include <drm/DrmInfoEvent.h>
24#include <drm/DrmRights.h>
25#include <drm/DrmConstraints.h>
Takeshi Aimidc9186562010-11-16 13:56:11 +090026#include <drm/DrmMetadata.h>
aimitakeshid074e302010-07-29 10:12:27 +090027#include <drm/DrmInfoStatus.h>
28#include <drm/DrmInfoRequest.h>
29#include <drm/DrmSupportInfo.h>
30#include <drm/DrmConvertedStatus.h>
31#include <IDrmEngine.h>
32
33#include "DrmManager.h"
34#include "ReadWriteUtils.h"
35
36#define DECRYPT_FILE_ERROR -1
37
38using namespace android;
39
40const String8 DrmManager::EMPTY_STRING("");
41
42DrmManager::DrmManager() :
43 mDecryptSessionId(0),
44 mConvertId(0) {
45
46}
47
48DrmManager::~DrmManager() {
49
50}
51
Gloria Wanga17d4542011-07-21 15:10:22 -070052int DrmManager::addUniqueId(bool isNative) {
Gloria Wang2ef2d492011-03-04 14:45:03 -080053 Mutex::Autolock _l(mLock);
Takeshi Aimidc549d62010-09-20 23:40:41 +090054
Gloria Wanga17d4542011-07-21 15:10:22 -070055 int temp = 0;
56 bool foundUniqueId = false;
57 const int size = mUniqueIdVector.size();
58 const int uniqueIdRange = 0xfff;
59 int maxLoopTimes = (uniqueIdRange - 1) / 2;
60 srand(time(NULL));
Takeshi Aimidc549d62010-09-20 23:40:41 +090061
Gloria Wanga17d4542011-07-21 15:10:22 -070062 while (!foundUniqueId) {
63 temp = rand() & uniqueIdRange;
64
65 if (isNative) {
66 // set a flag to differentiate DrmManagerClient
67 // created from native side and java side
68 temp |= 0x1000;
69 }
70
71 int index = 0;
72 for (; index < size; ++index) {
73 if (mUniqueIdVector.itemAt(index) == temp) {
74 foundUniqueId = false;
75 break;
Takeshi Aimidc549d62010-09-20 23:40:41 +090076 }
77 }
Gloria Wanga17d4542011-07-21 15:10:22 -070078 if (index == size) {
79 foundUniqueId = true;
80 }
81
82 maxLoopTimes --;
83 LOG_FATAL_IF(maxLoopTimes <= 0, "cannot find an unique ID for this session");
Takeshi Aimidc549d62010-09-20 23:40:41 +090084 }
Gloria Wanga17d4542011-07-21 15:10:22 -070085
86 mUniqueIdVector.push(temp);
87 return temp;
Takeshi Aimidc549d62010-09-20 23:40:41 +090088}
89
90void DrmManager::removeUniqueId(int uniqueId) {
Gloria Wang2ef2d492011-03-04 14:45:03 -080091 Mutex::Autolock _l(mLock);
Takeshi Aimidc549d62010-09-20 23:40:41 +090092 for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
93 if (uniqueId == mUniqueIdVector.itemAt(i)) {
94 mUniqueIdVector.removeAt(i);
95 break;
96 }
97 }
98}
99
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900100status_t DrmManager::loadPlugIns() {
Glenn Kastencbba7202011-01-11 17:15:49 -0800101 String8 pluginDirPath("/system/lib/drm");
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900102 return loadPlugIns(pluginDirPath);
aimitakeshid074e302010-07-29 10:12:27 +0900103}
104
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900105status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
aimitakeshid074e302010-07-29 10:12:27 +0900106 if (mSupportInfoToPlugInIdMap.isEmpty()) {
107 mPlugInManager.loadPlugIns(plugInDirPath);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900108 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
109 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
110 String8 plugInPath = plugInPathList[i];
111 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
112 if (NULL != info) {
113 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
James Dong3f0341c2011-04-24 12:38:35 -0700114 delete info;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900115 }
116 }
aimitakeshid074e302010-07-29 10:12:27 +0900117 }
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900118 return DRM_NO_ERROR;
119}
aimitakeshid074e302010-07-29 10:12:27 +0900120
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900121status_t DrmManager::unloadPlugIns() {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800122 Mutex::Autolock _l(mLock);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900123 mConvertSessionMap.clear();
124 mDecryptSessionMap.clear();
125 mPlugInManager.unloadPlugIns();
126 mSupportInfoToPlugInIdMap.clear();
aimitakeshid074e302010-07-29 10:12:27 +0900127 return DRM_NO_ERROR;
128}
129
130status_t DrmManager::setDrmServiceListener(
131 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
Gloria Wang192b5912011-03-11 14:07:21 -0800132 Mutex::Autolock _l(mListenerLock);
Takeshi Aimif05913a2010-11-30 16:27:42 +0900133 if (NULL != drmServiceListener.get()) {
134 mServiceListeners.add(uniqueId, drmServiceListener);
135 } else {
136 mServiceListeners.removeItem(uniqueId);
137 }
aimitakeshid074e302010-07-29 10:12:27 +0900138 return DRM_NO_ERROR;
139}
140
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900141void DrmManager::addClient(int uniqueId) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800142 Mutex::Autolock _l(mLock);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900143 if (!mSupportInfoToPlugInIdMap.isEmpty()) {
144 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
145 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
146 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
147 rDrmEngine.initialize(uniqueId);
148 rDrmEngine.setOnInfoListener(uniqueId, this);
149 }
150 }
151}
aimitakeshid074e302010-07-29 10:12:27 +0900152
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900153void DrmManager::removeClient(int uniqueId) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800154 Mutex::Autolock _l(mLock);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900155 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
aimitakeshid074e302010-07-29 10:12:27 +0900156 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
157 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
158 rDrmEngine.terminate(uniqueId);
159 }
aimitakeshid074e302010-07-29 10:12:27 +0900160}
161
162DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800163 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900164 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
165 if (EMPTY_STRING != plugInId) {
166 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
167 return rDrmEngine.getConstraints(uniqueId, path, action);
168 }
169 return NULL;
170}
171
Takeshi Aimidc9186562010-11-16 13:56:11 +0900172DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800173 Mutex::Autolock _l(mLock);
Takeshi Aimidc9186562010-11-16 13:56:11 +0900174 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
175 if (EMPTY_STRING != plugInId) {
176 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
177 return rDrmEngine.getMetadata(uniqueId, path);
178 }
179 return NULL;
180}
181
aimitakeshid074e302010-07-29 10:12:27 +0900182status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800183 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900184 mPlugInManager.loadPlugIn(absolutePath);
185
186 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
187 rDrmEngine.initialize(uniqueId);
188 rDrmEngine.setOnInfoListener(uniqueId, this);
189
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900190 DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
aimitakeshid074e302010-07-29 10:12:27 +0900191 mSupportInfoToPlugInIdMap.add(*info, absolutePath);
James Dong3f0341c2011-04-24 12:38:35 -0700192 delete info;
aimitakeshid074e302010-07-29 10:12:27 +0900193
194 return DRM_NO_ERROR;
195}
196
197bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800198 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900199 const String8 plugInId = getSupportedPlugInId(mimeType);
200 bool result = (EMPTY_STRING != plugInId) ? true : false;
201
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900202 if (0 < path.length()) {
aimitakeshid074e302010-07-29 10:12:27 +0900203 if (result) {
204 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
205 result = rDrmEngine.canHandle(uniqueId, path);
206 } else {
Gloria Wang289401b2011-03-02 12:33:00 -0800207 String8 extension = path.getPathExtension();
208 if (String8("") != extension) {
209 result = canHandle(uniqueId, path);
210 }
aimitakeshid074e302010-07-29 10:12:27 +0900211 }
212 }
213 return result;
214}
215
216DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800217 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900218 const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
219 if (EMPTY_STRING != plugInId) {
220 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
221 return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
222 }
223 return NULL;
224}
225
226bool DrmManager::canHandle(int uniqueId, const String8& path) {
227 bool result = false;
228 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
229
230 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
231 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
232 result = rDrmEngine.canHandle(uniqueId, path);
233
234 if (result) {
235 break;
236 }
237 }
238 return result;
239}
240
241DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800242 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900243 const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
244 if (EMPTY_STRING != plugInId) {
245 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
246 return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
247 }
248 return NULL;
249}
250
Takeshi Aimidc549d62010-09-20 23:40:41 +0900251status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
aimitakeshid074e302010-07-29 10:12:27 +0900252 const String8& rightsPath, const String8& contentPath) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800253 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900254 const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
Takeshi Aimidc549d62010-09-20 23:40:41 +0900255 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900256 if (EMPTY_STRING != plugInId) {
257 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900258 result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
aimitakeshid074e302010-07-29 10:12:27 +0900259 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900260 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900261}
262
263String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800264 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900265 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
266 if (EMPTY_STRING != plugInId) {
267 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
268 return rDrmEngine.getOriginalMimeType(uniqueId, path);
269 }
270 return EMPTY_STRING;
271}
272
273int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800274 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900275 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
276 if (EMPTY_STRING != plugInId) {
277 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
278 return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
279 }
280 return DrmObjectType::UNKNOWN;
281}
282
283int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800284 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900285 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
286 if (EMPTY_STRING != plugInId) {
287 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
288 return rDrmEngine.checkRightsStatus(uniqueId, path, action);
289 }
290 return RightsStatus::RIGHTS_INVALID;
291}
292
Takeshi Aimidc549d62010-09-20 23:40:41 +0900293status_t DrmManager::consumeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900294 int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
Takeshi Aimidc549d62010-09-20 23:40:41 +0900295 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800296 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900297 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
298 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900299 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
aimitakeshid074e302010-07-29 10:12:27 +0900300 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900301 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900302}
303
Takeshi Aimidc549d62010-09-20 23:40:41 +0900304status_t DrmManager::setPlaybackStatus(
Gloria Wang5fc3edb2010-11-19 15:19:36 -0800305 int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
Takeshi Aimidc549d62010-09-20 23:40:41 +0900306 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800307 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900308 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
309 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900310 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
aimitakeshid074e302010-07-29 10:12:27 +0900311 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900312 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900313}
314
315bool DrmManager::validateAction(
316 int uniqueId, const String8& path, int action, const ActionDescription& description) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800317 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900318 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
319 if (EMPTY_STRING != plugInId) {
320 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
321 return rDrmEngine.validateAction(uniqueId, path, action, description);
322 }
323 return false;
324}
325
Takeshi Aimidc549d62010-09-20 23:40:41 +0900326status_t DrmManager::removeRights(int uniqueId, const String8& path) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800327 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900328 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900329 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900330 if (EMPTY_STRING != plugInId) {
331 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900332 result = rDrmEngine.removeRights(uniqueId, path);
aimitakeshid074e302010-07-29 10:12:27 +0900333 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900334 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900335}
336
Takeshi Aimidc549d62010-09-20 23:40:41 +0900337status_t DrmManager::removeAllRights(int uniqueId) {
aimitakeshid074e302010-07-29 10:12:27 +0900338 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Takeshi Aimidc549d62010-09-20 23:40:41 +0900339 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900340 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
341 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900342 result = rDrmEngine.removeAllRights(uniqueId);
343 if (DRM_NO_ERROR != result) {
344 break;
345 }
aimitakeshid074e302010-07-29 10:12:27 +0900346 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900347 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900348}
349
350int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800351 Mutex::Autolock _l(mConvertLock);
aimitakeshid074e302010-07-29 10:12:27 +0900352 int convertId = -1;
353
354 const String8 plugInId = getSupportedPlugInId(mimeType);
355 if (EMPTY_STRING != plugInId) {
356 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
357
Takeshi Aimidc549d62010-09-20 23:40:41 +0900358 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
Takeshi Aimidc549d62010-09-20 23:40:41 +0900359 ++mConvertId;
360 convertId = mConvertId;
361 mConvertSessionMap.add(convertId, &rDrmEngine);
362 }
aimitakeshid074e302010-07-29 10:12:27 +0900363 }
364 return convertId;
365}
366
367DrmConvertedStatus* DrmManager::convertData(
368 int uniqueId, int convertId, const DrmBuffer* inputData) {
369 DrmConvertedStatus *drmConvertedStatus = NULL;
370
Gloria Wang2ef2d492011-03-04 14:45:03 -0800371 Mutex::Autolock _l(mConvertLock);
aimitakeshid074e302010-07-29 10:12:27 +0900372 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
373 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
374 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
375 }
376 return drmConvertedStatus;
377}
378
379DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800380 Mutex::Autolock _l(mConvertLock);
aimitakeshid074e302010-07-29 10:12:27 +0900381 DrmConvertedStatus *drmConvertedStatus = NULL;
382
383 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
384 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
385 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
386 mConvertSessionMap.removeItem(convertId);
387 }
388 return drmConvertedStatus;
389}
390
391status_t DrmManager::getAllSupportInfo(
392 int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
Gloria Wang2ef2d492011-03-04 14:45:03 -0800393 Mutex::Autolock _l(mLock);
aimitakeshid074e302010-07-29 10:12:27 +0900394 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
395 int size = plugInPathList.size();
396 int validPlugins = 0;
397
398 if (0 < size) {
399 Vector<DrmSupportInfo> drmSupportInfoList;
400
401 for (int i = 0; i < size; ++i) {
402 String8 plugInPath = plugInPathList[i];
403 DrmSupportInfo* drmSupportInfo
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900404 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
aimitakeshid074e302010-07-29 10:12:27 +0900405 if (NULL != drmSupportInfo) {
406 drmSupportInfoList.add(*drmSupportInfo);
407 delete drmSupportInfo; drmSupportInfo = NULL;
408 }
409 }
410
411 validPlugins = drmSupportInfoList.size();
412 if (0 < validPlugins) {
413 *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
414 for (int i = 0; i < validPlugins; ++i) {
415 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
416 }
417 }
418 }
419 *length = validPlugins;
420 return DRM_NO_ERROR;
421}
422
Gloria Wang5fc3edb2010-11-19 15:19:36 -0800423DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) {
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900424 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900425 status_t result = DRM_ERROR_CANNOT_HANDLE;
426 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
427
428 DecryptHandle* handle = new DecryptHandle();
429 if (NULL != handle) {
aimitakeshid074e302010-07-29 10:12:27 +0900430 handle->decryptId = mDecryptSessionId + 1;
431
432 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
433 String8 plugInId = plugInIdList.itemAt(index);
434 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
435 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
436
aimitakeshid074e302010-07-29 10:12:27 +0900437 if (DRM_NO_ERROR == result) {
438 ++mDecryptSessionId;
439 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
aimitakeshid074e302010-07-29 10:12:27 +0900440 break;
441 }
442 }
443 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900444 if (DRM_NO_ERROR != result) {
aimitakeshid074e302010-07-29 10:12:27 +0900445 delete handle; handle = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900446 }
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900447 return handle;
448}
aimitakeshid074e302010-07-29 10:12:27 +0900449
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900450DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
451 Mutex::Autolock _l(mDecryptLock);
452 status_t result = DRM_ERROR_CANNOT_HANDLE;
453 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
454
455 DecryptHandle* handle = new DecryptHandle();
456 if (NULL != handle) {
457 handle->decryptId = mDecryptSessionId + 1;
458
459 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
460 String8 plugInId = plugInIdList.itemAt(index);
461 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
462 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
463
464 if (DRM_NO_ERROR == result) {
465 ++mDecryptSessionId;
466 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
467 break;
468 }
469 }
470 }
471 if (DRM_NO_ERROR != result) {
472 delete handle; handle = NULL;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800473 LOGV("DrmManager::openDecryptSession: no capable plug-in found");
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900474 }
aimitakeshid074e302010-07-29 10:12:27 +0900475 return handle;
476}
477
Takeshi Aimidc549d62010-09-20 23:40:41 +0900478status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900479 Mutex::Autolock _l(mDecryptLock);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900480 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900481 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
482 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900483 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
484 if (DRM_NO_ERROR == result) {
485 mDecryptSessionMap.removeItem(decryptHandle->decryptId);
486 }
aimitakeshid074e302010-07-29 10:12:27 +0900487 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900488 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900489}
490
Takeshi Aimidc549d62010-09-20 23:40:41 +0900491status_t DrmManager::initializeDecryptUnit(
aimitakeshid074e302010-07-29 10:12:27 +0900492 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
Takeshi Aimidc549d62010-09-20 23:40:41 +0900493 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800494 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900495 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
496 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900497 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
aimitakeshid074e302010-07-29 10:12:27 +0900498 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900499 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900500}
501
Takeshi Aimidc549d62010-09-20 23:40:41 +0900502status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
503 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
504 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800505
506 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900507 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
508 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900509 result = drmEngine->decrypt(
510 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
aimitakeshid074e302010-07-29 10:12:27 +0900511 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900512 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900513}
514
Takeshi Aimidc549d62010-09-20 23:40:41 +0900515status_t DrmManager::finalizeDecryptUnit(
aimitakeshid074e302010-07-29 10:12:27 +0900516 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
Takeshi Aimidc549d62010-09-20 23:40:41 +0900517 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang2ef2d492011-03-04 14:45:03 -0800518 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900519 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
520 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimidc549d62010-09-20 23:40:41 +0900521 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
aimitakeshid074e302010-07-29 10:12:27 +0900522 }
Takeshi Aimidc549d62010-09-20 23:40:41 +0900523 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900524}
525
526ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
Gloria Wang5fc3edb2010-11-19 15:19:36 -0800527 void* buffer, ssize_t numBytes, off64_t offset) {
aimitakeshid074e302010-07-29 10:12:27 +0900528 ssize_t result = DECRYPT_FILE_ERROR;
529
Gloria Wang2ef2d492011-03-04 14:45:03 -0800530 Mutex::Autolock _l(mDecryptLock);
aimitakeshid074e302010-07-29 10:12:27 +0900531 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
532 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
533 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
534 }
535 return result;
536}
537
aimitakeshid074e302010-07-29 10:12:27 +0900538String8 DrmManager::getSupportedPlugInId(
539 int uniqueId, const String8& path, const String8& mimeType) {
540 String8 plugInId("");
541
542 if (EMPTY_STRING != mimeType) {
543 plugInId = getSupportedPlugInId(mimeType);
544 } else {
545 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
546 }
547 return plugInId;
548}
549
550String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
551 String8 plugInId("");
552
553 if (EMPTY_STRING != mimeType) {
554 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
555 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
556
557 if (drmSupportInfo.isSupportedMimeType(mimeType)) {
558 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
559 break;
560 }
561 }
562 }
563 return plugInId;
564}
565
566String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
567 String8 plugInId("");
568 const String8 fileSuffix = path.getPathExtension();
569
570 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
571 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
572
573 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
574 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
575 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
576
577 if (drmEngine.canHandle(uniqueId, path)) {
578 plugInId = key;
579 break;
580 }
581 }
582 }
583 return plugInId;
584}
585
586void DrmManager::onInfo(const DrmInfoEvent& event) {
Gloria Wang192b5912011-03-11 14:07:21 -0800587 Mutex::Autolock _l(mListenerLock);
aimitakeshid074e302010-07-29 10:12:27 +0900588 for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
589 int uniqueId = mServiceListeners.keyAt(index);
590
591 if (uniqueId == event.getUniqueId()) {
592 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
593 serviceListener->notify(event);
594 }
595 }
596}
597