DrmManager.cpp revision 0e0a5f9e0b7a7ca618e8a1f7ccecc57a17e0d1e2
1/* 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/DrmMetadata.h> 27#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 40Vector<int> DrmManager::mUniqueIdVector; 41const String8 DrmManager::EMPTY_STRING(""); 42 43DrmManager::DrmManager() : 44 mDecryptSessionId(0), 45 mConvertId(0) { 46 47} 48 49DrmManager::~DrmManager() { 50 51} 52 53int DrmManager::addUniqueId(int uniqueId) { 54 Mutex::Autolock _l(mLock); 55 if (0 == uniqueId) { 56 int temp = 0; 57 bool foundUniqueId = false; 58 srand(time(NULL)); 59 60 while (!foundUniqueId) { 61 const int size = mUniqueIdVector.size(); 62 temp = rand() % 100; 63 64 int index = 0; 65 for (; index < size; ++index) { 66 if (mUniqueIdVector.itemAt(index) == temp) { 67 foundUniqueId = false; 68 break; 69 } 70 } 71 if (index == size) { 72 foundUniqueId = true; 73 } 74 } 75 uniqueId = temp; 76 } 77 mUniqueIdVector.push(uniqueId); 78 return uniqueId; 79} 80 81void DrmManager::removeUniqueId(int uniqueId) { 82 Mutex::Autolock _l(mLock); 83 for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) { 84 if (uniqueId == mUniqueIdVector.itemAt(i)) { 85 mUniqueIdVector.removeAt(i); 86 break; 87 } 88 } 89} 90 91status_t DrmManager::loadPlugIns() { 92 String8 pluginDirPath("/system/lib/drm"); 93 return loadPlugIns(pluginDirPath); 94} 95 96status_t DrmManager::loadPlugIns(const String8& plugInDirPath) { 97 if (mSupportInfoToPlugInIdMap.isEmpty()) { 98 mPlugInManager.loadPlugIns(plugInDirPath); 99 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 100 for (unsigned int i = 0; i < plugInPathList.size(); ++i) { 101 String8 plugInPath = plugInPathList[i]; 102 DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); 103 if (NULL != info) { 104 mSupportInfoToPlugInIdMap.add(*info, plugInPath); 105 } 106 } 107 } 108 return DRM_NO_ERROR; 109} 110 111status_t DrmManager::unloadPlugIns() { 112 Mutex::Autolock _l(mLock); 113 mConvertSessionMap.clear(); 114 mDecryptSessionMap.clear(); 115 mPlugInManager.unloadPlugIns(); 116 mSupportInfoToPlugInIdMap.clear(); 117 return DRM_NO_ERROR; 118} 119 120status_t DrmManager::setDrmServiceListener( 121 int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) { 122 Mutex::Autolock _l(mListenerLock); 123 if (NULL != drmServiceListener.get()) { 124 mServiceListeners.add(uniqueId, drmServiceListener); 125 } else { 126 mServiceListeners.removeItem(uniqueId); 127 } 128 return DRM_NO_ERROR; 129} 130 131void DrmManager::addClient(int uniqueId) { 132 Mutex::Autolock _l(mLock); 133 if (!mSupportInfoToPlugInIdMap.isEmpty()) { 134 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 135 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 136 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 137 rDrmEngine.initialize(uniqueId); 138 rDrmEngine.setOnInfoListener(uniqueId, this); 139 } 140 } 141} 142 143void DrmManager::removeClient(int uniqueId) { 144 Mutex::Autolock _l(mLock); 145 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 146 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 147 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 148 rDrmEngine.terminate(uniqueId); 149 } 150} 151 152DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) { 153 Mutex::Autolock _l(mLock); 154 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path); 155 if (EMPTY_STRING != plugInId) { 156 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 157 return rDrmEngine.getConstraints(uniqueId, path, action); 158 } 159 return NULL; 160} 161 162DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) { 163 Mutex::Autolock _l(mLock); 164 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path); 165 if (EMPTY_STRING != plugInId) { 166 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 167 return rDrmEngine.getMetadata(uniqueId, path); 168 } 169 return NULL; 170} 171 172status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) { 173 Mutex::Autolock _l(mLock); 174 mPlugInManager.loadPlugIn(absolutePath); 175 176 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath); 177 rDrmEngine.initialize(uniqueId); 178 rDrmEngine.setOnInfoListener(uniqueId, this); 179 180 DrmSupportInfo* info = rDrmEngine.getSupportInfo(0); 181 mSupportInfoToPlugInIdMap.add(*info, absolutePath); 182 183 return DRM_NO_ERROR; 184} 185 186bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) { 187 Mutex::Autolock _l(mLock); 188 const String8 plugInId = getSupportedPlugInId(mimeType); 189 bool result = (EMPTY_STRING != plugInId) ? true : false; 190 191 if (0 < path.length()) { 192 if (result) { 193 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 194 result = rDrmEngine.canHandle(uniqueId, path); 195 } else { 196 String8 extension = path.getPathExtension(); 197 if (String8("") != extension) { 198 result = canHandle(uniqueId, path); 199 } 200 } 201 } 202 return result; 203} 204 205DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) { 206 Mutex::Autolock _l(mLock); 207 const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType()); 208 if (EMPTY_STRING != plugInId) { 209 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 210 return rDrmEngine.processDrmInfo(uniqueId, drmInfo); 211 } 212 return NULL; 213} 214 215bool DrmManager::canHandle(int uniqueId, const String8& path) { 216 bool result = false; 217 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 218 219 for (unsigned int i = 0; i < plugInPathList.size(); ++i) { 220 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]); 221 result = rDrmEngine.canHandle(uniqueId, path); 222 223 if (result) { 224 break; 225 } 226 } 227 return result; 228} 229 230DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) { 231 Mutex::Autolock _l(mLock); 232 const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType()); 233 if (EMPTY_STRING != plugInId) { 234 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 235 return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest); 236 } 237 return NULL; 238} 239 240status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights, 241 const String8& rightsPath, const String8& contentPath) { 242 Mutex::Autolock _l(mLock); 243 const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType()); 244 status_t result = DRM_ERROR_UNKNOWN; 245 if (EMPTY_STRING != plugInId) { 246 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 247 result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath); 248 } 249 return result; 250} 251 252String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) { 253 Mutex::Autolock _l(mLock); 254 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 255 if (EMPTY_STRING != plugInId) { 256 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 257 return rDrmEngine.getOriginalMimeType(uniqueId, path); 258 } 259 return EMPTY_STRING; 260} 261 262int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) { 263 Mutex::Autolock _l(mLock); 264 const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType); 265 if (EMPTY_STRING != plugInId) { 266 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 267 return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType); 268 } 269 return DrmObjectType::UNKNOWN; 270} 271 272int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) { 273 Mutex::Autolock _l(mLock); 274 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 275 if (EMPTY_STRING != plugInId) { 276 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 277 return rDrmEngine.checkRightsStatus(uniqueId, path, action); 278 } 279 return RightsStatus::RIGHTS_INVALID; 280} 281 282status_t DrmManager::consumeRights( 283 int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) { 284 status_t result = DRM_ERROR_UNKNOWN; 285 Mutex::Autolock _l(mDecryptLock); 286 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 287 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 288 result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve); 289 } 290 return result; 291} 292 293status_t DrmManager::setPlaybackStatus( 294 int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) { 295 status_t result = DRM_ERROR_UNKNOWN; 296 Mutex::Autolock _l(mDecryptLock); 297 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 298 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 299 result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position); 300 } 301 return result; 302} 303 304bool DrmManager::validateAction( 305 int uniqueId, const String8& path, int action, const ActionDescription& description) { 306 Mutex::Autolock _l(mLock); 307 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 308 if (EMPTY_STRING != plugInId) { 309 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 310 return rDrmEngine.validateAction(uniqueId, path, action, description); 311 } 312 return false; 313} 314 315status_t DrmManager::removeRights(int uniqueId, const String8& path) { 316 Mutex::Autolock _l(mLock); 317 const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 318 status_t result = DRM_ERROR_UNKNOWN; 319 if (EMPTY_STRING != plugInId) { 320 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 321 result = rDrmEngine.removeRights(uniqueId, path); 322 } 323 return result; 324} 325 326status_t DrmManager::removeAllRights(int uniqueId) { 327 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 328 status_t result = DRM_ERROR_UNKNOWN; 329 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 330 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index)); 331 result = rDrmEngine.removeAllRights(uniqueId); 332 if (DRM_NO_ERROR != result) { 333 break; 334 } 335 } 336 return result; 337} 338 339int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) { 340 Mutex::Autolock _l(mConvertLock); 341 int convertId = -1; 342 343 const String8 plugInId = getSupportedPlugInId(mimeType); 344 if (EMPTY_STRING != plugInId) { 345 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 346 347 if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) { 348 ++mConvertId; 349 convertId = mConvertId; 350 mConvertSessionMap.add(convertId, &rDrmEngine); 351 } 352 } 353 return convertId; 354} 355 356DrmConvertedStatus* DrmManager::convertData( 357 int uniqueId, int convertId, const DrmBuffer* inputData) { 358 DrmConvertedStatus *drmConvertedStatus = NULL; 359 360 Mutex::Autolock _l(mConvertLock); 361 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) { 362 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId); 363 drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData); 364 } 365 return drmConvertedStatus; 366} 367 368DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) { 369 Mutex::Autolock _l(mConvertLock); 370 DrmConvertedStatus *drmConvertedStatus = NULL; 371 372 if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) { 373 IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId); 374 drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId); 375 mConvertSessionMap.removeItem(convertId); 376 } 377 return drmConvertedStatus; 378} 379 380status_t DrmManager::getAllSupportInfo( 381 int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) { 382 Mutex::Autolock _l(mLock); 383 Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); 384 int size = plugInPathList.size(); 385 int validPlugins = 0; 386 387 if (0 < size) { 388 Vector<DrmSupportInfo> drmSupportInfoList; 389 390 for (int i = 0; i < size; ++i) { 391 String8 plugInPath = plugInPathList[i]; 392 DrmSupportInfo* drmSupportInfo 393 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); 394 if (NULL != drmSupportInfo) { 395 drmSupportInfoList.add(*drmSupportInfo); 396 delete drmSupportInfo; drmSupportInfo = NULL; 397 } 398 } 399 400 validPlugins = drmSupportInfoList.size(); 401 if (0 < validPlugins) { 402 *drmSupportInfoArray = new DrmSupportInfo[validPlugins]; 403 for (int i = 0; i < validPlugins; ++i) { 404 (*drmSupportInfoArray)[i] = drmSupportInfoList[i]; 405 } 406 } 407 } 408 *length = validPlugins; 409 return DRM_NO_ERROR; 410} 411 412DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) { 413 Mutex::Autolock _l(mDecryptLock); 414 status_t result = DRM_ERROR_CANNOT_HANDLE; 415 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 416 417 DecryptHandle* handle = new DecryptHandle(); 418 if (NULL != handle) { 419 handle->decryptId = mDecryptSessionId + 1; 420 421 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 422 String8 plugInId = plugInIdList.itemAt(index); 423 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 424 result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length); 425 426 if (DRM_NO_ERROR == result) { 427 ++mDecryptSessionId; 428 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine); 429 break; 430 } 431 } 432 } 433 if (DRM_NO_ERROR != result) { 434 delete handle; handle = NULL; 435 } 436 return handle; 437} 438 439DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) { 440 Mutex::Autolock _l(mDecryptLock); 441 status_t result = DRM_ERROR_CANNOT_HANDLE; 442 Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); 443 444 DecryptHandle* handle = new DecryptHandle(); 445 if (NULL != handle) { 446 handle->decryptId = mDecryptSessionId + 1; 447 448 for (unsigned int index = 0; index < plugInIdList.size(); index++) { 449 String8 plugInId = plugInIdList.itemAt(index); 450 IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); 451 result = rDrmEngine.openDecryptSession(uniqueId, handle, uri); 452 453 if (DRM_NO_ERROR == result) { 454 ++mDecryptSessionId; 455 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine); 456 break; 457 } 458 } 459 } 460 if (DRM_NO_ERROR != result) { 461 delete handle; handle = NULL; 462 LOGV("DrmManager::openDecryptSession: no capable plug-in found"); 463 } 464 return handle; 465} 466 467status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) { 468 Mutex::Autolock _l(mDecryptLock); 469 status_t result = DRM_ERROR_UNKNOWN; 470 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 471 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 472 result = drmEngine->closeDecryptSession(uniqueId, decryptHandle); 473 if (DRM_NO_ERROR == result) { 474 mDecryptSessionMap.removeItem(decryptHandle->decryptId); 475 } 476 } 477 return result; 478} 479 480status_t DrmManager::initializeDecryptUnit( 481 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) { 482 status_t result = DRM_ERROR_UNKNOWN; 483 Mutex::Autolock _l(mDecryptLock); 484 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 485 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 486 result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo); 487 } 488 return result; 489} 490 491status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, 492 const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) { 493 status_t result = DRM_ERROR_UNKNOWN; 494 495 Mutex::Autolock _l(mDecryptLock); 496 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 497 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 498 result = drmEngine->decrypt( 499 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV); 500 } 501 return result; 502} 503 504status_t DrmManager::finalizeDecryptUnit( 505 int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) { 506 status_t result = DRM_ERROR_UNKNOWN; 507 Mutex::Autolock _l(mDecryptLock); 508 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 509 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 510 result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId); 511 } 512 return result; 513} 514 515ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle, 516 void* buffer, ssize_t numBytes, off64_t offset) { 517 ssize_t result = DECRYPT_FILE_ERROR; 518 519 Mutex::Autolock _l(mDecryptLock); 520 if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) { 521 IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId); 522 result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset); 523 } 524 return result; 525} 526 527String8 DrmManager::getSupportedPlugInId( 528 int uniqueId, const String8& path, const String8& mimeType) { 529 String8 plugInId(""); 530 531 if (EMPTY_STRING != mimeType) { 532 plugInId = getSupportedPlugInId(mimeType); 533 } else { 534 plugInId = getSupportedPlugInIdFromPath(uniqueId, path); 535 } 536 return plugInId; 537} 538 539String8 DrmManager::getSupportedPlugInId(const String8& mimeType) { 540 String8 plugInId(""); 541 542 if (EMPTY_STRING != mimeType) { 543 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) { 544 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index); 545 546 if (drmSupportInfo.isSupportedMimeType(mimeType)) { 547 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo); 548 break; 549 } 550 } 551 } 552 return plugInId; 553} 554 555String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) { 556 String8 plugInId(""); 557 const String8 fileSuffix = path.getPathExtension(); 558 559 for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) { 560 const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index); 561 562 if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) { 563 String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo); 564 IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key); 565 566 if (drmEngine.canHandle(uniqueId, path)) { 567 plugInId = key; 568 break; 569 } 570 } 571 } 572 return plugInId; 573} 574 575void DrmManager::onInfo(const DrmInfoEvent& event) { 576 Mutex::Autolock _l(mListenerLock); 577 for (unsigned int index = 0; index < mServiceListeners.size(); index++) { 578 int uniqueId = mServiceListeners.keyAt(index); 579 580 if (uniqueId == event.getUniqueId()) { 581 sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId); 582 serviceListener->notify(event); 583 } 584 } 585} 586 587