Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp

Issue 2342953002: Update EME errors to use TypeError (Closed)
Patch Set: changes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 11 matching lines...) Expand all
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE. 23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "modules/encryptedmedia/MediaKeySession.h" 26 #include "modules/encryptedmedia/MediaKeySession.h"
27 27
28 #include "bindings/core/v8/DOMWrapperWorld.h" 28 #include "bindings/core/v8/DOMWrapperWorld.h"
29 #include "bindings/core/v8/ScriptPromise.h" 29 #include "bindings/core/v8/ScriptPromise.h"
30 #include "bindings/core/v8/ScriptPromiseResolver.h" 30 #include "bindings/core/v8/ScriptPromiseResolver.h"
31 #include "bindings/core/v8/ScriptState.h" 31 #include "bindings/core/v8/ScriptState.h"
32 #include "bindings/core/v8/V8ThrowException.h"
32 #include "core/dom/DOMArrayBuffer.h" 33 #include "core/dom/DOMArrayBuffer.h"
33 #include "core/dom/DOMException.h" 34 #include "core/dom/DOMException.h"
34 #include "core/dom/ExceptionCode.h" 35 #include "core/dom/ExceptionCode.h"
35 #include "core/events/Event.h" 36 #include "core/events/Event.h"
36 #include "core/events/GenericEventQueue.h" 37 #include "core/events/GenericEventQueue.h"
37 #include "modules/encryptedmedia/ContentDecryptionModuleResultPromise.h" 38 #include "modules/encryptedmedia/ContentDecryptionModuleResultPromise.h"
38 #include "modules/encryptedmedia/EncryptedMediaUtils.h" 39 #include "modules/encryptedmedia/EncryptedMediaUtils.h"
39 #include "modules/encryptedmedia/MediaKeyMessageEvent.h" 40 #include "modules/encryptedmedia/MediaKeyMessageEvent.h"
40 #include "modules/encryptedmedia/MediaKeys.h" 41 #include "modules/encryptedmedia/MediaKeys.h"
41 #include "platform/ContentDecryptionModuleResult.h" 42 #include "platform/ContentDecryptionModuleResult.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 75
75 // Check that the sessionId only contains alphanumeric characters. 76 // Check that the sessionId only contains alphanumeric characters.
76 for (unsigned i = 0; i < sessionId.length(); ++i) { 77 for (unsigned i = 0; i < sessionId.length(); ++i) {
77 if (!isASCIIAlphanumeric(sessionId[i])) 78 if (!isASCIIAlphanumeric(sessionId[i]))
78 return false; 79 return false;
79 } 80 }
80 81
81 return true; 82 return true;
82 } 83 }
83 84
85 static bool IsPersistentSessionType(WebEncryptedMediaSessionType sessionType) {
86 // This implements section 5.1.1 Is persistent session type? from
87 // https://w3c.github.io/encrypted-media/#is-persistent-session-type
88 switch (sessionType) {
89 case WebEncryptedMediaSessionType::Temporary:
90 return false;
91 case WebEncryptedMediaSessionType::PersistentLicense:
92 return true;
93 case WebEncryptedMediaSessionType::PersistentReleaseMessage:
94 return true;
95 case blink::WebEncryptedMediaSessionType::Unknown:
96 break;
97 }
98
99 NOTREACHED();
100 return false;
101 }
102
84 static String ConvertKeyStatusToString( 103 static String ConvertKeyStatusToString(
85 const WebEncryptedMediaKeyInformation::KeyStatus status) { 104 const WebEncryptedMediaKeyInformation::KeyStatus status) {
86 switch (status) { 105 switch (status) {
87 case WebEncryptedMediaKeyInformation::KeyStatus::Usable: 106 case WebEncryptedMediaKeyInformation::KeyStatus::Usable:
88 return "usable"; 107 return "usable";
89 case WebEncryptedMediaKeyInformation::KeyStatus::Expired: 108 case WebEncryptedMediaKeyInformation::KeyStatus::Expired:
90 return "expired"; 109 return "expired";
91 case WebEncryptedMediaKeyInformation::KeyStatus::Released: 110 case WebEncryptedMediaKeyInformation::KeyStatus::Released:
92 return "released"; 111 return "released";
93 case WebEncryptedMediaKeyInformation::KeyStatus::OutputRestricted: 112 case WebEncryptedMediaKeyInformation::KeyStatus::OutputRestricted:
(...skipping 10 matching lines...) Expand all
104 return "internal-error"; 123 return "internal-error";
105 } 124 }
106 125
107 static ScriptPromise CreateRejectedPromiseNotCallable( 126 static ScriptPromise CreateRejectedPromiseNotCallable(
108 ScriptState* scriptState) { 127 ScriptState* scriptState) {
109 return ScriptPromise::rejectWithDOMException( 128 return ScriptPromise::rejectWithDOMException(
110 scriptState, 129 scriptState,
111 DOMException::create(InvalidStateError, "The session is not callable.")); 130 DOMException::create(InvalidStateError, "The session is not callable."));
112 } 131 }
113 132
133 static ScriptPromise CreateRejectedPromiseAlreadyClosed(
134 ScriptState* scriptState) {
135 return ScriptPromise::rejectWithDOMException(
136 scriptState, DOMException::create(InvalidStateError,
137 "The session is already closed."));
138 }
139
114 static ScriptPromise CreateRejectedPromiseAlreadyInitialized( 140 static ScriptPromise CreateRejectedPromiseAlreadyInitialized(
115 ScriptState* scriptState) { 141 ScriptState* scriptState) {
116 return ScriptPromise::rejectWithDOMException( 142 return ScriptPromise::rejectWithDOMException(
117 scriptState, DOMException::create(InvalidStateError, 143 scriptState, DOMException::create(InvalidStateError,
118 "The session is already initialized.")); 144 "The session is already initialized."));
119 } 145 }
120 146
121 // A class holding a pending action. 147 // A class holding a pending action.
122 class MediaKeySession::PendingAction 148 class MediaKeySession::PendingAction
123 : public GarbageCollectedFinalized<MediaKeySession::PendingAction> { 149 : public GarbageCollectedFinalized<MediaKeySession::PendingAction> {
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, 446 ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState,
421 const String& initDataTypeString, 447 const String& initDataTypeString,
422 const DOMArrayPiece& initData) { 448 const DOMArrayPiece& initData) {
423 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " 449 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") "
424 << initDataTypeString; 450 << initDataTypeString;
425 451
426 // From https://w3c.github.io/encrypted-media/#generateRequest: 452 // From https://w3c.github.io/encrypted-media/#generateRequest:
427 // Generates a request based on the initData. When this method is invoked, 453 // Generates a request based on the initData. When this method is invoked,
428 // the user agent must run the following steps: 454 // the user agent must run the following steps:
429 455
430 // 1. If this object's uninitialized value is false, return a promise 456 // 1. If this object is closed, return a promise rejected with an
431 // rejected with a new DOMException whose name is "InvalidStateError". 457 // InvalidStateError.
458 if (m_isClosed)
459 return CreateRejectedPromiseAlreadyClosed(scriptState);
460
461 // 2. If this object's uninitialized value is false, return a promise
462 // rejected with an InvalidStateError.
432 if (!m_isUninitialized) 463 if (!m_isUninitialized)
433 return CreateRejectedPromiseAlreadyInitialized(scriptState); 464 return CreateRejectedPromiseAlreadyInitialized(scriptState);
434 465
435 // 2. Let this object's uninitialized be false. 466 // 3. Let this object's uninitialized be false.
436 m_isUninitialized = false; 467 m_isUninitialized = false;
437 468
438 // 3. If initDataType is an empty string, return a promise rejected with a 469 // 4. If initDataType is the empty string, return a promise rejected
439 // new DOMException whose name is "InvalidAccessError". 470 // with a newly created TypeError.
440 if (initDataTypeString.isEmpty()) { 471 if (initDataTypeString.isEmpty()) {
441 return ScriptPromise::rejectWithDOMException( 472 return ScriptPromise::reject(
442 scriptState, 473 scriptState,
443 DOMException::create(InvalidAccessError, 474 V8ThrowException::createTypeError(
444 "The initDataType parameter is empty.")); 475 scriptState->isolate(), "The initDataType parameter is empty."));
445 } 476 }
446 477
447 // 4. If initData is an empty array, return a promise rejected with a new 478 // 5. If initData is an empty array, return a promise rejected with a
448 // DOMException whose name is"InvalidAccessError". 479 // newly created TypeError.
449 if (!initData.byteLength()) { 480 if (!initData.byteLength()) {
450 return ScriptPromise::rejectWithDOMException( 481 return ScriptPromise::reject(
451 scriptState, DOMException::create(InvalidAccessError, 482 scriptState,
483 V8ThrowException::createTypeError(scriptState->isolate(),
452 "The initData parameter is empty.")); 484 "The initData parameter is empty."));
453 } 485 }
454 486
455 // 5. If the Key System implementation represented by this object's cdm 487 // 6. If the Key System implementation represented by this object's cdm
456 // implementation value does not support initDataType as an 488 // implementation value does not support initDataType as an
457 // Initialization Data Type, return a promise rejected with a new 489 // Initialization Data Type, return a promise rejected with a new
458 // DOMException whose name is NotSupportedError. String comparison 490 // DOMException whose name is NotSupportedError. String comparison
459 // is case-sensitive. 491 // is case-sensitive.
460 // (blink side doesn't know what the CDM supports, so the proper check 492 // (blink side doesn't know what the CDM supports, so the proper check
461 // will be done on the Chromium side. However, we can verify that 493 // will be done on the Chromium side. However, we can verify that
462 // |initDataType| is one of the registered values.) 494 // |initDataType| is one of the registered values.)
463 WebEncryptedMediaInitDataType initDataType = 495 WebEncryptedMediaInitDataType initDataType =
464 EncryptedMediaUtils::convertToInitDataType(initDataTypeString); 496 EncryptedMediaUtils::convertToInitDataType(initDataTypeString);
465 if (initDataType == WebEncryptedMediaInitDataType::Unknown) { 497 if (initDataType == WebEncryptedMediaInitDataType::Unknown) {
466 return ScriptPromise::rejectWithDOMException( 498 return ScriptPromise::rejectWithDOMException(
467 scriptState, 499 scriptState,
468 DOMException::create(NotSupportedError, 500 DOMException::create(NotSupportedError,
469 "The initialization data type '" + 501 "The initialization data type '" +
470 initDataTypeString + "' is not supported.")); 502 initDataTypeString + "' is not supported."));
471 } 503 }
472 504
473 // 6. Let init data be a copy of the contents of the initData parameter. 505 // 7. Let init data be a copy of the contents of the initData parameter.
474 DOMArrayBuffer* initDataBuffer = 506 DOMArrayBuffer* initDataBuffer =
475 DOMArrayBuffer::create(initData.data(), initData.byteLength()); 507 DOMArrayBuffer::create(initData.data(), initData.byteLength());
476 508
477 // 7. Let session type be this object's session type. 509 // 8. Let session type be this object's session type.
478 // (Done in constructor.) 510 // (Done in constructor.)
479 511
480 // 8. Let promise be a new promise. 512 // 9. Let promise be a new promise.
481 NewSessionResultPromise* result = 513 NewSessionResultPromise* result =
482 new NewSessionResultPromise(scriptState, this); 514 new NewSessionResultPromise(scriptState, this);
483 ScriptPromise promise = result->promise(); 515 ScriptPromise promise = result->promise();
484 516
485 // 9. Run the following steps asynchronously (documented in 517 // 10. Run the following steps asynchronously (documented in
486 // actionTimerFired()) 518 // actionTimerFired())
487 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest( 519 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(
488 result, initDataType, initDataBuffer)); 520 result, initDataType, initDataBuffer));
489 DCHECK(!m_actionTimer.isActive()); 521 DCHECK(!m_actionTimer.isActive());
490 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 522 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
491 523
492 // 10. Return promise. 524 // 11. Return promise.
493 return promise; 525 return promise;
494 } 526 }
495 527
496 ScriptPromise MediaKeySession::load(ScriptState* scriptState, 528 ScriptPromise MediaKeySession::load(ScriptState* scriptState,
497 const String& sessionId) { 529 const String& sessionId) {
498 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " 530 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") "
499 << sessionId; 531 << sessionId;
500 532
501 // From https://w3c.github.io/encrypted-media/#load: 533 // From https://w3c.github.io/encrypted-media/#load:
502 // Loads the data stored for the specified session into this object. When 534 // Loads the data stored for the specified session into this object. When
503 // this method is invoked, the user agent must run the following steps: 535 // this method is invoked, the user agent must run the following steps:
504 536
505 // 1. If this object's uninitialized value is false, return a promise 537 // 1. If this object is closed, return a promise rejected with an
506 // rejected with a new DOMException whose name is "InvalidStateError". 538 // InvalidStateError.
539 if (m_isClosed)
540 return CreateRejectedPromiseAlreadyClosed(scriptState);
541
542 // 2. If this object's uninitialized value is false, return a promise
543 // rejected with an InvalidStateError.
507 if (!m_isUninitialized) 544 if (!m_isUninitialized)
508 return CreateRejectedPromiseAlreadyInitialized(scriptState); 545 return CreateRejectedPromiseAlreadyInitialized(scriptState);
509 546
510 // 2. Let this object's uninitialized be false. 547 // 3. Let this object's uninitialized value be false.
511 m_isUninitialized = false; 548 m_isUninitialized = false;
512 549
513 // 3. If sessionId is an empty string, return a promise rejected with a 550 // 4. If sessionId is the empty string, return a promise rejected with
514 // new DOMException whose name is "InvalidAccessError". 551 // a newly created TypeError.
515 if (sessionId.isEmpty()) { 552 if (sessionId.isEmpty()) {
516 return ScriptPromise::rejectWithDOMException( 553 return ScriptPromise::reject(
517 scriptState, DOMException::create(InvalidAccessError, 554 scriptState,
555 V8ThrowException::createTypeError(scriptState->isolate(),
518 "The sessionId parameter is empty.")); 556 "The sessionId parameter is empty."));
519 } 557 }
520 558
521 // 4. If this object's session type is not "persistent-license" or 559 // 5. If the result of running the "Is persistent session type?" algorithm
522 // "persistent-release-message", return a promise rejected with a 560 // on this object's session type is false, return a promise rejected
523 // new DOMException whose name is InvalidAccessError. 561 // with a newly created TypeError.
524 if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense && 562 if (!IsPersistentSessionType(m_sessionType)) {
525 m_sessionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) { 563 return ScriptPromise::reject(
526 return ScriptPromise::rejectWithDOMException(
527 scriptState, 564 scriptState,
528 DOMException::create(InvalidAccessError, 565 V8ThrowException::createTypeError(
529 "The session type is not persistent.")); 566 scriptState->isolate(), "The session type is not persistent."));
530 } 567 }
531 568
532 // 5. If the Key System implementation represented by this object's cdm
533 // implementation value does not support loading previous sessions,
534 // return a promise rejected with a new DOMException whose name is
535 // NotSupportedError.
536 // FIXME: Implement this (http://crbug.com/448922).
537
538 // 6. Let origin be the origin of this object's Document. 569 // 6. Let origin be the origin of this object's Document.
539 // (Available as getExecutionContext()->getSecurityOrigin() anytime.) 570 // (Available as getExecutionContext()->getSecurityOrigin() anytime.)
540 571
541 // 7. Let promise be a new promise. 572 // 7. Let promise be a new promise.
542 LoadSessionResultPromise* result = 573 LoadSessionResultPromise* result =
543 new LoadSessionResultPromise(scriptState, this); 574 new LoadSessionResultPromise(scriptState, this);
544 ScriptPromise promise = result->promise(); 575 ScriptPromise promise = result->promise();
545 576
546 // 8. Run the following steps asynchronously (documented in 577 // 8. Run the following steps asynchronously (documented in
547 // actionTimerFired()) 578 // actionTimerFired())
548 m_pendingActions.append( 579 m_pendingActions.append(
549 PendingAction::CreatePendingLoadRequest(result, sessionId)); 580 PendingAction::CreatePendingLoadRequest(result, sessionId));
550 DCHECK(!m_actionTimer.isActive()); 581 DCHECK(!m_actionTimer.isActive());
551 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 582 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
552 583
553 // 9. Return promise. 584 // 9. Return promise.
554 return promise; 585 return promise;
555 } 586 }
556 587
557 ScriptPromise MediaKeySession::update(ScriptState* scriptState, 588 ScriptPromise MediaKeySession::update(ScriptState* scriptState,
558 const DOMArrayPiece& response) { 589 const DOMArrayPiece& response) {
559 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 590 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
560 DCHECK(!m_isClosed);
561 591
562 // From https://w3c.github.io/encrypted-media/#update: 592 // From https://w3c.github.io/encrypted-media/#update:
563 // Provides messages, including licenses, to the CDM. When this method is 593 // Provides messages, including licenses, to the CDM. When this method is
564 // invoked, the user agent must run the following steps: 594 // invoked, the user agent must run the following steps:
565 595
566 // 1. If this object's callable value is false, return a promise rejected 596 // 1. If this object is closed, return a promise rejected with an
567 // with a new DOMException whose name is InvalidStateError. 597 // InvalidStateError.
598 if (m_isClosed)
599 return CreateRejectedPromiseAlreadyClosed(scriptState);
600
601 // 2. If this object's callable value is false, return a promise
602 // rejected with an InvalidStateError.
568 if (!m_isCallable) 603 if (!m_isCallable)
569 return CreateRejectedPromiseNotCallable(scriptState); 604 return CreateRejectedPromiseNotCallable(scriptState);
570 605
571 // 2. If response is an empty array, return a promise rejected with a 606 // 3. If response is an empty array, return a promise rejected with a
572 // new DOMException whose name is InvalidAccessError. 607 // newly created TypeError.
573 if (!response.byteLength()) { 608 if (!response.byteLength()) {
574 return ScriptPromise::rejectWithDOMException( 609 return ScriptPromise::reject(
575 scriptState, DOMException::create(InvalidAccessError, 610 scriptState,
611 V8ThrowException::createTypeError(scriptState->isolate(),
576 "The response parameter is empty.")); 612 "The response parameter is empty."));
577 } 613 }
578 614
579 // 3. Let response copy be a copy of the contents of the response parameter. 615 // 4. Let response copy be a copy of the contents of the response parameter.
580 DOMArrayBuffer* responseCopy = 616 DOMArrayBuffer* responseCopy =
581 DOMArrayBuffer::create(response.data(), response.byteLength()); 617 DOMArrayBuffer::create(response.data(), response.byteLength());
582 618
583 // 4. Let promise be a new promise. 619 // 5. Let promise be a new promise.
584 SimpleResultPromise* result = new SimpleResultPromise(scriptState, this); 620 SimpleResultPromise* result = new SimpleResultPromise(scriptState, this);
585 ScriptPromise promise = result->promise(); 621 ScriptPromise promise = result->promise();
586 622
587 // 5. Run the following steps asynchronously (documented in 623 // 6. Run the following steps asynchronously (documented in
588 // actionTimerFired()) 624 // actionTimerFired())
589 m_pendingActions.append( 625 m_pendingActions.append(
590 PendingAction::CreatePendingUpdate(result, responseCopy)); 626 PendingAction::CreatePendingUpdate(result, responseCopy));
591 if (!m_actionTimer.isActive()) 627 if (!m_actionTimer.isActive())
592 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 628 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
593 629
594 // 6. Return promise. 630 // 7. Return promise.
595 return promise; 631 return promise;
596 } 632 }
597 633
598 ScriptPromise MediaKeySession::close(ScriptState* scriptState) { 634 ScriptPromise MediaKeySession::close(ScriptState* scriptState) {
599 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 635 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
600 636
601 // From https://w3c.github.io/encrypted-media/#close: 637 // From https://w3c.github.io/encrypted-media/#close:
602 // Indicates that the application no longer needs the session and the CDM 638 // Indicates that the application no longer needs the session and the CDM
603 // should release any resources associated with this object and close it. 639 // should release any resources associated with this object and close it.
604 // When this method is invoked, the user agent must run the following steps: 640 // When this method is invoked, the user agent must run the following steps:
(...skipping 22 matching lines...) Expand all
627 return promise; 663 return promise;
628 } 664 }
629 665
630 ScriptPromise MediaKeySession::remove(ScriptState* scriptState) { 666 ScriptPromise MediaKeySession::remove(ScriptState* scriptState) {
631 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 667 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
632 668
633 // From https://w3c.github.io/encrypted-media/#remove: 669 // From https://w3c.github.io/encrypted-media/#remove:
634 // Removes stored session data associated with this object. When this 670 // Removes stored session data associated with this object. When this
635 // method is invoked, the user agent must run the following steps: 671 // method is invoked, the user agent must run the following steps:
636 672
637 // 1. If this object's callable value is false, return a promise rejected 673 // 1. If this object is closed, return a promise rejected with an
638 // with a new DOMException whose name is "InvalidStateError". 674 // InvalidStateError.
675 if (m_isClosed)
676 return CreateRejectedPromiseAlreadyClosed(scriptState);
677
678 // 2. If this object's callable value is false, return a promise rejected
679 // with an InvalidStateError.
639 if (!m_isCallable) 680 if (!m_isCallable)
640 return CreateRejectedPromiseNotCallable(scriptState); 681 return CreateRejectedPromiseNotCallable(scriptState);
641 682
642 // 2. If this object's session type is not "persistent-license" or 683 // 3. If the result of running the "Is persistent session type?" algorithm
643 // "persistent-release-message", return a promise rejected with a 684 // on this object's session type is false, return a promise rejected
644 // new DOMException whose name is InvalidAccessError. 685 // with a newly created TypeError.
645 if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense && 686 if (!IsPersistentSessionType(m_sessionType)) {
646 m_sessionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) { 687 return ScriptPromise::reject(
647 return ScriptPromise::rejectWithDOMException(
648 scriptState, 688 scriptState,
649 DOMException::create(InvalidAccessError, 689 V8ThrowException::createTypeError(
650 "The session type is not persistent.")); 690 scriptState->isolate(), "The session type is not persistent."));
651 }
652
653 // 3. If the Session Close algorithm has been run on this object, return a
654 // promise rejected with a new DOMException whose name is
655 // "InvalidStateError".
656 if (m_isClosed) {
657 return ScriptPromise::rejectWithDOMException(
658 scriptState, DOMException::create(InvalidStateError,
659 "The session is already closed."));
660 } 691 }
661 692
662 // 4. Let promise be a new promise. 693 // 4. Let promise be a new promise.
663 SimpleResultPromise* result = new SimpleResultPromise(scriptState, this); 694 SimpleResultPromise* result = new SimpleResultPromise(scriptState, this);
664 ScriptPromise promise = result->promise(); 695 ScriptPromise promise = result->promise();
665 696
666 // 5. Run the following steps asynchronously (documented in 697 // 5. Run the following steps asynchronously (documented in
667 // actionTimerFired()). 698 // actionTimerFired()).
668 m_pendingActions.append(PendingAction::CreatePendingRemove(result)); 699 m_pendingActions.append(PendingAction::CreatePendingRemove(result));
669 if (!m_actionTimer.isActive()) 700 if (!m_actionTimer.isActive())
(...skipping 10 matching lines...) Expand all
680 // actions getting added to the queue. As a result, swap the queue to 711 // actions getting added to the queue. As a result, swap the queue to
681 // a local copy to avoid problems if this happens. 712 // a local copy to avoid problems if this happens.
682 HeapDeque<Member<PendingAction>> pendingActions; 713 HeapDeque<Member<PendingAction>> pendingActions;
683 pendingActions.swap(m_pendingActions); 714 pendingActions.swap(m_pendingActions);
684 715
685 while (!pendingActions.isEmpty()) { 716 while (!pendingActions.isEmpty()) {
686 PendingAction* action = pendingActions.takeFirst(); 717 PendingAction* action = pendingActions.takeFirst();
687 718
688 switch (action->getType()) { 719 switch (action->getType()) {
689 case PendingAction::GenerateRequest: 720 case PendingAction::GenerateRequest:
690 // NOTE: Continue step 9 of MediaKeySession::generateRequest(). 721 // NOTE: Continue step 10 of MediaKeySession::generateRequest().
691 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this 722 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this
692 << ") GenerateRequest"; 723 << ") GenerateRequest";
693 724
694 // initializeNewSession() in Chromium will execute steps 9.1 to 9.7. 725 // initializeNewSession() in Chromium will execute steps 10.1 to 10.9.
695 m_session->initializeNewSession( 726 m_session->initializeNewSession(
696 action->initDataType(), 727 action->initDataType(),
697 static_cast<unsigned char*>(action->data()->data()), 728 static_cast<unsigned char*>(action->data()->data()),
698 action->data()->byteLength(), m_sessionType, 729 action->data()->byteLength(), m_sessionType,
699 action->result()->result()); 730 action->result()->result());
700 731
701 // Remaining steps (from 9.8) executed in finishGenerateRequest(), 732 // Remaining steps (from 10.10) executed in finishGenerateRequest(),
702 // called when |result| is resolved. 733 // called when |result| is resolved.
703 break; 734 break;
704 735
705 case PendingAction::Load: 736 case PendingAction::Load:
706 // NOTE: Continue step 8 of MediaKeySession::load(). 737 // NOTE: Continue step 8 of MediaKeySession::load().
707 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this 738 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this
708 << ") Load"; 739 << ") Load";
709 740
710 // 8.1 Let sanitized session ID be a validated and/or sanitized 741 // 8.1 Let sanitized session ID be a validated and/or sanitized
711 // version of sessionId. The user agent should thoroughly 742 // version of sessionId. The user agent should thoroughly
712 // validate the sessionId value before passing it to the CDM. 743 // validate the sessionId value before passing it to the CDM.
713 // At a minimum, this should include checking that the length 744 // At a minimum, this should include checking that the length
714 // and value (e.g. alphanumeric) are reasonable. 745 // and value (e.g. alphanumeric) are reasonable.
715 // 8.2 If the previous step failed, reject promise with a new 746 // 8.2 If the preceding step failed, or if sanitized session ID
716 // DOMException whose name is "InvalidAccessError". 747 // is empty, reject promise with a newly created TypeError.
717 if (!isValidSessionId(action->sessionId())) { 748 if (!isValidSessionId(action->sessionId())) {
718 action->result()->completeWithError( 749 action->result()->completeWithError(
719 WebContentDecryptionModuleExceptionInvalidAccessError, 0, 750 WebContentDecryptionModuleExceptionTypeError, 0,
720 "Invalid sessionId"); 751 "Invalid sessionId");
721 return; 752 return;
722 } 753 }
723 754
724 // 8.3 If there is an unclosed session in the object's Document 755 // 8.3 If there is an unclosed session in the object's Document
725 // whose sessionId attribute is sanitized session ID, reject 756 // whose sessionId attribute is sanitized session ID, reject
726 // promise with a new DOMException whose name is 757 // promise with a new DOMException whose name is
727 // QuotaExceededError. In other words, do not create a session 758 // QuotaExceededError. In other words, do not create a session
728 // if a non-closed session, regardless of type, already exists 759 // if a non-closed session, regardless of type, already exists
729 // for this sanitized session ID in this browsing context. 760 // for this sanitized session ID in this browsing context.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 visitor->trace(m_asyncEventQueue); 1033 visitor->trace(m_asyncEventQueue);
1003 visitor->trace(m_pendingActions); 1034 visitor->trace(m_pendingActions);
1004 visitor->trace(m_mediaKeys); 1035 visitor->trace(m_mediaKeys);
1005 visitor->trace(m_keyStatusesMap); 1036 visitor->trace(m_keyStatusesMap);
1006 visitor->trace(m_closedPromise); 1037 visitor->trace(m_closedPromise);
1007 EventTargetWithInlineData::trace(visitor); 1038 EventTargetWithInlineData::trace(visitor);
1008 ActiveDOMObject::trace(visitor); 1039 ActiveDOMObject::trace(visitor);
1009 } 1040 }
1010 1041
1011 } // namespace blink 1042 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698