blob: 2fee59c3cc1cdbe2727e430220510d5ca2b6daea [file] [log] [blame]
aimitakeshi27ed8ad2010-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 Aimi2272ee22010-09-20 23:40:41 +090017//#define LOG_NDEBUG 0
aimitakeshi27ed8ad2010-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 Aimi34738462010-11-16 13:56:11 +090026#include <drm/DrmMetadata.h>
aimitakeshi27ed8ad2010-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
Takeshi Aimi2272ee22010-09-20 23:40:41 +090052int DrmManager::addUniqueId(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -080053 Mutex::Autolock _l(mLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +090054 if (0 == uniqueId) {
55 int temp = 0;
56 bool foundUniqueId = false;
57 srand(time(NULL));
58
59 while (!foundUniqueId) {
60 const int size = mUniqueIdVector.size();
61 temp = rand() % 100;
62
63 int index = 0;
64 for (; index < size; ++index) {
65 if (mUniqueIdVector.itemAt(index) == temp) {
66 foundUniqueId = false;
67 break;
68 }
69 }
70 if (index == size) {
71 foundUniqueId = true;
72 }
73 }
74 uniqueId = temp;
75 }
76 mUniqueIdVector.push(uniqueId);
77 return uniqueId;
78}
79
80void DrmManager::removeUniqueId(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -080081 Mutex::Autolock _l(mLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +090082 for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
83 if (uniqueId == mUniqueIdVector.itemAt(i)) {
84 mUniqueIdVector.removeAt(i);
85 break;
86 }
87 }
88}
89
Takeshi Aimie943f842010-10-08 23:05:49 +090090status_t DrmManager::loadPlugIns() {
Glenn Kastenfc4f5aa2011-01-11 17:15:49 -080091 String8 pluginDirPath("/system/lib/drm");
Takeshi Aimie943f842010-10-08 23:05:49 +090092 return loadPlugIns(pluginDirPath);
aimitakeshi27ed8ad2010-07-29 10:12:27 +090093}
94
Takeshi Aimie943f842010-10-08 23:05:49 +090095status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +090096 if (mSupportInfoToPlugInIdMap.isEmpty()) {
97 mPlugInManager.loadPlugIns(plugInDirPath);
Takeshi Aimie943f842010-10-08 23:05:49 +090098 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
99 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
100 String8 plugInPath = plugInPathList[i];
101 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
102 if (NULL != info) {
103 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
104 }
105 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900106 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900107 return DRM_NO_ERROR;
108}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900109
Takeshi Aimie943f842010-10-08 23:05:49 +0900110status_t DrmManager::unloadPlugIns() {
Gloria Wang6b610a32011-03-04 14:45:03 -0800111 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900112 mConvertSessionMap.clear();
113 mDecryptSessionMap.clear();
114 mPlugInManager.unloadPlugIns();
115 mSupportInfoToPlugInIdMap.clear();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900116 return DRM_NO_ERROR;
117}
118
119status_t DrmManager::setDrmServiceListener(
120 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800121 Mutex::Autolock _l(mListenerLock);
Takeshi Aimic618b5a2010-11-30 16:27:42 +0900122 if (NULL != drmServiceListener.get()) {
123 mServiceListeners.add(uniqueId, drmServiceListener);
124 } else {
125 mServiceListeners.removeItem(uniqueId);
126 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900127 return DRM_NO_ERROR;
128}
129
Takeshi Aimie943f842010-10-08 23:05:49 +0900130void DrmManager::addClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800131 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900132 if (!mSupportInfoToPlugInIdMap.isEmpty()) {
133 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
134 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
135 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
136 rDrmEngine.initialize(uniqueId);
137 rDrmEngine.setOnInfoListener(uniqueId, this);
138 }
139 }
140}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900141
Takeshi Aimie943f842010-10-08 23:05:49 +0900142void DrmManager::removeClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800143 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900144 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900145 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
146 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
147 rDrmEngine.terminate(uniqueId);
148 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900149}
150
151DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800152 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900153 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
154 if (EMPTY_STRING != plugInId) {
155 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
156 return rDrmEngine.getConstraints(uniqueId, path, action);
157 }
158 return NULL;
159}
160
Takeshi Aimi34738462010-11-16 13:56:11 +0900161DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800162 Mutex::Autolock _l(mLock);
Takeshi Aimi34738462010-11-16 13:56:11 +0900163 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
164 if (EMPTY_STRING != plugInId) {
165 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
166 return rDrmEngine.getMetadata(uniqueId, path);
167 }
168 return NULL;
169}
170
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900171status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800172 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900173 mPlugInManager.loadPlugIn(absolutePath);
174
175 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
176 rDrmEngine.initialize(uniqueId);
177 rDrmEngine.setOnInfoListener(uniqueId, this);
178
Takeshi Aimie943f842010-10-08 23:05:49 +0900179 DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900180 mSupportInfoToPlugInIdMap.add(*info, absolutePath);
181
182 return DRM_NO_ERROR;
183}
184
185bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800186 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900187 const String8 plugInId = getSupportedPlugInId(mimeType);
188 bool result = (EMPTY_STRING != plugInId) ? true : false;
189
Takeshi Aimie943f842010-10-08 23:05:49 +0900190 if (0 < path.length()) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900191 if (result) {
192 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
193 result = rDrmEngine.canHandle(uniqueId, path);
194 } else {
Gloria Wang7f89d092011-03-02 12:33:00 -0800195 String8 extension = path.getPathExtension();
196 if (String8("") != extension) {
197 result = canHandle(uniqueId, path);
198 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900199 }
200 }
201 return result;
202}
203
204DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800205 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900206 const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
207 if (EMPTY_STRING != plugInId) {
208 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
209 return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
210 }
211 return NULL;
212}
213
214bool DrmManager::canHandle(int uniqueId, const String8& path) {
215 bool result = false;
216 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
217
218 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
219 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
220 result = rDrmEngine.canHandle(uniqueId, path);
221
222 if (result) {
223 break;
224 }
225 }
226 return result;
227}
228
229DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800230 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900231 const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
232 if (EMPTY_STRING != plugInId) {
233 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
234 return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
235 }
236 return NULL;
237}
238
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900239status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900240 const String8& rightsPath, const String8& contentPath) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800241 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900242 const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900243 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900244 if (EMPTY_STRING != plugInId) {
245 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900246 result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900247 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900248 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900249}
250
251String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800252 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900253 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
254 if (EMPTY_STRING != plugInId) {
255 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
256 return rDrmEngine.getOriginalMimeType(uniqueId, path);
257 }
258 return EMPTY_STRING;
259}
260
261int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800262 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900263 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
264 if (EMPTY_STRING != plugInId) {
265 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
266 return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
267 }
268 return DrmObjectType::UNKNOWN;
269}
270
271int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800272 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900273 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
274 if (EMPTY_STRING != plugInId) {
275 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
276 return rDrmEngine.checkRightsStatus(uniqueId, path, action);
277 }
278 return RightsStatus::RIGHTS_INVALID;
279}
280
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900281status_t DrmManager::consumeRights(
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900282 int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900283 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800284 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900285 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
286 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900287 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900288 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900289 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900290}
291
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900292status_t DrmManager::setPlaybackStatus(
Gloria Wanga2cd44c2010-11-19 15:19:36 -0800293 int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900294 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800295 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900296 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
297 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900298 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900299 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900300 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900301}
302
303bool DrmManager::validateAction(
304 int uniqueId, const String8& path, int action, const ActionDescription& description) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800305 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900306 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
307 if (EMPTY_STRING != plugInId) {
308 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
309 return rDrmEngine.validateAction(uniqueId, path, action, description);
310 }
311 return false;
312}
313
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900314status_t DrmManager::removeRights(int uniqueId, const String8& path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800315 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900316 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900317 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900318 if (EMPTY_STRING != plugInId) {
319 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900320 result = rDrmEngine.removeRights(uniqueId, path);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900321 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900322 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900323}
324
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900325status_t DrmManager::removeAllRights(int uniqueId) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900326 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900327 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900328 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
329 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900330 result = rDrmEngine.removeAllRights(uniqueId);
331 if (DRM_NO_ERROR != result) {
332 break;
333 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900334 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900335 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900336}
337
338int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800339 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900340 int convertId = -1;
341
342 const String8 plugInId = getSupportedPlugInId(mimeType);
343 if (EMPTY_STRING != plugInId) {
344 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
345
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900346 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900347 ++mConvertId;
348 convertId = mConvertId;
349 mConvertSessionMap.add(convertId, &rDrmEngine);
350 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900351 }
352 return convertId;
353}
354
355DrmConvertedStatus* DrmManager::convertData(
356 int uniqueId, int convertId, const DrmBuffer* inputData) {
357 DrmConvertedStatus *drmConvertedStatus = NULL;
358
Gloria Wang6b610a32011-03-04 14:45:03 -0800359 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900360 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
361 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
362 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
363 }
364 return drmConvertedStatus;
365}
366
367DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800368 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900369 DrmConvertedStatus *drmConvertedStatus = NULL;
370
371 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
372 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
373 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
374 mConvertSessionMap.removeItem(convertId);
375 }
376 return drmConvertedStatus;
377}
378
379status_t DrmManager::getAllSupportInfo(
380 int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800381 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900382 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
383 int size = plugInPathList.size();
384 int validPlugins = 0;
385
386 if (0 < size) {
387 Vector<DrmSupportInfo> drmSupportInfoList;
388
389 for (int i = 0; i < size; ++i) {
390 String8 plugInPath = plugInPathList[i];
391 DrmSupportInfo* drmSupportInfo
Takeshi Aimie943f842010-10-08 23:05:49 +0900392 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900393 if (NULL != drmSupportInfo) {
394 drmSupportInfoList.add(*drmSupportInfo);
395 delete drmSupportInfo; drmSupportInfo = NULL;
396 }
397 }
398
399 validPlugins = drmSupportInfoList.size();
400 if (0 < validPlugins) {
401 *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
402 for (int i = 0; i < validPlugins; ++i) {
403 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
404 }
405 }
406 }
407 *length = validPlugins;
408 return DRM_NO_ERROR;
409}
410
Gloria Wanga2cd44c2010-11-19 15:19:36 -0800411DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900412 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900413 status_t result = DRM_ERROR_CANNOT_HANDLE;
414 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
415
416 DecryptHandle* handle = new DecryptHandle();
417 if (NULL != handle) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900418 handle->decryptId = mDecryptSessionId + 1;
419
420 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
421 String8 plugInId = plugInIdList.itemAt(index);
422 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
423 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
424
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900425 if (DRM_NO_ERROR == result) {
426 ++mDecryptSessionId;
427 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900428 break;
429 }
430 }
431 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900432 if (DRM_NO_ERROR != result) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900433 delete handle; handle = NULL;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900434 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900435 return handle;
436}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900437
Takeshi Aimie943f842010-10-08 23:05:49 +0900438DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
439 Mutex::Autolock _l(mDecryptLock);
440 status_t result = DRM_ERROR_CANNOT_HANDLE;
441 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
442
443 DecryptHandle* handle = new DecryptHandle();
444 if (NULL != handle) {
445 handle->decryptId = mDecryptSessionId + 1;
446
447 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
448 String8 plugInId = plugInIdList.itemAt(index);
449 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
450 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
451
452 if (DRM_NO_ERROR == result) {
453 ++mDecryptSessionId;
454 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
455 break;
456 }
457 }
458 }
459 if (DRM_NO_ERROR != result) {
460 delete handle; handle = NULL;
Gloria Wang6b610a32011-03-04 14:45:03 -0800461 LOGV("DrmManager::openDecryptSession: no capable plug-in found");
Takeshi Aimie943f842010-10-08 23:05:49 +0900462 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900463 return handle;
464}
465
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900466status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900467 Mutex::Autolock _l(mDecryptLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900468 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900469 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
470 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900471 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
472 if (DRM_NO_ERROR == result) {
473 mDecryptSessionMap.removeItem(decryptHandle->decryptId);
474 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900475 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900476 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900477}
478
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900479status_t DrmManager::initializeDecryptUnit(
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900480 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900481 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800482 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900483 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
484 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900485 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900486 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900487 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900488}
489
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900490status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
491 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
492 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800493
494 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900495 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
496 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900497 result = drmEngine->decrypt(
498 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900499 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900500 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900501}
502
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900503status_t DrmManager::finalizeDecryptUnit(
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900504 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900505 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800506 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900507 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
508 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900509 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900510 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900511 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900512}
513
514ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
Gloria Wanga2cd44c2010-11-19 15:19:36 -0800515 void* buffer, ssize_t numBytes, off64_t offset) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900516 ssize_t result = DECRYPT_FILE_ERROR;
517
Gloria Wang6b610a32011-03-04 14:45:03 -0800518 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900519 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
520 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
521 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
522 }
523 return result;
524}
525
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900526String8 DrmManager::getSupportedPlugInId(
527 int uniqueId, const String8& path, const String8& mimeType) {
528 String8 plugInId("");
529
530 if (EMPTY_STRING != mimeType) {
531 plugInId = getSupportedPlugInId(mimeType);
532 } else {
533 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
534 }
535 return plugInId;
536}
537
538String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
539 String8 plugInId("");
540
541 if (EMPTY_STRING != mimeType) {
542 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
543 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
544
545 if (drmSupportInfo.isSupportedMimeType(mimeType)) {
546 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
547 break;
548 }
549 }
550 }
551 return plugInId;
552}
553
554String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
555 String8 plugInId("");
556 const String8 fileSuffix = path.getPathExtension();
557
558 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
559 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
560
561 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
562 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
563 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
564
565 if (drmEngine.canHandle(uniqueId, path)) {
566 plugInId = key;
567 break;
568 }
569 }
570 }
571 return plugInId;
572}
573
574void DrmManager::onInfo(const DrmInfoEvent& event) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800575 Mutex::Autolock _l(mListenerLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900576 for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
577 int uniqueId = mServiceListeners.keyAt(index);
578
579 if (uniqueId == event.getUniqueId()) {
580 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
581 serviceListener->notify(event);
582 }
583 }
584}
585