зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1060179 - Generate a random node id for every EME (origin,topLevelOrigin) pair. r=bz
This commit is contained in:
Родитель
332803273c
Коммит
a40c6073a5
|
@ -545,6 +545,11 @@ public:
|
|||
|
||||
|
||||
bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
|
||||
|
||||
// Returns the principal of the "top level" document; the origin displayed
|
||||
// in the URL bar of the browser window.
|
||||
already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
|
||||
|
||||
#endif // MOZ_EME
|
||||
|
||||
bool MozAutoplayEnabled() const
|
||||
|
|
|
@ -3407,6 +3407,11 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged()
|
|||
OutputMediaStream* ms = &mOutputStreams[i];
|
||||
ms->mStream->CombineWithPrincipal(principal);
|
||||
}
|
||||
#ifdef MOZ_EME
|
||||
if (mMediaKeys && NS_FAILED(mMediaKeys->CheckPrincipals())) {
|
||||
mMediaKeys->Shutdown();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
|
||||
|
@ -4008,16 +4013,34 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
|||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
// TODO: Need to shutdown existing MediaKeys instance? bug 1016709.
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mMediaKeys != aMediaKeys) {
|
||||
mMediaKeys = aMediaKeys;
|
||||
if (mMediaKeys == aMediaKeys) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
if (mDecoder) {
|
||||
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
|
||||
if (aMediaKeys && aMediaKeys->IsBoundToMediaElement()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
if (mMediaKeys) {
|
||||
// Existing MediaKeys object. Shut it down.
|
||||
mMediaKeys->Shutdown();
|
||||
mMediaKeys = nullptr;
|
||||
}
|
||||
|
||||
mMediaKeys = aMediaKeys;
|
||||
if (mMediaKeys) {
|
||||
if (NS_FAILED(mMediaKeys->Bind(this))) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
mMediaKeys = nullptr;
|
||||
return promise.forget();
|
||||
}
|
||||
if (mDecoder) {
|
||||
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
|
||||
}
|
||||
}
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
|
@ -4063,6 +4086,28 @@ HTMLMediaElement::IsEventAttributeName(nsIAtom* aName)
|
|||
return aName == nsGkAtoms::onencrypted ||
|
||||
nsGenericHTMLElement::IsEventAttributeName(aName);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPrincipal>
|
||||
HTMLMediaElement::GetTopLevelPrincipal()
|
||||
{
|
||||
nsRefPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(OwnerDoc()->GetParentObject());
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
window->GetTop(getter_AddRefs(topWindow));
|
||||
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
|
||||
if (!top) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIDocument* doc = top->GetExtantDoc();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
principal = doc->NodePrincipal();
|
||||
return principal.forget();
|
||||
}
|
||||
#endif // MOZ_EME
|
||||
|
||||
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged()
|
||||
|
|
|
@ -36,17 +36,18 @@ CDMProxy::~CDMProxy()
|
|||
}
|
||||
|
||||
void
|
||||
CDMProxy::Init(PromiseId aPromiseId)
|
||||
CDMProxy::Init(PromiseId aPromiseId,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
|
||||
|
||||
mNodeId = mKeys->GetNodeId();
|
||||
if (mNodeId.IsEmpty()) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
EME_LOG("Creating CDMProxy for origin='%s'", GetNodeId().get());
|
||||
EME_LOG("CDMProxy::Init (%s, %s) %s",
|
||||
NS_ConvertUTF16toUTF8(aOrigin).get(),
|
||||
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
|
||||
(aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
|
||||
|
||||
if (!mGMPThread) {
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
|
@ -61,8 +62,15 @@ CDMProxy::Init(PromiseId aPromiseId)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> task(NS_NewRunnableMethodWithArg<uint32_t>(this, &CDMProxy::gmp_Init, aPromiseId));
|
||||
nsAutoPtr<InitData> data(new InitData());
|
||||
data->mPromiseId = aPromiseId;
|
||||
data->mOrigin = aOrigin;
|
||||
data->mTopLevelOrigin = aTopLevelOrigin;
|
||||
data->mInPrivateBrowsing = aInPrivateBrowsing;
|
||||
nsRefPtr<nsIRunnable> task(
|
||||
NS_NewRunnableMethodWithArg<nsAutoPtr<InitData>>(this,
|
||||
&CDMProxy::gmp_Init,
|
||||
data));
|
||||
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -75,26 +83,45 @@ CDMProxy::IsOnGMPThread()
|
|||
#endif
|
||||
|
||||
void
|
||||
CDMProxy::gmp_Init(uint32_t aPromiseId)
|
||||
CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
||||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (!mps) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = mps->GetNodeId(aData->mOrigin,
|
||||
aData->mTopLevelOrigin,
|
||||
aData->mInPrivateBrowsing,
|
||||
mNodeId);
|
||||
MOZ_ASSERT(!GetNodeId().IsEmpty());
|
||||
if (NS_FAILED(rv)) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
EME_LOG("CDMProxy::gmp_Init (%s, %s) %s NodeId=%s",
|
||||
NS_ConvertUTF16toUTF8(aData->mOrigin).get(),
|
||||
NS_ConvertUTF16toUTF8(aData->mTopLevelOrigin).get(),
|
||||
(aData->mInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"),
|
||||
GetNodeId().get());
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
|
||||
nsresult rv = mps->GetGMPDecryptor(&tags, GetNodeId(), &mCDM);
|
||||
rv = mps->GetGMPDecryptor(&tags, GetNodeId(), &mCDM);
|
||||
if (NS_FAILED(rv) || !mCDM) {
|
||||
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
} else {
|
||||
mCallback = new CDMCallbackProxy(this);
|
||||
mCDM->Init(mCallback);
|
||||
nsRefPtr<nsIRunnable> task(NS_NewRunnableMethodWithArg<uint32_t>(this, &CDMProxy::OnCDMCreated, aPromiseId));
|
||||
nsRefPtr<nsIRunnable> task(
|
||||
NS_NewRunnableMethodWithArg<uint32_t>(this,
|
||||
&CDMProxy::OnCDMCreated,
|
||||
aData->mPromiseId));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +133,8 @@ CDMProxy::OnCDMCreated(uint32_t aPromiseId)
|
|||
if (mKeys.IsNull()) {
|
||||
return;
|
||||
}
|
||||
mKeys->OnCDMCreated(aPromiseId);
|
||||
MOZ_ASSERT(!GetNodeId().IsEmpty());
|
||||
mKeys->OnCDMCreated(aPromiseId, GetNodeId());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -303,9 +331,7 @@ CDMProxy::Shutdown()
|
|||
mKeys.Clear();
|
||||
// Note: This may end up being the last owning reference to the CDMProxy.
|
||||
nsRefPtr<nsIRunnable> task(NS_NewRunnableMethod(this, &CDMProxy::gmp_Shutdown));
|
||||
if (mGMPThread) {
|
||||
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -48,7 +48,10 @@ public:
|
|||
// Main thread only.
|
||||
// Loads the CDM corresponding to mKeySystem.
|
||||
// Calls MediaKeys::OnCDMCreated() when the CDM is created.
|
||||
void Init(PromiseId aPromiseId);
|
||||
void Init(PromiseId aPromiseId,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing);
|
||||
|
||||
// Main thread only.
|
||||
// Uses the CDM to create a key session.
|
||||
|
@ -165,8 +168,15 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
struct InitData {
|
||||
uint32_t mPromiseId;
|
||||
nsAutoString mOrigin;
|
||||
nsAutoString mTopLevelOrigin;
|
||||
bool mInPrivateBrowsing;
|
||||
};
|
||||
|
||||
// GMP thread only.
|
||||
void gmp_Init(uint32_t aPromiseId);
|
||||
void gmp_Init(nsAutoPtr<InitData> aData);
|
||||
|
||||
// GMP thread only.
|
||||
void gmp_Shutdown();
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeys,
|
||||
mElement,
|
||||
mParent,
|
||||
mKeySessions,
|
||||
mPromises,
|
||||
|
@ -224,23 +225,85 @@ MediaKeys::Create(const GlobalObject& aGlobal,
|
|||
// CDMProxy keeps MediaKeys alive until it resolves the promise and thus
|
||||
// returns the MediaKeys object to JS.
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!window) {
|
||||
if (!window || !window->GetExtantDoc()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<MediaKeys> keys = new MediaKeys(window, aKeySystem);
|
||||
nsRefPtr<Promise> promise(keys->MakePromise(aRv));
|
||||
return keys->Init(aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::Init(ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise(MakePromise(aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!IsSupportedKeySystem(aKeySystem)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
if (!IsSupportedKeySystem(mKeySystem)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
keys->mProxy = new CDMProxy(keys, aKeySystem);
|
||||
mProxy = new CDMProxy(this, mKeySystem);
|
||||
|
||||
// Determine principal (at creation time) of the MediaKeys object.
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(GetParentObject());
|
||||
if (!sop) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
mPrincipal = sop->GetPrincipal();
|
||||
|
||||
// Determine principal of the "top-level" window; the principal of the
|
||||
// page that will display in the URL bar.
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(GetParentObject());
|
||||
if (!window) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
window->GetTop(getter_AddRefs(topWindow));
|
||||
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
|
||||
if (!top || !top->GetExtantDoc()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
mTopLevelPrincipal = top->GetExtantDoc()->NodePrincipal();
|
||||
|
||||
if (!mPrincipal || !mTopLevelPrincipal) {
|
||||
NS_WARNING("Failed to get principals when creating MediaKeys");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(mPrincipal, origin);
|
||||
if (NS_FAILED(rv)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
nsAutoString topLevelOrigin;
|
||||
rv = nsContentUtils::GetUTFOrigin(mTopLevelPrincipal, topLevelOrigin);
|
||||
if (NS_FAILED(rv)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!window) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
const bool inPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc);
|
||||
|
||||
EME_LOG("MediaKeys::Create() (%s, %s), %s",
|
||||
NS_ConvertUTF16toUTF8(origin).get(),
|
||||
NS_ConvertUTF16toUTF8(topLevelOrigin).get(),
|
||||
(inPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
|
||||
|
||||
// The CDMProxy's initialization is asynchronous. The MediaKeys is
|
||||
// refcounted, and its instance is returned to JS by promise once
|
||||
|
@ -250,22 +313,26 @@ MediaKeys::Create(const GlobalObject& aGlobal,
|
|||
// or its creation has failed. Store the id of the promise returned
|
||||
// here, and hold a self-reference until that promise is resolved or
|
||||
// rejected.
|
||||
MOZ_ASSERT(!keys->mCreatePromiseId, "Should only be created once!");
|
||||
keys->mCreatePromiseId = keys->StorePromise(promise);
|
||||
keys->AddRef();
|
||||
keys->mProxy->Init(keys->mCreatePromiseId);
|
||||
MOZ_ASSERT(!mCreatePromiseId, "Should only be created once!");
|
||||
mCreatePromiseId = StorePromise(promise);
|
||||
AddRef();
|
||||
mProxy->Init(mCreatePromiseId,
|
||||
origin,
|
||||
topLevelOrigin,
|
||||
inPrivateBrowsing);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
MediaKeys::OnCDMCreated(PromiseId aId)
|
||||
MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId)
|
||||
{
|
||||
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||
if (!promise) {
|
||||
NS_WARNING("MediaKeys tried to resolve a non-existent promise");
|
||||
return;
|
||||
}
|
||||
mNodeId = aNodeId;
|
||||
nsRefPtr<MediaKeys> keys(this);
|
||||
promise->MaybeResolve(keys);
|
||||
if (mCreatePromiseId == aId) {
|
||||
|
@ -367,32 +434,59 @@ MediaKeys::GetSession(const nsAString& aSessionId)
|
|||
}
|
||||
|
||||
const nsCString&
|
||||
MediaKeys::GetNodeId()
|
||||
MediaKeys::GetNodeId() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// TODO: Bug 1035637, return a combination of origin and URL bar origin.
|
||||
|
||||
if (!mNodeId.IsEmpty()) {
|
||||
return mNodeId;
|
||||
}
|
||||
|
||||
nsIPrincipal* principal = nullptr;
|
||||
nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(GetParentObject());
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
|
||||
do_QueryInterface(pWindow);
|
||||
if (scriptPrincipal) {
|
||||
principal = scriptPrincipal->GetPrincipal();
|
||||
}
|
||||
nsAutoString id;
|
||||
if (principal && NS_SUCCEEDED(nsContentUtils::GetUTFOrigin(principal, id))) {
|
||||
CopyUTF16toUTF8(id, mNodeId);
|
||||
EME_LOG("EME Origin = '%s'", mNodeId.get());
|
||||
}
|
||||
|
||||
return mNodeId;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaKeys::IsBoundToMediaElement() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mElement != nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaKeys::Bind(HTMLMediaElement* aElement)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (IsBoundToMediaElement()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mElement = aElement;
|
||||
nsresult rv = CheckPrincipals();
|
||||
if (NS_FAILED(rv)) {
|
||||
mElement = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaKeys::CheckPrincipals()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!IsBoundToMediaElement()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsIPrincipal> elementPrincipal(mElement->GetCurrentPrincipal());
|
||||
nsRefPtr<nsIPrincipal> elementTopLevelPrincipal(mElement->GetTopLevelPrincipal());
|
||||
if (!elementPrincipal ||
|
||||
!mPrincipal ||
|
||||
!elementPrincipal->Equals(mPrincipal) ||
|
||||
!elementTopLevelPrincipal ||
|
||||
!mTopLevelPrincipal ||
|
||||
!elementTopLevelPrincipal->Equals(mTopLevelPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
CopyArrayBufferViewOrArrayBufferData(const ArrayBufferViewOrArrayBuffer& aBufferOrView,
|
||||
nsTArray<uint8_t>& aOutData)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/MediaKeysBinding.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -26,6 +27,7 @@ class CDMProxy;
|
|||
namespace dom {
|
||||
|
||||
class MediaKeySession;
|
||||
class HTMLMediaElement;
|
||||
|
||||
typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
|
||||
typedef nsRefPtrHashtable<nsUint32HashKey, dom::Promise> PromiseHashMap;
|
||||
|
@ -55,6 +57,8 @@ public:
|
|||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
nsresult Bind(HTMLMediaElement* aElement);
|
||||
|
||||
// Javascript: readonly attribute DOMString keySystem;
|
||||
void GetKeySystem(nsString& retval) const;
|
||||
|
||||
|
@ -82,7 +86,7 @@ public:
|
|||
already_AddRefed<MediaKeySession> GetSession(const nsAString& aSessionId);
|
||||
|
||||
// Called once a Create() operation succeeds.
|
||||
void OnCDMCreated(PromiseId aId);
|
||||
void OnCDMCreated(PromiseId aId, const nsACString& aNodeId);
|
||||
// Called when GenerateRequest or Load have been called on a MediaKeySession
|
||||
// and we are waiting for its initialisation to finish.
|
||||
void OnSessionPending(PromiseId aId, MediaKeySession* aSession);
|
||||
|
@ -107,12 +111,22 @@ public:
|
|||
// Resolves promise with "undefined".
|
||||
void ResolvePromise(PromiseId aId);
|
||||
|
||||
const nsCString& GetNodeId();
|
||||
const nsCString& GetNodeId() const;
|
||||
|
||||
void Shutdown();
|
||||
|
||||
// Returns true if this MediaKeys has been bound to a media element.
|
||||
bool IsBoundToMediaElement() const;
|
||||
|
||||
// Return NS_OK if the principals are the same as when the MediaKeys
|
||||
// was created, failure otherwise.
|
||||
nsresult CheckPrincipals();
|
||||
|
||||
private:
|
||||
|
||||
bool IsInPrivateBrowsing();
|
||||
already_AddRefed<Promise> Init(ErrorResult& aRv);
|
||||
|
||||
// Removes promise from mPromises, and returns it.
|
||||
already_AddRefed<Promise> RetrievePromise(PromiseId aId);
|
||||
|
||||
|
@ -120,6 +134,8 @@ private:
|
|||
// and the MediaKeys destructor clears the proxy's reference to the MediaKeys.
|
||||
nsRefPtr<CDMProxy> mProxy;
|
||||
|
||||
nsRefPtr<HTMLMediaElement> mElement;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> mParent;
|
||||
nsString mKeySystem;
|
||||
nsCString mNodeId;
|
||||
|
@ -127,6 +143,10 @@ private:
|
|||
PromiseHashMap mPromises;
|
||||
PendingKeySessionsHashMap mPendingSessions;
|
||||
PromiseId mCreatePromiseId;
|
||||
|
||||
nsRefPtr<nsIPrincipal> mPrincipal;
|
||||
nsRefPtr<nsIPrincipal> mTopLevelPrincipal;
|
||||
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "nsComponentManagerUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "VideoUtils.h"
|
||||
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#endif
|
||||
|
@ -854,5 +855,28 @@ GeckoMediaPluginService::ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld)
|
|||
NS_DispatchToCurrentThread(WrapRunnableNM(&Dummy, aOld));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetNodeId(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing,
|
||||
nsACString& aOutId)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
LOGD(("%s::%s: (%s, %s), %s", __CLASS__, __FUNCTION__,
|
||||
NS_ConvertUTF16toUTF8(aOrigin).get(),
|
||||
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
|
||||
(aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing")));
|
||||
|
||||
nsAutoCString salt;
|
||||
nsresult rv = GenerateRandomPathName(salt, 32);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aOutId = salt;
|
||||
|
||||
// TODO: Store salt, so it can be retrieved in subsequent sessions.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -78,12 +78,7 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// TODO: When aOrigin is the same node-id as the GMP sees in the child
|
||||
// process (a UUID or somesuch), we can just append it un-hashed here.
|
||||
// This should reduce the chance of hash collsions exposing data.
|
||||
nsAutoString nodeIdHash;
|
||||
nodeIdHash.AppendInt(HashString(aNodeId));
|
||||
rv = tmpFile->Append(nodeIdHash);
|
||||
rv = tmpFile->AppendNative(aNodeId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class GMPVideoHost;
|
|||
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
||||
[ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
|
||||
|
||||
[scriptable, uuid(88ade941-a423-48f9-aa3d-a383af8de4b8)]
|
||||
[scriptable, uuid(3d811f9f-e1f8-48a5-a385-3657a641ee76)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
{
|
||||
|
||||
|
@ -89,4 +89,11 @@ interface mozIGeckoMediaPluginService : nsISupports
|
|||
* @note Main-thread API.
|
||||
*/
|
||||
void removePluginDirectory(in AString directory);
|
||||
|
||||
/**
|
||||
* Gets the NodeId for a (origin, urlbarOrigin, isInprivateBrowsing) tuple.
|
||||
*/
|
||||
ACString getNodeId(in AString origin,
|
||||
in AString topLevelOrigin,
|
||||
in bool inPrivateBrowsingMode);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче