diff --git a/dom/media/eme/MediaKeySession.cpp b/dom/media/eme/MediaKeySession.cpp index 1eb6bbf67b9d..8c31c00c726a 100644 --- a/dom/media/eme/MediaKeySession.cpp +++ b/dom/media/eme/MediaKeySession.cpp @@ -264,6 +264,16 @@ MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResu if (aRv.Failed()) { return nullptr; } + + if (!IsCallable()) { + // If this object's callable value is false, return a promise rejected + // with a new DOMException whose name is InvalidStateError. + EME_LOG("MediaKeySession[%p,''] Update() called before sessionId set by CDM", this); + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, + NS_LITERAL_CSTRING("MediaKeySession.Update() called before sessionId set by CDM")); + return promise.forget(); + } + nsTArray data; if (IsClosed() || !mKeys->GetCDMProxy()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, @@ -309,6 +319,14 @@ MediaKeySession::Close(ErrorResult& aRv) if (aRv.Failed()) { return nullptr; } + if (!IsCallable()) { + // If this object's callable value is false, return a promise rejected + // with a new DOMException whose name is InvalidStateError. + EME_LOG("MediaKeySession[%p,''] Close() called before sessionId set by CDM", this); + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, + NS_LITERAL_CSTRING("MediaKeySession.Close() called before sessionId set by CDM")); + return promise.forget(); + } if (IsClosed() || !mKeys->GetCDMProxy()) { EME_LOG("MediaKeySession[%p,'%s'] Close() already closed", this, NS_ConvertUTF16toUTF8(mSessionId).get()); @@ -352,6 +370,14 @@ MediaKeySession::Remove(ErrorResult& aRv) if (aRv.Failed()) { return nullptr; } + if (!IsCallable()) { + // If this object's callable value is false, return a promise rejected + // with a new DOMException whose name is InvalidStateError. + EME_LOG("MediaKeySession[%p,''] Remove() called before sessionId set by CDM", this); + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, + NS_LITERAL_CSTRING("MediaKeySession.Remove() called before sessionId set by CDM")); + return promise.forget(); + } if (mSessionType != SessionType::Persistent) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR, NS_LITERAL_CSTRING("Calling MediaKeySession.remove() on non-persistent session")); diff --git a/dom/media/eme/MediaKeySession.h b/dom/media/eme/MediaKeySession.h index a91a65055a03..b0b981799b62 100644 --- a/dom/media/eme/MediaKeySession.h +++ b/dom/media/eme/MediaKeySession.h @@ -101,6 +101,14 @@ private: ~MediaKeySession(); void UpdateKeyStatusMap(); + + bool IsCallable() const { + // The EME spec sets the "callable value" to true whenever the CDM sets + // the sessionId. When the session is initialized, sessionId is empty and + // callable is thus false. + return !mSessionId.IsEmpty(); + } + already_AddRefed MakePromise(ErrorResult& aRv, const nsACString& aName);