Home | History | Annotate | Download | only in src
      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 #include "SessionMap.h"
     18 #include "FwdLockEngine.h"
     19 #include <utils/Log.h>
     20 #include <errno.h>
     21 #include <stdio.h>
     22 #include <unistd.h>
     23 #include "drm_framework_common.h"
     24 #include <fcntl.h>
     25 #include <limits.h>
     26 #include <DrmRights.h>
     27 #include <DrmConstraints.h>
     28 #include <DrmMetadata.h>
     29 #include <DrmInfo.h>
     30 #include <DrmInfoStatus.h>
     31 #include <DrmInfoRequest.h>
     32 #include <DrmSupportInfo.h>
     33 #include <DrmConvertedStatus.h>
     34 #include <utils/String8.h>
     35 #include "FwdLockConv.h"
     36 #include "FwdLockFile.h"
     37 #include "FwdLockGlue.h"
     38 #include "FwdLockEngineConst.h"
     39 #include "MimeTypeUtil.h"
     40 
     41 #undef LOG_TAG
     42 #define LOG_TAG "FwdLockEngine"
     43 
     44 #ifdef DRM_OMA_FL_ENGINE_DEBUG
     45 #define LOG_NDEBUG 0
     46 #define LOG_VERBOSE(...) LOGV(__VA_ARGS__)
     47 #else
     48 #define LOG_VERBOSE(...)
     49 #endif
     50 
     51 using namespace android;
     52 // This extern "C" is mandatory to be managed by TPlugInManager
     53 extern "C" IDrmEngine* create() {
     54     return new FwdLockEngine();
     55 }
     56 
     57 // This extern "C" is mandatory to be managed by TPlugInManager
     58 extern "C" void destroy(IDrmEngine* plugIn) {
     59     delete plugIn;
     60 }
     61 
     62 FwdLockEngine::FwdLockEngine() {
     63     LOG_VERBOSE("FwdLockEngine Construction");
     64 }
     65 
     66 FwdLockEngine::~FwdLockEngine() {
     67     LOG_VERBOSE("FwdLockEngine Destruction");
     68 
     69     int size = decodeSessionMap.getSize();
     70 
     71     for (int i = 0; i < size; i++) {
     72         DecodeSession *session = (DecodeSession*) decodeSessionMap.getValueAt(i);
     73         FwdLockFile_detach(session->fileDesc);
     74         ::close(session->fileDesc);
     75     }
     76 
     77     size = convertSessionMap.getSize();
     78     for (int i = 0; i < size; i++) {
     79         ConvertSession *convSession = (ConvertSession*) convertSessionMap.getValueAt(i);
     80         FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output));
     81     }
     82 }
     83 
     84 int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
     85     int retStatus = DrmConvertedStatus::STATUS_ERROR;
     86 
     87     switch(status) {
     88         case FwdLockConv_Status_OK:
     89             retStatus = DrmConvertedStatus::STATUS_OK;
     90             break;
     91         case FwdLockConv_Status_SyntaxError:
     92         case FwdLockConv_Status_InvalidArgument:
     93         case FwdLockConv_Status_UnsupportedFileFormat:
     94         case FwdLockConv_Status_UnsupportedContentTransferEncoding:
     95             LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
     96                   "Returning STATUS_INPUTDATA_ERROR", status);
     97             retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR;
     98             break;
     99         default:
    100             LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
    101                   "Returning STATUS_ERROR", status);
    102             retStatus = DrmConvertedStatus::STATUS_ERROR;
    103             break;
    104     }
    105 
    106     return retStatus;
    107 }
    108 
    109 DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) {
    110     DrmConstraints* drmConstraints = NULL;
    111 
    112     LOG_VERBOSE("FwdLockEngine::onGetConstraints");
    113 
    114     if (NULL != path &&
    115         (RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) {
    116         // Return the empty constraints to show no error condition.
    117         drmConstraints = new DrmConstraints();
    118     }
    119 
    120     return drmConstraints;
    121 }
    122 
    123 DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
    124     DrmMetadata* drmMetadata = NULL;
    125 
    126     LOG_VERBOSE("FwdLockEngine::onGetMetadata");
    127 
    128     if (NULL != path) {
    129         // Returns empty metadata to show no error condition.
    130         drmMetadata = new DrmMetadata();
    131     }
    132 
    133     return drmMetadata;
    134 }
    135 
    136 android::status_t FwdLockEngine::onInitialize(int uniqueId) {
    137     LOG_VERBOSE("FwdLockEngine::onInitialize");
    138 
    139     if (FwdLockGlue_InitializeKeyEncryption()) {
    140         LOG_VERBOSE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
    141     } else {
    142         LOGE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
    143              "errno = %d", errno);
    144     }
    145 
    146     return DRM_NO_ERROR;
    147 }
    148 
    149 android::status_t
    150 FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
    151     // Not used
    152     LOG_VERBOSE("FwdLockEngine::onSetOnInfoListener");
    153 
    154     return DRM_NO_ERROR;
    155 }
    156 
    157 android::status_t FwdLockEngine::onTerminate(int uniqueId) {
    158     LOG_VERBOSE("FwdLockEngine::onTerminate");
    159 
    160     return DRM_NO_ERROR;
    161 }
    162 
    163 DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
    164     DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
    165 
    166     LOG_VERBOSE("FwdLockEngine::onGetSupportInfo");
    167 
    168     // fill all Forward Lock mimetypes and extensions
    169     if (NULL != pSupportInfo) {
    170         pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_FL));
    171         pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_FL));
    172         pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_DM));
    173         pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_DM));
    174 
    175         pSupportInfo->setDescription(String8(FWDLOCK_DESCRIPTION));
    176     }
    177 
    178     return pSupportInfo;
    179 }
    180 
    181 bool FwdLockEngine::onCanHandle(int uniqueId, const String8& path) {
    182     bool result = false;
    183 
    184     String8 extString = path.getPathExtension();
    185 
    186     extString.toLower();
    187 
    188     if ((extString == String8(FWDLOCK_DOTEXTENSION_FL)) ||
    189         (extString == String8(FWDLOCK_DOTEXTENSION_DM))) {
    190         result = true;
    191     }
    192     return result;
    193 }
    194 
    195 DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
    196     DrmInfoStatus *drmInfoStatus = NULL;
    197 
    198     // Nothing to process
    199 
    200     drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8(""));
    201 
    202     LOG_VERBOSE("FwdLockEngine::onProcessDrmInfo");
    203 
    204     return drmInfoStatus;
    205 }
    206 
    207 status_t FwdLockEngine::onSaveRights(
    208             int uniqueId,
    209             const DrmRights& drmRights,
    210             const String8& rightsPath,
    211             const String8& contentPath) {
    212     // No rights to save. Return
    213     LOG_VERBOSE("FwdLockEngine::onSaveRights");
    214     return DRM_ERROR_UNKNOWN;
    215 }
    216 
    217 DrmInfo* FwdLockEngine::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
    218     DrmInfo* drmInfo = NULL;
    219 
    220     // Nothing to be done for Forward Lock file
    221     LOG_VERBOSE("FwdLockEngine::onAcquireDrmInfo");
    222 
    223     return drmInfo;
    224 }
    225 
    226 int FwdLockEngine::onCheckRightsStatus(int uniqueId,
    227                                        const String8& path,
    228                                        int action) {
    229     int result = RightsStatus::RIGHTS_INVALID;
    230 
    231     LOG_VERBOSE("FwdLockEngine::onCheckRightsStatus");
    232 
    233     // Only Transfer action is not allowed for forward Lock files.
    234     if (onCanHandle(uniqueId, path)) {
    235         switch(action) {
    236             case Action::DEFAULT:
    237             case Action::PLAY:
    238             case Action::RINGTONE:
    239             case Action::OUTPUT:
    240             case Action::PREVIEW:
    241             case Action::EXECUTE:
    242             case Action::DISPLAY:
    243                 result = RightsStatus::RIGHTS_VALID;
    244                 break;
    245 
    246             case Action::TRANSFER:
    247             default:
    248                 result = RightsStatus::RIGHTS_INVALID;
    249                 break;
    250         }
    251     }
    252 
    253     return result;
    254 }
    255 
    256 status_t FwdLockEngine::onConsumeRights(int uniqueId,
    257                                         DecryptHandle* decryptHandle,
    258                                         int action,
    259                                         bool reserve) {
    260     // No rights consumption
    261     LOG_VERBOSE("FwdLockEngine::onConsumeRights");
    262     return DRM_NO_ERROR;
    263 }
    264 
    265 bool FwdLockEngine::onValidateAction(int uniqueId,
    266                                      const String8& path,
    267                                      int action,
    268                                      const ActionDescription& description) {
    269     LOG_VERBOSE("FwdLockEngine::onValidateAction");
    270 
    271     // For the forwardlock engine checkRights and ValidateAction are the same.
    272     return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID);
    273 }
    274 
    275 String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) {
    276     LOG_VERBOSE("FwdLockEngine::onGetOriginalMimeType");
    277     String8 mimeString = String8("");
    278     int fileDesc = FwdLockFile_open(path.string());
    279 
    280     if (-1 < fileDesc) {
    281         const char* pMimeType = FwdLockFile_GetContentType(fileDesc);
    282 
    283         if (NULL != pMimeType) {
    284             String8 contentType = String8(pMimeType);
    285             contentType.toLower();
    286             mimeString = MimeTypeUtil::convertMimeType(contentType);
    287         }
    288 
    289         FwdLockFile_close(fileDesc);
    290     }
    291 
    292     return mimeString;
    293 }
    294 
    295 int FwdLockEngine::onGetDrmObjectType(int uniqueId,
    296                                       const String8& path,
    297                                       const String8& mimeType) {
    298     String8 mimeStr = String8(mimeType);
    299 
    300     LOG_VERBOSE("FwdLockEngine::onGetDrmObjectType");
    301 
    302     mimeStr.toLower();
    303 
    304     /* Checks whether
    305     * 1. path and mime type both are not empty strings (meaning unavailable) else content is unknown
    306     * 2. if one of them is empty string and if other is known then its a DRM Content Object.
    307     * 3. if both of them are available, then both may be of known type
    308     *    (regardless of the relation between them to make it compatible with other DRM Engines)
    309     */
    310     if (((0 == path.length()) || onCanHandle(uniqueId, path)) &&
    311         ((0 == mimeType.length()) || ((mimeStr == String8(FWDLOCK_MIMETYPE_FL)) ||
    312         (mimeStr == String8(FWDLOCK_MIMETYPE_DM)))) && (mimeType != path) ) {
    313             return DrmObjectType::CONTENT;
    314     }
    315 
    316     return DrmObjectType::UNKNOWN;
    317 }
    318 
    319 status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
    320     // No Rights to remove
    321     LOG_VERBOSE("FwdLockEngine::onRemoveRights");
    322     return DRM_NO_ERROR;
    323 }
    324 
    325 status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
    326     // No rights to remove
    327     LOG_VERBOSE("FwdLockEngine::onRemoveAllRights");
    328     return DRM_NO_ERROR;
    329 }
    330 
    331 #ifdef USE_64BIT_DRM_API
    332 status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
    333                                             int playbackStatus, int64_t position) {
    334 #else
    335 status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
    336                                             int playbackStatus, int position) {
    337 #endif
    338     // Not used
    339     LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
    340     return DRM_NO_ERROR;
    341 }
    342 
    343 status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
    344                                          int convertId) {
    345     status_t result = DRM_ERROR_UNKNOWN;
    346     LOG_VERBOSE("FwdLockEngine::onOpenConvertSession");
    347     if (!convertSessionMap.isCreated(convertId)) {
    348         ConvertSession *newSession = new ConvertSession();
    349         if (FwdLockConv_Status_OK ==
    350             FwdLockConv_OpenSession(&(newSession->uniqueId), &(newSession->output))) {
    351             convertSessionMap.addValue(convertId, newSession);
    352             result = DRM_NO_ERROR;
    353         } else {
    354             LOGE("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
    355             delete newSession;
    356         }
    357     }
    358     return result;
    359 }
    360 
    361 DrmConvertedStatus* FwdLockEngine::onConvertData(int uniqueId,
    362                                                  int convertId,
    363                                                  const DrmBuffer* inputData) {
    364     FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument;
    365     DrmBuffer *convResult = new DrmBuffer(NULL, 0);
    366     int offset = -1;
    367 
    368     if (NULL != inputData && convertSessionMap.isCreated(convertId)) {
    369         ConvertSession *convSession = convertSessionMap.getValue(convertId);
    370 
    371         if (NULL != convSession) {
    372             retStatus = FwdLockConv_ConvertData(convSession->uniqueId,
    373                                                 inputData->data,
    374                                                 inputData->length,
    375                                                 &(convSession->output));
    376 
    377             if (FwdLockConv_Status_OK == retStatus) {
    378                 // return bytes from conversion if available
    379                 if (convSession->output.fromConvertData.numBytes > 0) {
    380                     convResult->data = new char[convSession->output.fromConvertData.numBytes];
    381 
    382                     if (NULL != convResult->data) {
    383                         convResult->length = convSession->output.fromConvertData.numBytes;
    384                         memcpy(convResult->data,
    385                                (char *)convSession->output.fromConvertData.pBuffer,
    386                                convResult->length);
    387                     }
    388                 }
    389             } else {
    390                 offset = convSession->output.fromConvertData.errorPos;
    391             }
    392         }
    393     }
    394     return new DrmConvertedStatus(getConvertedStatus(retStatus), convResult, offset);
    395 }
    396 
    397 DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int uniqueId,
    398                                                          int convertId) {
    399     FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument;
    400     DrmBuffer *convResult = new DrmBuffer(NULL, 0);
    401     int offset = -1;
    402 
    403     LOG_VERBOSE("FwdLockEngine::onCloseConvertSession");
    404 
    405     if (convertSessionMap.isCreated(convertId)) {
    406         ConvertSession *convSession = convertSessionMap.getValue(convertId);
    407 
    408         if (NULL != convSession) {
    409             retStatus = FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output));
    410 
    411             if (FwdLockConv_Status_OK == retStatus) {
    412                 offset = convSession->output.fromCloseSession.fileOffset;
    413                 convResult->data = new char[FWD_LOCK_SIGNATURES_SIZE];
    414 
    415                 if (NULL != convResult->data) {
    416                       convResult->length = FWD_LOCK_SIGNATURES_SIZE;
    417                       memcpy(convResult->data,
    418                              (char *)convSession->output.fromCloseSession.signatures,
    419                              convResult->length);
    420                 }
    421             }
    422         }
    423         convertSessionMap.removeValue(convertId);
    424     }
    425     return new DrmConvertedStatus(getConvertedStatus(retStatus), convResult, offset);
    426 }
    427 
    428 #ifdef USE_64BIT_DRM_API
    429 status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
    430                                              DecryptHandle* decryptHandle,
    431                                              int fd,
    432                                              off64_t offset,
    433                                              off64_t length) {
    434 #else
    435 status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
    436                                              DecryptHandle* decryptHandle,
    437                                              int fd,
    438                                              int offset,
    439                                              int length) {
    440 #endif
    441     status_t result = DRM_ERROR_CANNOT_HANDLE;
    442     int fileDesc = -1;
    443 
    444     LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
    445 
    446     if ((-1 < fd) &&
    447         (NULL != decryptHandle) &&
    448         (!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
    449         fileDesc = dup(fd);
    450     } else {
    451         LOGE("FwdLockEngine::onOpenDecryptSession parameter error");
    452         return result;
    453     }
    454 
    455     if (-1 < fileDesc &&
    456         -1 < ::lseek(fileDesc, offset, SEEK_SET) &&
    457         -1 < FwdLockFile_attach(fileDesc)) {
    458         // check for file integrity. This must be done to protect the content mangling.
    459         int retVal = FwdLockFile_CheckHeaderIntegrity(fileDesc);
    460         DecodeSession* decodeSession = new DecodeSession(fileDesc);
    461 
    462         if (retVal && NULL != decodeSession) {
    463             decodeSessionMap.addValue(decryptHandle->decryptId, decodeSession);
    464             const char *pmime= FwdLockFile_GetContentType(fileDesc);
    465             String8 contentType = String8(pmime == NULL ? "" : pmime);
    466             contentType.toLower();
    467             decryptHandle->mimeType = MimeTypeUtil::convertMimeType(contentType);
    468             decryptHandle->decryptApiType = DecryptApiType::CONTAINER_BASED;
    469             decryptHandle->status = RightsStatus::RIGHTS_VALID;
    470             decryptHandle->decryptInfo = NULL;
    471             result = DRM_NO_ERROR;
    472         } else {
    473             LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
    474             FwdLockFile_detach(fileDesc);
    475             delete decodeSession;
    476         }
    477     }
    478 
    479     if (DRM_NO_ERROR != result && -1 < fileDesc) {
    480         ::close(fileDesc);
    481     }
    482 
    483     LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
    484 
    485     return result;
    486 }
    487 
    488 status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
    489                                              DecryptHandle* decryptHandle,
    490                                              const char* uri) {
    491     status_t result = DRM_ERROR_CANNOT_HANDLE;
    492     const char fileTag [] = "file://";
    493 
    494     if (NULL != decryptHandle && NULL != uri && strlen(uri) > sizeof(fileTag)) {
    495         String8 uriTag = String8(uri);
    496         uriTag.toLower();
    497 
    498         if (0 == strncmp(uriTag.string(), fileTag, sizeof(fileTag) - 1)) {
    499             const char *filePath = strchr(uri + sizeof(fileTag) - 1, '/');
    500             if (NULL != filePath && onCanHandle(uniqueId, String8(filePath))) {
    501                 int fd = open(filePath, O_RDONLY);
    502 
    503                 if (-1 < fd) {
    504                     // offset is always 0 and length is not used. so any positive size.
    505                     result = onOpenDecryptSession(uniqueId, decryptHandle, fd, 0, 1);
    506 
    507                     // fd is duplicated already if success. closing the file
    508                     close(fd);
    509                 }
    510             }
    511         }
    512     }
    513 
    514     return result;
    515 }
    516 
    517 status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
    518                                               DecryptHandle* decryptHandle) {
    519     status_t result = DRM_ERROR_UNKNOWN;
    520     LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
    521 
    522     if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
    523         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
    524         if (NULL != session && session->fileDesc > -1) {
    525             FwdLockFile_detach(session->fileDesc);
    526             ::close(session->fileDesc);
    527             decodeSessionMap.removeValue(decryptHandle->decryptId);
    528             result = DRM_NO_ERROR;
    529         }
    530     }
    531 
    532     if (NULL != decryptHandle) {
    533         if (NULL != decryptHandle->decryptInfo) {
    534             delete decryptHandle->decryptInfo;
    535             decryptHandle->decryptInfo = NULL;
    536         }
    537 
    538         decryptHandle->copyControlVector.clear();
    539         decryptHandle->extendedData.clear();
    540 
    541         delete decryptHandle;
    542         decryptHandle = NULL;
    543     }
    544 
    545     LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
    546     return result;
    547 }
    548 
    549 status_t FwdLockEngine::onInitializeDecryptUnit(int uniqueId,
    550                                                 DecryptHandle* decryptHandle,
    551                                                 int decryptUnitId,
    552                                                 const DrmBuffer* headerInfo) {
    553     LOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
    554     return DRM_ERROR_UNKNOWN;
    555 }
    556 
    557 status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
    558             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
    559     LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
    560     return DRM_ERROR_UNKNOWN;
    561 }
    562 
    563 status_t FwdLockEngine::onDecrypt(int uniqueId,
    564                                   DecryptHandle* decryptHandle,
    565                                   int decryptUnitId,
    566                                   const DrmBuffer* encBuffer,
    567                                   DrmBuffer** decBuffer) {
    568     LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
    569     return DRM_ERROR_UNKNOWN;
    570 }
    571 
    572 status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
    573                                               DecryptHandle* decryptHandle,
    574                                               int decryptUnitId) {
    575     LOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
    576     return DRM_ERROR_UNKNOWN;
    577 }
    578 
    579 ssize_t FwdLockEngine::onRead(int uniqueId,
    580                               DecryptHandle* decryptHandle,
    581                               void* buffer,
    582                               int numBytes) {
    583     ssize_t size = -1;
    584 
    585     if (NULL != decryptHandle &&
    586        decodeSessionMap.isCreated(decryptHandle->decryptId) &&
    587         NULL != buffer &&
    588         numBytes > -1) {
    589         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
    590         if (NULL != session && session->fileDesc > -1) {
    591             size = FwdLockFile_read(session->fileDesc, buffer, numBytes);
    592 
    593             if (0 > size) {
    594                 session->offset = ((off_t)-1);
    595             } else {
    596                 session->offset += size;
    597             }
    598         }
    599     }
    600 
    601     return size;
    602 }
    603 
    604 #ifdef USE_64BIT_DRM_API
    605 off64_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle,
    606                                off64_t offset, int whence) {
    607 #else
    608 off_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle,
    609                              off_t offset, int whence) {
    610 #endif
    611     off_t offval = -1;
    612 
    613     if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
    614         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
    615         if (NULL != session && session->fileDesc > -1) {
    616             offval = FwdLockFile_lseek(session->fileDesc, offset, whence);
    617             session->offset = offval;
    618         }
    619     }
    620 
    621     return offval;
    622 }
    623 
    624 #ifdef USE_64BIT_DRM_API
    625 ssize_t FwdLockEngine::onPread(int uniqueId,
    626                                DecryptHandle* decryptHandle,
    627                                void* buffer,
    628                                ssize_t numBytes,
    629                                off64_t offset) {
    630 #else
    631 ssize_t FwdLockEngine::onPread(int uniqueId,
    632                                DecryptHandle* decryptHandle,
    633                                void* buffer,
    634                                ssize_t numBytes,
    635                                off_t offset) {
    636 #endif
    637     ssize_t bytesRead = -1;
    638 
    639     DecodeSession* decoderSession = NULL;
    640 
    641     if ((NULL != decryptHandle) &&
    642         (NULL != (decoderSession = decodeSessionMap.getValue(decryptHandle->decryptId))) &&
    643         (NULL != buffer) &&
    644         (numBytes > -1) &&
    645         (offset > -1)) {
    646         if (offset != decoderSession->offset) {
    647             decoderSession->offset = onLseek(uniqueId, decryptHandle, offset, SEEK_SET);
    648         }
    649 
    650         if (((off_t)-1) != decoderSession->offset) {
    651             bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes);
    652             if (bytesRead < 0) {
    653                 LOGE("FwdLockEngine::onPread error reading");
    654             }
    655         }
    656     } else {
    657         LOGE("FwdLockEngine::onPread decryptId not found");
    658     }
    659 
    660     return bytesRead;
    661 }
    662