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