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 #ifndef __FWDLOCKENGINE_H__ 18 #define __FWDLOCKENGINE_H__ 19 20 #include <DrmEngineBase.h> 21 #include <drm/DrmConstraints.h> 22 #include <drm/DrmRights.h> 23 #include <drm/DrmInfo.h> 24 #include <drm/DrmInfoStatus.h> 25 #include <drm/DrmConvertedStatus.h> 26 #include <drm/DrmInfoRequest.h> 27 #include <drm/DrmSupportInfo.h> 28 #include <drm/DrmInfoEvent.h> 29 30 #include "SessionMap.h" 31 #include "FwdLockConv.h" 32 33 namespace android { 34 35 /** 36 * Forward Lock Engine class. 37 */ 38 class FwdLockEngine : public android::DrmEngineBase { 39 40 public: 41 FwdLockEngine(); 42 virtual ~FwdLockEngine(); 43 44 protected: 45 /** 46 * Get constraint information associated with input content. 47 * 48 * @param uniqueId Unique identifier for a session 49 * @param path Path of the protected content 50 * @param action Actions defined such as, 51 * Action::DEFAULT, Action::PLAY, etc 52 * @return DrmConstraints 53 * key-value pairs of constraint are embedded in it 54 * @note 55 * In case of error, return NULL 56 */ 57 DrmConstraints* onGetConstraints(int uniqueId, const String8* path, int action); 58 59 /** 60 * Get metadata information associated with input content. 61 * 62 * @param uniqueId Unique identifier for a session 63 * @param path Path of the protected content 64 * @return DrmMetadata 65 * For Forward Lock engine, it returns an empty object 66 * @note 67 * In case of error, returns NULL 68 */ 69 DrmMetadata* onGetMetadata(int uniqueId, const String8* path); 70 71 /** 72 * Initialize plug-in. 73 * 74 * @param uniqueId Unique identifier for a session 75 * @return status_t 76 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 77 */ 78 status_t onInitialize(int uniqueId); 79 80 /** 81 * Register a callback to be invoked when the caller required to 82 * receive necessary information. 83 * 84 * @param uniqueId Unique identifier for a session 85 * @param infoListener Listener 86 * @return status_t 87 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 88 */ 89 status_t onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener); 90 91 /** 92 * Terminate the plug-in and release resources bound to it. 93 * 94 * @param uniqueId Unique identifier for a session 95 * @return status_t 96 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 97 */ 98 status_t onTerminate(int uniqueId); 99 100 /** 101 * Get whether the given content can be handled by this plugin or not. 102 * 103 * @param uniqueId Unique identifier for a session 104 * @param path Path to the protected object 105 * @return bool 106 * Returns true if this plugin can handle , false in case of not able to handle 107 */ 108 bool onCanHandle(int uniqueId, const String8& path); 109 110 /** 111 * Processes the given DRM information as appropriate for its type. 112 * Not used for Forward Lock Engine. 113 * 114 * @param uniqueId Unique identifier for a session 115 * @param drmInfo Information that needs to be processed 116 * @return DrmInfoStatus 117 * instance as a result of processing given input 118 */ 119 DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo); 120 121 /** 122 * Save DRM rights to specified rights path 123 * and make association with content path. 124 * 125 * @param uniqueId Unique identifier for a session 126 * @param drmRights DrmRights to be saved 127 * @param rightsPath File path where rights to be saved 128 * @param contentPath File path where content was saved 129 * @return status_t 130 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 131 */ 132 status_t onSaveRights(int uniqueId, 133 const DrmRights& drmRights, 134 const String8& rightsPath, 135 const String8& contentPath); 136 137 /** 138 * Retrieves necessary information for registration, unregistration or rights 139 * acquisition information. 140 * 141 * @param uniqueId Unique identifier for a session 142 * @param drmInfoRequest Request information to retrieve drmInfo 143 * @return DrmInfo 144 * instance as a result of processing given input 145 */ 146 DrmInfo* onAcquireDrmInfo(int uniqueId, 147 const DrmInfoRequest* drmInfoRequest); 148 149 /** 150 * Retrieves the mime type embedded inside the original content. 151 * 152 * @param uniqueId Unique identifier for a session 153 * @param path Path of the conent or null. 154 * @param fd descriptor of the protected content as a file source 155 * @return String8 156 * Returns mime-type of the original content, such as "video/mpeg" 157 */ 158 String8 onGetOriginalMimeType(int uniqueId, const String8& path, int fd); 159 160 /** 161 * Retrieves the type of the protected object (content, rights, etc..) 162 * using specified path or mimetype. At least one parameter should be non null 163 * to retrieve DRM object type. 164 * 165 * @param uniqueId Unique identifier for a session 166 * @param path Path of the content or null. 167 * @param mimeType Mime type of the content or null. 168 * @return type of the DRM content, 169 * such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT 170 */ 171 int onGetDrmObjectType(int uniqueId, 172 const String8& path, 173 const String8& mimeType); 174 175 /** 176 * Check whether the given content has valid rights or not. 177 * 178 * @param uniqueId Unique identifier for a session 179 * @param path Path of the protected content 180 * @param action Action to perform (Action::DEFAULT, Action::PLAY, etc) 181 * @return the status of the rights for the protected content, 182 * such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc. 183 */ 184 int onCheckRightsStatus(int uniqueId, 185 const String8& path, 186 int action); 187 188 /** 189 * Consumes the rights for a content. 190 * If the reserve parameter is true the rights are reserved until the same 191 * application calls this api again with the reserve parameter set to false. 192 * 193 * @param uniqueId Unique identifier for a session 194 * @param decryptHandle Handle for the decryption session 195 * @param action Action to perform. (Action::DEFAULT, Action::PLAY, etc) 196 * @param reserve True if the rights should be reserved. 197 * @return status_t 198 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 199 */ 200 status_t onConsumeRights(int uniqueId, 201 sp<DecryptHandle>& decryptHandle, 202 int action, 203 bool reserve); 204 205 /** 206 * Informs the DRM Engine about the playback actions performed on the DRM files. 207 * 208 * @param uniqueId Unique identifier for a session 209 * @param decryptHandle Handle for the decryption session 210 * @param playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE) 211 * @param position Position in the file (in milliseconds) where the start occurs. 212 * Only valid together with Playback::START. 213 * @return status_t 214 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 215 */ 216 #ifdef USE_64BIT_DRM_API 217 status_t onSetPlaybackStatus(int uniqueId, 218 sp<DecryptHandle>& decryptHandle, 219 int playbackStatus, 220 int64_t position); 221 #else 222 status_t onSetPlaybackStatus(int uniqueId, 223 sp<DecryptHandle>& decryptHandle, 224 int playbackStatus, 225 int position); 226 #endif 227 228 /** 229 * Validates whether an action on the DRM content is allowed or not. 230 * 231 * @param uniqueId Unique identifier for a session 232 * @param path Path of the protected content 233 * @param action Action to validate (Action::PLAY, Action::TRANSFER, etc) 234 * @param description Detailed description of the action 235 * @return true if the action is allowed. 236 */ 237 bool onValidateAction(int uniqueId, 238 const String8& path, 239 int action, 240 const ActionDescription& description); 241 242 /** 243 * Removes the rights associated with the given protected content. 244 * Not used for Forward Lock Engine. 245 * 246 * @param uniqueId Unique identifier for a session 247 * @param path Path of the protected content 248 * @return status_t 249 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 250 */ 251 status_t onRemoveRights(int uniqueId, const String8& path); 252 253 /** 254 * Removes all the rights information of each plug-in associated with 255 * DRM framework. Will be used in master reset but does nothing for 256 * Forward Lock Engine. 257 * 258 * @param uniqueId Unique identifier for a session 259 * @return status_t 260 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 261 */ 262 status_t onRemoveAllRights(int uniqueId); 263 264 /** 265 * Starts the Forward Lock file conversion session. 266 * Each time the application tries to download a new DRM file 267 * which needs to be converted, then the application has to 268 * begin with calling this API. The convertId is used as the conversion session key 269 * and must not be the same for different convert sessions. 270 * 271 * @param uniqueId Unique identifier for a session 272 * @param convertId Handle for the convert session 273 * @return status_t 274 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 275 */ 276 status_t onOpenConvertSession(int uniqueId, int convertId); 277 278 /** 279 * Accepts and converts the input data which is part of DRM file. 280 * The resultant converted data and the status is returned in the DrmConvertedInfo 281 * object. This method will be called each time there is a new block 282 * of data received by the application. 283 * 284 * @param uniqueId Unique identifier for a session 285 * @param convertId Handle for the convert session 286 * @param inputData Input Data which need to be converted 287 * @return Return object contains the status of the data conversion, 288 * the output converted data and offset. In this case the 289 * application will ignore the offset information. 290 */ 291 DrmConvertedStatus* onConvertData(int uniqueId, 292 int convertId, 293 const DrmBuffer* inputData); 294 295 /** 296 * Closes the convert session in case of data supply completed or error occurred. 297 * Upon successful conversion of the complete data, it returns signature calculated over 298 * the entire data used over a conversion session. This signature must be copied to the offset 299 * mentioned in the DrmConvertedStatus. Signature is used for data integrity protection. 300 * 301 * @param uniqueId Unique identifier for a session 302 * @param convertId Handle for the convert session 303 * @return Return object contains the status of the data conversion, 304 * the header and body signature data. It also informs 305 * the application about the file offset at which this 306 * signature data should be written. 307 */ 308 DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId); 309 310 /** 311 * Returns the information about the Drm Engine capabilities which includes 312 * supported MimeTypes and file suffixes. 313 * 314 * @param uniqueId Unique identifier for a session 315 * @return DrmSupportInfo 316 * instance which holds the capabilities of a plug-in 317 */ 318 DrmSupportInfo* onGetSupportInfo(int uniqueId); 319 320 /** 321 * Open the decrypt session to decrypt the given protected content. 322 * 323 * @param uniqueId Unique identifier for a session 324 * @param decryptHandle Handle for the current decryption session 325 * @param fd File descriptor of the protected content to be decrypted 326 * @param offset Start position of the content 327 * @param length The length of the protected content 328 * @return 329 * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success 330 */ 331 #ifdef USE_64BIT_DRM_API 332 status_t onOpenDecryptSession(int uniqueId, 333 sp<DecryptHandle>& decryptHandle, 334 int fd, off64_t offset, off64_t length); 335 #else 336 status_t onOpenDecryptSession(int uniqueId, 337 sp<DecryptHandle>& decryptHandle, 338 int fd, int offset, int length); 339 #endif 340 341 /** 342 * Open the decrypt session to decrypt the given protected content. 343 * 344 * @param uniqueId Unique identifier for a session 345 * @param decryptHandle Handle for the current decryption session 346 * @param uri Path of the protected content to be decrypted 347 * @return 348 * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success 349 */ 350 status_t onOpenDecryptSession(int uniqueId, 351 sp<DecryptHandle>& decryptHandle, 352 const char* uri); 353 354 /** 355 * Close the decrypt session for the given handle. 356 * 357 * @param uniqueId Unique identifier for a session 358 * @param decryptHandle Handle for the decryption session 359 * @return status_t 360 * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure 361 */ 362 status_t onCloseDecryptSession(int uniqueId, 363 sp<DecryptHandle>& decryptHandle); 364 365 /** 366 * Initialize decryption for the given unit of the protected content. 367 * 368 * @param uniqueId Unique identifier for a session 369 * @param decryptHandle Handle for the decryption session 370 * @param decryptUnitId ID which specifies decryption unit, such as track ID 371 * @param headerInfo Information for initializing decryption of this decrypUnit 372 * @return 373 * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success 374 */ 375 status_t onInitializeDecryptUnit(int uniqueId, 376 sp<DecryptHandle>& decryptHandle, 377 int decryptUnitId, 378 const DrmBuffer* headerInfo); 379 380 /** 381 * Decrypt the protected content buffers for the given unit. 382 * This method will be called any number of times, based on number of 383 * encrypted streams received from application. 384 * 385 * @param uniqueId Unique identifier for a session 386 * @param decryptHandle Handle for the decryption session 387 * @param decryptUnitId ID which specifies decryption unit, such as track ID 388 * @param encBuffer Encrypted data block 389 * @param decBuffer Decrypted data block 390 * @return status_t 391 * Returns the error code for this API 392 * DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED 393 * DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED, 394 * DRM_ERROR_DECRYPT for failure. 395 */ 396 status_t onDecrypt(int uniqueId, 397 sp<DecryptHandle>& decryptHandle, 398 int decryptUnitId, 399 const DrmBuffer* encBuffer, 400 DrmBuffer** decBuffer); 401 402 /** 403 * Decrypt the protected content buffers for the given unit. 404 * This method will be called any number of times, based on number of 405 * encrypted streams received from application. 406 * 407 * @param uniqueId Unique identifier for a session 408 * @param decryptId Handle for the decryption session 409 * @param decryptUnitId ID Specifies decryption unit, such as track ID 410 * @param encBuffer Encrypted data block 411 * @param decBuffer Decrypted data block 412 * @param IV Optional buffer 413 * @return status_t 414 * Returns the error code for this API 415 * DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED 416 * DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED, 417 * DRM_ERROR_DECRYPT for failure. 418 */ 419 status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, 420 int decryptUnitId, const DrmBuffer* encBuffer, 421 DrmBuffer** decBuffer, DrmBuffer* IV); 422 423 /** 424 * Finalize decryption for the given unit of the protected content. 425 * 426 * @param uniqueId Unique identifier for a session 427 * @param decryptHandle Handle for the decryption session 428 * @param decryptUnitId ID Specifies decryption unit, such as track ID 429 * @return 430 * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success 431 */ 432 status_t onFinalizeDecryptUnit(int uniqueId, 433 sp<DecryptHandle>& decryptHandle, 434 int decryptUnitId); 435 436 /** 437 * Reads the specified number of bytes from an open DRM file. 438 * 439 * @param uniqueId Unique identifier for a session 440 * @param decryptHandle Handle for the decryption session 441 * @param buffer Reference to the buffer that should receive the read data. 442 * @param numBytes Number of bytes to read. 443 * 444 * @return Number of bytes read. 445 * @retval -1 Failure. 446 */ 447 ssize_t onRead(int uniqueId, 448 sp<DecryptHandle>& decryptHandle, 449 void* pBuffer, 450 int numBytes); 451 452 /** 453 * Updates the file position within an open DRM file. 454 * 455 * @param uniqueId Unique identifier for a session 456 * @param decryptHandle Handle for the decryption session 457 * @param offset Offset with which to update the file position. 458 * @param whence One of SEEK_SET, SEEK_CUR, and SEEK_END. 459 * These constants are defined in unistd.h. 460 * 461 * @return New file position. 462 * @retval ((off_t)-1) Failure. 463 */ 464 #ifdef USE_64BIT_DRM_API 465 off64_t onLseek(int uniqueId, 466 sp<DecryptHandle>& decryptHandle, 467 off64_t offset, 468 int whence); 469 #else 470 off_t onLseek(int uniqueId, 471 sp<DecryptHandle>& decryptHandle, 472 off_t offset, 473 int whence); 474 #endif 475 476 /** 477 * Reads the specified number of bytes from an open DRM file. 478 * 479 * @param uniqueId Unique identifier for a session 480 * @param decryptHandle Handle for the decryption session 481 * @param buffer Reference to the buffer that should receive the read data. 482 * @param numBytes Number of bytes to read. 483 * @param offset Offset with which to update the file position. 484 * 485 * @return Number of bytes read. Returns -1 for Failure. 486 */ 487 #ifdef USE_64BIT_DRM_API 488 ssize_t onPread(int uniqueId, 489 sp<DecryptHandle>& decryptHandle, 490 void* buffer, 491 ssize_t numBytes, 492 off64_t offset); 493 #else 494 ssize_t onPread(int uniqueId, 495 sp<DecryptHandle>& decryptHandle, 496 void* buffer, 497 ssize_t numBytes, 498 off_t offset); 499 #endif 500 501 private: 502 503 static const String8 Description; 504 static const String8 FileSuffixes[]; 505 static const String8 MimeTypes[]; 506 static bool IsFileSuffixSupported(const String8& suffix); 507 static bool IsMimeTypeSupported(const String8& mime); 508 static void AddSupportedMimeTypes(DrmSupportInfo *info); 509 static void AddSupportedFileSuffixes(DrmSupportInfo *info); 510 511 /** 512 * Session Class for Forward Lock Conversion. An object of this class is created 513 * for every conversion. 514 */ 515 class ConvertSession { 516 public : 517 int uniqueId; 518 FwdLockConv_Output_t output; 519 ConvertSession()520 ConvertSession() { 521 uniqueId = 0; 522 memset(&output, 0, sizeof(FwdLockConv_Output_t)); 523 } 524 ~ConvertSession()525 virtual ~ConvertSession() {} 526 }; 527 528 /** 529 * Session Class for Forward Lock decoder. An object of this class is created 530 * for every decoding session. 531 */ 532 class DecodeSession { 533 public : 534 int fileDesc; 535 off_t offset; 536 DecodeSession()537 DecodeSession() { 538 fileDesc = -1; 539 offset = 0; 540 } 541 DecodeSession(int fd)542 explicit DecodeSession(int fd) { 543 fileDesc = fd; 544 offset = 0; 545 } 546 ~DecodeSession()547 virtual ~DecodeSession() {} 548 }; 549 550 /** 551 * Session Map Tables for Conversion and Decoding of forward lock files. 552 */ 553 SessionMap<ConvertSession*> convertSessionMap; 554 SessionMap<DecodeSession*> decodeSessionMap; 555 556 /** 557 * Converts the error code from Forward Lock Converter to DrmConvertStatus error code. 558 * 559 * @param Forward Lock Converter error code 560 * 561 * @return Status code from DrmConvertStatus. 562 */ 563 static int getConvertedStatus(FwdLockConv_Status_t status); 564 }; 565 566 }; 567 568 #endif /* __FWDLOCKENGINE_H__ */ 569