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