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