Bug 1395468 - [Part2] Remove the EMEVideoDecoder and GMPCDMProxy related files. r=cpearce

We remove the instantiation of EMEVideoDecoder and GMPCDMProxy in Part1. Just delete it and its h/cpp from moz.build

MozReview-Commit-ID: 8kGQK967pR0

--HG--
extra : rebase_source : 77750e6a92e6b649c41e7a8f769fa14c810e8e18
This commit is contained in:
James Cheng 2017-08-29 16:52:09 +08:00
Родитель 9d0d797c01
Коммит b01615f4a0
8 изменённых файлов: 0 добавлений и 1108 удалений

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

@ -15,7 +15,6 @@
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/Telemetry.h"
#include "GMPCDMProxy.h"
#ifdef MOZ_WIDGET_ANDROID
#include "mozilla/MediaDrmCDMProxy.h"
#endif

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

@ -1,773 +0,0 @@
/* -*- 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 "GMPCDMProxy.h"
#include "mozilla/EMEUtils.h"
#include "mozilla/PodOperations.h"
#include "mozilla/dom/MediaKeys.h"
#include "mozilla/dom/MediaKeySession.h"
#include "mozIGeckoMediaPluginService.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "prenv.h"
#include "GMPCDMCallbackProxy.h"
#include "GMPService.h"
#include "MainThreadUtils.h"
#include "MediaData.h"
#include "DecryptJob.h"
#include "GMPUtils.h"
namespace mozilla {
GMPCDMProxy::GMPCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,
GMPCrashHelper* aCrashHelper,
bool aDistinctiveIdentifierRequired,
bool aPersistentStateRequired,
nsIEventTarget* aMainThread)
: CDMProxy(aKeys,
aKeySystem,
aDistinctiveIdentifierRequired,
aPersistentStateRequired,
aMainThread)
, mCrashHelper(aCrashHelper)
, mCDM(nullptr)
, mShutdownCalled(false)
, mDecryptorId(0)
, mCreatePromiseId(0)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(GMPCDMProxy);
}
GMPCDMProxy::~GMPCDMProxy()
{
MOZ_COUNT_DTOR(GMPCDMProxy);
}
void
GMPCDMProxy::Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
EME_LOG("GMPCDMProxy::Init (%s, %s)",
NS_ConvertUTF16toUTF8(aOrigin).get(),
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get());
nsCString pluginVersion;
if (!mOwnerThread) {
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!mps) {
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::Init"));
return;
}
mps->GetThread(getter_AddRefs(mOwnerThread));
if (!mOwnerThread) {
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get GMP thread GMPCDMProxy::Init"));
return;
}
}
if (aGMPName.IsEmpty()) {
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get()));
return;
}
UniquePtr<InitData> data(new InitData());
data->mPromiseId = aPromiseId;
data->mOrigin = aOrigin;
data->mTopLevelOrigin = aTopLevelOrigin;
data->mGMPName = aGMPName;
data->mCrashHelper = mCrashHelper;
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<InitData>&&>("GMPCDMProxy::gmp_Init",
this,
&GMPCDMProxy::gmp_Init,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
#ifdef DEBUG
bool
GMPCDMProxy::IsOnOwnerThread()
{
return mOwnerThread->IsOnCurrentThread();
}
#endif
void
GMPCDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, UniquePtr<InitData>&& aData)
{
EME_LOG("GMPCDMProxy::gmp_InitDone");
if (mShutdownCalled) {
if (aCDM) {
aCDM->Close();
}
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("GMPCDMProxy was shut down before init could complete"));
return;
}
if (!aCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("GetGMPDecryptor failed to return a CDM"));
return;
}
mCDM = aCDM;
mCallback.reset(new GMPCDMCallbackProxy(this, mMainThread));
mCDM->Init(mCallback.get(),
mDistinctiveIdentifierRequired,
mPersistentStateRequired);
// Await the OnSetDecryptorId callback.
mCreatePromiseId = aData->mPromiseId;
}
void GMPCDMProxy::OnSetDecryptorId(uint32_t aId)
{
MOZ_ASSERT(mCreatePromiseId);
mDecryptorId = aId;
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<uint32_t>("GMPCDMProxy::OnCDMCreated",
this,
&GMPCDMProxy::OnCDMCreated,
mCreatePromiseId));
mMainThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
class gmp_InitDoneCallback : public GetGMPDecryptorCallback
{
public:
gmp_InitDoneCallback(GMPCDMProxy* aGMPCDMProxy,
UniquePtr<GMPCDMProxy::InitData>&& aData)
: mGMPCDMProxy(aGMPCDMProxy),
mData(Move(aData))
{
}
void Done(GMPDecryptorProxy* aCDM)
{
mGMPCDMProxy->gmp_InitDone(aCDM, Move(mData));
}
private:
RefPtr<GMPCDMProxy> mGMPCDMProxy;
UniquePtr<GMPCDMProxy::InitData> mData;
};
class gmp_InitGetGMPDecryptorCallback : public GetNodeIdCallback
{
public:
gmp_InitGetGMPDecryptorCallback(GMPCDMProxy* aGMPCDMProxy,
UniquePtr<GMPCDMProxy::InitData>&& aData)
: mGMPCDMProxy(aGMPCDMProxy),
mData(Move(aData))
{
}
void Done(nsresult aResult, const nsACString& aNodeId)
{
mGMPCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData));
}
private:
RefPtr<GMPCDMProxy> mGMPCDMProxy;
UniquePtr<GMPCDMProxy::InitData> mData;
};
void
GMPCDMProxy::gmp_Init(UniquePtr<InitData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!mps) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_Init"));
return;
}
// Make a copy before we transfer ownership of aData to the
// gmp_InitGetGMPDecryptorCallback.
InitData data(*aData);
UniquePtr<GetNodeIdCallback> callback(
new gmp_InitGetGMPDecryptorCallback(this, Move(aData)));
nsresult rv = mps->GetNodeId(data.mOrigin,
data.mTopLevelOrigin,
data.mGMPName,
Move(callback));
if (NS_FAILED(rv)) {
RejectPromise(data.mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Call to GetNodeId() failed early"));
}
}
void
GMPCDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult,
const nsACString& aNodeId,
UniquePtr<InitData>&& aData)
{
uint32_t promiseID = aData->mPromiseId;
if (NS_FAILED(aResult)) {
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("GetNodeId() called back, but with a failure result"));
return;
}
mNodeId = aNodeId;
MOZ_ASSERT(!GetNodeId().IsEmpty());
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!mps) {
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_InitGetGMPDecryptor"));
return;
}
EME_LOG("GMPCDMProxy::gmp_Init (%s, %s) NodeId=%s",
NS_ConvertUTF16toUTF8(aData->mOrigin).get(),
NS_ConvertUTF16toUTF8(aData->mTopLevelOrigin).get(),
GetNodeId().get());
nsTArray<nsCString> tags;
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
// Note: must capture helper refptr here, before the Move()
// when we create the GetGMPDecryptorCallback below.
RefPtr<GMPCrashHelper> crashHelper = Move(aData->mCrashHelper);
UniquePtr<GetGMPDecryptorCallback> callback(new gmp_InitDoneCallback(this,
Move(aData)));
nsresult rv = mps->GetGMPDecryptor(crashHelper,
&tags,
GetNodeId(),
Move(callback));
if (NS_FAILED(rv)) {
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Call to GetGMPDecryptor() failed early"));
}
}
void
GMPCDMProxy::OnCDMCreated(uint32_t aPromiseId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
MOZ_ASSERT(!GetNodeId().IsEmpty());
if (mCDM) {
mKeys->OnCDMCreated(aPromiseId, mCDM->GetPluginId());
} else {
// No CDM? Just reject the promise.
mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
}
}
void
GMPCDMProxy::CreateSession(uint32_t aCreateSessionToken,
dom::MediaKeySessionType aSessionType,
PromiseId aPromiseId,
const nsAString& aInitDataType,
nsTArray<uint8_t>& aInitData)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
UniquePtr<CreateSessionData> data(new CreateSessionData());
data->mSessionType = aSessionType;
data->mCreateSessionToken = aCreateSessionToken;
data->mPromiseId = aPromiseId;
data->mInitDataType = NS_ConvertUTF16toUTF8(aInitDataType);
data->mInitData = Move(aInitData);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<CreateSessionData>&&>("GMPCDMProxy::gmp_CreateSession",
this,
&GMPCDMProxy::gmp_CreateSession,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
GMPSessionType
ToGMPSessionType(dom::MediaKeySessionType aSessionType) {
switch (aSessionType) {
case dom::MediaKeySessionType::Temporary: return kGMPTemporySession;
case dom::MediaKeySessionType::Persistent_license: return kGMPPersistentSession;
default: return kGMPTemporySession;
};
};
void
GMPCDMProxy::gmp_CreateSession(UniquePtr<CreateSessionData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_CreateSession"));
return;
}
mCDM->CreateSession(aData->mCreateSessionToken,
aData->mPromiseId,
aData->mInitDataType,
aData->mInitData,
ToGMPSessionType(aData->mSessionType));
}
void
GMPCDMProxy::LoadSession(PromiseId aPromiseId,
dom::MediaKeySessionType aSessionType,
const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
UniquePtr<SessionOpData> data(new SessionOpData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<SessionOpData>&&>("GMPCDMProxy::gmp_LoadSession",
this,
&GMPCDMProxy::gmp_LoadSession,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
void
GMPCDMProxy::gmp_LoadSession(UniquePtr<SessionOpData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_LoadSession"));
return;
}
mCDM->LoadSession(aData->mPromiseId, aData->mSessionId);
}
void
GMPCDMProxy::SetServerCertificate(PromiseId aPromiseId,
nsTArray<uint8_t>& aCert)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
UniquePtr<SetServerCertificateData> data(new SetServerCertificateData());
data->mPromiseId = aPromiseId;
data->mCert = Move(aCert);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<SetServerCertificateData>&&>("GMPCDMProxy::gmp_SetServerCertificate",
this,
&GMPCDMProxy::gmp_SetServerCertificate,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
void
GMPCDMProxy::gmp_SetServerCertificate(UniquePtr<SetServerCertificateData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_SetServerCertificate"));
return;
}
mCDM->SetServerCertificate(aData->mPromiseId, aData->mCert);
}
void
GMPCDMProxy::UpdateSession(const nsAString& aSessionId,
PromiseId aPromiseId,
nsTArray<uint8_t>& aResponse)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
UniquePtr<UpdateSessionData> data(new UpdateSessionData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
data->mResponse = Move(aResponse);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<UpdateSessionData>&&>("GMPCDMProxy::gmp_UpdateSession",
this,
&GMPCDMProxy::gmp_UpdateSession,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
void
GMPCDMProxy::gmp_UpdateSession(UniquePtr<UpdateSessionData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_UpdateSession"));
return;
}
mCDM->UpdateSession(aData->mPromiseId,
aData->mSessionId,
aData->mResponse);
}
void
GMPCDMProxy::CloseSession(const nsAString& aSessionId,
PromiseId aPromiseId)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
UniquePtr<SessionOpData> data(new SessionOpData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<SessionOpData>&&>("GMPCDMProxy::gmp_CloseSession",
this,
&GMPCDMProxy::gmp_CloseSession,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
void
GMPCDMProxy::gmp_CloseSession(UniquePtr<SessionOpData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_CloseSession"));
return;
}
mCDM->CloseSession(aData->mPromiseId, aData->mSessionId);
}
void
GMPCDMProxy::RemoveSession(const nsAString& aSessionId,
PromiseId aPromiseId)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
UniquePtr<SessionOpData> data(new SessionOpData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<UniquePtr<SessionOpData>&&>("GMPCDMProxy::gmp_RemoveSession",
this,
&GMPCDMProxy::gmp_RemoveSession,
Move(data)));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
void
GMPCDMProxy::gmp_RemoveSession(UniquePtr<SessionOpData>&& aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in gmp_RemoveSession"));
return;
}
mCDM->RemoveSession(aData->mPromiseId, aData->mSessionId);
}
void
GMPCDMProxy::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
mKeys.Clear();
// Note: This may end up being the last owning reference to the GMPCDMProxy.
nsCOMPtr<nsIRunnable> task(NewRunnableMethod(
"GMPCDMProxy::gmp_Shutdown", this, &GMPCDMProxy::gmp_Shutdown));
if (mOwnerThread) {
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
}
void
GMPCDMProxy::gmp_Shutdown()
{
MOZ_ASSERT(IsOnOwnerThread());
mShutdownCalled = true;
// Abort any pending decrypt jobs, to awaken any clients waiting on a job.
for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
DecryptJob* job = mDecryptionJobs[i];
job->PostResult(eme::AbortedErr);
}
mDecryptionJobs.Clear();
if (mCDM) {
mCDM->Close();
mCDM = nullptr;
}
}
void
GMPCDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
const nsCString& aReason)
{
if (NS_IsMainThread()) {
if (!mKeys.IsNull()) {
mKeys->RejectPromise(aId, aCode, aReason);
}
} else {
nsCOMPtr<nsIRunnable> task(new RejectPromiseTask(this, aId, aCode,
aReason));
mMainThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
}
void
GMPCDMProxy::ResolvePromise(PromiseId aId)
{
if (NS_IsMainThread()) {
if (!mKeys.IsNull()) {
mKeys->ResolvePromise(aId);
} else {
NS_WARNING("GMPCDMProxy unable to resolve promise!");
}
} else {
nsCOMPtr<nsIRunnable> task;
task = NewRunnableMethod<PromiseId>(
"GMPCDMProxy::ResolvePromise", this, &GMPCDMProxy::ResolvePromise, aId);
mMainThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
}
const nsCString&
GMPCDMProxy::GetNodeId() const
{
return mNodeId;
}
void
GMPCDMProxy::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
GMPCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
mKeys->OnSessionLoaded(aPromiseId, aSuccess);
}
void
GMPCDMProxy::OnSessionMessage(const nsAString& aSessionId,
dom::MediaKeyMessageType aMessageType,
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);
}
}
void
GMPCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->DispatchKeyStatusesChange();
}
}
void
GMPCDMProxy::OnExpirationChange(const nsAString& aSessionId,
GMPTimestamp aExpiryTime)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
// Expiry of 0 is interpreted as "never expire". See bug 1345341.
double t = (aExpiryTime == 0) ? std::numeric_limits<double>::quiet_NaN()
: static_cast<double>(aExpiryTime);
session->SetExpiration(t);
}
}
void
GMPCDMProxy::OnSessionClosed(const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->OnClosed();
}
}
void
GMPCDMProxy::OnDecrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData)
{
MOZ_ASSERT(IsOnOwnerThread());
gmp_Decrypted(aId, aResult, aDecryptedData);
}
void
GMPCDMProxy::OnSessionError(const nsAString& aSessionId,
nsresult aException,
uint32_t aSystemCode,
const nsAString& aMsg)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->DispatchKeyError(aSystemCode);
}
LogToConsole(aMsg);
}
void
GMPCDMProxy::OnRejectPromise(uint32_t aPromiseId,
nsresult aDOMException,
const nsCString& aMsg)
{
MOZ_ASSERT(NS_IsMainThread());
RejectPromise(aPromiseId, aDOMException, aMsg);
}
const nsString&
GMPCDMProxy::KeySystem() const
{
return mKeySystem;
}
CDMCaps&
GMPCDMProxy::Capabilites() {
return mCapabilites;
}
RefPtr<DecryptPromise>
GMPCDMProxy::Decrypt(MediaRawData* aSample)
{
RefPtr<DecryptJob> job(new DecryptJob(aSample));
RefPtr<DecryptPromise> promise(job->Ensure());
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<RefPtr<DecryptJob>>("GMPCDMProxy::gmp_Decrypt",
this, &GMPCDMProxy::gmp_Decrypt, job));
mOwnerThread->EventTarget()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
return promise;
}
void
GMPCDMProxy::gmp_Decrypt(RefPtr<DecryptJob> aJob)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
aJob->PostResult(eme::AbortedErr);
return;
}
nsTArray<uint8_t> data;
data.AppendElements(aJob->mSample->Data(), aJob->mSample->Size());
mCDM->Decrypt(aJob->mId, aJob->mSample->mCrypto, data);
mDecryptionJobs.AppendElement(aJob.forget());
}
void
GMPCDMProxy::gmp_Decrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData)
{
MOZ_ASSERT(IsOnOwnerThread());
#ifdef DEBUG
bool jobIdFound = false;
#endif
for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
DecryptJob* job = mDecryptionJobs[i];
if (job->mId == aId) {
#ifdef DEBUG
jobIdFound = true;
#endif
job->PostResult(aResult, aDecryptedData);
mDecryptionJobs.RemoveElementAt(i);
}
}
#ifdef DEBUG
if (!jobIdFound) {
NS_WARNING("GMPDecryptorChild returned incorrect job ID");
}
#endif
}
void
GMPCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
nsTArray<nsCString>& aSessionIds)
{
CDMCaps::AutoLock caps(Capabilites());
caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
}
void
GMPCDMProxy::Terminated()
{
MOZ_ASSERT(NS_IsMainThread());
NS_WARNING("CDM terminated");
if (mCreatePromiseId) {
RejectPromise(mCreatePromiseId,
NS_ERROR_DOM_MEDIA_FATAL_ERR,
NS_LITERAL_CSTRING("Crashed waiting for CDM to initialize"));
mCreatePromiseId = 0;
}
if (!mKeys.IsNull()) {
mKeys->Terminated();
}
}
uint32_t
GMPCDMProxy::GetDecryptorId()
{
return mDecryptorId;
}
} // namespace mozilla

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

@ -1,236 +0,0 @@
/* -*- 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/. */
#ifndef GMPCDMProxy_h_
#define GMPCDMProxy_h_
#include "mozilla/CDMProxy.h"
#include "GMPCDMCallbackProxy.h"
#include "GMPDecryptorProxy.h"
namespace mozilla {
class MediaRawData;
class DecryptJob;
// Implementation of CDMProxy which is based on GMP architecture.
class GMPCDMProxy : public CDMProxy {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPCDMProxy, override)
GMPCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,
GMPCrashHelper* aCrashHelper,
bool aDistinctiveIdentifierRequired,
bool aPersistentStateRequired,
nsIEventTarget* aMainThread);
void Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName) override;
void OnSetDecryptorId(uint32_t aId) override;
void CreateSession(uint32_t aCreateSessionToken,
dom::MediaKeySessionType aSessionType,
PromiseId aPromiseId,
const nsAString& aInitDataType,
nsTArray<uint8_t>& aInitData) override;
void LoadSession(PromiseId aPromiseId,
dom::MediaKeySessionType aSessionType,
const nsAString& aSessionId) override;
void SetServerCertificate(PromiseId aPromiseId,
nsTArray<uint8_t>& aCert) override;
void UpdateSession(const nsAString& aSessionId,
PromiseId aPromiseId,
nsTArray<uint8_t>& aResponse) override;
void CloseSession(const nsAString& aSessionId,
PromiseId aPromiseId) override;
void RemoveSession(const nsAString& aSessionId,
PromiseId aPromiseId) override;
void Shutdown() override;
void Terminated() override;
const nsCString& GetNodeId() const override;
void OnSetSessionId(uint32_t aCreateSessionToken,
const nsAString& aSessionId) override;
void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) override;
void OnSessionMessage(const nsAString& aSessionId,
dom::MediaKeyMessageType aMessageType,
nsTArray<uint8_t>& aMessage) override;
void OnExpirationChange(const nsAString& aSessionId,
GMPTimestamp aExpiryTime) override;
void OnSessionClosed(const nsAString& aSessionId) override;
void OnSessionError(const nsAString& aSessionId,
nsresult aException,
uint32_t aSystemCode,
const nsAString& aMsg) override;
void OnRejectPromise(uint32_t aPromiseId,
nsresult aDOMException,
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 aExceptionCode,
const nsCString& aReason) override;
void ResolvePromise(PromiseId aId) override;
const nsString& KeySystem() const override;
CDMCaps& Capabilites() override;
void OnKeyStatusesChange(const nsAString& aSessionId) override;
void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
nsTArray<nsCString>& aSessionIds) override;
#ifdef DEBUG
bool IsOnOwnerThread() override;
#endif
uint32_t GetDecryptorId() override;
private:
friend class gmp_InitDoneCallback;
friend class gmp_InitGetGMPDecryptorCallback;
struct InitData {
uint32_t mPromiseId;
nsString mOrigin;
nsString mTopLevelOrigin;
nsString mGMPName;
RefPtr<GMPCrashHelper> mCrashHelper;
};
// GMP thread only.
void gmp_Init(UniquePtr<InitData>&& aData);
void gmp_InitDone(GMPDecryptorProxy* aCDM, UniquePtr<InitData>&& aData);
void gmp_InitGetGMPDecryptor(nsresult aResult,
const nsACString& aNodeId,
UniquePtr<InitData>&& aData);
// GMP thread only.
void gmp_Shutdown();
// Main thread only.
void OnCDMCreated(uint32_t aPromiseId);
struct CreateSessionData {
dom::MediaKeySessionType mSessionType;
uint32_t mCreateSessionToken;
PromiseId mPromiseId;
nsCString mInitDataType;
nsTArray<uint8_t> mInitData;
};
// GMP thread only.
void gmp_CreateSession(UniquePtr<CreateSessionData>&& aData);
struct SessionOpData {
PromiseId mPromiseId;
nsCString mSessionId;
};
// GMP thread only.
void gmp_LoadSession(UniquePtr<SessionOpData>&& aData);
struct SetServerCertificateData {
PromiseId mPromiseId;
nsTArray<uint8_t> mCert;
};
// GMP thread only.
void gmp_SetServerCertificate(UniquePtr<SetServerCertificateData>&& aData);
struct UpdateSessionData {
PromiseId mPromiseId;
nsCString mSessionId;
nsTArray<uint8_t> mResponse;
};
// GMP thread only.
void gmp_UpdateSession(UniquePtr<UpdateSessionData>&& aData);
// GMP thread only.
void gmp_CloseSession(UniquePtr<SessionOpData>&& aData);
// GMP thread only.
void gmp_RemoveSession(UniquePtr<SessionOpData>&& aData);
// GMP thread only.
void gmp_Decrypt(RefPtr<DecryptJob> aJob);
// GMP thread only.
void gmp_Decrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData);
class RejectPromiseTask : public Runnable {
public:
RejectPromiseTask(GMPCDMProxy* aProxy,
PromiseId aId,
nsresult aCode,
const nsCString& aReason)
: Runnable("GMPCDMProxy::RejectPromiseTask")
, mProxy(aProxy)
, mId(aId)
, mCode(aCode)
, mReason(aReason)
{
}
NS_IMETHOD Run() override {
mProxy->RejectPromise(mId, mCode, mReason);
return NS_OK;
}
private:
RefPtr<GMPCDMProxy> mProxy;
PromiseId mId;
nsresult mCode;
nsCString mReason;
};
~GMPCDMProxy();
GMPCrashHelper* mCrashHelper;
GMPDecryptorProxy* mCDM;
UniquePtr<GMPCDMCallbackProxy> mCallback;
// Decryption jobs sent to CDM, awaiting result.
// GMP thread only.
nsTArray<RefPtr<DecryptJob>> mDecryptionJobs;
// True if GMPCDMProxy::gmp_Shutdown was called.
// GMP thread only.
bool mShutdownCalled;
uint32_t mDecryptorId;
PromiseId mCreatePromiseId;
};
} // namespace mozilla
#endif // GMPCDMProxy_h_

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

@ -30,7 +30,6 @@ EXPORTS += [
'gmp-api/gmp-video-plane.h',
'GMPCallbackBase.h',
'GMPCDMCallbackProxy.h',
'GMPCDMProxy.h',
'GMPChild.h',
'GMPContentChild.h',
'GMPContentParent.h',
@ -78,7 +77,6 @@ UNIFIED_SOURCES += [
'ChromiumCDMProxy.cpp',
'DecryptJob.cpp',
'GMPCDMCallbackProxy.cpp',
'GMPCDMProxy.cpp',
'GMPChild.cpp',
'GMPContentChild.cpp',
'GMPContentParent.cpp',

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

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "EMEDecoderModule.h"
#include "EMEVideoDecoder.h"
#include "GMPDecoderModule.h"
#include "GMPService.h"
#include "MediaInfo.h"

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

@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "EMEVideoDecoder.h"
#include "GMPVideoEncodedFrameImpl.h"
#include "MP4Decoder.h"
#include "MediaData.h"
#include "PlatformDecoderModule.h"
#include "VPXDecoder.h"
#include "mozilla/CDMProxy.h"
namespace mozilla {
EMEVideoDecoder::EMEVideoDecoder(CDMProxy* aProxy,
const GMPVideoDecoderParams& aParams)
: GMPVideoDecoder(GMPVideoDecoderParams(aParams))
, mProxy(aProxy)
, mDecryptorId(aProxy->GetDecryptorId())
{
}
void
EMEVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
{
VideoInfo config = GetConfig();
if (MP4Decoder::IsH264(config.mMimeType)) {
aTags.AppendElement(NS_LITERAL_CSTRING("h264"));
} else if (VPXDecoder::IsVP8(config.mMimeType)) {
aTags.AppendElement(NS_LITERAL_CSTRING("vp8"));
} else if (VPXDecoder::IsVP9(config.mMimeType)) {
aTags.AppendElement(NS_LITERAL_CSTRING("vp9"));
}
aTags.AppendElement(NS_ConvertUTF16toUTF8(mProxy->KeySystem()));
}
nsCString
EMEVideoDecoder::GetNodeId()
{
return mProxy->GetNodeId();
}
GMPUniquePtr<GMPVideoEncodedFrame>
EMEVideoDecoder::CreateFrame(MediaRawData* aSample)
{
GMPUniquePtr<GMPVideoEncodedFrame> frame =
GMPVideoDecoder::CreateFrame(aSample);
if (frame && aSample->mCrypto.mValid) {
static_cast<gmp::GMPVideoEncodedFrameImpl*>(frame.get())
->InitCrypto(aSample->mCrypto);
}
return frame;
}
} // namespace mozilla

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

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 EMEVideoDecoder_h_
#define EMEVideoDecoder_h_
#include "GMPVideoDecoder.h"
namespace mozilla {
class CDMProxy;
class MediaRawData;
class TaskQueue;
class EMEVideoDecoder : public GMPVideoDecoder
{
public:
EMEVideoDecoder(CDMProxy* aProxy, const GMPVideoDecoderParams& aParams);
private:
void InitTags(nsTArray<nsCString>& aTags) override;
nsCString GetNodeId() override;
uint32_t DecryptorId() const override { return mDecryptorId; }
GMPUniquePtr<GMPVideoEncodedFrame>
CreateFrame(MediaRawData* aSample) override;
RefPtr<CDMProxy> mProxy;
uint32_t mDecryptorId;
};
} // namespace mozilla
#endif // EMEVideoDecoder_h_

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

@ -8,14 +8,12 @@ EXPORTS += [
'ChromiumCDMVideoDecoder.h',
'DecryptThroughputLimit.h',
'EMEDecoderModule.h',
'EMEVideoDecoder.h',
'SamplesWaitingForKey.h',
]
UNIFIED_SOURCES += [
'ChromiumCDMVideoDecoder.cpp',
'EMEDecoderModule.cpp',
'EMEVideoDecoder.cpp',
'SamplesWaitingForKey.cpp',
]