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(
    430         int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
    431 
    432     Mutex::Autolock _l(mDecryptLock);
    433     status_t result = DRM_ERROR_CANNOT_HANDLE;
    434     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
    435 
    436     DecryptHandle* handle = new DecryptHandle();
    437     if (NULL != handle) {
    438         handle->decryptId = mDecryptSessionId + 1;
    439 
    440         for (unsigned int index = 0; index < plugInIdList.size(); index++) {
    441             String8 plugInId = plugInIdList.itemAt(index);
    442             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
    443             result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
    444 
    445             if (DRM_NO_ERROR == result) {
    446                 ++mDecryptSessionId;
    447                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
    448                 break;
    449             }
    450         }
    451     }
    452     if (DRM_NO_ERROR != result) {
    453         delete handle; handle = NULL;
    454     }
    455     return handle;
    456 }
    457 
    458 DecryptHandle* DrmManager::openDecryptSession(
    459         int uniqueId, const char* uri, const char* mime) {
    460     Mutex::Autolock _l(mDecryptLock);
    461     status_t result = DRM_ERROR_CANNOT_HANDLE;
    462     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
    463 
    464     DecryptHandle* handle = new DecryptHandle();
    465     if (NULL != handle) {
    466         handle->decryptId = mDecryptSessionId + 1;
    467 
    468         for (unsigned int index = 0; index < plugInIdList.size(); index++) {
    469             String8 plugInId = plugInIdList.itemAt(index);
    470             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
    471             result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
    472 
    473             if (DRM_NO_ERROR == result) {
    474                 ++mDecryptSessionId;
    475                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
    476                 break;
    477             }
    478         }
    479     }
    480     if (DRM_NO_ERROR != result) {
    481         delete handle; 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 (unsigned int 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 (unsigned int 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 (unsigned int 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