Bug 1306572 - Part3 - Implement MediaCDMProxy and the callback proxy. r=cpearce

MozReview-Commit-ID: 3dFawuvhfWu

--HG--
extra : rebase_source : 2c77a0c1b9e7a3c1067f12ebf4a416ae4417f3e6
This commit is contained in:
James Cheng 2016-11-01 14:39:34 +08:00
parent 34683786c0
commit 15a599af5d
6 changed files with 879 additions and 0 deletions

View File

@ -0,0 +1,140 @@
/* -*- 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 "MediaDrmCDMCallbackProxy.h"
#include "mozilla/CDMProxy.h"
#include "nsString.h"
#include "mozilla/dom/MediaKeys.h"
#include "mozilla/dom/MediaKeySession.h"
#include "mozIGeckoMediaPluginService.h"
#include "nsContentCID.h"
#include "nsServiceManagerUtils.h"
#include "MainThreadUtils.h"
#include "mozilla/EMEUtils.h"
namespace mozilla {
MediaDrmCDMCallbackProxy::MediaDrmCDMCallbackProxy(CDMProxy* aProxy)
: mProxy(aProxy)
{
}
void
MediaDrmCDMCallbackProxy::SetSessionId(uint32_t aToken,
const nsCString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
mProxy->OnSetSessionId(aToken, NS_ConvertUTF8toUTF16(aSessionId));
}
void
MediaDrmCDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccess)
{
MOZ_ASSERT(NS_IsMainThread());
mProxy->OnResolveLoadSessionPromise(aPromiseId, aSuccess);
}
void
MediaDrmCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId)
{
// Note: CDMProxy proxies this from non-main threads to main thread.
mProxy->ResolvePromise(aPromiseId);
}
void
MediaDrmCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
nsresult aException,
const nsCString& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
mProxy->OnRejectPromise(aPromiseId, aException, aMessage);
}
void
MediaDrmCDMCallbackProxy::SessionMessage(const nsCString& aSessionId,
dom::MediaKeyMessageType aMessageType,
const nsTArray<uint8_t>& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
// For removing constness
nsTArray<uint8_t> message(aMessage);
mProxy->OnSessionMessage(NS_ConvertUTF8toUTF16(aSessionId), aMessageType, message);
}
void
MediaDrmCDMCallbackProxy::ExpirationChange(const nsCString& aSessionId,
UnixTime aExpiryTime)
{
MOZ_ASSERT(NS_IsMainThread());
mProxy->OnExpirationChange(NS_ConvertUTF8toUTF16(aSessionId), aExpiryTime);
}
void
MediaDrmCDMCallbackProxy::SessionClosed(const nsCString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
bool keyStatusesChange = false;
{
CDMCaps::AutoLock caps(mProxy->Capabilites());
keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId));
}
if (keyStatusesChange) {
mProxy->OnKeyStatusesChange(NS_ConvertUTF8toUTF16(aSessionId));
}
mProxy->OnSessionClosed(NS_ConvertUTF8toUTF16(aSessionId));
}
void
MediaDrmCDMCallbackProxy::SessionError(const nsCString& aSessionId,
nsresult aException,
uint32_t aSystemCode,
const nsCString& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
mProxy->OnSessionError(NS_ConvertUTF8toUTF16(aSessionId),
aException,
aSystemCode,
NS_ConvertUTF8toUTF16(aMessage));
}
void
MediaDrmCDMCallbackProxy::BatchedKeyStatusChanged(const nsCString& aSessionId,
const nsTArray<CDMKeyInfo>& aKeyInfos)
{
MOZ_ASSERT(NS_IsMainThread());
BatchedKeyStatusChangedInternal(aSessionId, aKeyInfos);
}
void
MediaDrmCDMCallbackProxy::BatchedKeyStatusChangedInternal(const nsCString& aSessionId,
const nsTArray<CDMKeyInfo>& aKeyInfos)
{
bool keyStatusesChange = false;
{
CDMCaps::AutoLock caps(mProxy->Capabilites());
for (size_t i = 0; i < aKeyInfos.Length(); i++) {
keyStatusesChange |=
caps.SetKeyStatus(aKeyInfos[i].mKeyId,
NS_ConvertUTF8toUTF16(aSessionId),
aKeyInfos[i].mStatus);
}
}
if (keyStatusesChange) {
mProxy->OnKeyStatusesChange(NS_ConvertUTF8toUTF16(aSessionId));
}
}
void
MediaDrmCDMCallbackProxy::Decrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData)
{
MOZ_ASSERT_UNREACHABLE("Fennec could not handle decrypted event");
}
} // namespace mozilla

View File

@ -0,0 +1,66 @@
/* -*- 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 MediaDrmCDMCallbackProxy_h_
#define MediaDrmCDMCallbackProxy_h_
#include "mozilla/CDMProxy.h"
#include "mozilla/DecryptorProxyCallback.h"
namespace mozilla {
class CDMProxy;
// Proxies call backs from the MediaDrmProxy -> MediaDrmProxySupport back to the MediaKeys
// object on the main thread.
// We used annotation calledFrom = "gecko" to ensure running on main thread.
class MediaDrmCDMCallbackProxy : public DecryptorProxyCallback {
public:
void SetSessionId(uint32_t aCreateSessionToken,
const nsCString& aSessionId) override;
void ResolveLoadSessionPromise(uint32_t aPromiseId,
bool aSuccess) override;
void ResolvePromise(uint32_t aPromiseId) override;
void RejectPromise(uint32_t aPromiseId,
nsresult aException,
const nsCString& aSessionId) override;
void SessionMessage(const nsCString& aSessionId,
dom::MediaKeyMessageType aMessageType,
const nsTArray<uint8_t>& aMessage) override;
void ExpirationChange(const nsCString& aSessionId,
UnixTime aExpiryTime) override;
void SessionClosed(const nsCString& aSessionId) override;
void SessionError(const nsCString& aSessionId,
nsresult aException,
uint32_t aSystemCode,
const nsCString& aMessage) override;
void Decrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData) override;
void BatchedKeyStatusChanged(const nsCString& aSessionId,
const nsTArray<CDMKeyInfo>& aKeyInfos) override;
~MediaDrmCDMCallbackProxy() {}
private:
friend class MediaDrmCDMProxy;
explicit MediaDrmCDMCallbackProxy(CDMProxy* aProxy);
void BatchedKeyStatusChangedInternal(const nsCString& aSessionId,
const nsTArray<CDMKeyInfo>& aKeyInfos);
// Warning: Weak ref.
CDMProxy* mProxy;
};
} // namespace mozilla
#endif

View File

@ -0,0 +1,467 @@
/* -*- 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 "mozilla/dom/MediaKeySession.h"
#include "mozilla/MediaDrmCDMProxy.h"
#include "MediaDrmCDMCallbackProxy.h"
using namespace mozilla::java::sdk;
namespace mozilla {
MediaDrmSessionType
ToMediaDrmSessionType(dom::MediaKeySessionType aSessionType)
{
switch (aSessionType) {
case dom::MediaKeySessionType::Temporary: return kKeyStreaming;
case dom::MediaKeySessionType::Persistent_license: return kKeyOffline;
default: return kKeyStreaming;
};
}
MediaDrmCDMProxy::MediaDrmCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,
bool aDistinctiveIdentifierRequired,
bool aPersistentStateRequired)
: CDMProxy(aKeys,
aKeySystem,
aDistinctiveIdentifierRequired,
aPersistentStateRequired)
, mCDM(nullptr)
, mShutdownCalled(false)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(MediaDrmCDMProxy);
}
MediaDrmCDMProxy::~MediaDrmCDMProxy()
{
MOZ_COUNT_DTOR(MediaDrmCDMProxy);
}
void
MediaDrmCDMProxy::Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aName,
bool aInPrivateBrowsing)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
EME_LOG("MediaDrmCDMProxy::Init (%s, %s) %s",
NS_ConvertUTF16toUTF8(aOrigin).get(),
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
(aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
// Create a thread to work with cdm.
if (!mOwnerThread) {
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"));
return;
}
}
mCDM = mozilla::MakeUnique<MediaDrmProxySupport>(mKeySystem);
nsCOMPtr<nsIRunnable> task(NewRunnableMethod<uint32_t>(this,
&MediaDrmCDMProxy::md_Init,
aPromiseId));
mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
}
void
MediaDrmCDMProxy::CreateSession(uint32_t aCreateSessionToken,
MediaKeySessionType aSessionType,
PromiseId aPromiseId,
const nsAString& aInitDataType,
nsTArray<uint8_t>& aInitData)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
nsAutoPtr<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<nsAutoPtr<CreateSessionData>>(this,
&MediaDrmCDMProxy::md_CreateSession,
data));
mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
}
void
MediaDrmCDMProxy::LoadSession(PromiseId aPromiseId,
const nsAString& aSessionId)
{
// TODO: Implement LoadSession.
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Currently Fennec did not support LoadSession"));
}
void
MediaDrmCDMProxy::SetServerCertificate(PromiseId aPromiseId,
nsTArray<uint8_t>& aCert)
{
// TODO: Implement SetServerCertificate.
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Currently Fennec did not support SetServerCertificate"));
}
void
MediaDrmCDMProxy::UpdateSession(const nsAString& aSessionId,
PromiseId aPromiseId,
nsTArray<uint8_t>& aResponse)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
nsAutoPtr<UpdateSessionData> data(new UpdateSessionData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
data->mResponse = Move(aResponse);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<nsAutoPtr<UpdateSessionData>>(this,
&MediaDrmCDMProxy::md_UpdateSession,
data));
mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
}
void
MediaDrmCDMProxy::CloseSession(const nsAString& aSessionId,
PromiseId aPromiseId)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
nsAutoPtr<SessionOpData> data(new SessionOpData());
data->mPromiseId = aPromiseId;
data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<nsAutoPtr<SessionOpData>>(this,
&MediaDrmCDMProxy::md_CloseSession,
data));
mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
}
void
MediaDrmCDMProxy::RemoveSession(const nsAString& aSessionId,
PromiseId aPromiseId)
{
// TODO: Implement RemoveSession.
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Currently Fennec did not support RemoveSession"));
}
void
MediaDrmCDMProxy::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mOwnerThread);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod(this, &MediaDrmCDMProxy::md_Shutdown));
mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
mOwnerThread->Shutdown();
mOwnerThread = nullptr;
}
void
MediaDrmCDMProxy::Terminated()
{
// TODO: Implement Terminated.
// Should find a way to handle the case when remote side MediaDrm crashed.
}
const nsCString&
MediaDrmCDMProxy::GetNodeId() const
{
return mNodeId;
}
void
MediaDrmCDMProxy::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
MediaDrmCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
mKeys->OnSessionLoaded(aPromiseId, aSuccess);
}
void
MediaDrmCDMProxy::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
MediaDrmCDMProxy::OnExpirationChange(const nsAString& aSessionId,
UnixTime aExpiryTime)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->SetExpiration(static_cast<double>(aExpiryTime));
}
}
void
MediaDrmCDMProxy::OnSessionClosed(const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->OnClosed();
}
}
void
MediaDrmCDMProxy::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);
}
}
void
MediaDrmCDMProxy::OnRejectPromise(uint32_t aPromiseId,
nsresult aDOMException,
const nsCString& aMsg)
{
MOZ_ASSERT(NS_IsMainThread());
RejectPromise(aPromiseId, aDOMException, aMsg);
}
RefPtr<MediaDrmCDMProxy::DecryptPromise>
MediaDrmCDMProxy::Decrypt(MediaRawData* aSample)
{
MOZ_ASSERT_UNREACHABLE("Fennec could not handle decrypting individually");
return nullptr;
}
void
MediaDrmCDMProxy::OnDecrypted(uint32_t aId,
DecryptStatus aResult,
const nsTArray<uint8_t>& aDecryptedData)
{
MOZ_ASSERT_UNREACHABLE("Fennec could not handle decrypted event");
}
void
MediaDrmCDMProxy::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));
NS_DispatchToMainThread(task);
}
}
void
MediaDrmCDMProxy::ResolvePromise(PromiseId aId)
{
if (NS_IsMainThread()) {
if (!mKeys.IsNull()) {
mKeys->ResolvePromise(aId);
} else {
NS_WARNING("MediaDrmCDMProxy unable to resolve promise!");
}
} else {
nsCOMPtr<nsIRunnable> task;
task = NewRunnableMethod<PromiseId>(this,
&MediaDrmCDMProxy::ResolvePromise,
aId);
NS_DispatchToMainThread(task);
}
}
const nsString&
MediaDrmCDMProxy::KeySystem() const
{
return mKeySystem;
}
CDMCaps&
MediaDrmCDMProxy::Capabilites()
{
return mCapabilites;
}
void
MediaDrmCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
if (session) {
session->DispatchKeyStatusesChange();
}
}
void
MediaDrmCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
nsTArray<nsCString>& aSessionIds)
{
CDMCaps::AutoLock caps(Capabilites());
caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
}
#ifdef DEBUG
bool
MediaDrmCDMProxy::IsOnOwnerThread()
{
return NS_GetCurrentThread() == mOwnerThread;
}
#endif
void
MediaDrmCDMProxy::OnCDMCreated(uint32_t aPromiseId)
{
MOZ_ASSERT(NS_IsMainThread());
if (mKeys.IsNull()) {
return;
}
if (mCDM) {
mKeys->OnCDMCreated(aPromiseId, GetNodeId(), 0);
return;
}
// No CDM? Just reject the promise.
mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
}
void
MediaDrmCDMProxy::md_Init(uint32_t aPromiseId)
{
MOZ_ASSERT(IsOnOwnerThread());
MOZ_ASSERT(mCDM);
mCallback = new MediaDrmCDMCallbackProxy(this);
mCDM->Init(mCallback);
nsCOMPtr<nsIRunnable> task(
NewRunnableMethod<uint32_t>(this,
&MediaDrmCDMProxy::OnCDMCreated,
aPromiseId));
NS_DispatchToMainThread(task);
}
void
MediaDrmCDMProxy::md_CreateSession(nsAutoPtr<CreateSessionData> aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in md_CreateSession"));
return;
}
mCDM->CreateSession(aData->mCreateSessionToken,
aData->mPromiseId,
aData->mInitDataType,
aData->mInitData,
ToMediaDrmSessionType(aData->mSessionType));
}
void
MediaDrmCDMProxy::md_UpdateSession(nsAutoPtr<UpdateSessionData> aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in md_UpdateSession"));
return;
}
mCDM->UpdateSession(aData->mPromiseId,
aData->mSessionId,
aData->mResponse);
}
void
MediaDrmCDMProxy::md_CloseSession(nsAutoPtr<SessionOpData> aData)
{
MOZ_ASSERT(IsOnOwnerThread());
if (!mCDM) {
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Null CDM in md_CloseSession"));
return;
}
mCDM->CloseSession(aData->mPromiseId, aData->mSessionId);
}
void
MediaDrmCDMProxy::md_Shutdown()
{
MOZ_ASSERT(IsOnOwnerThread());
MOZ_ASSERT(mCDM);
if (mShutdownCalled) {
return;
}
mShutdownCalled = true;
mCDM->Shutdown();
mCDM = nullptr;
}
} // namespace mozilla

View File

@ -0,0 +1,184 @@
/* -*- 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 MediaDrmCDMProxy_h_
#define MediaDrmCDMProxy_h_
#include <jni.h>
#include "mozilla/jni/Types.h"
#include "GeneratedJNINatives.h"
#include "mozilla/CDMProxy.h"
#include "mozilla/CDMCaps.h"
#include "mozilla/dom/MediaKeys.h"
#include "mozilla/MediaDrmProxySupport.h"
#include "mozilla/UniquePtr.h"
#include "MediaCodec.h"
#include "nsString.h"
#include "nsAutoPtr.h"
using namespace mozilla::java;
namespace mozilla {
class MediaDrmCDMCallbackProxy;
class MediaDrmCDMProxy : public CDMProxy {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCDMProxy)
MediaDrmCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,
bool aDistinctiveIdentifierRequired,
bool aPersistentStateRequired);
void Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing) override;
void CreateSession(uint32_t aCreateSessionToken,
MediaKeySessionType aSessionType,
PromiseId aPromiseId,
const nsAString& aInitDataType,
nsTArray<uint8_t>& aInitData) override;
void LoadSession(PromiseId aPromiseId,
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,
UnixTime 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 aCode,
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,
const nsCString& aReason) override;
// Resolves promise with "undefined".
// Can be called from any thread.
void ResolvePromise(PromiseId aId) override;
// Threadsafe.
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
private:
virtual ~MediaDrmCDMProxy();
void OnCDMCreated(uint32_t aPromiseId);
struct CreateSessionData {
MediaKeySessionType mSessionType;
uint32_t mCreateSessionToken;
PromiseId mPromiseId;
nsCString mInitDataType;
nsTArray<uint8_t> mInitData;
};
struct UpdateSessionData {
PromiseId mPromiseId;
nsCString mSessionId;
nsTArray<uint8_t> mResponse;
};
struct SessionOpData {
PromiseId mPromiseId;
nsCString mSessionId;
};
class RejectPromiseTask : public Runnable {
public:
RejectPromiseTask(MediaDrmCDMProxy* aProxy,
PromiseId aId,
nsresult aCode,
const nsCString& aReason)
: mProxy(aProxy)
, mId(aId)
, mCode(aCode)
, mReason(aReason)
{
}
NS_METHOD Run() {
mProxy->RejectPromise(mId, mCode, mReason);
return NS_OK;
}
private:
RefPtr<MediaDrmCDMProxy> mProxy;
PromiseId mId;
nsresult mCode;
nsCString mReason;
};
nsCString mNodeId;
mozilla::UniquePtr<MediaDrmProxySupport> mCDM;
nsAutoPtr<MediaDrmCDMCallbackProxy> mCallback;
bool mShutdownCalled;
// =====================================================================
// For MediaDrmProxySupport
void md_Init(uint32_t aPromiseId);
void md_CreateSession(nsAutoPtr<CreateSessionData> aData);
void md_UpdateSession(nsAutoPtr<UpdateSessionData> aData);
void md_CloseSession(nsAutoPtr<SessionOpData> aData);
void md_Shutdown();
// =====================================================================
};
} // namespace mozilla
#endif // MediaDrmCDMProxy_h_

View File

@ -0,0 +1,19 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.mozilla += [
'MediaDrmCDMCallbackProxy.h',
'MediaDrmCDMProxy.h',
'MediaDrmProxySupport.h',
]
UNIFIED_SOURCES += [
'MediaDrmCDMCallbackProxy.cpp',
'MediaDrmCDMProxy.cpp',
'MediaDrmProxySupport.cpp',
]
FINAL_LIBRARY = 'xul'

View File

@ -37,6 +37,9 @@ UNIFIED_SOURCES += [
'MediaKeySystemAccessManager.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
DIRS += ['mediadrm']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'