Bug 1315850 - Connect MediaKeys.createSession to Chromium CDM. r=gerald
MozReview-Commit-ID: AzvypvetoOL
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -26,16 +26,34 @@ ChromiumCDMParent::Init(ChromiumCDMProxy
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState)
{
mProxy = aProxy;
return SendInit(aAllowDistinctiveIdentifier, aAllowPersistentState);
}
void
+ChromiumCDMParent::CreateSession(uint32_t aCreateSessionToken,
+ uint32_t aSessionType,
+ uint32_t aInitDataType,
+ uint32_t aPromiseId,
+ const nsTArray<uint8_t>& aInitData)
+{
+ if (!SendCreateSessionAndGenerateRequest(
+ aPromiseId, aSessionType, aInitDataType, aInitData)) {
+ RejectPromise(
+ aPromiseId,
+ NS_ERROR_DOM_INVALID_STATE_ERR,
+ NS_LITERAL_CSTRING("Failed to send generateRequest to CDM process."));
+ return;
+ }
+ mPromiseToCreateSessionToken.Put(aPromiseId, aCreateSessionToken);
+}
+
+void
ChromiumCDMParent::SetServerCertificate(uint32_t aPromiseId,
const nsTArray<uint8_t>& aCert)
{
if (!SendSetServerCertificate(aPromiseId, aCert)) {
RejectPromise(
aPromiseId,
NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Failed to send setServerCertificate to CDM process"));
@@ -84,27 +102,54 @@ ChromiumCDMParent::Recv__delete__()
{
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnResolveNewSessionPromise(const uint32_t& aPromiseId,
const nsCString& aSessionId)
{
+ if (!mProxy) {
+ 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();
+ }
+
+ RefPtr<Runnable> task =
+ NewRunnableMethod<uint32_t, nsString>(mProxy,
+ &ChromiumCDMProxy::OnSetSessionId,
+ token.value(),
+ NS_ConvertUTF8toUTF16(aSessionId));
+ NS_DispatchToMainThread(task);
+
+ ResolvePromise(aPromiseId);
+
return IPC_OK();
}
+void
+ChromiumCDMParent::ResolvePromise(uint32_t aPromiseId)
+{
+ if (!mProxy) {
+ return;
+ }
+ NS_DispatchToMainThread(NewRunnableMethod<uint32_t>(
+ mProxy, &ChromiumCDMProxy::ResolvePromise, aPromiseId));
+}
+
ipc::IPCResult
ChromiumCDMParent::RecvOnResolvePromise(const uint32_t& aPromiseId)
{
- if (!mProxy) {
- return IPC_OK();
- }
- NS_DispatchToMainThread(NewRunnableMethod<uint32_t>(
- mProxy, &ChromiumCDMProxy::ResolvePromise, aPromiseId));
+ ResolvePromise(aPromiseId);
return IPC_OK();
}
static nsresult
ToNsresult(uint32_t aError)
{
switch (static_cast<cdm::Error>(aError)) {
case cdm::kNotSupportedError:
--- a/dom/media/gmp/ChromiumCDMParent.h
+++ b/dom/media/gmp/ChromiumCDMParent.h
@@ -6,16 +6,17 @@
#ifndef ChromiumCDMParent_h_
#define ChromiumCDMParent_h_
#include "GMPCrashHelper.h"
#include "GMPCrashHelperHolder.h"
#include "GMPMessageUtils.h"
#include "mozilla/gmp/PChromiumCDMParent.h"
#include "mozilla/RefPtr.h"
+#include "nsDataHashtable.h"
namespace mozilla {
class ChromiumCDMProxy;
namespace gmp {
class GMPContentParent;
@@ -30,27 +31,34 @@ public:
ChromiumCDMParent(GMPContentParent* aContentParent, uint32_t aPluginId);
uint32_t PluginId() const { return mPluginId; }
bool Init(ChromiumCDMProxy* aProxy,
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState);
+ void CreateSession(uint32_t aCreateSessionToken,
+ uint32_t aSessionType,
+ uint32_t aInitDataType,
+ uint32_t aPromiseId,
+ const nsTArray<uint8_t>& aInitData);
+
void SetServerCertificate(uint32_t aPromiseId,
const nsTArray<uint8_t>& aCert);
void UpdateSession(const nsCString& aSessionId,
uint32_t aPromiseId,
const nsTArray<uint8_t>& aResponse);
void CloseSession(const nsCString& aSessionId, uint32_t aPromiseId);
void RemoveSession(const nsCString& aSessionId, uint32_t aPromiseId);
+ // TODO: Add functions for clients to send data to CDM, and
// a Close() function.
protected:
~ChromiumCDMParent() {}
ipc::IPCResult Recv__delete__() override;
ipc::IPCResult RecvOnResolveNewSessionPromise(
const uint32_t& aPromiseId,
@@ -80,20 +88,23 @@ protected:
ipc::IPCResult RecvDecodeFailed(const uint32_t& aStatus) override;
ipc::IPCResult RecvShutdown() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void RejectPromise(uint32_t aPromiseId,
nsresult aError,
const nsCString& aErrorMessage);
+ void ResolvePromise(uint32_t aPromiseId);
+
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;
+ nsDataHashtable<nsUint32HashKey, uint32_t> mPromiseToCreateSessionToken;
};
} // 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 "mozilla/dom/MediaKeySession.h"
#include "GMPUtils.h"
#include "nsPrintfCString.h"
#include "GMPService.h"
#include "mozilla/dom/MediaKeySession.h"
namespace mozilla {
ChromiumCDMProxy::ChromiumCDMProxy(dom::MediaKeys* aKeys,
@@ -136,23 +137,68 @@ ChromiumCDMProxy::OnCDMCreated(uint32_t
#ifdef DEBUG
bool
ChromiumCDMProxy::IsOnOwnerThread()
{
return mGMPThread->IsCurrentThreadIn();
}
#endif
+static uint32_t
+ToCDMSessionType(dom::MediaKeySessionType aSessionType)
+{
+ switch (aSessionType) {
+ case dom::MediaKeySessionType::Temporary:
+ return static_cast<uint32_t>(cdm::kTemporary);
+ case dom::MediaKeySessionType::Persistent_license:
+ return static_cast<uint32_t>(cdm::kPersistentLicense);
+ default:
+ return static_cast<uint32_t>(cdm::kTemporary);
+ };
+};
+
+static uint32_t
+ToCDMInitDataType(const nsAString& aInitDataType)
+{
+ if (aInitDataType.EqualsLiteral("cenc")) {
+ return static_cast<uint32_t>(cdm::kCenc);
+ }
+ if (aInitDataType.EqualsLiteral("webm")) {
+ return static_cast<uint32_t>(cdm::kWebM);
+ }
+ if (aInitDataType.EqualsLiteral("keyids")) {
+ return static_cast<uint32_t>(cdm::kKeyIds);
+ }
+ return static_cast<uint32_t>(cdm::kCenc);
+}
+
void
ChromiumCDMProxy::CreateSession(uint32_t aCreateSessionToken,
dom::MediaKeySessionType aSessionType,
PromiseId aPromiseId,
const nsAString& aInitDataType,
nsTArray<uint8_t>& aInitData)
{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ uint32_t sessionType = ToCDMSessionType(aSessionType);
+ uint32_t initDataType = ToCDMInitDataType(aInitDataType);
+
+ mGMPThread->Dispatch(
+ NewRunnableMethod<uint32_t,
+ uint32_t,
+ uint32_t,
+ uint32_t,
+ nsTArray<uint8_t>>(mCDM,
+ &gmp::ChromiumCDMParent::CreateSession,
+ aCreateSessionToken,
+ sessionType,
+ initDataType,
+ aPromiseId,
+ Move(aInitData)));
}
void
ChromiumCDMProxy::LoadSession(PromiseId aPromiseId, const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
RejectPromise(aPromiseId,
@@ -255,16 +301,25 @@ ChromiumCDMProxy::GetNodeId() const
{
return mNodeId;
}
void
ChromiumCDMProxy::OnSetSessionId(uint32_t aCreateSessionToken,
const nsAString& aSessionId)
{
+ MOZ_ASSERT(NS_IsMainThread());
+ if (mKeys.IsNull()) {
+ return;
+ }
+ RefPtr<dom::MediaKeySession> session(
+ mKeys->GetPendingSession(aCreateSessionToken));
+ if (session) {
+ session->SetSessionId(aSessionId);
+ }
}
void
ChromiumCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccess)
{
}