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

Unified 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 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 8c283efbcc93489110347e8b01ba582087bb7070..b7f92d23268da99790262b38cb4cbc30a509f567 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/V8Binding.h"
#include "core/dom/DOMArrayBuffer.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
@@ -85,6 +86,23 @@ static bool isValidSessionId(const String& sessionId)
return true;
}
+static bool IsPersistentSessionType(WebEncryptedMediaSessionType sessionType)
+{
+ 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) {
@@ -114,6 +132,12 @@ static ScriptPromise CreateRejectedPromiseNotCallable(ScriptState* scriptState)
scriptState, 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(
@@ -400,29 +424,34 @@ ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const S
// 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(
- scriptState, DOMException::create(InvalidAccessError, "The initDataType parameter is empty."));
+ return ScriptPromise::reject(
+ scriptState, v8::Exception::TypeError(v8String(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, "The initData parameter is empty."));
+ return ScriptPromise::reject(
+ scriptState, v8::Exception::TypeError(v8String(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
@@ -436,23 +465,23 @@ ScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const S
scriptState, DOMException::create(NotSupportedError, "The initialization data type '" + 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;
}
@@ -464,35 +493,34 @@ ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess
// 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, "The sessionId parameter is empty."));
+ return ScriptPromise::reject(
+ scriptState, v8::Exception::TypeError(v8String(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(
- scriptState, DOMException::create(InvalidAccessError, "The session type is not persistent."));
+ // 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, v8::Exception::TypeError(v8String(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.)
@@ -513,38 +541,42 @@ ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess
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, "The response parameter is empty."));
+ return ScriptPromise::reject(
+ scriptState, v8::Exception::TypeError(v8String(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.
SimpleContentDecryptionModuleResultPromise* result = new SimpleContentDecryptionModuleResultPromise(scriptState);
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;
}
@@ -589,25 +621,22 @@ 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(
- 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."));
+ // 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, v8::Exception::TypeError(v8String(scriptState->isolate(), "The session type is not persistent.")));
}
// 4. Let promise be a new promise.
@@ -639,13 +668,13 @@ 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;
@@ -658,10 +687,10 @@ 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, "Invalid sessionId");
+ action->result()->completeWithError(WebContentDecryptionModuleExceptionTypeError, 0, "Invalid sessionId");
return;
}

Powered by Google App Engine
This is Rietveld 408576698