зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1615035. Use ErrorResults, not nsresults, to propagate errors in CDM code. r=bryce
Please review this very carefully! This exposes a bunch of error messages that used to only be visible on DetailedPromise to web content. Are there any privacy/security issues with exposing those? If needed, we could use more generic messages instead, but exposing this information if we can seemed like the right way to go. I did look over the error messages coming from GeckoMediaDrmBridgeV21.java and none of them look like they expose any interesting state. The messages from ChromiumCDMProxy expose mKeySystem, but that came from the web page to start with, I think. Also, are these messages even meaningful for web content? Some of the error messages (like the one from MediaDrmCDMProxy::md_SetServerCertificate) seem like they include internal function names, so are not great for web content... I'm not quite sure what the best thing to do there is. Note: There is a behavior change to ChromiumCDMParent::GetStatusForPolicy because NS_ERROR_INVALID_ARG is not a valid thing to throw to web content. I've used TypeError, since that's what normally gets used for invalid args. Differential Revision: https://phabricator.services.mozilla.com/D62645 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ac0a51e32c
Коммит
9789fc91bb
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/CDMCaps.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
|
||||
#include "mozilla/dom/MediaKeyMessageEvent.h"
|
||||
|
@ -182,7 +183,7 @@ class CDMProxy {
|
|||
uint32_t aSystemCode, const nsAString& aMsg) = 0;
|
||||
|
||||
// Main thread only.
|
||||
virtual void OnRejectPromise(uint32_t aPromiseId, nsresult aDOMException,
|
||||
virtual void OnRejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aMsg) = 0;
|
||||
|
||||
virtual RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) = 0;
|
||||
|
@ -191,9 +192,10 @@ class CDMProxy {
|
|||
virtual void OnDecrypted(uint32_t aId, DecryptStatus aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) = 0;
|
||||
|
||||
// Reject promise with DOMException corresponding to aExceptionCode.
|
||||
// Reject promise with the given ErrorResult.
|
||||
//
|
||||
// Can be called from any thread.
|
||||
virtual void RejectPromise(PromiseId aId, nsresult aExceptionCode,
|
||||
virtual void RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) = 0;
|
||||
|
||||
// Resolves promise with "undefined".
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
|
||||
#include "mozilla/dom/MediaKeyMessageEventBinding.h" // For MediaKeyMessageType
|
||||
#include "mozilla/CDMProxy.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
class DecryptorProxyCallback {
|
||||
public:
|
||||
|
@ -24,7 +25,8 @@ class DecryptorProxyCallback {
|
|||
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId, nsresult aException,
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
mozilla::ErrorResult&& aException,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void SessionMessage(const nsCString& aSessionId,
|
||||
|
|
|
@ -254,16 +254,17 @@ already_AddRefed<DetailedPromise> MediaKeys::RetrievePromise(PromiseId aId) {
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
void MediaKeys::RejectPromise(PromiseId aId, nsresult aExceptionCode,
|
||||
void MediaKeys::RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) {
|
||||
uint32_t errorCodeAsInt = aException.ErrorCodeAsInt();
|
||||
EME_LOG("MediaKeys[%p]::RejectPromise(%" PRIu32 ", 0x%" PRIx32 ")", this, aId,
|
||||
static_cast<uint32_t>(aExceptionCode));
|
||||
errorCodeAsInt);
|
||||
|
||||
RefPtr<DetailedPromise> promise(RetrievePromise(aId));
|
||||
if (!promise) {
|
||||
EME_LOG("MediaKeys[%p]::RejectPromise(%" PRIu32 ", 0x%" PRIx32
|
||||
") couldn't retrieve promise! Bailing!",
|
||||
this, aId, static_cast<uint32_t>(aExceptionCode));
|
||||
this, aId, errorCodeAsInt);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -278,19 +279,14 @@ void MediaKeys::RejectPromise(PromiseId aId, nsresult aExceptionCode,
|
|||
mPromiseIdToken.Remove(aId);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_FAILED(aExceptionCode));
|
||||
if (aExceptionCode == NS_ERROR_DOM_TYPE_ERR) {
|
||||
// This is supposed to be a TypeError, not a DOMException.
|
||||
promise->MaybeRejectWithTypeError(NS_ConvertUTF8toUTF16(aReason));
|
||||
} else {
|
||||
promise->MaybeReject(aExceptionCode, aReason);
|
||||
}
|
||||
MOZ_ASSERT(aException.Failed());
|
||||
promise->MaybeReject(std::move(aException), aReason);
|
||||
|
||||
if (mCreatePromiseId == aId) {
|
||||
// Note: This will probably destroy the MediaKeys object!
|
||||
EME_LOG("MediaKeys[%p]::RejectPromise(%" PRIu32 ", 0x%" PRIx32
|
||||
") calling Release()",
|
||||
this, aId, static_cast<uint32_t>(aExceptionCode));
|
||||
this, aId, errorCodeAsInt);
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,8 +123,8 @@ class MediaKeys final : public nsIDocumentActivity,
|
|||
// list of sessions awaiting a session id.
|
||||
void ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken);
|
||||
|
||||
// Reject promise with DOMException corresponding to aExceptionCode.
|
||||
void RejectPromise(PromiseId aId, nsresult aExceptionCode,
|
||||
// Reject promise with the given exception.
|
||||
void RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason);
|
||||
// Resolves promise with "undefined".
|
||||
void ResolvePromise(PromiseId aId);
|
||||
|
|
|
@ -37,10 +37,10 @@ void MediaDrmCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId) {
|
|||
}
|
||||
|
||||
void MediaDrmCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
|
||||
nsresult aException,
|
||||
ErrorResult&& aException,
|
||||
const nsCString& aMessage) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mProxy->OnRejectPromise(aPromiseId, aException, aMessage);
|
||||
mProxy->OnRejectPromise(aPromiseId, std::move(aException), aMessage);
|
||||
}
|
||||
|
||||
void MediaDrmCDMCallbackProxy::SessionMessage(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define MediaDrmCDMCallbackProxy_h_
|
||||
|
||||
#include "mozilla/CDMProxy.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/DecryptorProxyCallback.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -26,7 +27,7 @@ class MediaDrmCDMCallbackProxy : public DecryptorProxyCallback {
|
|||
|
||||
void ResolvePromise(uint32_t aPromiseId) override;
|
||||
|
||||
void RejectPromise(uint32_t aPromiseId, nsresult aException,
|
||||
void RejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aSessionId) override;
|
||||
|
||||
void SessionMessage(const nsCString& aSessionId,
|
||||
|
@ -60,4 +61,4 @@ class MediaDrmCDMCallbackProxy : public DecryptorProxyCallback {
|
|||
};
|
||||
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -53,9 +53,9 @@ void MediaDrmCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin,
|
|||
nsresult rv =
|
||||
NS_NewNamedThread("MDCDMThread", getter_AddRefs(mOwnerThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING(
|
||||
"Couldn't create CDM thread MediaDrmCDMProxy::Init"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING(
|
||||
"Couldn't create CDM thread MediaDrmCDMProxy::Init"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ void MediaDrmCDMProxy::LoadSession(PromiseId aPromiseId,
|
|||
dom::MediaKeySessionType aSessionType,
|
||||
const nsAString& aSessionId) {
|
||||
// TODO: Implement LoadSession.
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Currently Fennec does not support LoadSession"));
|
||||
}
|
||||
|
||||
|
@ -146,8 +146,8 @@ void MediaDrmCDMProxy::CloseSession(const nsAString& aSessionId,
|
|||
void MediaDrmCDMProxy::RemoveSession(const nsAString& aSessionId,
|
||||
PromiseId aPromiseId) {
|
||||
// TODO: Implement RemoveSession.
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Currently Fennec does not support RemoveSession"));
|
||||
}
|
||||
|
||||
|
@ -242,10 +242,10 @@ void MediaDrmCDMProxy::OnSessionError(const nsAString& aSessionId,
|
|||
}
|
||||
|
||||
void MediaDrmCDMProxy::OnRejectPromise(uint32_t aPromiseId,
|
||||
nsresult aDOMException,
|
||||
ErrorResult&& aException,
|
||||
const nsCString& aMsg) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RejectPromise(aPromiseId, aDOMException, aMsg);
|
||||
RejectPromise(aPromiseId, std::move(aException), aMsg);
|
||||
}
|
||||
|
||||
RefPtr<DecryptPromise> MediaDrmCDMProxy::Decrypt(MediaRawData* aSample) {
|
||||
|
@ -258,19 +258,26 @@ void MediaDrmCDMProxy::OnDecrypted(uint32_t aId, DecryptStatus aResult,
|
|||
MOZ_ASSERT_UNREACHABLE("Fennec could not handle decrypted event");
|
||||
}
|
||||
|
||||
void MediaDrmCDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
|
||||
void MediaDrmCDMProxy::RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) {
|
||||
if (NS_IsMainThread()) {
|
||||
if (!mKeys.IsNull()) {
|
||||
mKeys->RejectPromise(aId, aCode, aReason);
|
||||
mKeys->RejectPromise(aId, std::move(aException), aReason);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> task(
|
||||
new RejectPromiseTask(this, aId, aCode, aReason));
|
||||
new RejectPromiseTask(this, aId, std::move(aException), aReason));
|
||||
mMainThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDrmCDMProxy::RejectPromiseWithStateError(PromiseId aId,
|
||||
const nsCString& aReason) {
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(aReason);
|
||||
RejectPromise(aId, std::move(rv), aReason);
|
||||
}
|
||||
|
||||
void MediaDrmCDMProxy::ResolvePromise(PromiseId aId) {
|
||||
if (NS_IsMainThread()) {
|
||||
if (!mKeys.IsNull()) {
|
||||
|
@ -324,9 +331,11 @@ void MediaDrmCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId) {
|
|||
void MediaDrmCDMProxy::GetStatusForPolicy(PromiseId aPromiseId,
|
||||
const nsAString& aMinHdcpVersion) {
|
||||
// TODO: Implement GetStatusForPolicy.
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_NOT_SUPPORTED_ERR,
|
||||
NS_LITERAL_CSTRING(
|
||||
"Currently Fennec does not support GetStatusForPolicy"));
|
||||
NS_NAMED_LITERAL_CSTRING(
|
||||
err, "Currently Fennec does not support GetStatusForPolicy");
|
||||
ErrorResult rv;
|
||||
rv.ThrowNotSupportedError(err);
|
||||
RejectPromise(aPromiseId, std::move(rv), err);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -352,8 +361,10 @@ void MediaDrmCDMProxy::OnCDMCreated(uint32_t aPromiseId) {
|
|||
}
|
||||
|
||||
// No CDM? Just reject the promise.
|
||||
mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
|
||||
NS_NAMED_LITERAL_CSTRING(err, "Null CDM in OnCDMCreated()");
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(err);
|
||||
mKeys->RejectPromise(aPromiseId, std::move(rv), err);
|
||||
}
|
||||
|
||||
void MediaDrmCDMProxy::md_Init(uint32_t aPromiseId) {
|
||||
|
@ -372,8 +383,8 @@ void MediaDrmCDMProxy::md_CreateSession(UniquePtr<CreateSessionData>&& aData) {
|
|||
MOZ_ASSERT(IsOnOwnerThread());
|
||||
|
||||
if (!mCDM) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in md_CreateSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aData->mPromiseId, NS_LITERAL_CSTRING("Null CDM in md_CreateSession"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -387,17 +398,17 @@ void MediaDrmCDMProxy::md_SetServerCertificate(PromiseId aPromiseId,
|
|||
MOZ_ASSERT(IsOnOwnerThread());
|
||||
|
||||
if (!mCDM) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in md_SetServerCertificate"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in md_SetServerCertificate"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCDM->SetServerCertificate(aCert)) {
|
||||
ResolvePromiseWithResult(aPromiseId, true);
|
||||
} else {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING(
|
||||
"MediaDrmCDMProxy unable to set server certificate"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING(
|
||||
"MediaDrmCDMProxy unable to set server certificate"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,8 +416,8 @@ void MediaDrmCDMProxy::md_UpdateSession(UniquePtr<UpdateSessionData>&& aData) {
|
|||
MOZ_ASSERT(IsOnOwnerThread());
|
||||
|
||||
if (!mCDM) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in md_UpdateSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aData->mPromiseId, NS_LITERAL_CSTRING("Null CDM in md_UpdateSession"));
|
||||
return;
|
||||
}
|
||||
mCDM->UpdateSession(aData->mPromiseId, aData->mSessionId, aData->mResponse);
|
||||
|
@ -416,8 +427,8 @@ void MediaDrmCDMProxy::md_CloseSession(UniquePtr<SessionOpData>&& aData) {
|
|||
MOZ_ASSERT(IsOnOwnerThread());
|
||||
|
||||
if (!mCDM) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in md_CloseSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aData->mPromiseId, NS_LITERAL_CSTRING("Null CDM in md_CloseSession"));
|
||||
return;
|
||||
}
|
||||
mCDM->CloseSession(aData->mPromiseId, aData->mSessionId);
|
||||
|
|
|
@ -78,15 +78,17 @@ class MediaDrmCDMProxy : public CDMProxy {
|
|||
void OnSessionError(const nsAString& aSessionId, nsresult aException,
|
||||
uint32_t aSystemCode, const nsAString& aMsg) override;
|
||||
|
||||
void OnRejectPromise(uint32_t aPromiseId, nsresult aCode,
|
||||
void OnRejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aMsg) override;
|
||||
|
||||
RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) override;
|
||||
void OnDecrypted(uint32_t aId, DecryptStatus aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) override;
|
||||
|
||||
void RejectPromise(PromiseId aId, nsresult aCode,
|
||||
void RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) override;
|
||||
// Reject promise with an InvalidStateError and the given message.
|
||||
void RejectPromiseWithStateError(PromiseId aId, const nsCString& aReason);
|
||||
|
||||
// Resolves promise with "undefined".
|
||||
// Can be called from any thread.
|
||||
|
@ -137,22 +139,32 @@ class MediaDrmCDMProxy : public CDMProxy {
|
|||
|
||||
class RejectPromiseTask : public Runnable {
|
||||
public:
|
||||
RejectPromiseTask(MediaDrmCDMProxy* aProxy, PromiseId aId, nsresult aCode,
|
||||
const nsCString& aReason)
|
||||
RejectPromiseTask(MediaDrmCDMProxy* aProxy, PromiseId aId,
|
||||
ErrorResult&& aException, const nsCString& aReason)
|
||||
: Runnable("RejectPromiseTask"),
|
||||
mProxy(aProxy),
|
||||
mId(aId),
|
||||
mCode(aCode),
|
||||
mException(std::move(aException)),
|
||||
mReason(aReason) {}
|
||||
NS_IMETHOD Run() override {
|
||||
mProxy->RejectPromise(mId, mCode, mReason);
|
||||
// Moving into or out of a non-copyable ErrorResult will assert that both
|
||||
// ErorResults are from our current thread. Avoid the assertion by moving
|
||||
// into a current-thread CopyableErrorResult first. Note that this is
|
||||
// safe, because CopyableErrorResult never holds state that can't move
|
||||
// across threads.
|
||||
CopyableErrorResult rv(std::move(mException));
|
||||
mProxy->RejectPromise(mId, std::move(rv), mReason);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<MediaDrmCDMProxy> mProxy;
|
||||
PromiseId mId;
|
||||
nsresult mCode;
|
||||
// We use a CopyableErrorResult here, because we're going to dispatch to a
|
||||
// different thread and normal ErrorResult doesn't support that.
|
||||
// CopyableErrorResult ensures that it only stores values that are safe to
|
||||
// move across threads.
|
||||
CopyableErrorResult mException;
|
||||
nsCString mReason;
|
||||
};
|
||||
|
||||
|
|
|
@ -183,8 +183,9 @@ void MediaDrmJavaCallbacksSupport::OnRejectPromise(
|
|||
// Current implementation assume all the reject from MediaDrm is due to
|
||||
// invalid state. Other cases should be handled before calling into
|
||||
// MediaDrmProxy API.
|
||||
mDecryptorProxyCallback->RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, reason);
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(reason);
|
||||
mDecryptorProxyCallback->RejectPromise(aPromiseId, std::move(rv), reason);
|
||||
}
|
||||
|
||||
MediaDrmProxySupport::MediaDrmProxySupport(const nsAString& aKeySystem)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define ChromiumCDMCallback_h_
|
||||
|
||||
#include "mozilla/CDMProxy.h"
|
||||
#include "mozilla/ErrorResult.h" // For ErrorResult
|
||||
#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
|
||||
#include "mozilla/dom/MediaKeyMessageEventBinding.h" // For MediaKeyMessageType
|
||||
#include "mozilla/gmp/GMPTypes.h" // For CDMKeyInformation
|
||||
|
@ -26,7 +27,7 @@ class ChromiumCDMCallback {
|
|||
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId, nsresult aError,
|
||||
virtual void RejectPromise(uint32_t aPromiseId, mozilla::ErrorResult&& aError,
|
||||
const nsCString& aErrorMessage) = 0;
|
||||
|
||||
virtual void SessionMessage(const nsACString& aSessionId,
|
||||
|
|
|
@ -41,11 +41,16 @@ void ChromiumCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId) {
|
|||
}
|
||||
|
||||
void ChromiumCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
|
||||
nsresult aException,
|
||||
ErrorResult&& aException,
|
||||
const nsCString& aErrorMessage) {
|
||||
DispatchToMainThread("ChromiumCDMProxy::RejectPromise",
|
||||
&ChromiumCDMProxy::RejectPromise, aPromiseId, aException,
|
||||
aErrorMessage);
|
||||
// Use CopyableErrorResult to store our exception in the runnable,
|
||||
// because ErrorResult is not OK to move across threads.
|
||||
DispatchToMainThread<decltype(&ChromiumCDMProxy::RejectPromiseOnMainThread),
|
||||
int32_t, StoreCopyPassByRRef<CopyableErrorResult>,
|
||||
const nsCString&>(
|
||||
"ChromiumCDMProxy::RejectPromise",
|
||||
&ChromiumCDMProxy::RejectPromiseOnMainThread, aPromiseId,
|
||||
std::move(aException), aErrorMessage);
|
||||
}
|
||||
|
||||
static dom::MediaKeyMessageType ToDOMMessageType(uint32_t aMessageType) {
|
||||
|
|
|
@ -28,7 +28,7 @@ class ChromiumCDMCallbackProxy : public ChromiumCDMCallback {
|
|||
|
||||
void ResolvePromise(uint32_t aPromiseId) override;
|
||||
|
||||
void RejectPromise(uint32_t aPromiseId, nsresult aException,
|
||||
void RejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aErrorMessage) override;
|
||||
|
||||
void SessionMessage(const nsACString& aSessionId, uint32_t aMessageType,
|
||||
|
|
|
@ -122,14 +122,13 @@ void ChromiumCDMParent::CreateSession(uint32_t aCreateSessionToken,
|
|||
const nsTArray<uint8_t>& aInitData) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::CreateSession(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendCreateSessionAndGenerateRequest(aPromiseId, aSessionType,
|
||||
aInitDataType, aInitData)) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send generateRequest to CDM process."));
|
||||
return;
|
||||
}
|
||||
|
@ -142,14 +141,13 @@ void ChromiumCDMParent::LoadSession(uint32_t aPromiseId, uint32_t aSessionType,
|
|||
"ChromiumCDMParent::LoadSession(this=%p, pid=%u, type=%u, sid=%s)", this,
|
||||
aPromiseId, aSessionType, NS_ConvertUTF16toUTF8(aSessionId).get());
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendLoadSession(aPromiseId, aSessionType,
|
||||
NS_ConvertUTF16toUTF8(aSessionId))) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send loadSession to CDM process."));
|
||||
return;
|
||||
}
|
||||
|
@ -159,14 +157,13 @@ void ChromiumCDMParent::SetServerCertificate(uint32_t aPromiseId,
|
|||
const nsTArray<uint8_t>& aCert) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::SetServerCertificate(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendSetServerCertificate(aPromiseId, aCert)) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING(
|
||||
"Failed to send setServerCertificate to CDM process"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING(
|
||||
"Failed to send setServerCertificate to CDM process"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,13 +172,12 @@ void ChromiumCDMParent::UpdateSession(const nsCString& aSessionId,
|
|||
const nsTArray<uint8_t>& aResponse) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::UpdateSession(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendUpdateSession(aPromiseId, aSessionId, aResponse)) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send updateSession to CDM process"));
|
||||
}
|
||||
}
|
||||
|
@ -190,13 +186,12 @@ void ChromiumCDMParent::CloseSession(const nsCString& aSessionId,
|
|||
uint32_t aPromiseId) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::CloseSession(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendCloseSession(aPromiseId, aSessionId)) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send closeSession to CDM process"));
|
||||
}
|
||||
}
|
||||
|
@ -205,13 +200,12 @@ void ChromiumCDMParent::RemoveSession(const nsCString& aSessionId,
|
|||
uint32_t aPromiseId) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::RemoveSession(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
if (!SendRemoveSession(aPromiseId, aSessionId)) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send removeSession to CDM process"));
|
||||
}
|
||||
}
|
||||
|
@ -258,22 +252,26 @@ void ChromiumCDMParent::GetStatusForPolicy(uint32_t aPromiseId,
|
|||
const nsCString& aMinHdcpVersion) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::GetStatusForPolicy(this=%p)", this);
|
||||
if (mIsShutdown) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown."));
|
||||
RejectPromiseShutdown(aPromiseId);
|
||||
return;
|
||||
}
|
||||
auto hdcpVersionResult = ToCDMHdcpVersion(aMinHdcpVersion);
|
||||
if (hdcpVersionResult.isErr()) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_INVALID_ARG,
|
||||
NS_LITERAL_CSTRING(
|
||||
"getStatusForPolicy failed due to bad hdcp version argument"));
|
||||
ErrorResult rv;
|
||||
// XXXbz there's no spec for this yet, and
|
||||
// <https://github.com/WICG/hdcp-detection/blob/master/explainer.md>
|
||||
// does not define what exceptions get thrown. Let's assume
|
||||
// TypeError for invalid args, as usual.
|
||||
NS_NAMED_LITERAL_CSTRING(
|
||||
err, "getStatusForPolicy failed due to bad hdcp version argument");
|
||||
rv.ThrowTypeError(NS_ConvertUTF8toUTF16(err));
|
||||
RejectPromise(aPromiseId, std::move(rv), err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SendGetStatusForPolicy(aPromiseId, hdcpVersionResult.unwrap())) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Failed to send getStatusForPolicy to CDM process"));
|
||||
}
|
||||
}
|
||||
|
@ -414,8 +412,8 @@ ipc::IPCResult ChromiumCDMParent::RecvOnResolveNewSessionPromise(
|
|||
|
||||
Maybe<uint32_t> token = mPromiseToCreateSessionToken.GetAndRemove(aPromiseId);
|
||||
if (token.isNothing()) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Lost session token for new session."));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Lost session token for new session."));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -460,7 +458,8 @@ ipc::IPCResult ChromiumCDMParent::RecvOnResolvePromise(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void ChromiumCDMParent::RejectPromise(uint32_t aPromiseId, nsresult aException,
|
||||
void ChromiumCDMParent::RejectPromise(uint32_t aPromiseId,
|
||||
ErrorResult&& aException,
|
||||
const nsCString& aErrorMessage) {
|
||||
GMP_LOG_DEBUG("ChromiumCDMParent::RejectPromise(this=%p, pid=%u)", this,
|
||||
aPromiseId);
|
||||
|
@ -470,28 +469,52 @@ void ChromiumCDMParent::RejectPromise(uint32_t aPromiseId, nsresult aException,
|
|||
return;
|
||||
}
|
||||
|
||||
mCDMCallback->RejectPromise(aPromiseId, aException, aErrorMessage);
|
||||
mCDMCallback->RejectPromise(aPromiseId, std::move(aException), aErrorMessage);
|
||||
}
|
||||
|
||||
static nsresult ToNsresult(uint32_t aException) {
|
||||
void ChromiumCDMParent::RejectPromiseShutdown(uint32_t aPromiseId) {
|
||||
RejectPromiseWithStateError(aPromiseId,
|
||||
NS_LITERAL_CSTRING("CDM is shutdown"));
|
||||
}
|
||||
|
||||
void ChromiumCDMParent::RejectPromiseWithStateError(
|
||||
uint32_t aPromiseId, const nsCString& aErrorMessage) {
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(aErrorMessage);
|
||||
RejectPromise(aPromiseId, std::move(rv), aErrorMessage);
|
||||
}
|
||||
|
||||
static ErrorResult ToErrorResult(uint32_t aException,
|
||||
const nsCString& aErrorMessage) {
|
||||
// XXXbz could we have a CopyableErrorResult sent to us with a better error
|
||||
// message?
|
||||
ErrorResult rv;
|
||||
switch (static_cast<cdm::Exception>(aException)) {
|
||||
case cdm::Exception::kExceptionNotSupportedError:
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
rv.ThrowNotSupportedError(aErrorMessage);
|
||||
break;
|
||||
case cdm::Exception::kExceptionInvalidStateError:
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
rv.ThrowInvalidStateError(aErrorMessage);
|
||||
break;
|
||||
case cdm::Exception::kExceptionTypeError:
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
rv.ThrowTypeError(NS_ConvertUTF8toUTF16(aErrorMessage));
|
||||
break;
|
||||
case cdm::Exception::kExceptionQuotaExceededError:
|
||||
return NS_ERROR_DOM_QUOTA_EXCEEDED_ERR;
|
||||
rv.ThrowQuotaExceededError(aErrorMessage);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid cdm::Exception enum value.");
|
||||
// Note: Unique placeholder.
|
||||
rv.ThrowTimeoutError(aErrorMessage);
|
||||
};
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid cdm::Exception enum value.");
|
||||
return NS_ERROR_DOM_TIMEOUT_ERR; // Note: Unique placeholder.
|
||||
return rv;
|
||||
}
|
||||
|
||||
ipc::IPCResult ChromiumCDMParent::RecvOnRejectPromise(
|
||||
const uint32_t& aPromiseId, const uint32_t& aException,
|
||||
const uint32_t& aSystemCode, const nsCString& aErrorMessage) {
|
||||
RejectPromise(aPromiseId, ToNsresult(aException), aErrorMessage);
|
||||
RejectPromise(aPromiseId, ToErrorResult(aException, aErrorMessage),
|
||||
aErrorMessage);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsDataHashtable.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "ReorderQueue.h"
|
||||
|
||||
|
@ -130,10 +131,16 @@ class ChromiumCDMParent final : public PChromiumCDMParent,
|
|||
|
||||
void ReorderAndReturnOutput(RefPtr<VideoData>&& aFrame);
|
||||
|
||||
void RejectPromise(uint32_t aPromiseId, nsresult aError,
|
||||
void RejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aErrorMessage);
|
||||
|
||||
void ResolvePromise(uint32_t aPromiseId);
|
||||
// Helpers to reject our promise if we are shut down.
|
||||
void RejectPromiseShutdown(uint32_t aPromiseId);
|
||||
// Helper to reject our promise with an InvalidStateError and the given
|
||||
// message.
|
||||
void RejectPromiseWithStateError(uint32_t aPromiseId,
|
||||
const nsCString& aErrorMessage);
|
||||
|
||||
bool InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample);
|
||||
|
||||
|
|
|
@ -52,16 +52,16 @@ void ChromiumCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin,
|
|||
NS_ConvertUTF16toUTF8(aGMPName).get());
|
||||
|
||||
if (!mGMPThread) {
|
||||
RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Couldn't get GMP thread ChromiumCDMProxy::Init"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (aGMPName.IsEmpty()) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
nsPrintfCString("Unknown GMP for keysystem '%s'",
|
||||
NS_ConvertUTF16toUTF8(mKeySystem).get()));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, nsPrintfCString("Unknown GMP for keysystem '%s'",
|
||||
NS_ConvertUTF16toUTF8(mKeySystem).get()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,8 @@ void ChromiumCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin,
|
|||
RefPtr<gmp::GeckoMediaPluginService> service =
|
||||
gmp::GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
if (!service) {
|
||||
self->RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
self->RejectPromiseWithStateError(
|
||||
aPromiseId,
|
||||
NS_LITERAL_CSTRING("Couldn't get GeckoMediaPluginService in "
|
||||
"ChromiumCDMProxy::Init"));
|
||||
return;
|
||||
|
@ -103,11 +103,10 @@ void ChromiumCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin,
|
|||
self->mCDM = cdm;
|
||||
}
|
||||
if (self->mIsShutdown) {
|
||||
self->RejectPromise(
|
||||
aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING(
|
||||
"ChromiumCDMProxy shutdown during "
|
||||
"ChromiumCDMProxy::Init"));
|
||||
self->RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING(
|
||||
"ChromiumCDMProxy shutdown "
|
||||
"during ChromiumCDMProxy::Init"));
|
||||
// If shutdown happened while waiting to init, we
|
||||
// need to explicitly shutdown the CDM to avoid it
|
||||
// referencing this proxy which is on its way out.
|
||||
|
@ -117,14 +116,25 @@ void ChromiumCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin,
|
|||
self->OnCDMCreated(aPromiseId);
|
||||
},
|
||||
[self, aPromiseId](MediaResult aResult) {
|
||||
// CDM init failed
|
||||
self->RejectPromise(aPromiseId, aResult.Code(),
|
||||
// CDM init failed.
|
||||
ErrorResult rv;
|
||||
// XXXbz MediaResult should really store a
|
||||
// CopyableErrorResult or something. See
|
||||
// <https://bugzilla.mozilla.org/show_bug.cgi?id=1612216>.
|
||||
rv.Throw(aResult.Code());
|
||||
self->RejectPromise(aPromiseId, std::move(rv),
|
||||
aResult.Message());
|
||||
});
|
||||
},
|
||||
[self, aPromiseId](MediaResult rv) {
|
||||
// service->GetCDM failed
|
||||
self->RejectPromise(aPromiseId, rv.Code(), rv.Description());
|
||||
ErrorResult result;
|
||||
// XXXbz MediaResult should really store a CopyableErrorResult or
|
||||
// something. See
|
||||
// <https://bugzilla.mozilla.org/show_bug.cgi?id=1612216>.
|
||||
result.Throw(rv.Code());
|
||||
self->RejectPromise(aPromiseId, std::move(result),
|
||||
rv.Description());
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -146,8 +156,10 @@ void ChromiumCDMProxy::OnCDMCreated(uint32_t aPromiseId) {
|
|||
mKeys->OnCDMCreated(aPromiseId, cdm->PluginId());
|
||||
} else {
|
||||
// No CDM? Shouldn't be possible, but reject the promise anyway...
|
||||
mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
|
||||
NS_NAMED_LITERAL_CSTRING(err, "Null CDM in OnCDMCreated()");
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(err);
|
||||
mKeys->RejectPromise(aPromiseId, std::move(rv), err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,8 +234,8 @@ void ChromiumCDMProxy::CreateSession(uint32_t aCreateSessionToken,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in CreateSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in CreateSession"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -241,8 +253,8 @@ void ChromiumCDMProxy::LoadSession(PromiseId aPromiseId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in LoadSession"));
|
||||
RejectPromiseWithStateError(aPromiseId,
|
||||
NS_LITERAL_CSTRING("Null CDM in LoadSession"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,8 +273,8 @@ void ChromiumCDMProxy::SetServerCertificate(PromiseId aPromiseId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in SetServerCertificate"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in SetServerCertificate"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -284,8 +296,8 @@ void ChromiumCDMProxy::UpdateSession(const nsAString& aSessionId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in UpdateSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in UpdateSession"));
|
||||
return;
|
||||
}
|
||||
mGMPThread->Dispatch(
|
||||
|
@ -303,8 +315,8 @@ void ChromiumCDMProxy::CloseSession(const nsAString& aSessionId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in CloseSession"));
|
||||
RejectPromiseWithStateError(aPromiseId,
|
||||
NS_LITERAL_CSTRING("Null CDM in CloseSession"));
|
||||
return;
|
||||
}
|
||||
mGMPThread->Dispatch(NewRunnableMethod<nsCString, uint32_t>(
|
||||
|
@ -321,8 +333,8 @@ void ChromiumCDMProxy::RemoveSession(const nsAString& aSessionId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in RemoveSession"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in RemoveSession"));
|
||||
return;
|
||||
}
|
||||
mGMPThread->Dispatch(NewRunnableMethod<nsCString, uint32_t>(
|
||||
|
@ -343,25 +355,47 @@ void ChromiumCDMProxy::Shutdown() {
|
|||
ShutdownCDMIfExists();
|
||||
}
|
||||
|
||||
void ChromiumCDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
|
||||
void ChromiumCDMProxy::RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) {
|
||||
if (!NS_IsMainThread()) {
|
||||
// Use CopyableErrorResult to store our exception in the runnable,
|
||||
// because ErrorResult is not OK to move across threads.
|
||||
mMainThread->Dispatch(
|
||||
NewRunnableMethod<PromiseId, nsresult, nsCString>(
|
||||
NewRunnableMethod<PromiseId, StoreCopyPassByRRef<CopyableErrorResult>,
|
||||
nsCString>(
|
||||
"ChromiumCDMProxy::RejectPromise", this,
|
||||
&ChromiumCDMProxy::RejectPromise, aId, aCode, aReason),
|
||||
&ChromiumCDMProxy::RejectPromiseOnMainThread, aId,
|
||||
std::move(aException), aReason),
|
||||
NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
EME_LOG("ChromiumCDMProxy::RejectPromise(this=%p, pid=%" PRIu32
|
||||
", code=0x%x, "
|
||||
"reason='%s')",
|
||||
this, aId, static_cast<uint32_t>(aCode), aReason.get());
|
||||
this, aId, aException.ErrorCodeAsInt(), aReason.get());
|
||||
if (!mKeys.IsNull()) {
|
||||
mKeys->RejectPromise(aId, aCode, aReason);
|
||||
mKeys->RejectPromise(aId, std::move(aException), aReason);
|
||||
}
|
||||
}
|
||||
|
||||
void ChromiumCDMProxy::RejectPromiseWithStateError(PromiseId aId,
|
||||
const nsCString& aReason) {
|
||||
ErrorResult rv;
|
||||
rv.ThrowInvalidStateError(aReason);
|
||||
RejectPromise(aId, std::move(rv), aReason);
|
||||
}
|
||||
|
||||
void ChromiumCDMProxy::RejectPromiseOnMainThread(
|
||||
PromiseId aId, CopyableErrorResult&& aException, const nsCString& aReason) {
|
||||
// Moving into or out of a non-copyable ErrorResult will assert that both
|
||||
// ErorResults are from our current thread. Avoid the assertion by moving
|
||||
// into a current-thread CopyableErrorResult first. Note that this is safe,
|
||||
// because CopyableErrorResult never holds state that can't move across
|
||||
// threads.
|
||||
CopyableErrorResult rv(std::move(aException));
|
||||
RejectPromise(aId, std::move(rv), aReason);
|
||||
}
|
||||
|
||||
void ChromiumCDMProxy::ResolvePromise(PromiseId aId) {
|
||||
if (!NS_IsMainThread()) {
|
||||
mMainThread->Dispatch(
|
||||
|
@ -494,10 +528,10 @@ void ChromiumCDMProxy::OnSessionError(const nsAString& aSessionId,
|
|||
}
|
||||
|
||||
void ChromiumCDMProxy::OnRejectPromise(uint32_t aPromiseId,
|
||||
nsresult aDOMException,
|
||||
ErrorResult&& aException,
|
||||
const nsCString& aMsg) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RejectPromise(aPromiseId, aDOMException, aMsg);
|
||||
RejectPromise(aPromiseId, std::move(aException), aMsg);
|
||||
}
|
||||
|
||||
const nsString& ChromiumCDMProxy::KeySystem() const { return mKeySystem; }
|
||||
|
@ -524,8 +558,8 @@ void ChromiumCDMProxy::GetStatusForPolicy(PromiseId aPromiseId,
|
|||
|
||||
RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
|
||||
if (!cdm) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
NS_LITERAL_CSTRING("Null CDM in GetStatusForPolicy"));
|
||||
RejectPromiseWithStateError(
|
||||
aPromiseId, NS_LITERAL_CSTRING("Null CDM in GetStatusForPolicy"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define ChromiumCDMProxy_h_
|
||||
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/CDMProxy.h"
|
||||
#include "ChromiumCDMParent.h"
|
||||
|
||||
|
@ -71,7 +72,7 @@ class ChromiumCDMProxy : public CDMProxy {
|
|||
void OnSessionError(const nsAString& aSessionId, nsresult aException,
|
||||
uint32_t aSystemCode, const nsAString& aMsg) override;
|
||||
|
||||
void OnRejectPromise(uint32_t aPromiseId, nsresult aDOMException,
|
||||
void OnRejectPromise(uint32_t aPromiseId, ErrorResult&& aException,
|
||||
const nsCString& aMsg) override;
|
||||
|
||||
RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) override;
|
||||
|
@ -79,8 +80,14 @@ class ChromiumCDMProxy : public CDMProxy {
|
|||
void OnDecrypted(uint32_t aId, DecryptStatus aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) override;
|
||||
|
||||
void RejectPromise(PromiseId aId, nsresult aExceptionCode,
|
||||
void RejectPromise(PromiseId aId, ErrorResult&& aException,
|
||||
const nsCString& aReason) override;
|
||||
// Reject promise with an InvalidStateError and the given message.
|
||||
void RejectPromiseWithStateError(PromiseId aId, const nsCString& aReason);
|
||||
// For use for moving rejections from off-main thread.
|
||||
void RejectPromiseOnMainThread(PromiseId aId,
|
||||
CopyableErrorResult&& aException,
|
||||
const nsCString& aReason);
|
||||
|
||||
void ResolvePromise(PromiseId aId) override;
|
||||
|
||||
|
|
|
@ -1000,7 +1000,7 @@ class CDMStorageTest {
|
|||
|
||||
void ResolvePromise(uint32_t aPromiseId) override {}
|
||||
|
||||
void RejectPromise(uint32_t aPromiseId, nsresult aError,
|
||||
void RejectPromise(uint32_t aPromiseId, ErrorResult&& aError,
|
||||
const nsCString& aErrorMessage) override {}
|
||||
|
||||
void SessionMessage(const nsACString& aSessionId, uint32_t aMessageType,
|
||||
|
|
Загрузка…
Ссылка в новой задаче