blob: 44886f9a5cc9093884576a7620680f8e8b9d0755 [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
17#define LOG_NDEBUG 0
18#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>
26#include <drm/DrmInfoStatus.h>
27#include <drm/DrmInfoRequest.h>
28#include <drm/DrmSupportInfo.h>
29#include <drm/DrmConvertedStatus.h>
30#include <IDrmEngine.h>
31
32#include "DrmManager.h"
33#include "ReadWriteUtils.h"
34
35#define DECRYPT_FILE_ERROR -1
36
37using namespace android;
38
39const String8 DrmManager::EMPTY_STRING("");
40
41DrmManager::DrmManager() :
42 mDecryptSessionId(0),
43 mConvertId(0) {
44
45}
46
47DrmManager::~DrmManager() {
48
49}
50
51status_t DrmManager::loadPlugIns(int uniqueId) {
52 String8 pluginDirPath("/system/lib/drm/plugins/native");
53 return loadPlugIns(uniqueId, pluginDirPath);
54}
55
56status_t DrmManager::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
57 if (mSupportInfoToPlugInIdMap.isEmpty()) {
58 mPlugInManager.loadPlugIns(plugInDirPath);
59
60 initializePlugIns(uniqueId);
61
62 populate(uniqueId);
63 } else {
64 initializePlugIns(uniqueId);
65 }
66
67 return DRM_NO_ERROR;
68}
69
70status_t DrmManager::setDrmServiceListener(
71 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
72 Mutex::Autolock _l(mLock);
73 mServiceListeners.add(uniqueId, drmServiceListener);
74 return DRM_NO_ERROR;
75}
76
77status_t DrmManager::unloadPlugIns(int uniqueId) {
78 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
79
80 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
81 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
82 rDrmEngine.terminate(uniqueId);
83 }
84
85 mConvertSessionMap.clear();
86 mDecryptSessionMap.clear();
87 mSupportInfoToPlugInIdMap.clear();
88 mPlugInManager.unloadPlugIns();
89 return DRM_NO_ERROR;
90}
91
92DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
93 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
94 if (EMPTY_STRING != plugInId) {
95 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
96 return rDrmEngine.getConstraints(uniqueId, path, action);
97 }
98 return NULL;
99}
100
101status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
102 mPlugInManager.loadPlugIn(absolutePath);
103
104 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
105 rDrmEngine.initialize(uniqueId);
106 rDrmEngine.setOnInfoListener(uniqueId, this);
107
108 DrmSupportInfo* info = rDrmEngine.getSupportInfo(uniqueId);
109 mSupportInfoToPlugInIdMap.add(*info, absolutePath);
110
111 return DRM_NO_ERROR;
112}
113
114bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
115 const String8 plugInId = getSupportedPlugInId(mimeType);
116 bool result = (EMPTY_STRING != plugInId) ? true : false;
117
118 if (NULL != path) {
119 if (result) {
120 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
121 result = rDrmEngine.canHandle(uniqueId, path);
122 } else {
123 result = canHandle(uniqueId, path);
124 }
125 }
126 return result;
127}
128
129DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
130 const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
131 if (EMPTY_STRING != plugInId) {
132 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
133 return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
134 }
135 return NULL;
136}
137
138bool DrmManager::canHandle(int uniqueId, const String8& path) {
139 bool result = false;
140 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
141
142 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
143 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
144 result = rDrmEngine.canHandle(uniqueId, path);
145
146 if (result) {
147 break;
148 }
149 }
150 return result;
151}
152
153DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
154 const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
155 if (EMPTY_STRING != plugInId) {
156 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
157 return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
158 }
159 return NULL;
160}
161
162void DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
163 const String8& rightsPath, const String8& contentPath) {
164 const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
165 if (EMPTY_STRING != plugInId) {
166 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
167 rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
168 }
169}
170
171String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
172 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
173 if (EMPTY_STRING != plugInId) {
174 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
175 return rDrmEngine.getOriginalMimeType(uniqueId, path);
176 }
177 return EMPTY_STRING;
178}
179
180int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
181 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
182 if (EMPTY_STRING != plugInId) {
183 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
184 return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
185 }
186 return DrmObjectType::UNKNOWN;
187}
188
189int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
190 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
191 if (EMPTY_STRING != plugInId) {
192 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
193 return rDrmEngine.checkRightsStatus(uniqueId, path, action);
194 }
195 return RightsStatus::RIGHTS_INVALID;
196}
197
198void DrmManager::consumeRights(
199 int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
200 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
201 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
202 drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
203 }
204}
205
206void DrmManager::setPlaybackStatus(
207 int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
208
209 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
210 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
211 drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
212 }
213}
214
215bool DrmManager::validateAction(
216 int uniqueId, const String8& path, int action, const ActionDescription& description) {
217 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
218 if (EMPTY_STRING != plugInId) {
219 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
220 return rDrmEngine.validateAction(uniqueId, path, action, description);
221 }
222 return false;
223}
224
225void DrmManager::removeRights(int uniqueId, const String8& path) {
226 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
227 if (EMPTY_STRING != plugInId) {
228 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
229 rDrmEngine.removeRights(uniqueId, path);
230 }
231}
232
233void DrmManager::removeAllRights(int uniqueId) {
234 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
235
236 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
237 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
238 rDrmEngine.removeAllRights(uniqueId);
239 }
240}
241
242int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
243 int convertId = -1;
244
245 const String8 plugInId = getSupportedPlugInId(mimeType);
246 if (EMPTY_STRING != plugInId) {
247 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
248
249 Mutex::Autolock _l(mConvertLock);
250 ++mConvertId;
251 convertId = mConvertId;
252 mConvertSessionMap.add(mConvertId, &rDrmEngine);
253
254 rDrmEngine.openConvertSession(uniqueId, mConvertId);
255 }
256 return convertId;
257}
258
259DrmConvertedStatus* DrmManager::convertData(
260 int uniqueId, int convertId, const DrmBuffer* inputData) {
261 DrmConvertedStatus *drmConvertedStatus = NULL;
262
263 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
264 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
265 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
266 }
267 return drmConvertedStatus;
268}
269
270DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
271 DrmConvertedStatus *drmConvertedStatus = NULL;
272
273 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
274 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
275 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
276 mConvertSessionMap.removeItem(convertId);
277 }
278 return drmConvertedStatus;
279}
280
281status_t DrmManager::getAllSupportInfo(
282 int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
283 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
284 int size = plugInPathList.size();
285 int validPlugins = 0;
286
287 if (0 < size) {
288 Vector<DrmSupportInfo> drmSupportInfoList;
289
290 for (int i = 0; i < size; ++i) {
291 String8 plugInPath = plugInPathList[i];
292 DrmSupportInfo* drmSupportInfo
293 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(uniqueId);
294 if (NULL != drmSupportInfo) {
295 drmSupportInfoList.add(*drmSupportInfo);
296 delete drmSupportInfo; drmSupportInfo = NULL;
297 }
298 }
299
300 validPlugins = drmSupportInfoList.size();
301 if (0 < validPlugins) {
302 *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
303 for (int i = 0; i < validPlugins; ++i) {
304 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
305 }
306 }
307 }
308 *length = validPlugins;
309 return DRM_NO_ERROR;
310}
311
312DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, int offset, int length) {
313 LOGV("Entering DrmManager::openDecryptSession");
314 status_t result = DRM_ERROR_CANNOT_HANDLE;
315 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
316
317 DecryptHandle* handle = new DecryptHandle();
318 if (NULL != handle) {
319 Mutex::Autolock _l(mDecryptLock);
320 handle->decryptId = mDecryptSessionId + 1;
321
322 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
323 String8 plugInId = plugInIdList.itemAt(index);
324 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
325 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
326
327 LOGV("plug-in %s return value = %d", plugInId.string(), result);
328
329 if (DRM_NO_ERROR == result) {
330 ++mDecryptSessionId;
331 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
332 LOGV("plug-in %s is selected", plugInId.string());
333 break;
334 }
335 }
336 }
337
338 if (DRM_ERROR_CANNOT_HANDLE == result) {
339 delete handle; handle = NULL;
340 LOGE("DrmManager::openDecryptSession: no capable plug-in found");
341 }
342
343 return handle;
344}
345
346void DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
347 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
348 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
349 drmEngine->closeDecryptSession(uniqueId, decryptHandle);
350
351 mDecryptSessionMap.removeItem(decryptHandle->decryptId);
352 }
353}
354
355void DrmManager::initializeDecryptUnit(
356 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
357 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
358 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
359 drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
360 }
361}
362
363status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle,
364 int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
365 status_t status = DRM_ERROR_UNKNOWN;
366 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
367 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
368 status = drmEngine->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
369 }
370 return status;
371}
372
373void DrmManager::finalizeDecryptUnit(
374 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
375 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
376 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
377 drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
378 }
379}
380
381ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
382 void* buffer, ssize_t numBytes, off_t offset) {
383 ssize_t result = DECRYPT_FILE_ERROR;
384
385 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
386 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
387 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
388 }
389 return result;
390}
391
392void DrmManager::initializePlugIns(int uniqueId) {
393 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
394
395 for (unsigned int index = 0; index < plugInIdList.size(); index++) {
396 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
397 rDrmEngine.initialize(uniqueId);
398 rDrmEngine.setOnInfoListener(uniqueId, this);
399 }
400}
401
402void DrmManager::populate(int uniqueId) {
403 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
404
405 for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
406 String8 plugInPath = plugInPathList[i];
407 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(uniqueId);
408 if (NULL != info) {
409 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
410 }
411 }
412}
413
414String8 DrmManager::getSupportedPlugInId(
415 int uniqueId, const String8& path, const String8& mimeType) {
416 String8 plugInId("");
417
418 if (EMPTY_STRING != mimeType) {
419 plugInId = getSupportedPlugInId(mimeType);
420 } else {
421 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
422 }
423 return plugInId;
424}
425
426String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
427 String8 plugInId("");
428
429 if (EMPTY_STRING != mimeType) {
430 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
431 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
432
433 if (drmSupportInfo.isSupportedMimeType(mimeType)) {
434 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
435 break;
436 }
437 }
438 }
439 return plugInId;
440}
441
442String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
443 String8 plugInId("");
444 const String8 fileSuffix = path.getPathExtension();
445
446 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
447 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
448
449 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
450 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
451 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
452
453 if (drmEngine.canHandle(uniqueId, path)) {
454 plugInId = key;
455 break;
456 }
457 }
458 }
459 return plugInId;
460}
461
462void DrmManager::onInfo(const DrmInfoEvent& event) {
463 Mutex::Autolock _l(mLock);
464 for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
465 int uniqueId = mServiceListeners.keyAt(index);
466
467 if (uniqueId == event.getUniqueId()) {
468 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
469 serviceListener->notify(event);
470 }
471 }
472}
473