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