blob: e2ea83af6f30953966b8332133c7ba373e569c52 [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"));
Robert Shihec056ae2019-08-17 01:54:04 -070062 item->setUid(IPCThreadState::self()->getCallingUid());
63 item->setCString("function_name", func);
64 item->setCString("plugin_id", plugInId.getPathLeaf().getBasePath().c_str());
65
66 std::unique_ptr<DrmSupportInfo> info(engine.getSupportInfo(0));
67 if (NULL != info) {
68 item->setCString("description", info->getDescription().c_str());
69 }
70
71 if (!mimeType.isEmpty()) {
72 item->setCString("mime_types", mimeType.c_str());
73 } else if (NULL != info) {
74 DrmSupportInfo::MimeTypeIterator mimeIter = info->getMimeTypeIterator();
75 String8 mimes;
76 while (mimeIter.hasNext()) {
77 mimes += mimeIter.next();
78 if (mimeIter.hasNext()) {
79 mimes += ",";
80 }
81 }
82 item->setCString("mime_types", mimes.c_str());
83 }
84
85 if (!item->selfrecord()) {
86 ALOGE("Failed to record metrics");
87 }
88}
89
Gloria Wang8f001512011-07-21 15:10:22 -070090int DrmManager::addUniqueId(bool isNative) {
Gloria Wang6b610a32011-03-04 14:45:03 -080091 Mutex::Autolock _l(mLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +090092
Henrik B Andersson13f7fe72012-10-26 15:15:15 +020093 int uniqueId = -1;
94 int random = rand();
Takeshi Aimi2272ee22010-09-20 23:40:41 +090095
Henrik B Andersson13f7fe72012-10-26 15:15:15 +020096 for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
97 int temp = (random + index) % kMaxNumUniqueIds;
98 if (!mUniqueIdArray[temp]) {
99 uniqueId = temp;
100 mUniqueIdArray[uniqueId] = true;
Gloria Wang8f001512011-07-21 15:10:22 -0700101
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200102 if (isNative) {
103 // set a flag to differentiate DrmManagerClient
104 // created from native side and java side
105 uniqueId |= 0x1000;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900106 }
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200107 break;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900108 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900109 }
Gloria Wang8f001512011-07-21 15:10:22 -0700110
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200111 // -1 indicates that no unique id can be allocated.
112 return uniqueId;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900113}
114
115void DrmManager::removeUniqueId(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800116 Mutex::Autolock _l(mLock);
Henrik B Andersson13f7fe72012-10-26 15:15:15 +0200117 if (uniqueId & 0x1000) {
118 // clear the flag for the native side.
119 uniqueId &= ~(0x1000);
120 }
121
122 if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
123 mUniqueIdArray[uniqueId] = false;
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900124 }
125}
126
Takeshi Aimie943f842010-10-08 23:05:49 +0900127status_t DrmManager::loadPlugIns() {
James Dong785ee062011-12-14 10:57:05 -0800128 String8 pluginDirPath("/system/lib/drm");
129 loadPlugIns(pluginDirPath);
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700130 return DRM_NO_ERROR;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900131}
132
Takeshi Aimie943f842010-10-08 23:05:49 +0900133status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700134 mPlugInManager.loadPlugIns(plugInDirPath);
135 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700136 for (size_t i = 0; i < plugInPathList.size(); ++i) {
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700137 String8 plugInPath = plugInPathList[i];
138 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
139 if (NULL != info) {
140 if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900141 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
142 }
Edwin Wong5f6f4e42011-09-21 19:18:30 -0700143 delete info;
Takeshi Aimie943f842010-10-08 23:05:49 +0900144 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900145 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900146 return DRM_NO_ERROR;
147}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900148
Takeshi Aimie943f842010-10-08 23:05:49 +0900149status_t DrmManager::unloadPlugIns() {
Gloria Wang6b610a32011-03-04 14:45:03 -0800150 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900151 mConvertSessionMap.clear();
152 mDecryptSessionMap.clear();
153 mPlugInManager.unloadPlugIns();
154 mSupportInfoToPlugInIdMap.clear();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900155 return DRM_NO_ERROR;
156}
157
158status_t DrmManager::setDrmServiceListener(
159 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800160 Mutex::Autolock _l(mListenerLock);
Takeshi Aimic618b5a2010-11-30 16:27:42 +0900161 if (NULL != drmServiceListener.get()) {
162 mServiceListeners.add(uniqueId, drmServiceListener);
163 } else {
164 mServiceListeners.removeItem(uniqueId);
165 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900166 return DRM_NO_ERROR;
167}
168
Takeshi Aimie943f842010-10-08 23:05:49 +0900169void DrmManager::addClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800170 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900171 if (!mSupportInfoToPlugInIdMap.isEmpty()) {
172 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700173 for (size_t index = 0; index < plugInIdList.size(); index++) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900174 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
175 rDrmEngine.initialize(uniqueId);
176 rDrmEngine.setOnInfoListener(uniqueId, this);
177 }
178 }
179}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900180
Takeshi Aimie943f842010-10-08 23:05:49 +0900181void DrmManager::removeClient(int uniqueId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800182 Mutex::Autolock _l(mLock);
Takeshi Aimie943f842010-10-08 23:05:49 +0900183 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700184 for (size_t index = 0; index < plugInIdList.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900185 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
186 rDrmEngine.terminate(uniqueId);
Robert Shihec056ae2019-08-17 01:54:04 -0700187 reportEngineMetrics(__func__, plugInIdList[index]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900188 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900189}
190
191DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800192 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700193 DrmConstraints *constraints = NULL;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900194 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
195 if (EMPTY_STRING != plugInId) {
196 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700197 constraints = rDrmEngine.getConstraints(uniqueId, path, action);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900198 }
Robert Shihec056ae2019-08-17 01:54:04 -0700199 if (NULL != constraints) {
200 reportEngineMetrics(__func__, plugInId);
201 }
202 return constraints;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900203}
204
Takeshi Aimi34738462010-11-16 13:56:11 +0900205DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800206 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700207 DrmMetadata *meta = NULL;
Takeshi Aimi34738462010-11-16 13:56:11 +0900208 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
209 if (EMPTY_STRING != plugInId) {
210 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700211 meta = rDrmEngine.getMetadata(uniqueId, path);
Takeshi Aimi34738462010-11-16 13:56:11 +0900212 }
Robert Shihec056ae2019-08-17 01:54:04 -0700213 if (NULL != meta) {
214 reportEngineMetrics(__func__, plugInId);
215 }
216 return meta;
Takeshi Aimi34738462010-11-16 13:56:11 +0900217}
218
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900219bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800220 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900221 const String8 plugInId = getSupportedPlugInId(mimeType);
222 bool result = (EMPTY_STRING != plugInId) ? true : false;
223
Robert Shihec056ae2019-08-17 01:54:04 -0700224 if (result) {
225 reportEngineMetrics(__func__, plugInId, mimeType);
226 }
227
Takeshi Aimie943f842010-10-08 23:05:49 +0900228 if (0 < path.length()) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900229 if (result) {
230 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
231 result = rDrmEngine.canHandle(uniqueId, path);
232 } else {
Gloria Wang7f89d092011-03-02 12:33:00 -0800233 String8 extension = path.getPathExtension();
234 if (String8("") != extension) {
235 result = canHandle(uniqueId, path);
236 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900237 }
238 }
239 return result;
240}
241
242DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800243 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700244 DrmInfoStatus *infoStatus = NULL;
245 const String8 mimeType = drmInfo->getMimeType();
246 const String8 plugInId = getSupportedPlugInId(mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900247 if (EMPTY_STRING != plugInId) {
248 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700249 infoStatus = rDrmEngine.processDrmInfo(uniqueId, drmInfo);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900250 }
Robert Shihec056ae2019-08-17 01:54:04 -0700251 if (NULL != infoStatus) {
252 reportEngineMetrics(__func__, plugInId, mimeType);
253 }
254 return infoStatus;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900255}
256
257bool DrmManager::canHandle(int uniqueId, const String8& path) {
258 bool result = false;
259 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
260
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700261 for (size_t i = 0; i < plugInPathList.size(); ++i) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900262 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
263 result = rDrmEngine.canHandle(uniqueId, path);
264
265 if (result) {
Robert Shihec056ae2019-08-17 01:54:04 -0700266 reportEngineMetrics(__func__, plugInPathList[i]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900267 break;
268 }
269 }
270 return result;
271}
272
273DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800274 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700275 DrmInfo *info = NULL;
276 const String8 mimeType = drmInfoRequest->getMimeType();
277 const String8 plugInId = getSupportedPlugInId(mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900278 if (EMPTY_STRING != plugInId) {
279 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700280 info = rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900281 }
Robert Shihec056ae2019-08-17 01:54:04 -0700282 if (NULL != info) {
283 reportEngineMetrics(__func__, plugInId, mimeType);
284 }
285 return info;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900286}
287
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900288status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900289 const String8& rightsPath, const String8& contentPath) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800290 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700291 const String8 mimeType = drmRights.getMimeType();
292 const String8 plugInId = getSupportedPlugInId(mimeType);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900293 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900294 if (EMPTY_STRING != plugInId) {
295 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900296 result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900297 }
Robert Shihec056ae2019-08-17 01:54:04 -0700298 if (DRM_NO_ERROR == result) {
299 reportEngineMetrics(__func__, plugInId, mimeType);
300 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900301 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900302}
303
James Dongbf5b3b22012-07-30 17:57:39 -0700304String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800305 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700306 String8 mimeType(EMPTY_STRING);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900307 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
308 if (EMPTY_STRING != plugInId) {
309 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700310 mimeType = rDrmEngine.getOriginalMimeType(uniqueId, path, fd);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900311 }
Robert Shihec056ae2019-08-17 01:54:04 -0700312 if (!mimeType.isEmpty()) {
313 reportEngineMetrics(__func__, plugInId, mimeType);
314 }
315 return mimeType;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900316}
317
318int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800319 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700320 int type = DrmObjectType::UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900321 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
322 if (EMPTY_STRING != plugInId) {
323 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700324 type = rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900325 }
Robert Shihec056ae2019-08-17 01:54:04 -0700326 if (DrmObjectType::UNKNOWN != type) {
327 reportEngineMetrics(__func__, plugInId, mimeType);
328 }
329 return type;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900330}
331
332int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800333 Mutex::Autolock _l(mLock);
Robert Shihec056ae2019-08-17 01:54:04 -0700334 int rightsStatus = RightsStatus::RIGHTS_INVALID;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900335 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
336 if (EMPTY_STRING != plugInId) {
337 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Robert Shihec056ae2019-08-17 01:54:04 -0700338 rightsStatus = rDrmEngine.checkRightsStatus(uniqueId, path, action);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900339 }
Robert Shihec056ae2019-08-17 01:54:04 -0700340 if (RightsStatus::RIGHTS_INVALID != rightsStatus) {
341 reportEngineMetrics(__func__, plugInId);
342 }
343 return rightsStatus;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900344}
345
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900346status_t DrmManager::consumeRights(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700347 int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900348 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800349 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900350 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
351 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900352 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900353 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900354 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900355}
356
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900357status_t DrmManager::setPlaybackStatus(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700358 int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900359 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800360 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900361 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
362 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900363 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900364 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900365 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900366}
367
368bool DrmManager::validateAction(
369 int uniqueId, const String8& path, int action, const ActionDescription& description) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800370 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900371 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
372 if (EMPTY_STRING != plugInId) {
373 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
374 return rDrmEngine.validateAction(uniqueId, path, action, description);
375 }
376 return false;
377}
378
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900379status_t DrmManager::removeRights(int uniqueId, const String8& path) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800380 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900381 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900382 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900383 if (EMPTY_STRING != plugInId) {
384 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900385 result = rDrmEngine.removeRights(uniqueId, path);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900386 }
Robert Shihec056ae2019-08-17 01:54:04 -0700387 if (DRM_NO_ERROR == result) {
388 reportEngineMetrics(__func__, plugInId);
389 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900390 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900391}
392
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900393status_t DrmManager::removeAllRights(int uniqueId) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900394 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900395 status_t result = DRM_ERROR_UNKNOWN;
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700396 for (size_t index = 0; index < plugInIdList.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900397 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900398 result = rDrmEngine.removeAllRights(uniqueId);
399 if (DRM_NO_ERROR != result) {
400 break;
401 }
Robert Shihec056ae2019-08-17 01:54:04 -0700402 reportEngineMetrics(__func__, plugInIdList[index]);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900403 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900404 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900405}
406
407int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800408 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900409 int convertId = -1;
410
411 const String8 plugInId = getSupportedPlugInId(mimeType);
412 if (EMPTY_STRING != plugInId) {
413 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
414
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900415 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900416 ++mConvertId;
417 convertId = mConvertId;
418 mConvertSessionMap.add(convertId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700419 reportEngineMetrics(__func__, plugInId, mimeType);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900420 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900421 }
422 return convertId;
423}
424
425DrmConvertedStatus* DrmManager::convertData(
426 int uniqueId, int convertId, const DrmBuffer* inputData) {
427 DrmConvertedStatus *drmConvertedStatus = NULL;
428
Gloria Wang6b610a32011-03-04 14:45:03 -0800429 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900430 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
431 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
432 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
433 }
434 return drmConvertedStatus;
435}
436
437DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800438 Mutex::Autolock _l(mConvertLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900439 DrmConvertedStatus *drmConvertedStatus = NULL;
440
441 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
442 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
443 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
444 mConvertSessionMap.removeItem(convertId);
445 }
446 return drmConvertedStatus;
447}
448
449status_t DrmManager::getAllSupportInfo(
Aurimas Liutikasb2231172016-02-12 16:57:08 -0800450 int /* uniqueId */, int* length, DrmSupportInfo** drmSupportInfoArray) {
Gloria Wang6b610a32011-03-04 14:45:03 -0800451 Mutex::Autolock _l(mLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900452 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
453 int size = plugInPathList.size();
454 int validPlugins = 0;
455
456 if (0 < size) {
457 Vector<DrmSupportInfo> drmSupportInfoList;
458
459 for (int i = 0; i < size; ++i) {
460 String8 plugInPath = plugInPathList[i];
461 DrmSupportInfo* drmSupportInfo
Takeshi Aimie943f842010-10-08 23:05:49 +0900462 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900463 if (NULL != drmSupportInfo) {
464 drmSupportInfoList.add(*drmSupportInfo);
465 delete drmSupportInfo; drmSupportInfo = NULL;
466 }
467 }
468
469 validPlugins = drmSupportInfoList.size();
470 if (0 < validPlugins) {
471 *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
472 for (int i = 0; i < validPlugins; ++i) {
473 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
474 }
475 }
476 }
477 *length = validPlugins;
478 return DRM_NO_ERROR;
479}
480
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700481sp<DecryptHandle> DrmManager::openDecryptSession(
James Dong9d2f3862012-01-10 08:24:37 -0800482 int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
483
Takeshi Aimie943f842010-10-08 23:05:49 +0900484 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900485 status_t result = DRM_ERROR_CANNOT_HANDLE;
486 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
487
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700488 sp<DecryptHandle> handle = new DecryptHandle();
489 if (NULL != handle.get()) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900490 handle->decryptId = mDecryptSessionId + 1;
491
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700492 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700493 const String8& plugInId = plugInIdList.itemAt(index);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900494 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
James Dong9d2f3862012-01-10 08:24:37 -0800495 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900496
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900497 if (DRM_NO_ERROR == result) {
498 ++mDecryptSessionId;
499 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700500 reportEngineMetrics(__func__, plugInId, String8(mime));
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900501 break;
502 }
503 }
504 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900505 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700506 handle.clear();
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900507 }
Takeshi Aimie943f842010-10-08 23:05:49 +0900508 return handle;
509}
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900510
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700511sp<DecryptHandle> DrmManager::openDecryptSession(
James Dong9d2f3862012-01-10 08:24:37 -0800512 int uniqueId, const char* uri, const char* mime) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900513 Mutex::Autolock _l(mDecryptLock);
514 status_t result = DRM_ERROR_CANNOT_HANDLE;
515 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
516
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700517 sp<DecryptHandle> handle = new DecryptHandle();
518 if (NULL != handle.get()) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900519 handle->decryptId = mDecryptSessionId + 1;
520
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700521 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700522 const String8& plugInId = plugInIdList.itemAt(index);
Takeshi Aimie943f842010-10-08 23:05:49 +0900523 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
James Dong9d2f3862012-01-10 08:24:37 -0800524 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
Takeshi Aimie943f842010-10-08 23:05:49 +0900525
526 if (DRM_NO_ERROR == result) {
527 ++mDecryptSessionId;
528 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700529 reportEngineMetrics(__func__, plugInId, String8(mime));
Takeshi Aimie943f842010-10-08 23:05:49 +0900530 break;
531 }
532 }
533 }
534 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700535 handle.clear();
Steve Block3856b092011-10-20 11:56:00 +0100536 ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
Takeshi Aimie943f842010-10-08 23:05:49 +0900537 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900538 return handle;
539}
540
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700541sp<DecryptHandle> DrmManager::openDecryptSession(
Kei Takahashicba7b322012-01-18 17:10:19 +0900542 int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
543 Mutex::Autolock _l(mDecryptLock);
544 status_t result = DRM_ERROR_CANNOT_HANDLE;
545 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
546
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700547 sp<DecryptHandle> handle = new DecryptHandle();
548 if (NULL != handle.get()) {
Kei Takahashicba7b322012-01-18 17:10:19 +0900549 handle->decryptId = mDecryptSessionId + 1;
550
551 for (size_t index = 0; index < plugInIdList.size(); index++) {
Chih-Hung Hsieh8c0164c2016-08-09 14:20:59 -0700552 const String8& plugInId = plugInIdList.itemAt(index);
Kei Takahashicba7b322012-01-18 17:10:19 +0900553 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
554 result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
555
556 if (DRM_NO_ERROR == result) {
557 ++mDecryptSessionId;
558 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
Robert Shihec056ae2019-08-17 01:54:04 -0700559 reportEngineMetrics(__func__, plugInId, mimeType);
Kei Takahashicba7b322012-01-18 17:10:19 +0900560 break;
561 }
562 }
563 }
564 if (DRM_NO_ERROR != result) {
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700565 handle.clear();
Kei Takahashicba7b322012-01-18 17:10:19 +0900566 ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
567 }
568 return handle;
569}
570
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700571status_t DrmManager::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
Takeshi Aimie943f842010-10-08 23:05:49 +0900572 Mutex::Autolock _l(mDecryptLock);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900573 status_t result = DRM_ERROR_UNKNOWN;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900574 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
575 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900576 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700577 if (DRM_NO_ERROR == result && NULL != decryptHandle.get()) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900578 mDecryptSessionMap.removeItem(decryptHandle->decryptId);
579 }
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900580 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900581 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900582}
583
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900584status_t DrmManager::initializeDecryptUnit(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700585 int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
586 const DrmBuffer* headerInfo) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900587 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800588 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900589 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
590 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900591 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900592 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900593 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900594}
595
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700596status_t DrmManager::decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900597 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
598 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800599
600 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900601 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
602 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900603 result = drmEngine->decrypt(
604 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900605 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900606 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900607}
608
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900609status_t DrmManager::finalizeDecryptUnit(
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700610 int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900611 status_t result = DRM_ERROR_UNKNOWN;
Gloria Wang6b610a32011-03-04 14:45:03 -0800612 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900613 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
614 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900615 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900616 }
Takeshi Aimi2272ee22010-09-20 23:40:41 +0900617 return result;
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900618}
619
Jeff Tinker5d49bef2018-10-03 23:01:09 -0700620ssize_t DrmManager::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
Gloria Wanga2cd44c2010-11-19 15:19:36 -0800621 void* buffer, ssize_t numBytes, off64_t offset) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900622 ssize_t result = DECRYPT_FILE_ERROR;
623
Gloria Wang6b610a32011-03-04 14:45:03 -0800624 Mutex::Autolock _l(mDecryptLock);
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900625 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
626 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
627 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
628 }
629 return result;
630}
631
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900632String8 DrmManager::getSupportedPlugInId(
633 int uniqueId, const String8& path, const String8& mimeType) {
634 String8 plugInId("");
635
636 if (EMPTY_STRING != mimeType) {
637 plugInId = getSupportedPlugInId(mimeType);
638 } else {
639 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
640 }
641 return plugInId;
642}
643
644String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
645 String8 plugInId("");
646
647 if (EMPTY_STRING != mimeType) {
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700648 for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900649 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
650
651 if (drmSupportInfo.isSupportedMimeType(mimeType)) {
652 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
653 break;
654 }
655 }
656 }
657 return plugInId;
658}
659
660String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
661 String8 plugInId("");
662 const String8 fileSuffix = path.getPathExtension();
663
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700664 for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900665 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
666
667 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
668 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
669 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
670
671 if (drmEngine.canHandle(uniqueId, path)) {
672 plugInId = key;
673 break;
674 }
675 }
676 }
677 return plugInId;
678}
679
680void DrmManager::onInfo(const DrmInfoEvent& event) {
Gloria Wang0e0a5f92011-03-11 14:07:21 -0800681 Mutex::Autolock _l(mListenerLock);
Mark Salyzyn3ab368e2014-04-15 14:55:53 -0700682 for (size_t index = 0; index < mServiceListeners.size(); index++) {
aimitakeshi27ed8ad2010-07-29 10:12:27 +0900683 int uniqueId = mServiceListeners.keyAt(index);
684
685 if (uniqueId == event.getUniqueId()) {
686 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
687 serviceListener->notify(event);
688 }
689 }
690}
691