blob: 66610b34644aba776cc4fa376d9df4316ef47387 [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>
Robert Shihec056ae2019-08-17 01:54:04 -070022
23#include <binder/IPCThreadState.h>
aimitakeshi27ed8ad2010-07-29 10:12:27 +090024#include <drm/DrmInfo.h>
Robert Shihec056ae2019-08-17 01:54:04 -070025
aimitakeshi27ed8ad2010-07-29 10:12:27 +090026#include <drm/DrmInfoEvent.h>
27#include <drm/DrmRights.h>
28#include <drm/DrmConstraints.h>
Takeshi Aimi34738462010-11-16 13:56:11 +090029#include <drm/DrmMetadata.h>
aimitakeshi27ed8ad2010-07-29 10:12:27 +090030#include <drm/DrmInfoStatus.h>
31#include <drm/DrmInfoRequest.h>
32#include <drm/DrmSupportInfo.h>
33#include <drm/DrmConvertedStatus.h>
Robert Shihec056ae2019-08-17 01:54:04 -070034#include <media/MediaAnalyticsItem.h>
aimitakeshi27ed8ad2010-07-29 10:12:27 +090035#include <IDrmEngine.h>
36
37#include "DrmManager.h"
38#include "ReadWriteUtils.h"
39
Chih-Hung Hsieh92c6b822016-05-17 15:20:14 -070040#define DECRYPT_FILE_ERROR (-1)
aimitakeshi27ed8ad2010-07-29 10:12:27 +090041
42using namespace android;
43
44const String8 DrmManager::EMPTY_STRING("");
45
46DrmManager::DrmManager() :
47 mDecryptSessionId(0),
48 mConvertId(0) {
Henrik B Andersson13f7fe72012-10-26 15:15:15 +020049 srand(time(NULL));
50 memset(mUniqueIdArray, 0, sizeof(bool) * kMaxNumUniqueIds);
aimitakeshi27ed8ad2010-07-29 10:12:27 +090051}
52
53DrmManager::~DrmManager() {
54
55}
56
Robert Shihec056ae2019-08-17 01:54:04 -070057void DrmManager::reportEngineMetrics(
58 const char func[], const String8& plugInId, const String8& mimeType) {
59 IDrmEngine& engine = mPlugInManager.getPlugIn(plugInId);
60
61 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("drmmanager"));
62 item->generateSessionID();
63 item->setUid(IPCThreadState::self()->getCallingUid());
64 item->setCString("function_name", func);
65 item->setCString("plugin_id", plugInId.getPathLeaf().getBasePath().c_str());
66
67 std::unique_ptr<DrmSupportInfo> info(engine.getSupportInfo(0));
68 if (NULL != info) {
69 item->setCString("description", info->getDescription().c_str());
70 }
71
72 if (!mimeType.isEmpty()) {
73 item->setCString("mime_types", mimeType.c_str());
74 } else if (NULL != info) {
75 DrmSupportInfo::MimeTypeIterator mimeIter = info->getMimeTypeIterator();
76 String8 mimes;
77 while (mimeIter.hasNext()) {
78 mimes += mimeIter.next();
79 if (mimeIter.hasNext()) {
80 mimes += ",";
81 }
82 }
83 item->setCString("mime_types", mimes.c_str());
84 }
85
86 if (!item->selfrecord()) {
87 ALOGE("Failed to record metrics");
88 }
89}
90
Gloria Wang8f001512011-07-21 15:10:22 -070091int DrmManager::addUniqueId(bool isNative) {
Gloria Wang6b610a32011-03-04 14:45:03 -080092 Mutex::Autolock _l(mLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +090093
Henrik B Andersson13f7fe72012-10-26 15:15:15 +020094 int uniqueId = -1;
95 int random = rand();
Takeshi Aimi2272ee22010-09-20 23:40:41 +090096
Henrik B Andersson13f7fe72012-10-26 15:15:15 +020097 for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
98 int temp = (random + index) % kMaxNumUniqueIds;
99 if (!mUniqueIdArray[temp]) {
100 uniqueId = temp;
101 mUniqueIdArray[uniqueId] = true;
Gloria Wang8f001512011-07-21 15:10:22 -0700102
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200103 if (isNative) {
104 // set a flag to differentiate DrmManagerClient
105 // created from native side and java side
106 uniqueId |= 0x1000;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900107 }
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200108 break;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900109 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900110 }
Gloria Wang8f001512011-07-21 15:10:22 -0700111
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200112 // -1 indicates that no unique id can be allocated.
113 return uniqueId;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900114}
115
116void DrmManager::removeUniqueId(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800117 Mutex::Autolock _l(mLock);
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200118 if (uniqueId & 0x1000) {
119 // clear the flag for the native side.
120 uniqueId &= ~(0x1000);
121 }
122
123 if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
124 mUniqueIdArray[uniqueId] = false;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900125 }
126}
127
Takeshi Aimie943f842010-10-08 23:05:49 +0900128status_t DrmManager::loadPlugIns() {
James Dong785ee062011-12-14 10:57:05 -0800129 String8 pluginDirPath("/system/lib/drm");
130 loadPlugIns(pluginDirPath);
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700131 return DRM_NO_ERROR;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900132}
133
Takeshi Aimie943f842010-10-08 23:05:49 +0900134status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700135 mPlugInManager.loadPlugIns(plugInDirPath);
136 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700137 for (size_t i = 0; i < plugInPathList.size(); ++i) {
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700138 String8 plugInPath = plugInPathList[i];
139 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
140 if (NULL != info) {
141 if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900142 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
143 }
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700144 delete info;
Takeshi Aimie943f842010-10-08 23:05:49 +0900145 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900146 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900147 return DRM_NO_ERROR;
148}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900149
Takeshi Aimie943f842010-10-08 23:05:49 +0900150status_t DrmManager::unloadPlugIns() {
Gloria Wang6b610a32011-03-04 14:45:03 -0800151 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900152 mConvertSessionMap.clear();
153 mDecryptSessionMap.clear();
154 mPlugInManager.unloadPlugIns();
155 mSupportInfoToPlugInIdMap.clear();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900156 return DRM_NO_ERROR;
157}
158
159status_t DrmManager::setDrmServiceListener(
160 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800161 Mutex::Autolock _l(mListenerLock);
Takeshi Aimic618b5a2010-11-30 16:27:42 +0900162 if (NULL != drmServiceListener.get()) {
163 mServiceListeners.add(uniqueId, drmServiceListener);
164 } else {
165 mServiceListeners.removeItem(uniqueId);
166 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900167 return DRM_NO_ERROR;
168}
169
Takeshi Aimie943f842010-10-08 23:05:49 +0900170void DrmManager::addClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800171 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900172 if (!mSupportInfoToPlugInIdMap.isEmpty()) {
173 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700174 for (size_t index = 0; index < plugInIdList.size(); index++) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900175 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
176 rDrmEngine.initialize(uniqueId);
177 rDrmEngine.setOnInfoListener(uniqueId, this);
178 }
179 }
180}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900181
Takeshi Aimie943f842010-10-08 23:05:49 +0900182void DrmManager::removeClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800183 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900184 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700185 for (size_t index = 0; index < plugInIdList.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900186 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
187 rDrmEngine.terminate(uniqueId);
Robert Shihec056ae2019-08-17 01:54:04 -0700188 reportEngineMetrics(__func__, plugInIdList[index]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900189 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900190}
191
192DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800193 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700194 DrmConstraints *constraints = NULL;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900195 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
196 if (EMPTY_STRING != plugInId) {
197 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700198 constraints = rDrmEngine.getConstraints(uniqueId, path, action);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900199 }
Robert Shihec056ae2019-08-17 01:54:04 -0700200 if (NULL != constraints) {
201 reportEngineMetrics(__func__, plugInId);
202 }
203 return constraints;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900204}
205
Takeshi Aimi34738462010-11-16 13:56:11 +0900206DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800207 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700208 DrmMetadata *meta = NULL;
Takeshi Aimi34738462010-11-16 13:56:11 +0900209 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
210 if (EMPTY_STRING != plugInId) {
211 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700212 meta = rDrmEngine.getMetadata(uniqueId, path);
Takeshi Aimi34738462010-11-16 13:56:11 +0900213 }
Robert Shihec056ae2019-08-17 01:54:04 -0700214 if (NULL != meta) {
215 reportEngineMetrics(__func__, plugInId);
216 }
217 return meta;
Takeshi Aimi34738462010-11-16 13:56:11 +0900218}
219
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900220bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800221 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900222 const String8 plugInId = getSupportedPlugInId(mimeType);
223 bool result = (EMPTY_STRING != plugInId) ? true : false;
224
Robert Shihec056ae2019-08-17 01:54:04 -0700225 if (result) {
226 reportEngineMetrics(__func__, plugInId, mimeType);
227 }
228
Takeshi Aimie943f842010-10-08 23:05:49 +0900229 if (0 < path.length()) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900230 if (result) {
231 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
232 result = rDrmEngine.canHandle(uniqueId, path);
233 } else {
Gloria Wang7f89d092011-03-02 12:33:00 -0800234 String8 extension = path.getPathExtension();
235 if (String8("") != extension) {
236 result = canHandle(uniqueId, path);
237 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900238 }
239 }
240 return result;
241}
242
243DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800244 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700245 DrmInfoStatus *infoStatus = NULL;
246 const String8 mimeType = drmInfo->getMimeType();
247 const String8 plugInId = getSupportedPlugInId(mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900248 if (EMPTY_STRING != plugInId) {
249 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700250 infoStatus = rDrmEngine.processDrmInfo(uniqueId, drmInfo);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900251 }
Robert Shihec056ae2019-08-17 01:54:04 -0700252 if (NULL != infoStatus) {
253 reportEngineMetrics(__func__, plugInId, mimeType);
254 }
255 return infoStatus;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900256}
257
258bool DrmManager::canHandle(int uniqueId, const String8& path) {
259 bool result = false;
260 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
261
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700262 for (size_t i = 0; i < plugInPathList.size(); ++i) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900263 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
264 result = rDrmEngine.canHandle(uniqueId, path);
265
266 if (result) {
Robert Shihec056ae2019-08-17 01:54:04 -0700267 reportEngineMetrics(__func__, plugInPathList[i]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900268 break;
269 }
270 }
271 return result;
272}
273
274DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800275 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700276 DrmInfo *info = NULL;
277 const String8 mimeType = drmInfoRequest->getMimeType();
278 const String8 plugInId = getSupportedPlugInId(mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900279 if (EMPTY_STRING != plugInId) {
280 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700281 info = rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900282 }
Robert Shihec056ae2019-08-17 01:54:04 -0700283 if (NULL != info) {
284 reportEngineMetrics(__func__, plugInId, mimeType);
285 }
286 return info;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900287}
288
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900289status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900290 const String8& rightsPath, const String8& contentPath) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800291 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700292 const String8 mimeType = drmRights.getMimeType();
293 const String8 plugInId = getSupportedPlugInId(mimeType);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900294 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900295 if (EMPTY_STRING != plugInId) {
296 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900297 result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900298 }
Robert Shihec056ae2019-08-17 01:54:04 -0700299 if (DRM_NO_ERROR == result) {
300 reportEngineMetrics(__func__, plugInId, mimeType);
301 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900302 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900303}
304
James Dongbf5b3b22012-07-30 17:57:39 -0700305String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800306 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700307 String8 mimeType(EMPTY_STRING);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900308 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
309 if (EMPTY_STRING != plugInId) {
310 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700311 mimeType = rDrmEngine.getOriginalMimeType(uniqueId, path, fd);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900312 }
Robert Shihec056ae2019-08-17 01:54:04 -0700313 if (!mimeType.isEmpty()) {
314 reportEngineMetrics(__func__, plugInId, mimeType);
315 }
316 return mimeType;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900317}
318
319int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800320 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700321 int type = DrmObjectType::UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900322 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
323 if (EMPTY_STRING != plugInId) {
324 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700325 type = rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900326 }
Robert Shihec056ae2019-08-17 01:54:04 -0700327 if (DrmObjectType::UNKNOWN != type) {
328 reportEngineMetrics(__func__, plugInId, mimeType);
329 }
330 return type;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900331}
332
333int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800334 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700335 int rightsStatus = RightsStatus::RIGHTS_INVALID;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900336 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
337 if (EMPTY_STRING != plugInId) {
338 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700339 rightsStatus = rDrmEngine.checkRightsStatus(uniqueId, path, action);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900340 }
Robert Shihec056ae2019-08-17 01:54:04 -0700341 if (RightsStatus::RIGHTS_INVALID != rightsStatus) {
342 reportEngineMetrics(__func__, plugInId);
343 }
344 return rightsStatus;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900345}
346
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900347status_t DrmManager::consumeRights(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700348 int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900349 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800350 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900351 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
352 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900353 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900354 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900355 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900356}
357
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900358status_t DrmManager::setPlaybackStatus(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700359 int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900360 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800361 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900362 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
363 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900364 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900365 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900366 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900367}
368
369bool DrmManager::validateAction(
370 int uniqueId, const String8& path, int action, const ActionDescription& description) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800371 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900372 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
373 if (EMPTY_STRING != plugInId) {
374 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
375 return rDrmEngine.validateAction(uniqueId, path, action, description);
376 }
377 return false;
378}
379
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900380status_t DrmManager::removeRights(int uniqueId, const String8& path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800381 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900382 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900383 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900384 if (EMPTY_STRING != plugInId) {
385 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900386 result = rDrmEngine.removeRights(uniqueId, path);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900387 }
Robert Shihec056ae2019-08-17 01:54:04 -0700388 if (DRM_NO_ERROR == result) {
389 reportEngineMetrics(__func__, plugInId);
390 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900391 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900392}
393
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900394status_t DrmManager::removeAllRights(int uniqueId) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900395 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900396 status_t result = DRM_ERROR_UNKNOWN;
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700397 for (size_t index = 0; index < plugInIdList.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900398 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900399 result = rDrmEngine.removeAllRights(uniqueId);
400 if (DRM_NO_ERROR != result) {
401 break;
402 }
Robert Shihec056ae2019-08-17 01:54:04 -0700403 reportEngineMetrics(__func__, plugInIdList[index]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900404 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900405 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900406}
407
408int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800409 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900410 int convertId = -1;
411
412 const String8 plugInId = getSupportedPlugInId(mimeType);
413 if (EMPTY_STRING != plugInId) {
414 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
415
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900416 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900417 ++mConvertId;
418 convertId = mConvertId;
419 mConvertSessionMap.add(convertId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700420 reportEngineMetrics(__func__, plugInId, mimeType);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900421 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900422 }
423 return convertId;
424}
425
426DrmConvertedStatus* DrmManager::convertData(
427 int uniqueId, int convertId, const DrmBuffer* inputData) {
428 DrmConvertedStatus *drmConvertedStatus = NULL;
429
Gloria Wang6b610a32011-03-04 14:45:03 -0800430 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900431 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
432 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
433 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
434 }
435 return drmConvertedStatus;
436}
437
438DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800439 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900440 DrmConvertedStatus *drmConvertedStatus = NULL;
441
442 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
443 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
444 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
445 mConvertSessionMap.removeItem(convertId);
446 }
447 return drmConvertedStatus;
448}
449
450status_t DrmManager::getAllSupportInfo(
Aurimas Liutikasb2231172016-02-12 16:57:08 -0800451 int /* uniqueId */, int* length, DrmSupportInfo** drmSupportInfoArray) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800452 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900453 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
454 int size = plugInPathList.size();
455 int validPlugins = 0;
456
457 if (0 < size) {
458 Vector<DrmSupportInfo> drmSupportInfoList;
459
460 for (int i = 0; i < size; ++i) {
461 String8 plugInPath = plugInPathList[i];
462 DrmSupportInfo* drmSupportInfo
Takeshi Aimie943f842010-10-08 23:05:49 +0900463 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900464 if (NULL != drmSupportInfo) {
465 drmSupportInfoList.add(*drmSupportInfo);
466 delete drmSupportInfo; drmSupportInfo = NULL;
467 }
468 }
469
470 validPlugins = drmSupportInfoList.size();
471 if (0 < validPlugins) {
472 *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
473 for (int i = 0; i < validPlugins; ++i) {
474 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
475 }
476 }
477 }
478 *length = validPlugins;
479 return DRM_NO_ERROR;
480}
481
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700482sp<DecryptHandle> DrmManager::openDecryptSession(
James Dong9d2f3862012-01-10 08:24:37 -0800483 int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
484
Takeshi Aimie943f842010-10-08 23:05:49 +0900485 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900486 status_t result = DRM_ERROR_CANNOT_HANDLE;
487 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
488
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700489 sp<DecryptHandle> handle = new DecryptHandle();
490 if (NULL != handle.get()) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900491 handle->decryptId = mDecryptSessionId + 1;
492
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700493 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700494 const String8& plugInId = plugInIdList.itemAt(index);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900495 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
James Dong9d2f3862012-01-10 08:24:37 -0800496 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900497
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900498 if (DRM_NO_ERROR == result) {
499 ++mDecryptSessionId;
500 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700501 reportEngineMetrics(__func__, plugInId, String8(mime));
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900502 break;
503 }
504 }
505 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900506 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700507 handle.clear();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900508 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900509 return handle;
510}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900511
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700512sp<DecryptHandle> DrmManager::openDecryptSession(
James Dong9d2f3862012-01-10 08:24:37 -0800513 int uniqueId, const char* uri, const char* mime) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900514 Mutex::Autolock _l(mDecryptLock);
515 status_t result = DRM_ERROR_CANNOT_HANDLE;
516 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
517
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700518 sp<DecryptHandle> handle = new DecryptHandle();
519 if (NULL != handle.get()) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900520 handle->decryptId = mDecryptSessionId + 1;
521
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700522 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700523 const String8& plugInId = plugInIdList.itemAt(index);
Takeshi Aimie943f842010-10-08 23:05:49 +0900524 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
James Dong9d2f3862012-01-10 08:24:37 -0800525 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
Takeshi Aimie943f842010-10-08 23:05:49 +0900526
527 if (DRM_NO_ERROR == result) {
528 ++mDecryptSessionId;
529 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700530 reportEngineMetrics(__func__, plugInId, String8(mime));
Takeshi Aimie943f842010-10-08 23:05:49 +0900531 break;
532 }
533 }
534 }
535 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700536 handle.clear();
Steve Block3856b092011-10-20 11:56:00 +0100537 ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
Takeshi Aimie943f842010-10-08 23:05:49 +0900538 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900539 return handle;
540}
541
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700542sp<DecryptHandle> DrmManager::openDecryptSession(
Kei Takahashicba7b322012-01-18 17:10:19 +0900543 int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
544 Mutex::Autolock _l(mDecryptLock);
545 status_t result = DRM_ERROR_CANNOT_HANDLE;
546 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
547
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700548 sp<DecryptHandle> handle = new DecryptHandle();
549 if (NULL != handle.get()) {
Kei Takahashicba7b322012-01-18 17:10:19 +0900550 handle->decryptId = mDecryptSessionId + 1;
551
552 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700553 const String8& plugInId = plugInIdList.itemAt(index);
Kei Takahashicba7b322012-01-18 17:10:19 +0900554 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
555 result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
556
557 if (DRM_NO_ERROR == result) {
558 ++mDecryptSessionId;
559 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700560 reportEngineMetrics(__func__, plugInId, mimeType);
Kei Takahashicba7b322012-01-18 17:10:19 +0900561 break;
562 }
563 }
564 }
565 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700566 handle.clear();
Kei Takahashicba7b322012-01-18 17:10:19 +0900567 ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
568 }
569 return handle;
570}
571
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700572status_t DrmManager::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900573 Mutex::Autolock _l(mDecryptLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900574 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900575 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
576 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900577 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700578 if (DRM_NO_ERROR == result && NULL != decryptHandle.get()) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900579 mDecryptSessionMap.removeItem(decryptHandle->decryptId);
580 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900581 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900582 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900583}
584
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900585status_t DrmManager::initializeDecryptUnit(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700586 int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
587 const DrmBuffer* headerInfo) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900588 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800589 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900590 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
591 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900592 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900593 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900594 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900595}
596
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700597status_t DrmManager::decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900598 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
599 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800600
601 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900602 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
603 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900604 result = drmEngine->decrypt(
605 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900606 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900607 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900608}
609
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900610status_t DrmManager::finalizeDecryptUnit(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700611 int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900612 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800613 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900614 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
615 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900616 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900617 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900618 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900619}
620
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700621ssize_t DrmManager::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
Gloria Wanga2cd44c2010-11-19 15:19:36 -0800622 void* buffer, ssize_t numBytes, off64_t offset) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900623 ssize_t result = DECRYPT_FILE_ERROR;
624
Gloria Wang6b610a32011-03-04 14:45:03 -0800625 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900626 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
627 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
628 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
629 }
630 return result;
631}
632
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900633String8 DrmManager::getSupportedPlugInId(
634 int uniqueId, const String8& path, const String8& mimeType) {
635 String8 plugInId("");
636
637 if (EMPTY_STRING != mimeType) {
638 plugInId = getSupportedPlugInId(mimeType);
639 } else {
640 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
641 }
642 return plugInId;
643}
644
645String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
646 String8 plugInId("");
647
648 if (EMPTY_STRING != mimeType) {
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700649 for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900650 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
651
652 if (drmSupportInfo.isSupportedMimeType(mimeType)) {
653 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
654 break;
655 }
656 }
657 }
658 return plugInId;
659}
660
661String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
662 String8 plugInId("");
663 const String8 fileSuffix = path.getPathExtension();
664
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700665 for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900666 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
667
668 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
669 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
670 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
671
672 if (drmEngine.canHandle(uniqueId, path)) {
673 plugInId = key;
674 break;
675 }
676 }
677 }
678 return plugInId;
679}
680
681void DrmManager::onInfo(const DrmInfoEvent& event) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800682 Mutex::Autolock _l(mListenerLock);
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700683 for (size_t index = 0; index < mServiceListeners.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900684 int uniqueId = mServiceListeners.keyAt(index);
685
686 if (uniqueId == event.getUniqueId()) {
687 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
688 serviceListener->notify(event);
689 }
690 }
691}
692