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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
index 4a2156406347405f106e4e61514867f112cfc714..b248dba590c4c12ab5a98bc0f81211dc2207e22d 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -29,6 +29,7 @@
#include "bindings/core/v8/ScriptPromise.h"
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8ThrowException.h"
#include "core/dom/DOMArrayBuffer.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
@@ -81,6 +82,24 @@ static bool isValidSessionId(const String& sessionId) {
return true;
}
+static bool IsPersistentSessionType(WebEncryptedMediaSessionType sessionType) {
+ // This implements section 5.1.1 Is persistent session type? from
+ // https://w3c.github.io/encrypted-media/#is-persistent-session-type
+ switch (sessionType) {
+ case WebEncryptedMediaSessionType::Temporary:
+ return false;
+ case WebEncryptedMediaSessionType::PersistentLicense:
+ return true;
+ case WebEncryptedMediaSessionType::PersistentReleaseMessage:
+ return true;
+ case blink::WebEncryptedMediaSessionType::Unknown:
+ break;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
static String ConvertKeyStatusToString(
const WebEncryptedMediaKeyInformation::KeyStatus status) {
switch (status) {
@@ -111,6 +130,13 @@ static ScriptPromise CreateRejectedPromiseNotCallable(
DOMException::create(InvalidStateError, "The session is not callable."));
}
+static ScriptPromise CreateRejectedPromiseAlreadyClosed(
+ ScriptState* scriptState) {
+ return ScriptPromise::rejectWithDOMException(
+ scriptState, DOMException::create(InvalidStateError,
+ "The session is already closed."));
+}
+
static ScriptPromise CreateRejectedPromiseAlreadyInitialized(
ScriptState* scriptState) {
return ScriptPromise::rejectWithDOMException(
@@ -427,32 +453,38 @@ ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState,
// Generates a request based on the initData. When this method is invoked,
// the user agent must run the following steps:
- // 1. If this object's uninitialized value is false, return a promise
- // rejected with a new DOMException whose name is "InvalidStateError".
+ // 1. If this object is closed, return a promise rejected with an
+ // InvalidStateError.
+ if (m_isClosed)
+ return CreateRejectedPromiseAlreadyClosed(scriptState);
+
+ // 2. If this object's uninitialized value is false, return a promise
+ // rejected with an InvalidStateError.
if (!m_isUninitialized)
return CreateRejectedPromiseAlreadyInitialized(scriptState);
- // 2. Let this object's uninitialized be false.
+ // 3. Let this object's uninitialized be false.
m_isUninitialized = false;
- // 3. If initDataType is an empty string, return a promise rejected with a
- // new DOMException whose name is "InvalidAccessError".
+ // 4. If initDataType is the empty string, return a promise rejected
+ // with a newly created TypeError.
if (initDataTypeString.isEmpty()) {
- return ScriptPromise::rejectWithDOMException(
+ return ScriptPromise::reject(
scriptState,
- DOMException::create(InvalidAccessError,
- "The initDataType parameter is empty."));
+ V8ThrowException::createTypeError(
+ scriptState->isolate(), "The initDataType parameter is empty."));
}
- // 4. If initData is an empty array, return a promise rejected with a new
- // DOMException whose name is"InvalidAccessError".
+ // 5. If initData is an empty array, return a promise rejected with a
+ // newly created TypeError.
if (!initData.byteLength()) {
- return ScriptPromise::rejectWithDOMException(
- scriptState, DOMException::create(InvalidAccessError,
+ return ScriptPromise::reject(
+ scriptState,
+ V8ThrowException::createTypeError(scriptState->isolate(),
"The initData parameter is empty."));
}
- // 5. If the Key System implementation represented by this object's cdm
+ // 6. If the Key System implementation represented by this object's cdm
// implementation value does not support initDataType as an
// Initialization Data Type, return a promise rejected with a new
// DOMException whose name is NotSupportedError. String comparison
@@ -470,26 +502,26 @@ ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState,
initDataTypeString + "' is not supported."));
}
- // 6. Let init data be a copy of the contents of the initData parameter.
+ // 7. Let init data be a copy of the contents of the initData parameter.
DOMArrayBuffer* initDataBuffer =
DOMArrayBuffer::create(initData.data(), initData.byteLength());
- // 7. Let session type be this object's session type.
+ // 8. Let session type be this object's session type.
// (Done in constructor.)
- // 8. Let promise be a new promise.
+ // 9. Let promise be a new promise.
NewSessionResultPromise* result =
new NewSessionResultPromise(scriptState, this);
ScriptPromise promise = result->promise();
- // 9. Run the following steps asynchronously (documented in
- // actionTimerFired())
+ // 10. Run the following steps asynchronously (documented in
+ // actionTimerFired())
m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(
result, initDataType, initDataBuffer));
DCHECK(!m_actionTimer.isActive());
m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
- // 10. Return promise.
+ // 11. Return promise.
return promise;
}
@@ -502,39 +534,38 @@ ScriptPromise MediaKeySession::load(ScriptState* scriptState,
// Loads the data stored for the specified session into this object. When
// this method is invoked, the user agent must run the following steps:
- // 1. If this object's uninitialized value is false, return a promise
- // rejected with a new DOMException whose name is "InvalidStateError".
+ // 1. If this object is closed, return a promise rejected with an
+ // InvalidStateError.
+ if (m_isClosed)
+ return CreateRejectedPromiseAlreadyClosed(scriptState);
+
+ // 2. If this object's uninitialized value is false, return a promise
+ // rejected with an InvalidStateError.
if (!m_isUninitialized)
return CreateRejectedPromiseAlreadyInitialized(scriptState);
- // 2. Let this object's uninitialized be false.
+ // 3. Let this object's uninitialized value be false.
m_isUninitialized = false;
- // 3. If sessionId is an empty string, return a promise rejected with a
- // new DOMException whose name is "InvalidAccessError".
+ // 4. If sessionId is the empty string, return a promise rejected with
+ // a newly created TypeError.
if (sessionId.isEmpty()) {
- return ScriptPromise::rejectWithDOMException(
- scriptState, DOMException::create(InvalidAccessError,
+ return ScriptPromise::reject(
+ scriptState,
+ V8ThrowException::createTypeError(scriptState->isolate(),
"The sessionId parameter is empty."));
}
- // 4. If this object's session type is not "persistent-license" or
- // "persistent-release-message", return a promise rejected with a
- // new DOMException whose name is InvalidAccessError.
- if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense &&
- m_sessionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) {
- return ScriptPromise::rejectWithDOMException(
+ // 5. If the result of running the "Is persistent session type?" algorithm
+ // on this object's session type is false, return a promise rejected
+ // with a newly created TypeError.
+ if (!IsPersistentSessionType(m_sessionType)) {
+ return ScriptPromise::reject(
scriptState,
- DOMException::create(InvalidAccessError,
- "The session type is not persistent."));
+ V8ThrowException::createTypeError(
+ scriptState->isolate(), "The session type is not persistent."));
}
- // 5. If the Key System implementation represented by this object's cdm
- // implementation value does not support loading previous sessions,
- // return a promise rejected with a new DOMException whose name is
- // NotSupportedError.
- // FIXME: Implement this (http://crbug.com/448922).
-
// 6. Let origin be the origin of this object's Document.
// (Available as getExecutionContext()->getSecurityOrigin() anytime.)
@@ -557,41 +588,46 @@ ScriptPromise MediaKeySession::load(ScriptState* scriptState,
ScriptPromise MediaKeySession::update(ScriptState* scriptState,
const DOMArrayPiece& response) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
- DCHECK(!m_isClosed);
// From https://w3c.github.io/encrypted-media/#update:
// Provides messages, including licenses, to the CDM. When this method is
// invoked, the user agent must run the following steps:
- // 1. If this object's callable value is false, return a promise rejected
- // with a new DOMException whose name is InvalidStateError.
+ // 1. If this object is closed, return a promise rejected with an
+ // InvalidStateError.
+ if (m_isClosed)
+ return CreateRejectedPromiseAlreadyClosed(scriptState);
+
+ // 2. If this object's callable value is false, return a promise
+ // rejected with an InvalidStateError.
if (!m_isCallable)
return CreateRejectedPromiseNotCallable(scriptState);
- // 2. If response is an empty array, return a promise rejected with a
- // new DOMException whose name is InvalidAccessError.
+ // 3. If response is an empty array, return a promise rejected with a
+ // newly created TypeError.
if (!response.byteLength()) {
- return ScriptPromise::rejectWithDOMException(
- scriptState, DOMException::create(InvalidAccessError,
+ return ScriptPromise::reject(
+ scriptState,
+ V8ThrowException::createTypeError(scriptState->isolate(),
"The response parameter is empty."));
}
- // 3. Let response copy be a copy of the contents of the response parameter.
+ // 4. Let response copy be a copy of the contents of the response parameter.
DOMArrayBuffer* responseCopy =
DOMArrayBuffer::create(response.data(), response.byteLength());
- // 4. Let promise be a new promise.
+ // 5. Let promise be a new promise.
SimpleResultPromise* result = new SimpleResultPromise(scriptState, this);
ScriptPromise promise = result->promise();
- // 5. Run the following steps asynchronously (documented in
+ // 6. Run the following steps asynchronously (documented in
// actionTimerFired())
m_pendingActions.append(
PendingAction::CreatePendingUpdate(result, responseCopy));
if (!m_actionTimer.isActive())
m_actionTimer.startOneShot(0, BLINK_FROM_HERE);
- // 6. Return promise.
+ // 7. Return promise.
return promise;
}
@@ -634,29 +670,24 @@ ScriptPromise MediaKeySession::remove(ScriptState* scriptState) {
// Removes stored session data associated with this object. When this
// method is invoked, the user agent must run the following steps:
- // 1. If this object's callable value is false, return a promise rejected
- // with a new DOMException whose name is "InvalidStateError".
+ // 1. If this object is closed, return a promise rejected with an
+ // InvalidStateError.
+ if (m_isClosed)
+ return CreateRejectedPromiseAlreadyClosed(scriptState);
+
+ // 2. If this object's callable value is false, return a promise rejected
+ // with an InvalidStateError.
if (!m_isCallable)
return CreateRejectedPromiseNotCallable(scriptState);
- // 2. If this object's session type is not "persistent-license" or
- // "persistent-release-message", return a promise rejected with a
- // new DOMException whose name is InvalidAccessError.
- if (m_sessionType != WebEncryptedMediaSessionType::PersistentLicense &&
- m_sessionType != WebEncryptedMediaSessionType::PersistentReleaseMessage) {
- return ScriptPromise::rejectWithDOMException(
+ // 3. If the result of running the "Is persistent session type?" algorithm
+ // on this object's session type is false, return a promise rejected
+ // with a newly created TypeError.
+ if (!IsPersistentSessionType(m_sessionType)) {
+ return ScriptPromise::reject(
scriptState,
- DOMException::create(InvalidAccessError,
- "The session type is not persistent."));
- }
-
- // 3. If the Session Close algorithm has been run on this object, return a
- // promise rejected with a new DOMException whose name is
- // "InvalidStateError".
- if (m_isClosed) {
- return ScriptPromise::rejectWithDOMException(
- scriptState, DOMException::create(InvalidStateError,
- "The session is already closed."));
+ V8ThrowException::createTypeError(
+ scriptState->isolate(), "The session type is not persistent."));
}
// 4. Let promise be a new promise.
@@ -687,18 +718,18 @@ void MediaKeySession::actionTimerFired(TimerBase*) {
switch (action->getType()) {
case PendingAction::GenerateRequest:
- // NOTE: Continue step 9 of MediaKeySession::generateRequest().
+ // NOTE: Continue step 10 of MediaKeySession::generateRequest().
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this
<< ") GenerateRequest";
- // initializeNewSession() in Chromium will execute steps 9.1 to 9.7.
+ // initializeNewSession() in Chromium will execute steps 10.1 to 10.9.
m_session->initializeNewSession(
action->initDataType(),
static_cast<unsigned char*>(action->data()->data()),
action->data()->byteLength(), m_sessionType,
action->result()->result());
- // Remaining steps (from 9.8) executed in finishGenerateRequest(),
+ // Remaining steps (from 10.10) executed in finishGenerateRequest(),
// called when |result| is resolved.
break;
@@ -712,11 +743,11 @@ void MediaKeySession::actionTimerFired(TimerBase*) {
// validate the sessionId value before passing it to the CDM.
// At a minimum, this should include checking that the length
// and value (e.g. alphanumeric) are reasonable.
- // 8.2 If the previous step failed, reject promise with a new
- // DOMException whose name is "InvalidAccessError".
+ // 8.2 If the preceding step failed, or if sanitized session ID
+ // is empty, reject promise with a newly created TypeError.
if (!isValidSessionId(action->sessionId())) {
action->result()->completeWithError(
- WebContentDecryptionModuleExceptionInvalidAccessError, 0,
+ WebContentDecryptionModuleExceptionTypeError, 0,
"Invalid sessionId");
return;
}

Powered by Google App Engine
This is Rietveld 408576698