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