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

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

Issue 2342953002: Update EME errors to use TypeError (Closed)
Patch Set: Created 4 years, 3 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/V8Binding.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 "modules/encryptedmedia/SimpleContentDecryptionModuleResultPromise.h" 42 #include "modules/encryptedmedia/SimpleContentDecryptionModuleResultPromise.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 79
79 // Check that the sessionId only contains alphanumeric characters. 80 // Check that the sessionId only contains alphanumeric characters.
80 for (unsigned i = 0; i < sessionId.length(); ++i) { 81 for (unsigned i = 0; i < sessionId.length(); ++i) {
81 if (!isASCIIAlphanumeric(sessionId[i])) 82 if (!isASCIIAlphanumeric(sessionId[i]))
82 return false; 83 return false;
83 } 84 }
84 85
85 return true; 86 return true;
86 } 87 }
87 88
89 static bool IsPersistentSessionType(WebEncryptedMediaSessionType sessionType)
90 {
91 switch (sessionType) {
92 case WebEncryptedMediaSessionType::Temporary:
93 return false;
94 case WebEncryptedMediaSessionType::PersistentLicense:
95 return true;
96 case WebEncryptedMediaSessionType::PersistentReleaseMessage:
97 return true;
98 case blink::WebEncryptedMediaSessionType::Unknown:
99 break;
100 }
101
102 NOTREACHED();
103 return false;
104 }
105
88 static String ConvertKeyStatusToString(const WebEncryptedMediaKeyInformation::Ke yStatus status) 106 static String ConvertKeyStatusToString(const WebEncryptedMediaKeyInformation::Ke yStatus status)
89 { 107 {
90 switch (status) { 108 switch (status) {
91 case WebEncryptedMediaKeyInformation::KeyStatus::Usable: 109 case WebEncryptedMediaKeyInformation::KeyStatus::Usable:
92 return "usable"; 110 return "usable";
93 case WebEncryptedMediaKeyInformation::KeyStatus::Expired: 111 case WebEncryptedMediaKeyInformation::KeyStatus::Expired:
94 return "expired"; 112 return "expired";
95 case WebEncryptedMediaKeyInformation::KeyStatus::Released: 113 case WebEncryptedMediaKeyInformation::KeyStatus::Released:
96 return "released"; 114 return "released";
97 case WebEncryptedMediaKeyInformation::KeyStatus::OutputRestricted: 115 case WebEncryptedMediaKeyInformation::KeyStatus::OutputRestricted:
98 return "output-restricted"; 116 return "output-restricted";
99 case WebEncryptedMediaKeyInformation::KeyStatus::OutputDownscaled: 117 case WebEncryptedMediaKeyInformation::KeyStatus::OutputDownscaled:
100 return "output-downscaled"; 118 return "output-downscaled";
101 case WebEncryptedMediaKeyInformation::KeyStatus::StatusPending: 119 case WebEncryptedMediaKeyInformation::KeyStatus::StatusPending:
102 return "status-pending"; 120 return "status-pending";
103 case WebEncryptedMediaKeyInformation::KeyStatus::InternalError: 121 case WebEncryptedMediaKeyInformation::KeyStatus::InternalError:
104 return "internal-error"; 122 return "internal-error";
105 } 123 }
106 124
107 NOTREACHED(); 125 NOTREACHED();
108 return "internal-error"; 126 return "internal-error";
109 } 127 }
110 128
111 static ScriptPromise CreateRejectedPromiseNotCallable(ScriptState* scriptState) 129 static ScriptPromise CreateRejectedPromiseNotCallable(ScriptState* scriptState)
112 { 130 {
113 return ScriptPromise::rejectWithDOMException( 131 return ScriptPromise::rejectWithDOMException(
114 scriptState, DOMException::create(InvalidStateError, "The session is not callable.")); 132 scriptState, DOMException::create(InvalidStateError, "The session is not callable."));
115 } 133 }
116 134
135 static ScriptPromise CreateRejectedPromiseAlreadyClosed(ScriptState* scriptState )
136 {
137 return ScriptPromise::rejectWithDOMException(
138 scriptState, DOMException::create(InvalidStateError, "The session is alr eady closed."));
139 }
140
117 static ScriptPromise CreateRejectedPromiseAlreadyInitialized(ScriptState* script State) 141 static ScriptPromise CreateRejectedPromiseAlreadyInitialized(ScriptState* script State)
118 { 142 {
119 return ScriptPromise::rejectWithDOMException( 143 return ScriptPromise::rejectWithDOMException(
120 scriptState, DOMException::create(InvalidStateError, "The session is alr eady initialized.")); 144 scriptState, DOMException::create(InvalidStateError, "The session is alr eady initialized."));
121 } 145 }
122 146
123 // A class holding a pending action. 147 // A class holding a pending action.
124 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> { 148 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> {
125 public: 149 public:
126 enum Type { 150 enum Type {
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 417 }
394 418
395 ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const S tring& initDataTypeString, const DOMArrayPiece& initData) 419 ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const S tring& initDataTypeString, const DOMArrayPiece& initData)
396 { 420 {
397 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " << ini tDataTypeString; 421 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " << ini tDataTypeString;
398 422
399 // From https://w3c.github.io/encrypted-media/#generateRequest: 423 // From https://w3c.github.io/encrypted-media/#generateRequest:
400 // Generates a request based on the initData. When this method is invoked, 424 // Generates a request based on the initData. When this method is invoked,
401 // the user agent must run the following steps: 425 // the user agent must run the following steps:
402 426
403 // 1. If this object's uninitialized value is false, return a promise 427 // 1. If this object is closed, return a promise rejected with an
404 // rejected with a new DOMException whose name is "InvalidStateError". 428 // InvalidStateError.
429 if (m_isClosed)
430 return CreateRejectedPromiseAlreadyClosed(scriptState);
431
432 // 2. If this object's uninitialized value is false, return a promise
433 // rejected with an InvalidStateError.
405 if (!m_isUninitialized) 434 if (!m_isUninitialized)
406 return CreateRejectedPromiseAlreadyInitialized(scriptState); 435 return CreateRejectedPromiseAlreadyInitialized(scriptState);
407 436
408 // 2. Let this object's uninitialized be false. 437 // 3. Let this object's uninitialized be false.
409 m_isUninitialized = false; 438 m_isUninitialized = false;
410 439
411 // 3. If initDataType is an empty string, return a promise rejected with a 440 // 4. If initDataType is the empty string, return a promise rejected
412 // new DOMException whose name is "InvalidAccessError". 441 // with a newly created TypeError.
413 if (initDataTypeString.isEmpty()) { 442 if (initDataTypeString.isEmpty()) {
414 return ScriptPromise::rejectWithDOMException( 443 return ScriptPromise::reject(
415 scriptState, DOMException::create(InvalidAccessError, "The initDataT ype parameter is empty.")); 444 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The initDataType parameter is empty.")));
416 } 445 }
417 446
418 // 4. If initData is an empty array, return a promise rejected with a new 447 // 5. If initData is an empty array, return a promise rejected with a
419 // DOMException whose name is"InvalidAccessError". 448 // newly created TypeError.
420 if (!initData.byteLength()) { 449 if (!initData.byteLength()) {
421 return ScriptPromise::rejectWithDOMException( 450 return ScriptPromise::reject(
422 scriptState, DOMException::create(InvalidAccessError, "The initData parameter is empty.")); 451 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The initData parameter is empty.")));
423 } 452 }
424 453
425 // 5. If the Key System implementation represented by this object's cdm 454 // 6. If the Key System implementation represented by this object's cdm
426 // implementation value does not support initDataType as an 455 // implementation value does not support initDataType as an
427 // Initialization Data Type, return a promise rejected with a new 456 // Initialization Data Type, return a promise rejected with a new
428 // DOMException whose name is NotSupportedError. String comparison 457 // DOMException whose name is NotSupportedError. String comparison
429 // is case-sensitive. 458 // is case-sensitive.
430 // (blink side doesn't know what the CDM supports, so the proper check 459 // (blink side doesn't know what the CDM supports, so the proper check
431 // will be done on the Chromium side. However, we can verify that 460 // will be done on the Chromium side. However, we can verify that
432 // |initDataType| is one of the registered values.) 461 // |initDataType| is one of the registered values.)
433 WebEncryptedMediaInitDataType initDataType = EncryptedMediaUtils::convertToI nitDataType(initDataTypeString); 462 WebEncryptedMediaInitDataType initDataType = EncryptedMediaUtils::convertToI nitDataType(initDataTypeString);
434 if (initDataType == WebEncryptedMediaInitDataType::Unknown) { 463 if (initDataType == WebEncryptedMediaInitDataType::Unknown) {
435 return ScriptPromise::rejectWithDOMException( 464 return ScriptPromise::rejectWithDOMException(
436 scriptState, DOMException::create(NotSupportedError, "The initializa tion data type '" + initDataTypeString + "' is not supported.")); 465 scriptState, DOMException::create(NotSupportedError, "The initializa tion data type '" + initDataTypeString + "' is not supported."));
437 } 466 }
438 467
439 // 6. Let init data be a copy of the contents of the initData parameter. 468 // 7. Let init data be a copy of the contents of the initData parameter.
440 DOMArrayBuffer* initDataBuffer = DOMArrayBuffer::create(initData.data(), ini tData.byteLength()); 469 DOMArrayBuffer* initDataBuffer = DOMArrayBuffer::create(initData.data(), ini tData.byteLength());
441 470
442 // 7. Let session type be this object's session type. 471 // 8. Let session type be this object's session type.
443 // (Done in constructor.) 472 // (Done in constructor.)
444 473
445 // 8. Let promise be a new promise. 474 // 9. Let promise be a new promise.
446 NewSessionResultPromise* result = new NewSessionResultPromise(scriptState, t his); 475 NewSessionResultPromise* result = new NewSessionResultPromise(scriptState, t his);
447 ScriptPromise promise = result->promise(); 476 ScriptPromise promise = result->promise();
448 477
449 // 9. Run the following steps asynchronously (documented in 478 // 10. Run the following steps asynchronously (documented in
450 // actionTimerFired()) 479 // actionTimerFired())
451 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initDataBuffer)); 480 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initDataBuffer));
452 DCHECK(!m_actionTimer.isActive()); 481 DCHECK(!m_actionTimer.isActive());
453 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 482 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
454 483
455 // 10. Return promise. 484 // 11. Return promise.
456 return promise; 485 return promise;
457 } 486 }
458 487
459 ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess ionId) 488 ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess ionId)
460 { 489 {
461 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " << ses sionId; 490 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") " << ses sionId;
462 491
463 // From https://w3c.github.io/encrypted-media/#load: 492 // From https://w3c.github.io/encrypted-media/#load:
464 // Loads the data stored for the specified session into this object. When 493 // Loads the data stored for the specified session into this object. When
465 // this method is invoked, the user agent must run the following steps: 494 // this method is invoked, the user agent must run the following steps:
466 495
467 // 1. If this object's uninitialized value is false, return a promise 496 // 1. If this object is closed, return a promise rejected with an
468 // rejected with a new DOMException whose name is "InvalidStateError". 497 // InvalidStateError.
498 if (m_isClosed)
499 return CreateRejectedPromiseAlreadyClosed(scriptState);
500
501 // 2. If this object's uninitialized value is false, return a promise
502 // rejected with an InvalidStateError.
469 if (!m_isUninitialized) 503 if (!m_isUninitialized)
470 return CreateRejectedPromiseAlreadyInitialized(scriptState); 504 return CreateRejectedPromiseAlreadyInitialized(scriptState);
471 505
472 // 2. Let this object's uninitialized be false. 506 // 3. Let this object's uninitialized value be false.
473 m_isUninitialized = false; 507 m_isUninitialized = false;
474 508
475 // 3. If sessionId is an empty string, return a promise rejected with a 509 // 4. If sessionId is the empty string, return a promise rejected with
476 // new DOMException whose name is "InvalidAccessError". 510 // a newly created TypeError.
477 if (sessionId.isEmpty()) { 511 if (sessionId.isEmpty()) {
478 return ScriptPromise::rejectWithDOMException( 512 return ScriptPromise::reject(
479 scriptState, DOMException::create(InvalidAccessError, "The sessionId parameter is empty.")); 513 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The sessionId parameter is empty.")));
480 } 514 }
481 515
482 // 4. If this object's session type is not "persistent-license" or 516 // 5. If the result of running the "Is persistent session type?" algorithm
483 // "persistent-release-message", return a promise rejected with a 517 // on this object's session type is false, return a promise rejected
484 // new DOMException whose name is InvalidAccessError. 518 // with a newly created TypeError.
485 if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense && m_se ssionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) { 519 if (!IsPersistentSessionType(m_sessionType)) {
486 return ScriptPromise::rejectWithDOMException( 520 return ScriptPromise::reject(
487 scriptState, DOMException::create(InvalidAccessError, "The session t ype is not persistent.")); 521 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The session type is not persistent.")));
488 } 522 }
489 523
490 // 5. If the Key System implementation represented by this object's cdm
491 // implementation value does not support loading previous sessions,
492 // return a promise rejected with a new DOMException whose name is
493 // NotSupportedError.
494 // FIXME: Implement this (http://crbug.com/448922).
495
496 // 6. Let origin be the origin of this object's Document. 524 // 6. Let origin be the origin of this object's Document.
497 // (Available as getExecutionContext()->getSecurityOrigin() anytime.) 525 // (Available as getExecutionContext()->getSecurityOrigin() anytime.)
498 526
499 // 7. Let promise be a new promise. 527 // 7. Let promise be a new promise.
500 LoadSessionResultPromise* result = new LoadSessionResultPromise(scriptState, this); 528 LoadSessionResultPromise* result = new LoadSessionResultPromise(scriptState, this);
501 ScriptPromise promise = result->promise(); 529 ScriptPromise promise = result->promise();
502 530
503 // 8. Run the following steps asynchronously (documented in 531 // 8. Run the following steps asynchronously (documented in
504 // actionTimerFired()) 532 // actionTimerFired())
505 m_pendingActions.append(PendingAction::CreatePendingLoadRequest(result, sess ionId)); 533 m_pendingActions.append(PendingAction::CreatePendingLoadRequest(result, sess ionId));
506 DCHECK(!m_actionTimer.isActive()); 534 DCHECK(!m_actionTimer.isActive());
507 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 535 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
508 536
509 // 9. Return promise. 537 // 9. Return promise.
510 return promise; 538 return promise;
511 } 539 }
512 540
513 ScriptPromise MediaKeySession::update(ScriptState* scriptState, const DOMArrayPi ece& response) 541 ScriptPromise MediaKeySession::update(ScriptState* scriptState, const DOMArrayPi ece& response)
514 { 542 {
515 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 543 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
516 DCHECK(!m_isClosed);
517 544
518 // From https://w3c.github.io/encrypted-media/#update: 545 // From https://w3c.github.io/encrypted-media/#update:
519 // Provides messages, including licenses, to the CDM. When this method is 546 // Provides messages, including licenses, to the CDM. When this method is
520 // invoked, the user agent must run the following steps: 547 // invoked, the user agent must run the following steps:
521 548
522 // 1. If this object's callable value is false, return a promise rejected 549 // 1. If this object is closed, return a promise rejected with an
523 // with a new DOMException whose name is InvalidStateError. 550 // InvalidStateError.
551 if (m_isClosed)
552 return CreateRejectedPromiseAlreadyClosed(scriptState);
553
554 // 2. If this object's callable value is false, return a promise
555 // rejected with an InvalidStateError.
524 if (!m_isCallable) 556 if (!m_isCallable)
525 return CreateRejectedPromiseNotCallable(scriptState); 557 return CreateRejectedPromiseNotCallable(scriptState);
526 558
527 // 2. If response is an empty array, return a promise rejected with a 559 // 3. If response is an empty array, return a promise rejected with a
528 // new DOMException whose name is InvalidAccessError. 560 // newly created TypeError.
529 if (!response.byteLength()) { 561 if (!response.byteLength()) {
530 return ScriptPromise::rejectWithDOMException( 562 return ScriptPromise::reject(
531 scriptState, DOMException::create(InvalidAccessError, "The response parameter is empty.")); 563 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The response parameter is empty.")));
532 } 564 }
533 565
534 // 3. Let response copy be a copy of the contents of the response parameter. 566 // 4. Let response copy be a copy of the contents of the response parameter.
535 DOMArrayBuffer* responseCopy = DOMArrayBuffer::create(response.data(), respo nse.byteLength()); 567 DOMArrayBuffer* responseCopy = DOMArrayBuffer::create(response.data(), respo nse.byteLength());
536 568
537 // 4. Let promise be a new promise. 569 // 5. Let promise be a new promise.
538 SimpleContentDecryptionModuleResultPromise* result = new SimpleContentDecryp tionModuleResultPromise(scriptState); 570 SimpleContentDecryptionModuleResultPromise* result = new SimpleContentDecryp tionModuleResultPromise(scriptState);
539 ScriptPromise promise = result->promise(); 571 ScriptPromise promise = result->promise();
540 572
541 // 5. Run the following steps asynchronously (documented in 573 // 6. Run the following steps asynchronously (documented in
542 // actionTimerFired()) 574 // actionTimerFired())
543 m_pendingActions.append(PendingAction::CreatePendingUpdate(result, responseC opy)); 575 m_pendingActions.append(PendingAction::CreatePendingUpdate(result, responseC opy));
544 if (!m_actionTimer.isActive()) 576 if (!m_actionTimer.isActive())
545 m_actionTimer.startOneShot(0, BLINK_FROM_HERE); 577 m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
546 578
547 // 6. Return promise. 579 // 7. Return promise.
548 return promise; 580 return promise;
549 } 581 }
550 582
551 ScriptPromise MediaKeySession::close(ScriptState* scriptState) 583 ScriptPromise MediaKeySession::close(ScriptState* scriptState)
552 { 584 {
553 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 585 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
554 586
555 // From https://w3c.github.io/encrypted-media/#close: 587 // From https://w3c.github.io/encrypted-media/#close:
556 // Indicates that the application no longer needs the session and the CDM 588 // Indicates that the application no longer needs the session and the CDM
557 // should release any resources associated with this object and close it. 589 // should release any resources associated with this object and close it.
(...skipping 24 matching lines...) Expand all
582 } 614 }
583 615
584 ScriptPromise MediaKeySession::remove(ScriptState* scriptState) 616 ScriptPromise MediaKeySession::remove(ScriptState* scriptState)
585 { 617 {
586 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; 618 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
587 619
588 // From https://w3c.github.io/encrypted-media/#remove: 620 // From https://w3c.github.io/encrypted-media/#remove:
589 // Removes stored session data associated with this object. When this 621 // Removes stored session data associated with this object. When this
590 // method is invoked, the user agent must run the following steps: 622 // method is invoked, the user agent must run the following steps:
591 623
592 // 1. If this object's callable value is false, return a promise rejected 624 // 1. If this object is closed, return a promise rejected with an
593 // with a new DOMException whose name is "InvalidStateError". 625 // InvalidStateError.
626 if (m_isClosed)
627 return CreateRejectedPromiseAlreadyClosed(scriptState);
628
629 // 2. If this object's callable value is false, return a promise rejected
630 // with an InvalidStateError.
594 if (!m_isCallable) 631 if (!m_isCallable)
595 return CreateRejectedPromiseNotCallable(scriptState); 632 return CreateRejectedPromiseNotCallable(scriptState);
596 633
597 // 2. If this object's session type is not "persistent-license" or 634 // 3. If the result of running the "Is persistent session type?" algorithm
598 // "persistent-release-message", return a promise rejected with a 635 // on this object's session type is false, return a promise rejected
599 // new DOMException whose name is InvalidAccessError. 636 // with a newly created TypeError.
600 if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense && m_se ssionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) { 637 if (!IsPersistentSessionType(m_sessionType)) {
601 return ScriptPromise::rejectWithDOMException( 638 return ScriptPromise::reject(
602 scriptState, DOMException::create(InvalidAccessError, "The session t ype is not persistent.")); 639 scriptState, v8::Exception::TypeError(v8String(scriptState->isolate( ), "The session type is not persistent.")));
603 }
604
605 // 3. If the Session Close algorithm has been run on this object, return a
606 // promise rejected with a new DOMException whose name is
607 // "InvalidStateError".
608 if (m_isClosed) {
609 return ScriptPromise::rejectWithDOMException(
610 scriptState, DOMException::create(InvalidStateError, "The session is already closed."));
611 } 640 }
612 641
613 // 4. Let promise be a new promise. 642 // 4. Let promise be a new promise.
614 SimpleContentDecryptionModuleResultPromise* result = new SimpleContentDecryp tionModuleResultPromise(scriptState); 643 SimpleContentDecryptionModuleResultPromise* result = new SimpleContentDecryp tionModuleResultPromise(scriptState);
615 ScriptPromise promise = result->promise(); 644 ScriptPromise promise = result->promise();
616 645
617 // 5. Run the following steps asynchronously (documented in 646 // 5. Run the following steps asynchronously (documented in
618 // actionTimerFired()). 647 // actionTimerFired()).
619 m_pendingActions.append(PendingAction::CreatePendingRemove(result)); 648 m_pendingActions.append(PendingAction::CreatePendingRemove(result));
620 if (!m_actionTimer.isActive()) 649 if (!m_actionTimer.isActive())
(...skipping 11 matching lines...) Expand all
632 // actions getting added to the queue. As a result, swap the queue to 661 // actions getting added to the queue. As a result, swap the queue to
633 // a local copy to avoid problems if this happens. 662 // a local copy to avoid problems if this happens.
634 HeapDeque<Member<PendingAction>> pendingActions; 663 HeapDeque<Member<PendingAction>> pendingActions;
635 pendingActions.swap(m_pendingActions); 664 pendingActions.swap(m_pendingActions);
636 665
637 while (!pendingActions.isEmpty()) { 666 while (!pendingActions.isEmpty()) {
638 PendingAction* action = pendingActions.takeFirst(); 667 PendingAction* action = pendingActions.takeFirst();
639 668
640 switch (action->getType()) { 669 switch (action->getType()) {
641 case PendingAction::GenerateRequest: 670 case PendingAction::GenerateRequest:
642 // NOTE: Continue step 9 of MediaKeySession::generateRequest(). 671 // NOTE: Continue step 10 of MediaKeySession::generateRequest().
643 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") GenerateRequest"; 672 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") GenerateRequest";
644 673
645 // initializeNewSession() in Chromium will execute steps 9.1 to 9.7. 674 // initializeNewSession() in Chromium will execute steps 10.1 to 10. 9.
646 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result()); 675 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result());
647 676
648 // Remaining steps (from 9.8) executed in finishGenerateRequest(), 677 // Remaining steps (from 10.10) executed in finishGenerateRequest(),
649 // called when |result| is resolved. 678 // called when |result| is resolved.
650 break; 679 break;
651 680
652 case PendingAction::Load: 681 case PendingAction::Load:
653 // NOTE: Continue step 8 of MediaKeySession::load(). 682 // NOTE: Continue step 8 of MediaKeySession::load().
654 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") Load"; 683 DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ") Load";
655 684
656 // 8.1 Let sanitized session ID be a validated and/or sanitized 685 // 8.1 Let sanitized session ID be a validated and/or sanitized
657 // version of sessionId. The user agent should thoroughly 686 // version of sessionId. The user agent should thoroughly
658 // validate the sessionId value before passing it to the CDM. 687 // validate the sessionId value before passing it to the CDM.
659 // At a minimum, this should include checking that the length 688 // At a minimum, this should include checking that the length
660 // and value (e.g. alphanumeric) are reasonable. 689 // and value (e.g. alphanumeric) are reasonable.
661 // 8.2 If the previous step failed, reject promise with a new 690 // 8.2 If the preceding step failed, or if sanitized session ID
662 // DOMException whose name is "InvalidAccessError". 691 // is empty, reject promise with a newly created TypeError.
663 if (!isValidSessionId(action->sessionId())) { 692 if (!isValidSessionId(action->sessionId())) {
664 action->result()->completeWithError(WebContentDecryptionModuleEx ceptionInvalidAccessError, 0, "Invalid sessionId"); 693 action->result()->completeWithError(WebContentDecryptionModuleEx ceptionTypeError, 0, "Invalid sessionId");
665 return; 694 return;
666 } 695 }
667 696
668 // 8.3 If there is an unclosed session in the object's Document 697 // 8.3 If there is an unclosed session in the object's Document
669 // whose sessionId attribute is sanitized session ID, reject 698 // whose sessionId attribute is sanitized session ID, reject
670 // promise with a new DOMException whose name is 699 // promise with a new DOMException whose name is
671 // QuotaExceededError. In other words, do not create a session 700 // QuotaExceededError. In other words, do not create a session
672 // if a non-closed session, regardless of type, already exists 701 // if a non-closed session, regardless of type, already exists
673 // for this sanitized session ID in this browsing context. 702 // for this sanitized session ID in this browsing context.
674 // (Done in the CDM.) 703 // (Done in the CDM.)
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 visitor->trace(m_asyncEventQueue); 955 visitor->trace(m_asyncEventQueue);
927 visitor->trace(m_pendingActions); 956 visitor->trace(m_pendingActions);
928 visitor->trace(m_mediaKeys); 957 visitor->trace(m_mediaKeys);
929 visitor->trace(m_keyStatusesMap); 958 visitor->trace(m_keyStatusesMap);
930 visitor->trace(m_closedPromise); 959 visitor->trace(m_closedPromise);
931 EventTargetWithInlineData::trace(visitor); 960 EventTargetWithInlineData::trace(visitor);
932 ActiveDOMObject::trace(visitor); 961 ActiveDOMObject::trace(visitor);
933 } 962 }
934 963
935 } // namespace blink 964 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698