new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMCallback.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ChromiumCDMCallback_h_
+#define ChromiumCDMCallback_h_
+
+#include "mozilla/CDMProxy.h"
+#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
+#include "mozilla/dom/MediaKeyMessageEventBinding.h" // For MediaKeyMessageType
+#include "mozilla/gmp/GMPTypes.h" // For CDMKeyInformation
+
+class ChromiumCDMCallback {
+public:
+
+ virtual ~ChromiumCDMCallback() {}
+
+ virtual void SetSessionId(uint32_t aPromiseId,
+ const nsCString& aSessionId) = 0;
+
+ virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
+ bool aSuccessful) = 0;
+
+ virtual void ResolvePromise(uint32_t aPromiseId) = 0;
+
+ virtual void RejectPromise(uint32_t aPromiseId,
+ nsresult aError,
+ const nsCString& aErrorMessage) = 0;
+
+ virtual void SessionMessage(const nsACString& aSessionId,
+ uint32_t aMessageType,
+ nsTArray<uint8_t>&& aMessage) = 0;
+
+ virtual void SessionKeysChange(const nsCString& aSessionId,
+ nsTArray<mozilla::gmp::CDMKeyInformation>&& aKeysInfo) = 0;
+
+ virtual void ExpirationChange(const nsCString& aSessionId,
+ double aSecondsSinceEpoch) = 0;
+
+ virtual void SessionClosed(const nsCString& aSessionId) = 0;
+
+ virtual void LegacySessionError(const nsCString& aSessionId,
+ nsresult aError,
+ uint32_t aSystemCode,
+ const nsCString& aMessage) = 0;
+ virtual void Terminated() = 0;
+
+ virtual void Shutdown() = 0;
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMCallbackProxy.cpp
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ChromiumCDMCallbackProxy.h"
+
+#include "ChromiumCDMProxy.h"
+#include "content_decryption_module.h"
+
+namespace mozilla {
+
+template<class Func, class... Args>
+void ChromiumCDMCallbackProxy::DispatchToMainThread(const char* const aLabel,
+ Func aFunc,
+ Args&&... aArgs)
+{
+ mMainThread->Dispatch(
+ // Use Decay to ensure all the types are passed by value not by reference.
+ NewRunnableMethod<typename Decay<Args>::Type...>(
+ aLabel,
+ mProxy,
+ aFunc,
+ Forward<Args>(aArgs)...),
+ NS_DISPATCH_NORMAL);
+}
+
+void
+ChromiumCDMCallbackProxy::SetSessionId(uint32_t aPromiseId,
+ const nsCString& aSessionId)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnSetSessionId",
+ &ChromiumCDMProxy::OnSetSessionId,
+ aPromiseId,
+ NS_ConvertUTF8toUTF16(aSessionId));
+}
+
+void
+ChromiumCDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId,
+ bool aSuccessful)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnResolveLoadSessionPromise",
+ &ChromiumCDMProxy::OnResolveLoadSessionPromise,
+ aPromiseId,
+ aSuccessful);
+}
+
+void
+ChromiumCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId)
+{
+ DispatchToMainThread("ChromiumCDMProxy::ResolvePromise",
+ &ChromiumCDMProxy::ResolvePromise,
+ aPromiseId);
+}
+
+void
+ChromiumCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
+ nsresult aError,
+ const nsCString& aErrorMessage)
+{
+ DispatchToMainThread("ChromiumCDMProxy::RejectPromise",
+ &ChromiumCDMProxy::RejectPromise,
+ aPromiseId,
+ aError,
+ aErrorMessage);
+}
+
+
+static dom::MediaKeyMessageType
+ToDOMMessageType(uint32_t aMessageType)
+{
+ switch (static_cast<cdm::MessageType>(aMessageType)) {
+ case cdm::kLicenseRequest:
+ return dom::MediaKeyMessageType::License_request;
+ case cdm::kLicenseRenewal:
+ return dom::MediaKeyMessageType::License_renewal;
+ case cdm::kLicenseRelease:
+ return dom::MediaKeyMessageType::License_release;
+ }
+ MOZ_ASSERT_UNREACHABLE("Invalid cdm::MessageType enum value.");
+ return dom::MediaKeyMessageType::License_request;
+}
+
+void
+ChromiumCDMCallbackProxy::SessionMessage(const nsACString& aSessionId,
+ uint32_t aMessageType,
+ nsTArray<uint8_t>&& aMessage)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnSessionMessage",
+ &ChromiumCDMProxy::OnSessionMessage,
+ NS_ConvertUTF8toUTF16(aSessionId),
+ ToDOMMessageType(aMessageType),
+ Move(aMessage));
+}
+
+static dom::MediaKeyStatus
+ToDOMMediaKeyStatus(uint32_t aStatus)
+{
+ switch (static_cast<cdm::KeyStatus>(aStatus)) {
+ case cdm::kUsable:
+ return dom::MediaKeyStatus::Usable;
+ case cdm::kInternalError:
+ return dom::MediaKeyStatus::Internal_error;
+ case cdm::kExpired:
+ return dom::MediaKeyStatus::Expired;
+ case cdm::kOutputRestricted:
+ return dom::MediaKeyStatus::Output_restricted;
+ case cdm::kOutputDownscaled:
+ return dom::MediaKeyStatus::Output_downscaled;
+ case cdm::kStatusPending:
+ return dom::MediaKeyStatus::Status_pending;
+ case cdm::kReleased:
+ return dom::MediaKeyStatus::Released;
+ }
+ MOZ_ASSERT_UNREACHABLE("Invalid cdm::KeyStatus enum value.");
+ return dom::MediaKeyStatus::Internal_error;
+}
+
+void
+ChromiumCDMCallbackProxy::SessionKeysChange(const nsCString& aSessionId,
+ nsTArray<mozilla::gmp::CDMKeyInformation> && aKeysInfo)
+{
+ bool keyStatusesChange = false;
+ {
+ CDMCaps::AutoLock caps(mProxy->Capabilites());
+ for (const auto& keyInfo : aKeysInfo) {
+ keyStatusesChange |=
+ caps.SetKeyStatus(keyInfo.mKeyId(),
+ NS_ConvertUTF8toUTF16(aSessionId),
+ dom::Optional<dom::MediaKeyStatus>(
+ ToDOMMediaKeyStatus(keyInfo.mStatus())));
+ }
+ }
+ if (keyStatusesChange) {
+ DispatchToMainThread("ChromiumCDMProxy::OnKeyStatusesChange",
+ &ChromiumCDMProxy::OnKeyStatusesChange,
+ NS_ConvertUTF8toUTF16(aSessionId));
+ }
+}
+
+void
+ChromiumCDMCallbackProxy::ExpirationChange(const nsCString& aSessionId,
+ double aSecondsSinceEpoch)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnExpirationChange",
+ &ChromiumCDMProxy::OnExpirationChange,
+ NS_ConvertUTF8toUTF16(aSessionId),
+ UnixTime(aSecondsSinceEpoch * 1000));
+
+}
+
+void
+ChromiumCDMCallbackProxy::SessionClosed(const nsCString& aSessionId)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnSessionClosed",
+ &ChromiumCDMProxy::OnSessionClosed ,
+ NS_ConvertUTF8toUTF16(aSessionId));
+}
+
+void
+ChromiumCDMCallbackProxy::LegacySessionError(const nsCString& aSessionId,
+ nsresult aError,
+ uint32_t aSystemCode,
+ const nsCString& aMessage)
+{
+ DispatchToMainThread("ChromiumCDMProxy::OnSessionError",
+ &ChromiumCDMProxy::OnSessionError ,
+ NS_ConvertUTF8toUTF16(aSessionId),
+ aError,
+ aSystemCode,
+ NS_ConvertUTF8toUTF16(aMessage));
+}
+
+void
+ChromiumCDMCallbackProxy::Terminated()
+{
+ DispatchToMainThread("ChromiumCDMProxy::Terminated",
+ &ChromiumCDMProxy::Terminated);
+}
+
+void
+ChromiumCDMCallbackProxy::Shutdown()
+{
+ DispatchToMainThread("ChromiumCDMProxy::Shutdown",
+ &ChromiumCDMProxy::Shutdown);
+}
+
+} //namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMCallbackProxy.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ChromiumCDMCallbackProxy_h_
+#define ChromiumCDMCallbackProxy_h_
+
+#include "ChromiumCDMCallback.h"
+#include "ChromiumCDMProxy.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla {
+
+class ChromiumCDMCallbackProxy : public ChromiumCDMCallback {
+public:
+
+ ChromiumCDMCallbackProxy(ChromiumCDMProxy* aProxy,
+ nsIEventTarget* aMainThread)
+ : mProxy(aProxy), mMainThread(aMainThread)
+ {
+ }
+
+ void SetSessionId(uint32_t aPromiseId,
+ const nsCString& aSessionId) override;
+
+ void ResolveLoadSessionPromise(uint32_t aPromiseId,
+ bool aSuccessful) override;
+
+ void ResolvePromise(uint32_t aPromiseId) override;
+
+ void RejectPromise(uint32_t aPromiseId,
+ nsresult aError,
+ const nsCString& aErrorMessage) override;
+
+ void SessionMessage(const nsACString& aSessionId,
+ uint32_t aMessageType,
+ nsTArray<uint8_t>&& aMessage) override;
+
+ void SessionKeysChange(const nsCString& aSessionId,
+ nsTArray<mozilla::gmp::CDMKeyInformation>&& aKeysInfo) override;
+
+ void ExpirationChange(const nsCString& aSessionId,
+ double aSecondsSinceEpoch) override;
+
+ void SessionClosed(const nsCString& aSessionId) override;
+
+ void LegacySessionError(const nsCString& aSessionId,
+ nsresult aError,
+ uint32_t aSystemCode,
+ const nsCString& aMessage) override;
+ void Terminated() override;
+
+ void Shutdown() override;
+
+private:
+ template<class Func, class... Args>
+ void DispatchToMainThread(const char* const aLabel,
+ Func aFunc,
+ Args&&... aArgs);
+ // Warning: Weak ref.
+ ChromiumCDMProxy* mProxy;
+ const nsCOMPtr<nsIEventTarget> mMainThread;
+
+};
+
+} //namespace mozilla
+#endif
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -1,15 +1,17 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ChromiumCDMParent.h"
+#include "ChromiumCDMCallback.h"
+#include "ChromiumCDMCallbackProxy.h"
#include "ChromiumCDMProxy.h"
#include "content_decryption_module.h"
#include "GMPContentChild.h"
#include "GMPContentParent.h"
#include "GMPLog.h"
#include "GMPUtils.h"
#include "MediaPrefs.h"
#include "mozilla/dom/MediaKeyMessageEventBinding.h"
@@ -35,26 +37,26 @@ ChromiumCDMParent::ChromiumCDMParent(GMP
GMP_LOG(
"ChromiumCDMParent::ChromiumCDMParent(this=%p, contentParent=%p, id=%u)",
this,
aContentParent,
aPluginId);
}
bool
-ChromiumCDMParent::Init(ChromiumCDMProxy* aProxy,
+ChromiumCDMParent::Init(ChromiumCDMCallback* aCDMCallback,
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState,
nsIEventTarget* aMainThread)
{
GMP_LOG("ChromiumCDMParent::Init(this=%p)", this);
- if (!aProxy || !aMainThread) {
+ if (!aCDMCallback || !aMainThread) {
return false;
}
- mProxy = aProxy;
+ mCDMCallback = aCDMCallback;
mMainThread = aMainThread;
return SendInit(aAllowDistinctiveIdentifier, aAllowPersistentState);
}
void
ChromiumCDMParent::CreateSession(uint32_t aCreateSessionToken,
uint32_t aSessionType,
uint32_t aInitDataType,
@@ -274,92 +276,91 @@ ipc::IPCResult
ChromiumCDMParent::RecvOnResolveNewSessionPromise(const uint32_t& aPromiseId,
const nsCString& aSessionId)
{
GMP_LOG("ChromiumCDMParent::RecvOnResolveNewSessionPromise(this=%p, pid=%u, "
"sid=%s)",
this,
aPromiseId,
aSessionId.get());
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
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."));
return IPC_OK();
}
- mMainThread->Dispatch(
- NewRunnableMethod<uint32_t, nsString>("ChromiumCDMProxy::OnSetSessionId",
- mProxy,
- &ChromiumCDMProxy::OnSetSessionId,
- token.value(),
- NS_ConvertUTF8toUTF16(aSessionId)),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->SetSessionId(token.value(), aSessionId);
ResolvePromise(aPromiseId);
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvResolveLoadSessionPromise(const uint32_t& aPromiseId,
const bool& aSuccessful)
{
GMP_LOG("ChromiumCDMParent::RecvResolveLoadSessionPromise(this=%p, pid=%u, "
"successful=%d)",
this,
aPromiseId,
aSuccessful);
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- mMainThread->Dispatch(
- NewRunnableMethod<uint32_t, bool>(
- "ChromiumCDMProxy::OnResolveLoadSessionPromise",
- mProxy,
- &ChromiumCDMProxy::OnResolveLoadSessionPromise,
- aPromiseId,
- aSuccessful),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->ResolveLoadSessionPromise(aPromiseId, aSuccessful);
return IPC_OK();
}
+
void
ChromiumCDMParent::ResolvePromise(uint32_t aPromiseId)
{
GMP_LOG(
"ChromiumCDMParent::ResolvePromise(this=%p, pid=%u)", this, aPromiseId);
// Note: The MediaKeys rejects all pending DOM promises when it
// initiates shutdown.
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return;
}
- mMainThread->Dispatch(
- NewRunnableMethod<uint32_t>("ChromiumCDMProxy::ResolvePromise",
- mProxy,
- &ChromiumCDMProxy::ResolvePromise,
- aPromiseId),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->ResolvePromise(aPromiseId);
}
ipc::IPCResult
ChromiumCDMParent::RecvOnResolvePromise(const uint32_t& aPromiseId)
{
ResolvePromise(aPromiseId);
return IPC_OK();
}
+void
+ChromiumCDMParent::RejectPromise(uint32_t aPromiseId,
+ nsresult aError,
+ const nsCString& aErrorMessage)
+{
+ GMP_LOG(
+ "ChromiumCDMParent::RejectPromise(this=%p, pid=%u)", this, aPromiseId);
+ // Note: The MediaKeys rejects all pending DOM promises when it
+ // initiates shutdown.
+ if (!mCDMCallback || mIsShutdown) {
+ return;
+ }
+
+ mCDMCallback->RejectPromise(aPromiseId, aError, aErrorMessage);
+}
+
static nsresult
ToNsresult(uint32_t aError)
{
switch (static_cast<cdm::Error>(aError)) {
case cdm::kNotSupportedError:
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
case cdm::kInvalidStateError:
return NS_ERROR_DOM_INVALID_STATE_ERR;
@@ -377,204 +378,96 @@ ToNsresult(uint32_t aError)
return NS_ERROR_DOM_ABORT_ERR; // Note: Unique placeholder.
case cdm::kOutputError:
return NS_ERROR_DOM_SECURITY_ERR; // Note: Unique placeholder.
};
MOZ_ASSERT_UNREACHABLE("Invalid cdm::Error enum value.");
return NS_ERROR_DOM_TIMEOUT_ERR; // Note: Unique placeholder.
}
-void
-ChromiumCDMParent::RejectPromise(uint32_t aPromiseId,
- nsresult aError,
- const nsCString& aErrorMessage)
-{
- GMP_LOG(
- "ChromiumCDMParent::RejectPromise(this=%p, pid=%u)", this, aPromiseId);
- // Note: The MediaKeys rejects all pending DOM promises when it
- // initiates shutdown.
- if (!mProxy || mIsShutdown) {
- return;
- }
-
- mMainThread->Dispatch(
- NewRunnableMethod<uint32_t, nsresult, nsCString>(
- "ChromiumCDMProxy::RejectPromise",
- mProxy,
- &ChromiumCDMProxy::RejectPromise,
- aPromiseId,
- aError,
- aErrorMessage),
- NS_DISPATCH_NORMAL);
-}
-
ipc::IPCResult
ChromiumCDMParent::RecvOnRejectPromise(const uint32_t& aPromiseId,
const uint32_t& aError,
const uint32_t& aSystemCode,
const nsCString& aErrorMessage)
{
RejectPromise(aPromiseId, ToNsresult(aError), aErrorMessage);
return IPC_OK();
}
-static dom::MediaKeyMessageType
-ToDOMMessageType(uint32_t aMessageType)
-{
- switch (static_cast<cdm::MessageType>(aMessageType)) {
- case cdm::kLicenseRequest:
- return dom::MediaKeyMessageType::License_request;
- case cdm::kLicenseRenewal:
- return dom::MediaKeyMessageType::License_renewal;
- case cdm::kLicenseRelease:
- return dom::MediaKeyMessageType::License_release;
- }
- MOZ_ASSERT_UNREACHABLE("Invalid cdm::MessageType enum value.");
- return dom::MediaKeyMessageType::License_request;
-}
-
ipc::IPCResult
ChromiumCDMParent::RecvOnSessionMessage(const nsCString& aSessionId,
const uint32_t& aMessageType,
nsTArray<uint8_t>&& aMessage)
{
GMP_LOG("ChromiumCDMParent::RecvOnSessionMessage(this=%p, sid=%s)",
this,
aSessionId.get());
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- RefPtr<CDMProxy> proxy = mProxy;
- nsString sid = NS_ConvertUTF8toUTF16(aSessionId);
- dom::MediaKeyMessageType messageType = ToDOMMessageType(aMessageType);
- nsTArray<uint8_t> msg(Move(aMessage));
- mMainThread->Dispatch(
- NS_NewRunnableFunction("gmp::ChromiumCDMParent::RecvOnSessionMessage",
- [proxy, sid, messageType, msg]() mutable {
- proxy->OnSessionMessage(sid, messageType, msg);
- }),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->SessionMessage(aSessionId, aMessageType, Move(aMessage));
return IPC_OK();
}
-static dom::MediaKeyStatus
-ToDOMMediaKeyStatus(uint32_t aStatus)
-{
- switch (static_cast<cdm::KeyStatus>(aStatus)) {
- case cdm::kUsable:
- return dom::MediaKeyStatus::Usable;
- case cdm::kInternalError:
- return dom::MediaKeyStatus::Internal_error;
- case cdm::kExpired:
- return dom::MediaKeyStatus::Expired;
- case cdm::kOutputRestricted:
- return dom::MediaKeyStatus::Output_restricted;
- case cdm::kOutputDownscaled:
- return dom::MediaKeyStatus::Output_downscaled;
- case cdm::kStatusPending:
- return dom::MediaKeyStatus::Status_pending;
- case cdm::kReleased:
- return dom::MediaKeyStatus::Released;
- }
- MOZ_ASSERT_UNREACHABLE("Invalid cdm::KeyStatus enum value.");
- return dom::MediaKeyStatus::Internal_error;
-}
-
ipc::IPCResult
ChromiumCDMParent::RecvOnSessionKeysChange(
const nsCString& aSessionId,
nsTArray<CDMKeyInformation>&& aKeysInfo)
{
GMP_LOG("ChromiumCDMParent::RecvOnSessionKeysChange(this=%p)", this);
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- bool keyStatusesChange = false;
- {
- CDMCaps::AutoLock caps(mProxy->Capabilites());
- for (size_t i = 0; i < aKeysInfo.Length(); i++) {
- keyStatusesChange |=
- caps.SetKeyStatus(aKeysInfo[i].mKeyId(),
- NS_ConvertUTF8toUTF16(aSessionId),
- dom::Optional<dom::MediaKeyStatus>(
- ToDOMMediaKeyStatus(aKeysInfo[i].mStatus())));
- }
- }
- if (keyStatusesChange) {
- mMainThread->Dispatch(
- NewRunnableMethod<nsString>("ChromiumCDMProxy::OnKeyStatusesChange",
- mProxy,
- &ChromiumCDMProxy::OnKeyStatusesChange,
- NS_ConvertUTF8toUTF16(aSessionId)),
- NS_DISPATCH_NORMAL);
- }
+
+ mCDMCallback->SessionKeysChange(aSessionId, Move(aKeysInfo));
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnExpirationChange(const nsCString& aSessionId,
const double& aSecondsSinceEpoch)
{
GMP_LOG("ChromiumCDMParent::RecvOnExpirationChange(this=%p) time=%lf",
this,
aSecondsSinceEpoch);
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- mMainThread->Dispatch(
- NewRunnableMethod<nsString, UnixTime>(
- "ChromiumCDMProxy::OnExpirationChange",
- mProxy,
- &ChromiumCDMProxy::OnExpirationChange,
- NS_ConvertUTF8toUTF16(aSessionId),
- GMPTimestamp(aSecondsSinceEpoch * 1000)),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->ExpirationChange(aSessionId, aSecondsSinceEpoch);
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnSessionClosed(const nsCString& aSessionId)
{
GMP_LOG("ChromiumCDMParent::RecvOnSessionClosed(this=%p)", this);
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- mMainThread->Dispatch(
- NewRunnableMethod<nsString>("ChromiumCDMProxy::OnSessionClosed",
- mProxy,
- &ChromiumCDMProxy::OnSessionClosed,
- NS_ConvertUTF8toUTF16(aSessionId)),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->SessionClosed(aSessionId);
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnLegacySessionError(const nsCString& aSessionId,
const uint32_t& aError,
const uint32_t& aSystemCode,
const nsCString& aMessage)
{
GMP_LOG("ChromiumCDMParent::RecvOnLegacySessionError(this=%p)", this);
- if (!mProxy || mIsShutdown) {
+ if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
- mMainThread->Dispatch(
- NewRunnableMethod<nsString, nsresult, uint32_t, nsString>(
- "ChromiumCDMProxy::OnSessionError",
- mProxy,
- &ChromiumCDMProxy::OnSessionError,
- NS_ConvertUTF8toUTF16(aSessionId),
- ToNsresult(aError),
- aSystemCode,
- NS_ConvertUTF8toUTF16(aMessage)),
- NS_DISPATCH_NORMAL);
+ mCDMCallback->LegacySessionError(
+ aSessionId, ToNsresult(aError), aSystemCode, aMessage);
return IPC_OK();
}
DecryptStatus
ToDecryptStatus(uint32_t aError)
{
switch (static_cast<cdm::Status>(aError)) {
case cdm::kSuccess:
@@ -929,37 +822,32 @@ ChromiumCDMParent::RecvShutdown()
}
void
ChromiumCDMParent::ActorDestroy(ActorDestroyReason aWhy)
{
GMP_LOG("ChromiumCDMParent::ActorDestroy(this=%p, reason=%d)", this, aWhy);
MOZ_ASSERT(!mActorDestroyed);
mActorDestroyed = true;
- // Shutdown() will clear mProxy, so let's keep a reference for later use.
- RefPtr<ChromiumCDMProxy> proxy = mProxy;
+ // Shutdown() will clear mCDMCallback, so let's keep a reference for later use.
+ auto callback = mCDMCallback;
if (!mIsShutdown) {
// Plugin crash.
MOZ_ASSERT(aWhy == AbnormalShutdown);
Shutdown();
}
MOZ_ASSERT(mIsShutdown);
RefPtr<ChromiumCDMParent> kungFuDeathGrip(this);
if (mContentParent) {
mContentParent->ChromiumCDMDestroyed(this);
mContentParent = nullptr;
}
bool abnormalShutdown = (aWhy == AbnormalShutdown);
- if (abnormalShutdown && proxy) {
- mMainThread->Dispatch(
- NewRunnableMethod(
- "ChromiumCDMProxy::Terminated",
- proxy,
- &ChromiumCDMProxy::Terminated),
- NS_DISPATCH_NORMAL);
+ if (abnormalShutdown && callback) {
+ callback->Terminated();
}
MaybeDisconnect(abnormalShutdown);
}
RefPtr<MediaDataDecoder::InitPromise>
ChromiumCDMParent::InitializeVideoDecoder(
const gmp::CDMVideoDecoderConfig& aConfig,
const VideoInfo& aInfo,
@@ -1185,29 +1073,24 @@ ChromiumCDMParent::Shutdown()
}
mIsShutdown = true;
// If we're shutting down due to the plugin shutting down due to application
// shutdown, we should tell the CDM proxy to also shutdown. Otherwise the
// proxy will shutdown when the owning MediaKeys is destroyed during cycle
// collection, and that will not shut down cleanly as the GMP thread will be
// shutdown by then.
- if (mProxy) {
- mMainThread->Dispatch(
- NewRunnableMethod(
- "ChromiumCDMProxy::Shutdown",
- mProxy,
- &ChromiumCDMProxy::Shutdown),
- NS_DISPATCH_NORMAL);
+ if (mCDMCallback) {
+ mCDMCallback->Shutdown();
}
- // We may be called from a task holding the last reference to the proxy, so
+ // We may be called from a task holding the last reference to the CDM callback, so
// let's clear our local weak pointer to ensure it will not be used afterward
// (including from an already-queued task, e.g.: ActorDestroy).
- mProxy = nullptr;
+ mCDMCallback = nullptr;
mReorderQueue.Clear();
for (RefPtr<DecryptJob>& decrypt : mDecrypts) {
decrypt->PostResult(eme::AbortedErr);
}
mDecrypts.Clear();
--- a/dom/media/gmp/ChromiumCDMParent.h
+++ b/dom/media/gmp/ChromiumCDMParent.h
@@ -13,16 +13,18 @@
#include "mozilla/gmp/PChromiumCDMParent.h"
#include "mozilla/RefPtr.h"
#include "nsDataHashtable.h"
#include "PlatformDecoderModule.h"
#include "ImageContainer.h"
#include "mozilla/Span.h"
#include "ReorderQueue.h"
+class ChromiumCDMCallback;
+
namespace mozilla {
class MediaRawData;
class ChromiumCDMProxy;
namespace gmp {
class GMPContentParent;
@@ -33,17 +35,17 @@ class ChromiumCDMParent final
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMParent)
ChromiumCDMParent(GMPContentParent* aContentParent, uint32_t aPluginId);
uint32_t PluginId() const { return mPluginId; }
- bool Init(ChromiumCDMProxy* aProxy,
+ bool Init(ChromiumCDMCallback* aCDMCallback,
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState,
nsIEventTarget* aMainThread);
void CreateSession(uint32_t aCreateSessionToken,
uint32_t aSessionType,
uint32_t aInitDataType,
uint32_t aPromiseId,
@@ -143,20 +145,19 @@ protected:
bool PurgeShmems();
bool EnsureSufficientShmems(size_t aVideoFrameSize);
already_AddRefed<VideoData> CreateVideoFrame(const CDMVideoFrame& aFrame,
Span<uint8_t> aData);
const uint32_t mPluginId;
GMPContentParent* mContentParent;
- // Note: this pointer is a weak reference because otherwise it would cause
- // a cycle, as ChromiumCDMProxy has a strong reference to the
- // ChromiumCDMParent.
- ChromiumCDMProxy* mProxy = nullptr;
+ // Note: this pointer is a weak reference as ChromiumCDMProxy has a strong reference to the
+ // ChromiumCDMCallback.
+ ChromiumCDMCallback* mCDMCallback = nullptr;
nsDataHashtable<nsUint32HashKey, uint32_t> mPromiseToCreateSessionToken;
nsTArray<RefPtr<DecryptJob>> mDecrypts;
MozPromiseHolder<MediaDataDecoder::InitPromise> mInitVideoDecoderPromise;
MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
RefPtr<layers::ImageContainer> mImageContainer;
VideoInfo mVideoInfo;
@@ -183,15 +184,15 @@ protected:
// before presenting. mMaxRefFrames is non-zero if we have an initialized
// decoder and we are decoding H.264. If so, it stores the maximum length of
// the reorder queue that we need. Note we may have multiple decoders for the
// life time of this object, but never more than one active at once.
uint32_t mMaxRefFrames = 0;
ReorderQueue mReorderQueue;
// The main thread associated with the root document. Must be set in Init().
- nsCOMPtr<nsIEventTarget> mMainThread;
+ nsCOMPtr<nsIEventTarget> mMainThread;
};
} // namespace gmp
} // namespace mozilla
#endif // ChromiumCDMParent_h_
--- a/dom/media/gmp/ChromiumCDMProxy.cpp
+++ b/dom/media/gmp/ChromiumCDMProxy.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ChromiumCDMProxy.h"
+#include "ChromiumCDMCallbackProxy.h"
#include "mozilla/dom/MediaKeySession.h"
#include "GMPUtils.h"
#include "nsPrintfCString.h"
#include "GMPService.h"
#include "content_decryption_module.h"
#define NS_DispatchToMainThread(...) CompileError_UseAbstractMainThreadInstead
@@ -92,17 +93,19 @@ ChromiumCDMProxy::Init(PromiseId aPromis
return;
}
RefPtr<gmp::GetCDMParentPromise> promise =
service->GetCDM(nodeId, { keySystem }, helper);
promise->Then(
thread,
__func__,
[self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) {
- if (!cdm->Init(self,
+ self->mCallback =
+ MakeUnique<ChromiumCDMCallbackProxy>(self, self->mMainThread);
+ if (!cdm->Init(self->mCallback.get(),
self->mDistinctiveIdentifierRequired,
self->mPersistentStateRequired,
self->mMainThread)) {
self->RejectPromise(aPromiseId,
NS_ERROR_FAILURE,
NS_LITERAL_CSTRING("GetCDM failed."));
return;
}
@@ -459,17 +462,17 @@ ChromiumCDMProxy::OnResolveLoadSessionPr
return;
}
mKeys->OnSessionLoaded(aPromiseId, aSuccess);
}
void
ChromiumCDMProxy::OnSessionMessage(const nsAString& aSessionId,
dom::MediaKeyMessageType aMessageType,
- nsTArray<uint8_t>& aMessage)
+ const nsTArray<uint8_t>& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->DispatchKeyMessage(aMessageType, aMessage);
--- a/dom/media/gmp/ChromiumCDMProxy.h
+++ b/dom/media/gmp/ChromiumCDMProxy.h
@@ -10,17 +10,17 @@
#include "mozilla/CDMProxy.h"
#include "mozilla/AbstractThread.h"
#include "ChromiumCDMParent.h"
namespace mozilla {
class MediaRawData;
class DecryptJob;
-
+class ChromiumCDMCallbackProxy;
class ChromiumCDMProxy : public CDMProxy
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMProxy, override)
ChromiumCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,
GMPCrashHelper* aCrashHelper,
@@ -120,13 +120,14 @@ private:
~ChromiumCDMProxy();
GMPCrashHelper* mCrashHelper;
Mutex mCDMMutex;
RefPtr<gmp::ChromiumCDMParent> mCDM;
RefPtr<AbstractThread> mGMPThread;
+ UniquePtr<ChromiumCDMCallbackProxy> mCallback;
};
} // namespace mozilla
#endif // GMPCDMProxy_h_
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -7,16 +7,17 @@
XPIDL_MODULE = 'content_geckomediaplugins'
XPIDL_SOURCES += [
'mozIGeckoMediaPluginChromeService.idl',
'mozIGeckoMediaPluginService.idl',
]
EXPORTS += [
+ 'ChromiumCDMCallback.h',
'ChromiumCDMParent.h',
'ChromiumCDMProxy.h',
'DecryptJob.h',
'gmp-api/gmp-decryption.h',
'gmp-api/gmp-entrypoints.h',
'gmp-api/gmp-errors.h',
'gmp-api/gmp-platform.h',
'gmp-api/gmp-storage.h',
@@ -67,16 +68,17 @@ EXPORTS += [
'GMPVideoPlaneImpl.h',
'widevine-adapter/content_decryption_module.h',
'widevine-adapter/content_decryption_module_export.h',
'widevine-adapter/content_decryption_module_ext.h',
]
UNIFIED_SOURCES += [
'ChromiumCDMAdapter.cpp',
+ 'ChromiumCDMCallbackProxy.cpp',
'ChromiumCDMChild.cpp',
'ChromiumCDMParent.cpp',
'ChromiumCDMProxy.cpp',
'DecryptJob.cpp',
'GMPCDMCallbackProxy.cpp',
'GMPChild.cpp',
'GMPContentChild.cpp',
'GMPContentParent.cpp',