Bug 1404230 - Part4 - Add GetStatusForPolicy method in ipdl and implement it by calling CDM. r=cpearce

MozReview-Commit-ID: 8L0qKgnKMES

--HG--
extra : rebase_source : 05b6fe33a9c0cbe5ca52f245decc167889bbe6d9
This commit is contained in:
James Cheng 2017-10-24 10:55:03 +08:00
Родитель c48a2cbcfa
Коммит f733aff224
13 изменённых файлов: 176 добавлений и 3 удалений

Просмотреть файл

@ -624,10 +624,24 @@ MediaKeys::GetStatusForPolicy(const MediaKeysPolicy& aPolicy,
}
EME_LOG("GetStatusForPolicy minHdcpVersion = %s.", NS_ConvertUTF16toUTF8(aPolicy.mMinHdcpVersion).get());
// TODO: Ask CDM to get the real policy.
promise->MaybeResolve(MediaKeyStatus::Usable);
mProxy->GetStatusForPolicy(StorePromise(promise), aPolicy.mMinHdcpVersion);
return promise.forget();
}
void
MediaKeys::ResolvePromiseWithKeyStatus(PromiseId aId, MediaKeyStatus aMediaKeyStatus)
{
RefPtr<DetailedPromise> promise(RetrievePromise(aId));
if (!promise) {
return;
}
RefPtr<MediaKeys> keys(this);
EME_LOG("MediaKeys[%p]::ResolvePromiseWithKeyStatus() resolve promise id=%d, keystatus=%" PRIu8,
this,
aId,
static_cast<uint8_t>(aMediaKeyStatus));
promise->MaybeResolve(aMediaKeyStatus);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -16,6 +16,7 @@
#include "nsRefPtrHashtable.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/MediaKeysBinding.h"
#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
#include "mozilla/dom/MediaKeySystemAccessBinding.h"
#include "mozIGeckoMediaPluginService.h"
#include "mozilla/DetailedPromise.h"
@ -134,6 +135,8 @@ public:
// JavaScript: MediaKeys.GetStatusForPolicy()
already_AddRefed<Promise> GetStatusForPolicy(const MediaKeysPolicy& aPolicy,
ErrorResult& aR);
// Called by CDMProxy when CDM successfully GetStatusForPolicy.
void ResolvePromiseWithKeyStatus(PromiseId aId, dom::MediaKeyStatus aMediaKeyStatus);
private:

Просмотреть файл

@ -22,6 +22,9 @@ public:
virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccessful) = 0;
virtual void ResolvePromiseWithKeyStatus(uint32_t aPromiseId,
uint32_t aKeyStatus) = 0;
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
virtual void RejectPromise(uint32_t aPromiseId,

Просмотреть файл

@ -116,6 +116,16 @@ ToDOMMediaKeyStatus(uint32_t aStatus)
return dom::MediaKeyStatus::Internal_error;
}
void
ChromiumCDMCallbackProxy::ResolvePromiseWithKeyStatus(uint32_t aPromiseId,
uint32_t aKeyStatus)
{
DispatchToMainThread("ChromiumCDMProxy::OnResolvePromiseWithKeyStatus",
&ChromiumCDMProxy::OnResolvePromiseWithKeyStatus,
aPromiseId,
ToDOMMediaKeyStatus(aKeyStatus));
}
void
ChromiumCDMCallbackProxy::SessionKeysChange(const nsCString& aSessionId,
nsTArray<mozilla::gmp::CDMKeyInformation> && aKeysInfo)

Просмотреть файл

@ -27,6 +27,9 @@ public:
void ResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccessful) override;
void ResolvePromiseWithKeyStatus(uint32_t aPromiseId,
uint32_t aKeyStatus) override;
void ResolvePromise(uint32_t aPromiseId) override;
void RejectPromise(uint32_t aPromiseId,

Просмотреть файл

@ -226,7 +226,13 @@ ChromiumCDMChild::CallOnMessageLoopThread(const char* const aName,
void
ChromiumCDMChild::OnResolveKeyStatusPromise(uint32_t aPromiseId,
cdm::KeyStatus aKeyStatus) {
//TODO: The callback of GetStatusForPolicy, will implement it in Bug 1404230.
GMP_LOG("ChromiumCDMChild::OnResolveKeyStatusPromise(pid=%" PRIu32 "keystatus=%d)",
aPromiseId,
aKeyStatus);
CallOnMessageLoopThread("gmp::ChromiumCDMChild::OnResolveKeyStatusPromise",
&ChromiumCDMChild::SendOnResolvePromiseWithKeyStatus,
aPromiseId,
static_cast<uint32_t>(aKeyStatus));
}
bool
@ -624,6 +630,64 @@ ChromiumCDMChild::RecvRemoveSession(const uint32_t& aPromiseId,
return IPC_OK();
}
// See https://cs.chromium.org/chromium/src/media/blink/webcontentdecryptionmodule_impl.cc?rcl=9d4e17194fbae2839d269e0b625520eac09efa9b&l=40
static cdm::HdcpVersion
ToCDMHdcpVersion(const nsCString& aMinHdcpVersion)
{
// String compare with ignoring case.
if (aMinHdcpVersion.IsEmpty()) {
return cdm::HdcpVersion::kHdcpVersionNone;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-1.0")) {
return cdm::HdcpVersion::kHdcpVersion1_0;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-1.1")) {
return cdm::HdcpVersion::kHdcpVersion1_1;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-1.2")) {
return cdm::HdcpVersion::kHdcpVersion1_2;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-1.3")) {
return cdm::HdcpVersion::kHdcpVersion1_3;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-1.4")) {
return cdm::HdcpVersion::kHdcpVersion1_4;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-2.0")) {
return cdm::HdcpVersion::kHdcpVersion2_0;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-2.1")) {
return cdm::HdcpVersion::kHdcpVersion2_1;
}
if (aMinHdcpVersion.EqualsIgnoreCase("hdcp-2.2")) {
return cdm::HdcpVersion::kHdcpVersion2_2;
}
// Invalid hdcp version string.
return cdm::HdcpVersion::kHdcpVersionNone;
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvGetStatusForPolicy(const uint32_t& aPromiseId,
const nsCString& aMinHdcpVersion)
{
MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvGetStatusForPolicy(pid=%" PRIu32 ", MinHdcpVersion=%s)",
aPromiseId,
aMinHdcpVersion.get());
if (mCDM) {
cdm::Policy policy;
// We didn't check the return value of ToCDMHdcpVersion.
// Let CDM to handle the cdm::HdcpVersion::kHdcpVersionNone case.
// ChromiumCDM8BackwardsCompat::GetStatusForPolicy will reject the promise
// since this API is only supported by CDM version 9.
// CDM will callback by OnResolveKeyStatusPromise when it successfully executes.
policy.min_hdcp_version = ToCDMHdcpVersion(aMinHdcpVersion);
mCDM->GetStatusForPolicy(aPromiseId, policy);
}
return IPC_OK();
}
static void
InitInputBuffer(const CDMInputBuffer& aBuffer,
nsTArray<cdm::SubsampleEntry>& aSubSamples,

Просмотреть файл

@ -128,6 +128,8 @@ protected:
const nsCString& aSessionId) override;
ipc::IPCResult RecvRemoveSession(const uint32_t& aPromiseId,
const nsCString& aSessionId) override;
ipc::IPCResult RecvGetStatusForPolicy(const uint32_t& aPromiseId,
const nsCString& aMinHdcpVersion) override;
ipc::IPCResult RecvDecrypt(const uint32_t& aId,
const CDMInputBuffer& aBuffer) override;
ipc::IPCResult RecvInitializeVideoDecoder(

Просмотреть файл

@ -186,6 +186,25 @@ ChromiumCDMParent::RemoveSession(const nsCString& aSessionId,
}
}
void
ChromiumCDMParent::GetStatusForPolicy(uint32_t aPromiseId,
const nsCString& aMinHdcpVersion)
{
GMP_LOG("ChromiumCDMParent::GetStatusForPolicy(this=%p)", this);
if (mIsShutdown) {
RejectPromise(aPromiseId,
NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("CDM is shutdown."));
return;
}
if (!SendGetStatusForPolicy(aPromiseId, aMinHdcpVersion)) {
RejectPromise(
aPromiseId,
NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Failed to send getStatusForPolicy to CDM process"));
}
}
bool
ChromiumCDMParent::InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer,
MediaRawData* aSample)
@ -274,6 +293,24 @@ ChromiumCDMParent::Recv__delete__()
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnResolvePromiseWithKeyStatus(const uint32_t& aPromiseId,
const uint32_t& aKeyStatus)
{
GMP_LOG("ChromiumCDMParent::RecvOnResolvePromiseWithKeyStatus(this=%p, pid=%u, "
"keystatus=%u)",
this,
aPromiseId,
aKeyStatus);
if (!mCDMCallback || mIsShutdown) {
return IPC_OK();
}
mCDMCallback->ResolvePromiseWithKeyStatus(aPromiseId, aKeyStatus);
return IPC_OK();
}
ipc::IPCResult
ChromiumCDMParent::RecvOnResolveNewSessionPromise(const uint32_t& aPromiseId,
const nsCString& aSessionId)

Просмотреть файл

@ -66,6 +66,9 @@ public:
void RemoveSession(const nsCString& aSessionId, uint32_t aPromiseId);
void GetStatusForPolicy(uint32_t aPromiseId,
const nsCString& aMinHdcpVersion);
RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample);
// TODO: Add functions for clients to send data to CDM, and
@ -90,6 +93,9 @@ protected:
~ChromiumCDMParent() {}
ipc::IPCResult Recv__delete__() override;
ipc::IPCResult RecvOnResolvePromiseWithKeyStatus(
const uint32_t& aPromiseId,
const uint32_t& aKeyStatus) override;
ipc::IPCResult RecvOnResolveNewSessionPromise(
const uint32_t& aPromiseId,
const nsCString& aSessionId) override;

Просмотреть файл

@ -465,6 +465,17 @@ ChromiumCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId,
mKeys->OnSessionLoaded(aPromiseId, aSuccess);
}
void
ChromiumCDMProxy::OnResolvePromiseWithKeyStatus(uint32_t aPromiseId,
dom::MediaKeyStatus aKeyStatus)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
mKeys->ResolvePromiseWithKeyStatus(aPromiseId, aKeyStatus);
}
void
ChromiumCDMProxy::OnSessionMessage(const nsAString& aSessionId,
dom::MediaKeyMessageType aMessageType,
@ -614,6 +625,13 @@ ChromiumCDMProxy::GetStatusForPolicy(PromiseId aPromiseId,
NS_LITERAL_CSTRING("Null CDM in GetStatusForPolicy"));
return;
}
mGMPThread->Dispatch(NewRunnableMethod<uint32_t, nsCString>(
"gmp::ChromiumCDMParent::GetStatusForPolicy",
cdm,
&gmp::ChromiumCDMParent::GetStatusForPolicy,
aPromiseId,
NS_ConvertUTF16toUTF8(aMinHdcpVersion)));
}
void

Просмотреть файл

@ -118,6 +118,9 @@ public:
// CDM, which will fail on all operations.
already_AddRefed<gmp::ChromiumCDMParent> GetCDMParent();
void OnResolvePromiseWithKeyStatus(uint32_t aPromiseId,
dom::MediaKeyStatus aKeyStatus);
private:
void OnCDMCreated(uint32_t aPromiseId);

Просмотреть файл

@ -58,9 +58,16 @@ child:
async PurgeShmems();
// cdm::ContentDecryptionModule9
async GetStatusForPolicy(uint32_t aPromiseId,
nsCString aMinHdcpVersion);
parent:
async __delete__();
// cdm::Host9
async OnResolvePromiseWithKeyStatus(uint32_t aPromiseId, uint32_t aKeyStatus);
// cdm::Host8
async OnResolveNewSessionPromise(uint32_t aPromiseId, nsCString aSessionId);

Просмотреть файл

@ -1072,6 +1072,9 @@ private:
void ResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccessful) override { }
void ResolvePromiseWithKeyStatus(uint32_t aPromiseId,
uint32_t aKeyStatus) override { }
void ResolvePromise(uint32_t aPromiseId) override { }
void RejectPromise(uint32_t aPromiseId,