зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound. a=merge
This commit is contained in:
Коммит
1755e88a07
|
@ -1177,6 +1177,8 @@ pref("dom.ipc.plugins.enabled.x86_64", true);
|
|||
pref("dom.ipc.plugins.enabled", true);
|
||||
#endif
|
||||
|
||||
pref("dom.ipc.shims.enabledWarnings", false);
|
||||
|
||||
// Start the browser in e10s mode
|
||||
pref("browser.tabs.remote.autostart", false);
|
||||
pref("browser.tabs.remote.desktopbehavior", true);
|
||||
|
|
|
@ -1801,13 +1801,10 @@ nsSHistory::SetRootDocShell(nsIDocShell * aDocShell)
|
|||
NS_IMETHODIMP
|
||||
nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator)
|
||||
{
|
||||
nsresult status = NS_OK;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aEnumerator);
|
||||
nsSHEnumerator * iterator = new nsSHEnumerator(this);
|
||||
if (iterator && NS_FAILED(status = CallQueryInterface(iterator, aEnumerator)))
|
||||
delete iterator;
|
||||
return status;
|
||||
nsRefPtr<nsSHEnumerator> iterator = new nsSHEnumerator(this);
|
||||
iterator.forget(aEnumerator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ MultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return CallQueryInterface(stream, aStream);
|
||||
stream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<FileImpl>
|
||||
|
|
|
@ -2499,7 +2499,9 @@ nsFrameLoader::GetMessageManager(nsIMessageSender** aManager)
|
|||
{
|
||||
EnsureMessageManager();
|
||||
if (mMessageManager) {
|
||||
CallQueryInterface(mMessageManager, aManager);
|
||||
nsRefPtr<nsFrameMessageManager> mm(mMessageManager);
|
||||
mm.forget(aManager);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1490,11 +1490,12 @@ NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
|
|||
{
|
||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
nsFrameMessageManager* mm = new nsFrameMessageManager(nullptr,
|
||||
nullptr,
|
||||
MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
|
||||
nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
|
||||
nullptr,
|
||||
MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
|
||||
RegisterStrongMemoryReporter(new MessageManagerReporter());
|
||||
return CallQueryInterface(mm, aResult);
|
||||
mm.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>*
|
||||
|
@ -2008,7 +2009,8 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
|
|||
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
|
||||
nsFrameMessageManager::sParentProcessManager = mm;
|
||||
nsFrameMessageManager::NewProcessMessageManager(false); // Create same process message manager.
|
||||
return CallQueryInterface(mm, aResult);
|
||||
mm.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2055,9 +2057,10 @@ NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
|
|||
nullptr,
|
||||
MM_PROCESSMANAGER | MM_OWNSCALLBACK);
|
||||
nsFrameMessageManager::SetChildProcessManager(mm);
|
||||
ProcessGlobal* global = new ProcessGlobal(mm);
|
||||
nsRefPtr<ProcessGlobal> global = new ProcessGlobal(mm);
|
||||
NS_ENSURE_TRUE(global->Init(), NS_ERROR_UNEXPECTED);
|
||||
return CallQueryInterface(global, aResult);
|
||||
global.forget(aResult);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -40,14 +40,12 @@
|
|||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
nsresult
|
||||
NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
{
|
||||
nsHTMLContentSerializer* it = new nsHTMLContentSerializer();
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aSerializer);
|
||||
nsRefPtr<nsHTMLContentSerializer> it = new nsHTMLContentSerializer();
|
||||
it.forget(aSerializer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::nsHTMLContentSerializer()
|
||||
|
|
|
@ -54,14 +54,12 @@ static int32_t GetUnicharStringWidth(const char16_t* pwcs, int32_t n);
|
|||
static const uint32_t TagStackSize = 500;
|
||||
static const uint32_t OLStackSize = 100;
|
||||
|
||||
nsresult NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
|
||||
nsresult
|
||||
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
|
||||
{
|
||||
nsPlainTextSerializer* it = new nsPlainTextSerializer();
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aSerializer);
|
||||
nsRefPtr<nsPlainTextSerializer> it = new nsPlainTextSerializer();
|
||||
it.forget(aSerializer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPlainTextSerializer::nsPlainTextSerializer()
|
||||
|
|
|
@ -40,14 +40,12 @@ static const int32_t kLongLineLen = 128;
|
|||
|
||||
#define kXMLNS "xmlns"
|
||||
|
||||
nsresult NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
nsresult
|
||||
NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
{
|
||||
nsXHTMLContentSerializer* it = new nsXHTMLContentSerializer();
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aSerializer);
|
||||
nsRefPtr<nsXHTMLContentSerializer> it = new nsXHTMLContentSerializer();
|
||||
it.forget(aSerializer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXHTMLContentSerializer::nsXHTMLContentSerializer()
|
||||
|
|
|
@ -43,14 +43,12 @@ using namespace mozilla::dom;
|
|||
#define INDENT_STRING " "
|
||||
#define INDENT_STRING_LENGTH 2
|
||||
|
||||
nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
nsresult
|
||||
NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
{
|
||||
nsXMLContentSerializer* it = new nsXMLContentSerializer();
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aSerializer);
|
||||
nsRefPtr<nsXMLContentSerializer> it = new nsXMLContentSerializer();
|
||||
it.forget(aSerializer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXMLContentSerializer::nsXMLContentSerializer()
|
||||
|
|
|
@ -23,6 +23,7 @@ skip-if = debug == false
|
|||
[test_bug963382.html]
|
||||
skip-if = debug == false
|
||||
[test_bug1041646.html]
|
||||
[test_bug1123875.html]
|
||||
[test_barewordGetsWindow.html]
|
||||
[test_callback_default_thisval.html]
|
||||
[test_cloneAndImportNode.html]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for Bug 1123875</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<div id=log></div>
|
||||
<script>
|
||||
test(() => {
|
||||
assert_throws(new TypeError, () => {
|
||||
"use strict";
|
||||
document.childNodes.length = 0;
|
||||
});
|
||||
}, "setting a readonly attribute on a proxy in strict mode should throw a TypeError");
|
||||
</script>
|
|
@ -1910,7 +1910,7 @@ HTMLInputElement::GetList(nsIDOMHTMLElement** aValue)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
CallQueryInterface(element, aValue);
|
||||
element.forget(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@
|
|||
#include "mozilla/dom/voicemail/VoicemailIPCService.h"
|
||||
#include "mozilla/net/NeckoMessageUtils.h"
|
||||
#include "mozilla/RemoteSpellCheckEngineChild.h"
|
||||
#include "GMPServiceChild.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::docshell;
|
||||
|
@ -191,6 +192,7 @@ using namespace mozilla::dom::mobilemessage;
|
|||
using namespace mozilla::dom::telephony;
|
||||
using namespace mozilla::dom::voicemail;
|
||||
using namespace mozilla::embedding;
|
||||
using namespace mozilla::gmp;
|
||||
using namespace mozilla::hal_sandbox;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
|
@ -1036,6 +1038,13 @@ ContentChild::AllocPContentBridgeParent(mozilla::ipc::Transport* aTransport,
|
|||
return mLastBridge;
|
||||
}
|
||||
|
||||
PGMPServiceChild*
|
||||
ContentChild::AllocPGMPServiceChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
{
|
||||
return GMPServiceChild::Create(aTransport, aOtherProcess);
|
||||
}
|
||||
|
||||
PCompositorChild*
|
||||
ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
|
|
|
@ -115,6 +115,10 @@ public:
|
|||
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
|
||||
base::ProcessId otherProcess) override;
|
||||
|
||||
PGMPServiceChild*
|
||||
AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
|
||||
base::ProcessId otherProcess) override;
|
||||
|
||||
PCompositorChild*
|
||||
AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) override;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "AudioChannelService.h"
|
||||
#include "BlobParent.h"
|
||||
#include "CrashReporterParent.h"
|
||||
#include "GMPServiceParent.h"
|
||||
#include "IHistory.h"
|
||||
#include "mozIApplication.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
|
@ -233,6 +234,7 @@ using namespace mozilla::dom::mobilemessage;
|
|||
using namespace mozilla::dom::telephony;
|
||||
using namespace mozilla::dom::voicemail;
|
||||
using namespace mozilla::embedding;
|
||||
using namespace mozilla::gmp;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
|
@ -981,6 +983,23 @@ static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
|
|||
return docShell;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvCreateGMPService()
|
||||
{
|
||||
return PGMPService::Open(this);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,
|
||||
nsTArray<nsCString>&& aTags,
|
||||
bool* aHasVersion,
|
||||
nsCString* aVersion)
|
||||
{
|
||||
return GMPServiceParent::RecvGetGMPPluginVersionForAPI(aAPI, Move(aTags),
|
||||
aHasVersion,
|
||||
aVersion);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv)
|
||||
{
|
||||
|
@ -3062,6 +3081,13 @@ ContentParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc, PDocAcc
|
|||
return true;
|
||||
}
|
||||
|
||||
PGMPServiceParent*
|
||||
ContentParent::AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
{
|
||||
return GMPServiceParent::Create(aTransport, aOtherProcess);
|
||||
}
|
||||
|
||||
PCompositorParent*
|
||||
ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
|
|
|
@ -153,6 +153,12 @@ public:
|
|||
TabId* aTabId) override;
|
||||
virtual bool RecvBridgeToChildProcess(const ContentParentId& aCpId) override;
|
||||
|
||||
virtual bool RecvCreateGMPService() override;
|
||||
virtual bool RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,
|
||||
nsTArray<nsCString>&& aTags,
|
||||
bool* aHasPlugin,
|
||||
nsCString* aVersion) override;
|
||||
|
||||
virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
|
||||
|
@ -488,6 +494,9 @@ private:
|
|||
|
||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
PGMPServiceParent*
|
||||
AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) override;
|
||||
PCompositorParent*
|
||||
AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) override;
|
||||
|
|
|
@ -27,7 +27,15 @@ include protocol PImageBridge;
|
|||
include protocol PMemoryReportRequest;
|
||||
include protocol PMobileConnection;
|
||||
include protocol PNecko;
|
||||
// FIXME This is pretty ridiculous, but we have to keep the order of the
|
||||
// following 4 includes, or the parser is confused about PGMPContent
|
||||
// bridging PContent and PGMP. As soon as it registers the bridge between
|
||||
// PContent and PPluginModule it seems to think that PContent's parent and
|
||||
// child live in the same process!
|
||||
include protocol PGMPContent;
|
||||
include protocol PGMPService;
|
||||
include protocol PPluginModule;
|
||||
include protocol PGMP;
|
||||
include protocol PPrinting;
|
||||
include protocol POfflineCacheUpdate;
|
||||
include protocol PScreenManager;
|
||||
|
@ -364,6 +372,7 @@ prio(normal upto urgent) sync protocol PContent
|
|||
parent opens PProcessHangMonitor;
|
||||
parent opens PSharedBufferManager;
|
||||
parent opens PImageBridge;
|
||||
parent opens PGMPService;
|
||||
child opens PBackground;
|
||||
|
||||
manages PAsmJSCacheEntry;
|
||||
|
@ -608,6 +617,10 @@ parent:
|
|||
returns (ContentParentId cpId, bool isForApp, bool isForBrowser, TabId tabId);
|
||||
sync BridgeToChildProcess(ContentParentId cpId);
|
||||
|
||||
async CreateGMPService();
|
||||
sync GetGMPPluginVersionForAPI(nsCString api, nsCString[] tags)
|
||||
returns (bool hasPlugin, nsCString version);
|
||||
|
||||
/**
|
||||
* This call connects the content process to a plugin process. While this
|
||||
* call runs, a new PluginModuleParent will be created in the ContentChild
|
||||
|
|
|
@ -25,6 +25,7 @@ CDMProxy::CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem)
|
|||
, mKeySystem(aKeySystem)
|
||||
, mCDM(nullptr)
|
||||
, mDecryptionJobCount(0)
|
||||
, mShutdownCalled(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_COUNT_CTOR(CDMProxy);
|
||||
|
@ -70,7 +71,7 @@ CDMProxy::Init(PromiseId aPromiseId,
|
|||
nsCOMPtr<nsIRunnable> task(
|
||||
NS_NewRunnableMethodWithArg<nsAutoPtr<InitData>>(this,
|
||||
&CDMProxy::gmp_Init,
|
||||
data));
|
||||
Move(data)));
|
||||
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,69 @@ CDMProxy::IsOnGMPThread()
|
|||
#endif
|
||||
|
||||
void
|
||||
CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
||||
CDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData)
|
||||
{
|
||||
EME_LOG("CDMProxy::gmp_InitDone");
|
||||
if (!aCDM || mShutdownCalled) {
|
||||
if (aCDM) {
|
||||
aCDM->Close();
|
||||
}
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
mCDM = aCDM;
|
||||
mCallback = new CDMCallbackProxy(this);
|
||||
mCDM->Init(mCallback);
|
||||
nsCOMPtr<nsIRunnable> task(
|
||||
NS_NewRunnableMethodWithArg<uint32_t>(this,
|
||||
&CDMProxy::OnCDMCreated,
|
||||
aData->mPromiseId));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
class gmp_InitDoneCallback : public GetGMPDecryptorCallback
|
||||
{
|
||||
public:
|
||||
gmp_InitDoneCallback(CDMProxy* aCDMProxy,
|
||||
nsAutoPtr<CDMProxy::InitData>&& aData)
|
||||
: mCDMProxy(aCDMProxy),
|
||||
mData(Move(aData))
|
||||
{
|
||||
}
|
||||
|
||||
void Done(GMPDecryptorProxy* aCDM)
|
||||
{
|
||||
mCDMProxy->gmp_InitDone(aCDM, Move(mData));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<CDMProxy> mCDMProxy;
|
||||
nsAutoPtr<CDMProxy::InitData> mData;
|
||||
};
|
||||
|
||||
class gmp_InitGetGMPDecryptorCallback : public GetNodeIdCallback
|
||||
{
|
||||
public:
|
||||
gmp_InitGetGMPDecryptorCallback(CDMProxy* aCDMProxy,
|
||||
nsAutoPtr<CDMProxy::InitData>&& aData)
|
||||
: mCDMProxy(aCDMProxy),
|
||||
mData(aData)
|
||||
{
|
||||
}
|
||||
|
||||
void Done(nsresult aResult, const nsACString& aNodeId)
|
||||
{
|
||||
mCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<CDMProxy> mCDMProxy;
|
||||
nsAutoPtr<CDMProxy::InitData> mData;
|
||||
};
|
||||
|
||||
void
|
||||
CDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData)
|
||||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
|
@ -94,13 +157,38 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
|||
return;
|
||||
}
|
||||
|
||||
nsresult rv = mps->GetNodeId(aData->mOrigin,
|
||||
aData->mTopLevelOrigin,
|
||||
aData->mInPrivateBrowsing,
|
||||
mNodeId);
|
||||
MOZ_ASSERT(!GetNodeId().IsEmpty());
|
||||
// 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.mInPrivateBrowsing,
|
||||
Move(callback));
|
||||
if (NS_FAILED(rv)) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
RejectPromise(data.mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult,
|
||||
const nsACString& aNodeId,
|
||||
nsAutoPtr<InitData>&& aData)
|
||||
{
|
||||
uint32_t promiseID = aData->mPromiseId;
|
||||
if (NS_FAILED(aResult)) {
|
||||
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -112,17 +200,12 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
|||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
|
||||
rv = mps->GetGMPDecryptor(&tags, GetNodeId(), &mCDM);
|
||||
if (NS_FAILED(rv) || !mCDM) {
|
||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
} else {
|
||||
mCallback = new CDMCallbackProxy(this);
|
||||
mCDM->Init(mCallback);
|
||||
nsCOMPtr<nsIRunnable> task(
|
||||
NS_NewRunnableMethodWithArg<uint32_t>(this,
|
||||
&CDMProxy::OnCDMCreated,
|
||||
aData->mPromiseId));
|
||||
NS_DispatchToMainThread(task);
|
||||
|
||||
UniquePtr<GetGMPDecryptorCallback> callback(new gmp_InitDoneCallback(this,
|
||||
Move(aData)));
|
||||
nsresult rv = mps->GetGMPDecryptor(&tags, GetNodeId(), Move(callback));
|
||||
if (NS_FAILED(rv)) {
|
||||
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,6 +424,8 @@ CDMProxy::gmp_Shutdown()
|
|||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
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];
|
||||
|
|
|
@ -174,6 +174,8 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
friend class gmp_InitDoneCallback;
|
||||
friend class gmp_InitGetGMPDecryptorCallback;
|
||||
|
||||
struct InitData {
|
||||
uint32_t mPromiseId;
|
||||
|
@ -183,7 +185,11 @@ private:
|
|||
};
|
||||
|
||||
// GMP thread only.
|
||||
void gmp_Init(nsAutoPtr<InitData> aData);
|
||||
void gmp_Init(nsAutoPtr<InitData>&& aData);
|
||||
void gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData);
|
||||
void gmp_InitGetGMPDecryptor(nsresult aResult,
|
||||
const nsACString& aNodeId,
|
||||
nsAutoPtr<InitData>&& aData);
|
||||
|
||||
// GMP thread only.
|
||||
void gmp_Shutdown();
|
||||
|
@ -320,6 +326,10 @@ private:
|
|||
// from it.
|
||||
// GMP thread only.
|
||||
uint32_t mDecryptionJobCount;
|
||||
|
||||
// True if CDMProxy::gmp_Shutdown was called.
|
||||
// GMP thread only.
|
||||
bool mShutdownCalled;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -93,25 +93,34 @@ HaveGMPFor(mozIGeckoMediaPluginService* aGMPService,
|
|||
static MediaKeySystemStatus
|
||||
EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
|
||||
const nsAString& aKeySystem,
|
||||
int32_t aMinCdmVersion)
|
||||
int32_t aMinCdmVersion,
|
||||
bool aCheckForV6=false)
|
||||
{
|
||||
if (aMinCdmVersion == NO_CDM_VERSION) {
|
||||
return MediaKeySystemStatus::Available;
|
||||
}
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_ConvertUTF16toUTF8(aKeySystem));
|
||||
bool hasPlugin;
|
||||
nsAutoCString versionStr;
|
||||
if (NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
|
||||
&tags,
|
||||
versionStr)) &&
|
||||
&hasPlugin,
|
||||
versionStr)) ||
|
||||
// XXX to be removed later in bug 1147692
|
||||
NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT),
|
||||
&tags,
|
||||
versionStr))) {
|
||||
(aCheckForV6 && !hasPlugin &&
|
||||
NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT),
|
||||
&tags,
|
||||
&hasPlugin,
|
||||
versionStr)))) {
|
||||
return MediaKeySystemStatus::Error;
|
||||
}
|
||||
|
||||
if (!hasPlugin) {
|
||||
return MediaKeySystemStatus::Cdm_not_installed;
|
||||
}
|
||||
|
||||
if (aMinCdmVersion == NO_CDM_VERSION) {
|
||||
return MediaKeySystemStatus::Available;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
int32_t version = versionStr.ToInteger(&rv);
|
||||
if (NS_FAILED(rv) || version < 0 || aMinCdmVersion > version) {
|
||||
|
@ -137,11 +146,6 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
|||
if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
|
||||
return MediaKeySystemStatus::Cdm_disabled;
|
||||
}
|
||||
if (!HaveGMPFor(mps,
|
||||
NS_LITERAL_CSTRING("org.w3.clearkey"),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
|
||||
return MediaKeySystemStatus::Cdm_not_installed;
|
||||
}
|
||||
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
|
||||
}
|
||||
|
||||
|
@ -155,16 +159,7 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
|||
if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
|
||||
return MediaKeySystemStatus::Cdm_disabled;
|
||||
}
|
||||
if (!HaveGMPFor(mps,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)) &&
|
||||
// XXX to be removed later in bug 1147692
|
||||
!HaveGMPFor(mps,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT))) {
|
||||
return MediaKeySystemStatus::Cdm_not_installed;
|
||||
}
|
||||
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
|
||||
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPAudioDecoder.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -132,6 +133,39 @@ GMPAudioDecoder::GetNodeId()
|
|||
return NS_LITERAL_CSTRING("");
|
||||
}
|
||||
|
||||
void
|
||||
GMPAudioDecoder::GetGMPAPI(GMPInitDoneRunnable* aInitDone)
|
||||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
InitTags(tags);
|
||||
UniquePtr<GetGMPAudioDecoderCallback> callback(
|
||||
new GMPInitDoneCallback(this, aInitDone));
|
||||
if (NS_FAILED(mMPS->GetGMPAudioDecoder(&tags, GetNodeId(), Move(callback)))) {
|
||||
aInitDone->Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPAudioDecoder::GMPInitDone(GMPAudioDecoderProxy* aGMP)
|
||||
{
|
||||
MOZ_ASSERT(aGMP);
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
codecSpecific.AppendElements(mConfig.audio_specific_config->Elements(),
|
||||
mConfig.audio_specific_config->Length());
|
||||
|
||||
nsresult rv = aGMP->InitDecode(kGMPAudioCodecAAC,
|
||||
mConfig.channel_count,
|
||||
mConfig.bits_per_sample,
|
||||
mConfig.samples_per_second,
|
||||
codecSpecific,
|
||||
mAdapter);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mGMP = aGMP;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPAudioDecoder::Init()
|
||||
{
|
||||
|
@ -140,25 +174,20 @@ GMPAudioDecoder::Init()
|
|||
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
MOZ_ASSERT(mMPS);
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
InitTags(tags);
|
||||
nsresult rv = mMPS->GetGMPAudioDecoder(&tags, GetNodeId(), &mGMP);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ASSERT(mGMP);
|
||||
nsCOMPtr<nsIThread> gmpThread = NS_GetCurrentThread();
|
||||
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
codecSpecific.AppendElements(mConfig.audio_specific_config->Elements(),
|
||||
mConfig.audio_specific_config->Length());
|
||||
nsRefPtr<GMPInitDoneRunnable> initDone(new GMPInitDoneRunnable());
|
||||
gmpThread->Dispatch(
|
||||
NS_NewRunnableMethodWithArg<GMPInitDoneRunnable*>(this,
|
||||
&GMPAudioDecoder::GetGMPAPI,
|
||||
initDone),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
rv = mGMP->InitDecode(kGMPAudioCodecAAC,
|
||||
mConfig.channel_count,
|
||||
mConfig.bits_per_sample,
|
||||
mConfig.samples_per_second,
|
||||
codecSpecific,
|
||||
mAdapter);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
while (!initDone->IsDone()) {
|
||||
NS_ProcessNextEvent(gmpThread, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return mGMP ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -80,6 +80,63 @@ protected:
|
|||
virtual nsCString GetNodeId();
|
||||
|
||||
private:
|
||||
class GMPInitDoneRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
GMPInitDoneRunnable()
|
||||
: mInitDone(false),
|
||||
mThread(do_GetCurrentThread())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mInitDone = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Dispatch()
|
||||
{
|
||||
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
bool IsDone()
|
||||
{
|
||||
MOZ_ASSERT(nsCOMPtr<nsIThread>(do_GetCurrentThread()) == mThread);
|
||||
return mInitDone;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mInitDone;
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
};
|
||||
|
||||
void GetGMPAPI(GMPInitDoneRunnable* aInitDone);
|
||||
|
||||
class GMPInitDoneCallback : public GetGMPAudioDecoderCallback
|
||||
{
|
||||
public:
|
||||
GMPInitDoneCallback(GMPAudioDecoder* aDecoder,
|
||||
GMPInitDoneRunnable* aGMPInitDone)
|
||||
: mDecoder(aDecoder)
|
||||
, mGMPInitDone(aGMPInitDone)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Done(GMPAudioDecoderProxy* aGMP)
|
||||
{
|
||||
if (aGMP) {
|
||||
mDecoder->GMPInitDone(aGMP);
|
||||
}
|
||||
mGMPInitDone->Dispatch();
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPAudioDecoder> mDecoder;
|
||||
nsRefPtr<GMPInitDoneRunnable> mGMPInitDone;
|
||||
};
|
||||
void GMPInitDone(GMPAudioDecoderProxy* aGMP);
|
||||
|
||||
const mp4_demuxer::AudioDecoderConfig& mConfig;
|
||||
MediaDataDecoderCallbackProxy* mCallback;
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||
|
|
|
@ -157,29 +157,24 @@ GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample)
|
|||
return frame;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoDecoder::Init()
|
||||
void
|
||||
GMPVideoDecoder::GetGMPAPI(GMPInitDoneRunnable* aInitDone)
|
||||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
MOZ_ASSERT(mMPS);
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
InitTags(tags);
|
||||
nsresult rv = mMPS->GetGMPVideoDecoder(&tags, GetNodeId(), &mHost, &mGMP);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ASSERT(mHost && mGMP);
|
||||
UniquePtr<GetGMPVideoDecoderCallback> callback(
|
||||
new GMPInitDoneCallback(this, aInitDone));
|
||||
if (NS_FAILED(mMPS->GetGMPVideoDecoder(&tags, GetNodeId(), Move(callback)))) {
|
||||
aInitDone->Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
// GMP implementations have interpreted the meaning of GMP_BufferLength32
|
||||
// differently. The OpenH264 GMP expects GMP_BufferLength32 to behave as
|
||||
// specified in the GMP API, where each buffer is prefixed by a 32-bit
|
||||
// host-endian buffer length that includes the size of the buffer length
|
||||
// field. Other existing GMPs currently expect GMP_BufferLength32 (when
|
||||
// combined with kGMPVideoCodecH264) to mean "like AVCC but restricted to
|
||||
// 4-byte NAL lengths" (i.e. buffer lengths are specified in big-endian
|
||||
// and do not include the length of the buffer length field.
|
||||
mConvertNALUnitLengths = mGMP->GetDisplayName().EqualsLiteral("gmpopenh264");
|
||||
void
|
||||
GMPVideoDecoder::GMPInitDone(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost)
|
||||
{
|
||||
MOZ_ASSERT(aHost && aGMP);
|
||||
|
||||
GMPVideoCodec codec;
|
||||
memset(&codec, 0, sizeof(codec));
|
||||
|
@ -195,13 +190,48 @@ GMPVideoDecoder::Init()
|
|||
codecSpecific.AppendElements(mConfig.extra_data->Elements(),
|
||||
mConfig.extra_data->Length());
|
||||
|
||||
rv = mGMP->InitDecode(codec,
|
||||
codecSpecific,
|
||||
mAdapter,
|
||||
PR_GetNumberOfProcessors());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = aGMP->InitDecode(codec,
|
||||
codecSpecific,
|
||||
mAdapter,
|
||||
PR_GetNumberOfProcessors());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mGMP = aGMP;
|
||||
mHost = aHost;
|
||||
|
||||
return NS_OK;
|
||||
// GMP implementations have interpreted the meaning of GMP_BufferLength32
|
||||
// differently. The OpenH264 GMP expects GMP_BufferLength32 to behave as
|
||||
// specified in the GMP API, where each buffer is prefixed by a 32-bit
|
||||
// host-endian buffer length that includes the size of the buffer length
|
||||
// field. Other existing GMPs currently expect GMP_BufferLength32 (when
|
||||
// combined with kGMPVideoCodecH264) to mean "like AVCC but restricted to
|
||||
// 4-byte NAL lengths" (i.e. buffer lengths are specified in big-endian
|
||||
// and do not include the length of the buffer length field.
|
||||
mConvertNALUnitLengths = mGMP->GetDisplayName().EqualsLiteral("gmpopenh264");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoDecoder::Init()
|
||||
{
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
MOZ_ASSERT(mMPS);
|
||||
|
||||
nsCOMPtr<nsIThread> gmpThread = NS_GetCurrentThread();
|
||||
|
||||
nsRefPtr<GMPInitDoneRunnable> initDone(new GMPInitDoneRunnable());
|
||||
gmpThread->Dispatch(
|
||||
NS_NewRunnableMethodWithArg<GMPInitDoneRunnable*>(this,
|
||||
&GMPVideoDecoder::GetGMPAPI,
|
||||
initDone),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
while (!initDone->IsDone()) {
|
||||
NS_ProcessNextEvent(gmpThread, true);
|
||||
}
|
||||
|
||||
return mGMP ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -96,6 +96,63 @@ protected:
|
|||
virtual GMPUnique<GMPVideoEncodedFrame>::Ptr CreateFrame(mp4_demuxer::MP4Sample* aSample);
|
||||
|
||||
private:
|
||||
class GMPInitDoneRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
GMPInitDoneRunnable()
|
||||
: mInitDone(false),
|
||||
mThread(do_GetCurrentThread())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mInitDone = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Dispatch()
|
||||
{
|
||||
mThread->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
bool IsDone()
|
||||
{
|
||||
MOZ_ASSERT(nsCOMPtr<nsIThread>(do_GetCurrentThread()) == mThread);
|
||||
return mInitDone;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mInitDone;
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
};
|
||||
|
||||
void GetGMPAPI(GMPInitDoneRunnable* aInitDone);
|
||||
|
||||
class GMPInitDoneCallback : public GetGMPVideoDecoderCallback
|
||||
{
|
||||
public:
|
||||
GMPInitDoneCallback(GMPVideoDecoder* aDecoder,
|
||||
GMPInitDoneRunnable* aGMPInitDone)
|
||||
: mDecoder(aDecoder)
|
||||
, mGMPInitDone(aGMPInitDone)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Done(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost)
|
||||
{
|
||||
if (aGMP) {
|
||||
mDecoder->GMPInitDone(aGMP, aHost);
|
||||
}
|
||||
mGMPInitDone->Dispatch();
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPVideoDecoder> mDecoder;
|
||||
nsRefPtr<GMPInitDoneRunnable> mGMPInitDone;
|
||||
};
|
||||
void GMPInitDone(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost);
|
||||
|
||||
const mp4_demuxer::VideoDecoderConfig& mConfig;
|
||||
MediaDataDecoderCallbackProxy* mCallback;
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "WMFMediaDataDecoder.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "GfxDriverInfo.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPAudioDecoderChild.h"
|
||||
#include "GMPChild.h"
|
||||
#include "GMPContentChild.h"
|
||||
#include "GMPAudioHost.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include <stdio.h>
|
||||
|
@ -12,7 +12,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPChild* aPlugin)
|
||||
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPContentChild* aPlugin)
|
||||
: mPlugin(aPlugin)
|
||||
, mAudioDecoder(nullptr)
|
||||
{
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
class GMPContentChild;
|
||||
|
||||
class GMPAudioDecoderChild : public PGMPAudioDecoderChild,
|
||||
public GMPAudioDecoderCallback
|
||||
{
|
||||
public:
|
||||
explicit GMPAudioDecoderChild(GMPChild* aPlugin);
|
||||
explicit GMPAudioDecoderChild(GMPContentChild* aPlugin);
|
||||
virtual ~GMPAudioDecoderChild();
|
||||
|
||||
void Init(GMPAudioDecoder* aDecoder);
|
||||
|
@ -40,7 +40,7 @@ private:
|
|||
virtual bool RecvDrain() override;
|
||||
virtual bool RecvDecodingComplete() override;
|
||||
|
||||
GMPChild* mPlugin;
|
||||
GMPContentChild* mPlugin;
|
||||
GMPAudioDecoder* mAudioDecoder;
|
||||
GMPAudioHostImpl mAudioHost;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPAudioDecoderParent.h"
|
||||
#include "GMPParent.h"
|
||||
#include "GMPContentParent.h"
|
||||
#include <stdio.h>
|
||||
#include "mozilla/unused.h"
|
||||
#include "GMPMessageUtils.h"
|
||||
|
@ -29,7 +29,7 @@ extern PRLogModuleInfo* GetGMPLog();
|
|||
|
||||
namespace gmp {
|
||||
|
||||
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPParent* aPlugin)
|
||||
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPContentParent* aPlugin)
|
||||
: mIsOpen(false)
|
||||
, mShuttingDown(false)
|
||||
, mPlugin(aPlugin)
|
||||
|
@ -263,6 +263,13 @@ GMPAudioDecoderParent::RecvError(const GMPErr& aError)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPAudioDecoderParent::RecvShutdown()
|
||||
{
|
||||
Shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPAudioDecoderParent::Recv__delete__()
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
class GMPContentParent;
|
||||
|
||||
class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
|
||||
, public PGMPAudioDecoderParent
|
||||
|
@ -24,7 +24,7 @@ class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
|
|||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPAudioDecoderParent)
|
||||
|
||||
explicit GMPAudioDecoderParent(GMPParent *aPlugin);
|
||||
explicit GMPAudioDecoderParent(GMPContentParent *aPlugin);
|
||||
|
||||
nsresult Shutdown();
|
||||
|
||||
|
@ -50,11 +50,12 @@ private:
|
|||
virtual bool RecvDrainComplete() override;
|
||||
virtual bool RecvResetComplete() override;
|
||||
virtual bool RecvError(const GMPErr& aError) override;
|
||||
virtual bool RecvShutdown() override;
|
||||
virtual bool Recv__delete__() override;
|
||||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
nsRefPtr<GMPParent> mPlugin;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
GMPAudioDecoderCallbackProxy* mCallback;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPChild.h"
|
||||
#include "GMPContentChild.h"
|
||||
#include "GMPProcessChild.h"
|
||||
#include "GMPLoader.h"
|
||||
#include "GMPVideoDecoderChild.h"
|
||||
|
@ -256,12 +257,6 @@ GMPChild::StartMacSandbox()
|
|||
}
|
||||
#endif // XP_MACOSX && MOZ_GMP_SANDBOX
|
||||
|
||||
void
|
||||
GMPChild::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::Init(const std::string& aPluginPath,
|
||||
const std::string& aVoucherPath,
|
||||
|
@ -467,6 +462,11 @@ GMPChild::ActorDestroy(ActorDestroyReason aWhy)
|
|||
{
|
||||
LOGD("%s reason=%d", __FUNCTION__, aWhy);
|
||||
|
||||
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
|
||||
MOZ_ASSERT_IF(aWhy == NormalShutdown, !mGMPContentChildren[i - 1]->IsUsed());
|
||||
mGMPContentChildren[i - 1]->Close();
|
||||
}
|
||||
|
||||
if (mGMPLoader) {
|
||||
mGMPLoader->Shutdown();
|
||||
}
|
||||
|
@ -501,19 +501,6 @@ GMPChild::ProcessingError(Result aCode, const char* aReason)
|
|||
}
|
||||
}
|
||||
|
||||
PGMPAudioDecoderChild*
|
||||
GMPChild::AllocPGMPAudioDecoderChild()
|
||||
{
|
||||
return new GMPAudioDecoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::dom::PCrashReporterChild*
|
||||
GMPChild::AllocPCrashReporterChild(const NativeThreadId& aThread)
|
||||
{
|
||||
|
@ -527,120 +514,6 @@ GMPChild::DeallocPCrashReporterChild(PCrashReporterChild* aCrashReporter)
|
|||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoDecoderChild*
|
||||
GMPChild::AllocPGMPVideoDecoderChild()
|
||||
{
|
||||
return new GMPVideoDecoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorChild*
|
||||
GMPChild::AllocPGMPDecryptorChild()
|
||||
{
|
||||
GMPDecryptorChild* actor = new GMPDecryptorChild(this, mPluginVoucher, mSandboxVoucher);
|
||||
actor->AddRef();
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
static_cast<GMPDecryptorChild*>(aActor)->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor)
|
||||
{
|
||||
auto vdc = static_cast<GMPAudioDecoderChild*>(aActor);
|
||||
|
||||
void* vd = nullptr;
|
||||
GMPErr err = GetAPI(GMP_API_AUDIO_DECODER, &vdc->Host(), &vd);
|
||||
if (err != GMPNoErr || !vd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vdc->Init(static_cast<GMPAudioDecoder*>(vd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoEncoderChild*
|
||||
GMPChild::AllocPGMPVideoEncoderChild()
|
||||
{
|
||||
return new GMPVideoEncoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor)
|
||||
{
|
||||
auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
|
||||
|
||||
void* vd = nullptr;
|
||||
GMPErr err = GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
|
||||
if (err != GMPNoErr || !vd) {
|
||||
NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
|
||||
return false;
|
||||
}
|
||||
|
||||
vdc->Init(static_cast<GMPVideoDecoder*>(vd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor)
|
||||
{
|
||||
auto vec = static_cast<GMPVideoEncoderChild*>(aActor);
|
||||
|
||||
void* ve = nullptr;
|
||||
GMPErr err = GetAPI(GMP_API_VIDEO_ENCODER, &vec->Host(), &ve);
|
||||
if (err != GMPNoErr || !ve) {
|
||||
NS_WARNING("GMPGetAPI call failed trying to construct encoder.");
|
||||
return false;
|
||||
}
|
||||
|
||||
vec->Init(static_cast<GMPVideoEncoder*>(ve));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
|
||||
GMPDecryptorHost* host = static_cast<GMPDecryptorHost*>(child);
|
||||
|
||||
void* session = nullptr;
|
||||
GMPErr err = GetAPI(GMP_API_DECRYPTOR, host, &session);
|
||||
|
||||
if (err != GMPNoErr && !session) {
|
||||
// XXX to remove in bug 1147692
|
||||
err = GetAPI(GMP_API_DECRYPTOR_COMPAT, host, &session);
|
||||
}
|
||||
|
||||
if (err != GMPNoErr || !session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
child->Init(static_cast<GMPDecryptor*>(session));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPTimerChild*
|
||||
GMPChild::AllocPGMPTimerChild()
|
||||
{
|
||||
|
@ -715,6 +588,15 @@ GMPChild::RecvBeginAsyncShutdown()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvCloseActive()
|
||||
{
|
||||
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
|
||||
mGMPContentChildren[i - 1]->CloseActive();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GMPChild::ShutdownComplete()
|
||||
{
|
||||
|
@ -802,6 +684,32 @@ GMPChild::PreLoadSandboxVoucher()
|
|||
}
|
||||
}
|
||||
|
||||
PGMPContentChild*
|
||||
GMPChild::AllocPGMPContentChild(Transport* aTransport,
|
||||
ProcessId aOtherPid)
|
||||
{
|
||||
GMPContentChild* child =
|
||||
mGMPContentChildren.AppendElement(new GMPContentChild(this))->get();
|
||||
child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
void
|
||||
GMPChild::GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild)
|
||||
{
|
||||
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
|
||||
UniquePtr<GMPContentChild>& toDestroy = mGMPContentChildren[i - 1];
|
||||
if (toDestroy.get() == aGMPContentChild) {
|
||||
SendPGMPContentChildDestroyed();
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
new DeleteTask<GMPContentChild>(toDestroy.release()));
|
||||
mGMPContentChildren.RemoveElementAt(i - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define GMPChild_h_
|
||||
|
||||
#include "mozilla/gmp/PGMPChild.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "GMPTimerChild.h"
|
||||
#include "GMPStorageChild.h"
|
||||
#include "GMPLoader.h"
|
||||
|
@ -18,8 +17,9 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPContentChild;
|
||||
|
||||
class GMPChild : public PGMPChild
|
||||
, public GMPSharedMem
|
||||
, public GMPAsyncShutdownHost
|
||||
{
|
||||
public:
|
||||
|
@ -40,9 +40,6 @@ public:
|
|||
GMPTimerChild* GetGMPTimers();
|
||||
GMPStorageChild* GetGMPStorage();
|
||||
|
||||
// GMPSharedMem
|
||||
virtual void CheckThread() override;
|
||||
|
||||
// GMPAsyncShutdownHost
|
||||
void ShutdownComplete() override;
|
||||
|
||||
|
@ -51,6 +48,7 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
friend class GMPContentChild;
|
||||
|
||||
bool PreLoadPluginVoucher(const std::string& aPluginPath);
|
||||
void PreLoadSandboxVoucher();
|
||||
|
@ -63,36 +61,27 @@ private:
|
|||
virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
|
||||
virtual bool DeallocPCrashReporterChild(PCrashReporterChild*) override;
|
||||
|
||||
virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() override;
|
||||
virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
|
||||
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) override;
|
||||
|
||||
virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
|
||||
virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
|
||||
virtual bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
|
||||
|
||||
virtual PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
|
||||
virtual bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
|
||||
virtual bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
|
||||
|
||||
virtual PGMPAudioDecoderChild* AllocPGMPAudioDecoderChild() override;
|
||||
virtual bool DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor) override;
|
||||
virtual bool RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor) override;
|
||||
|
||||
virtual PGMPTimerChild* AllocPGMPTimerChild() override;
|
||||
virtual bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) override;
|
||||
|
||||
virtual PGMPStorageChild* AllocPGMPStorageChild() override;
|
||||
virtual bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) override;
|
||||
|
||||
virtual PGMPContentChild* AllocPGMPContentChild(Transport* aTransport,
|
||||
ProcessId aOtherPid) override;
|
||||
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
|
||||
|
||||
virtual bool RecvCrashPluginNow() override;
|
||||
virtual bool RecvBeginAsyncShutdown() override;
|
||||
virtual bool RecvCloseActive() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
virtual void ProcessingError(Result aCode, const char* aReason) override;
|
||||
|
||||
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI);
|
||||
|
||||
nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
|
||||
|
||||
GMPAsyncShutdown* mAsyncShutdown;
|
||||
nsRefPtr<GMPTimerChild> mTimerChild;
|
||||
nsRefPtr<GMPStorageChild> mStorage;
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "GMPContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPContentChild::GMPContentChild(GMPChild* aChild)
|
||||
: mGMPChild(aChild)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GMPContentChild);
|
||||
}
|
||||
|
||||
GMPContentChild::~GMPContentChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GMPContentChild);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new DeleteTask<Transport>(GetTransport()));
|
||||
}
|
||||
|
||||
MessageLoop*
|
||||
GMPContentChild::GMPMessageLoop()
|
||||
{
|
||||
return mGMPChild->GMPMessageLoop();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentChild::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mGMPChild->mGMPMessageLoop == MessageLoop::current());
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mGMPChild->GMPContentChildActorDestroy(this);
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentChild::ProcessingError(Result aCode, const char* aReason)
|
||||
{
|
||||
mGMPChild->ProcessingError(aCode, aReason);
|
||||
}
|
||||
|
||||
PGMPAudioDecoderChild*
|
||||
GMPContentChild::AllocPGMPAudioDecoderChild()
|
||||
{
|
||||
return new GMPAudioDecoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorChild*
|
||||
GMPContentChild::AllocPGMPDecryptorChild()
|
||||
{
|
||||
GMPDecryptorChild* actor = new GMPDecryptorChild(this,
|
||||
mGMPChild->mPluginVoucher,
|
||||
mGMPChild->mSandboxVoucher);
|
||||
actor->AddRef();
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
static_cast<GMPDecryptorChild*>(aActor)->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoDecoderChild*
|
||||
GMPContentChild::AllocPGMPVideoDecoderChild()
|
||||
{
|
||||
return new GMPVideoDecoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoEncoderChild*
|
||||
GMPContentChild::AllocPGMPVideoEncoderChild()
|
||||
{
|
||||
return new GMPVideoEncoderChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
|
||||
GMPDecryptorHost* host = static_cast<GMPDecryptorHost*>(child);
|
||||
|
||||
void* session = nullptr;
|
||||
GMPErr err = mGMPChild->GetAPI(GMP_API_DECRYPTOR, host, &session);
|
||||
if (err != GMPNoErr && !session) {
|
||||
// XXX to remove in bug 1147692
|
||||
err = mGMPChild->GetAPI(GMP_API_DECRYPTOR_COMPAT, host, &session);
|
||||
}
|
||||
|
||||
if (err != GMPNoErr || !session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
child->Init(static_cast<GMPDecryptor*>(session));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor)
|
||||
{
|
||||
auto vdc = static_cast<GMPAudioDecoderChild*>(aActor);
|
||||
|
||||
void* vd = nullptr;
|
||||
GMPErr err = mGMPChild->GetAPI(GMP_API_AUDIO_DECODER, &vdc->Host(), &vd);
|
||||
if (err != GMPNoErr || !vd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vdc->Init(static_cast<GMPAudioDecoder*>(vd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor)
|
||||
{
|
||||
auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
|
||||
|
||||
void* vd = nullptr;
|
||||
GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
|
||||
if (err != GMPNoErr || !vd) {
|
||||
NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
|
||||
return false;
|
||||
}
|
||||
|
||||
vdc->Init(static_cast<GMPVideoDecoder*>(vd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor)
|
||||
{
|
||||
auto vec = static_cast<GMPVideoEncoderChild*>(aActor);
|
||||
|
||||
void* ve = nullptr;
|
||||
GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_ENCODER, &vec->Host(), &ve);
|
||||
if (err != GMPNoErr || !ve) {
|
||||
NS_WARNING("GMPGetAPI call failed trying to construct encoder.");
|
||||
return false;
|
||||
}
|
||||
|
||||
vec->Init(static_cast<GMPVideoEncoder*>(ve));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentChild::CloseActive()
|
||||
{
|
||||
// Invalidate and remove any remaining API objects.
|
||||
const nsTArray<PGMPAudioDecoderChild*>& audioDecoders =
|
||||
ManagedPGMPAudioDecoderChild();
|
||||
for (uint32_t i = audioDecoders.Length(); i > 0; i--) {
|
||||
audioDecoders[i - 1]->SendShutdown();
|
||||
}
|
||||
|
||||
const nsTArray<PGMPDecryptorChild*>& decryptors =
|
||||
ManagedPGMPDecryptorChild();
|
||||
for (uint32_t i = decryptors.Length(); i > 0; i--) {
|
||||
decryptors[i - 1]->SendShutdown();
|
||||
}
|
||||
|
||||
const nsTArray<PGMPVideoDecoderChild*>& videoDecoders =
|
||||
ManagedPGMPVideoDecoderChild();
|
||||
for (uint32_t i = videoDecoders.Length(); i > 0; i--) {
|
||||
videoDecoders[i - 1]->SendShutdown();
|
||||
}
|
||||
|
||||
const nsTArray<PGMPVideoEncoderChild*>& videoEncoders =
|
||||
ManagedPGMPVideoEncoderChild();
|
||||
for (uint32_t i = videoEncoders.Length(); i > 0; i--) {
|
||||
videoEncoders[i - 1]->SendShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentChild::IsUsed()
|
||||
{
|
||||
return !ManagedPGMPAudioDecoderChild().IsEmpty() ||
|
||||
!ManagedPGMPDecryptorChild().IsEmpty() ||
|
||||
!ManagedPGMPVideoDecoderChild().IsEmpty() ||
|
||||
!ManagedPGMPVideoEncoderChild().IsEmpty();
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 GMPContentChild_h_
|
||||
#define GMPContentChild_h_
|
||||
|
||||
#include "mozilla/gmp/PGMPContentChild.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
|
||||
class GMPContentChild : public PGMPContentChild
|
||||
, public GMPSharedMem
|
||||
{
|
||||
public:
|
||||
explicit GMPContentChild(GMPChild* aChild);
|
||||
virtual ~GMPContentChild();
|
||||
|
||||
MessageLoop* GMPMessageLoop();
|
||||
|
||||
virtual bool RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor) override;
|
||||
virtual bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
|
||||
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) override;
|
||||
virtual bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
|
||||
|
||||
virtual PGMPAudioDecoderChild* AllocPGMPAudioDecoderChild() override;
|
||||
virtual bool DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor) override;
|
||||
|
||||
virtual PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
|
||||
virtual bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
|
||||
|
||||
virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() override;
|
||||
virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
|
||||
|
||||
virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
|
||||
virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
virtual void ProcessingError(Result aCode, const char* aReason) override;
|
||||
|
||||
// GMPSharedMem
|
||||
virtual void CheckThread() override;
|
||||
|
||||
void CloseActive();
|
||||
bool IsUsed();
|
||||
|
||||
GMPChild* mGMPChild;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPContentChild_h_
|
|
@ -0,0 +1,302 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "GMPContentParent.h"
|
||||
#include "GMPAudioDecoderParent.h"
|
||||
#include "GMPDecryptorParent.h"
|
||||
#include "GMPParent.h"
|
||||
#include "GMPServiceChild.h"
|
||||
#include "GMPVideoDecoderParent.h"
|
||||
#include "GMPVideoEncoderParent.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "prlog.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#ifdef LOG
|
||||
#undef LOG
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
extern PRLogModuleInfo* GetGMPLog();
|
||||
|
||||
#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
|
||||
#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
|
||||
#else
|
||||
#define LOGD(msg)
|
||||
#define LOG(level, msg)
|
||||
#endif
|
||||
|
||||
#ifdef __CLASS__
|
||||
#undef __CLASS__
|
||||
#endif
|
||||
#define __CLASS__ "GMPContentParent"
|
||||
|
||||
namespace gmp {
|
||||
|
||||
GMPContentParent::GMPContentParent(GMPParent* aParent)
|
||||
: mParent(aParent)
|
||||
{
|
||||
if (mParent) {
|
||||
SetDisplayName(mParent->GetDisplayName());
|
||||
SetPluginId(mParent->GetPluginId());
|
||||
}
|
||||
}
|
||||
|
||||
GMPContentParent::~GMPContentParent()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new DeleteTask<Transport>(GetTransport()));
|
||||
}
|
||||
|
||||
class ReleaseGMPContentParent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit ReleaseGMPContentParent(GMPContentParent* aToRelease)
|
||||
: mToRelease(aToRelease)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPContentParent> mToRelease;
|
||||
};
|
||||
|
||||
void
|
||||
GMPContentParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
MOZ_ASSERT(mAudioDecoders.IsEmpty() &&
|
||||
mDecryptors.IsEmpty() &&
|
||||
mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty());
|
||||
NS_DispatchToCurrentThread(new ReleaseGMPContentParent(this));
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mAudioDecoders.RemoveElement(aDecoder));
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// If the constructor fails, we'll get called before it's added
|
||||
unused << NS_WARN_IF(!mVideoDecoders.RemoveElement(aDecoder));
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// If the constructor fails, we'll get called before it's added
|
||||
unused << NS_WARN_IF(!mVideoEncoders.RemoveElement(aEncoder));
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mDecryptors.RemoveElement(aSession));
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CloseIfUnused()
|
||||
{
|
||||
if (mAudioDecoders.IsEmpty() &&
|
||||
mDecryptors.IsEmpty() &&
|
||||
mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty()) {
|
||||
nsRefPtr<GMPContentParent> toClose;
|
||||
if (mParent) {
|
||||
toClose = mParent->ForgetGMPContentParent();
|
||||
} else {
|
||||
toClose = this;
|
||||
nsRefPtr<GeckoMediaPluginServiceChild> gmp(
|
||||
GeckoMediaPluginServiceChild::GetSingleton());
|
||||
gmp->RemoveGMPContentParent(toClose);
|
||||
}
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableMethod(toClose,
|
||||
&GMPContentParent::Close));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPContentParent::GetGMPDecryptor(GMPDecryptorParent** aGMPDP)
|
||||
{
|
||||
PGMPDecryptorParent* pdp = SendPGMPDecryptorConstructor();
|
||||
if (!pdp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPDecryptorParent* dp = static_cast<GMPDecryptorParent*>(pdp);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(dp);
|
||||
mDecryptors.AppendElement(dp);
|
||||
*aGMPDP = dp;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIThread*
|
||||
GMPContentParent::GMPThread()
|
||||
{
|
||||
if (!mGMPThread) {
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
MOZ_ASSERT(mps);
|
||||
if (!mps) {
|
||||
return nullptr;
|
||||
}
|
||||
// Not really safe if we just grab to the mGMPThread, as we don't know
|
||||
// what thread we're running on and other threads may be trying to
|
||||
// access this without locks! However, debug only, and primary failure
|
||||
// mode outside of compiler-helped TSAN is a leak. But better would be
|
||||
// to use swap() under a lock.
|
||||
mps->GetThread(getter_AddRefs(mGMPThread));
|
||||
MOZ_ASSERT(mGMPThread);
|
||||
}
|
||||
|
||||
return mGMPThread;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPContentParent::GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD)
|
||||
{
|
||||
PGMPAudioDecoderParent* pvap = SendPGMPAudioDecoderConstructor();
|
||||
if (!pvap) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPAudioDecoderParent* vap = static_cast<GMPAudioDecoderParent*>(pvap);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vap);
|
||||
*aGMPAD = vap;
|
||||
mAudioDecoders.AppendElement(vap);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPContentParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD)
|
||||
{
|
||||
// returned with one anonymous AddRef that locks it until Destroy
|
||||
PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor();
|
||||
if (!pvdp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPVideoDecoderParent *vdp = static_cast<GMPVideoDecoderParent*>(pvdp);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vdp);
|
||||
*aGMPVD = vdp;
|
||||
mVideoDecoders.AppendElement(vdp);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPContentParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE)
|
||||
{
|
||||
// returned with one anonymous AddRef that locks it until Destroy
|
||||
PGMPVideoEncoderParent* pvep = SendPGMPVideoEncoderConstructor();
|
||||
if (!pvep) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPVideoEncoderParent *vep = static_cast<GMPVideoEncoderParent*>(pvep);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vep);
|
||||
*aGMPVE = vep;
|
||||
mVideoEncoders.AppendElement(vep);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PGMPVideoDecoderParent*
|
||||
GMPContentParent::AllocPGMPVideoDecoderParent()
|
||||
{
|
||||
GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
|
||||
NS_ADDREF(vdp);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
|
||||
{
|
||||
GMPVideoDecoderParent* vdp = static_cast<GMPVideoDecoderParent*>(aActor);
|
||||
NS_RELEASE(vdp);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoEncoderParent*
|
||||
GMPContentParent::AllocPGMPVideoEncoderParent()
|
||||
{
|
||||
GMPVideoEncoderParent* vep = new GMPVideoEncoderParent(this);
|
||||
NS_ADDREF(vep);
|
||||
return vep;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentParent::DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor)
|
||||
{
|
||||
GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(aActor);
|
||||
NS_RELEASE(vep);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorParent*
|
||||
GMPContentParent::AllocPGMPDecryptorParent()
|
||||
{
|
||||
GMPDecryptorParent* ksp = new GMPDecryptorParent(this);
|
||||
NS_ADDREF(ksp);
|
||||
return ksp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentParent::DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor)
|
||||
{
|
||||
GMPDecryptorParent* ksp = static_cast<GMPDecryptorParent*>(aActor);
|
||||
NS_RELEASE(ksp);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPAudioDecoderParent*
|
||||
GMPContentParent::AllocPGMPAudioDecoderParent()
|
||||
{
|
||||
GMPAudioDecoderParent* vdp = new GMPAudioDecoderParent(this);
|
||||
NS_ADDREF(vdp);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPContentParent::DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor)
|
||||
{
|
||||
GMPAudioDecoderParent* vdp = static_cast<GMPAudioDecoderParent*>(aActor);
|
||||
NS_RELEASE(vdp);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,105 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 GMPContentParent_h_
|
||||
#define GMPContentParent_h_
|
||||
|
||||
#include "mozilla/gmp/PGMPContentParent.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsITimer;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GeckoMediaPluginService;
|
||||
class GMPAudioDecoderParent;
|
||||
class GMPCapability;
|
||||
class GMPDecryptorParent;
|
||||
class GMPParent;
|
||||
class GMPVideoDecoderParent;
|
||||
class GMPVideoEncoderParent;
|
||||
|
||||
class GMPContentParent final : public PGMPContentParent,
|
||||
public GMPSharedMem
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPContentParent)
|
||||
|
||||
explicit GMPContentParent(GMPParent* aParent = nullptr);
|
||||
|
||||
nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
|
||||
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
|
||||
|
||||
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
|
||||
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
|
||||
|
||||
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
|
||||
void DecryptorDestroyed(GMPDecryptorParent* aSession);
|
||||
|
||||
nsresult GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD);
|
||||
void AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder);
|
||||
|
||||
nsIThread* GMPThread();
|
||||
|
||||
// GMPSharedMem
|
||||
virtual void CheckThread() override;
|
||||
|
||||
void SetDisplayName(const nsCString& aDisplayName)
|
||||
{
|
||||
mDisplayName = aDisplayName;
|
||||
}
|
||||
const nsCString& GetDisplayName()
|
||||
{
|
||||
return mDisplayName;
|
||||
}
|
||||
void SetPluginId(const nsCString& aPluginId)
|
||||
{
|
||||
mPluginId = aPluginId;
|
||||
}
|
||||
const nsCString& GetPluginId()
|
||||
{
|
||||
return mPluginId;
|
||||
}
|
||||
|
||||
private:
|
||||
~GMPContentParent();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() override;
|
||||
virtual bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
|
||||
|
||||
virtual PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
|
||||
virtual bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
|
||||
|
||||
virtual PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
|
||||
virtual bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
|
||||
|
||||
virtual PGMPAudioDecoderParent* AllocPGMPAudioDecoderParent() override;
|
||||
virtual bool DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor) override;
|
||||
|
||||
void CloseIfUnused();
|
||||
// Needed because NS_NewRunnableMethod tried to use the class that the method
|
||||
// lives on to store the receiver, but PGMPContentParent isn't refcounted.
|
||||
void Close()
|
||||
{
|
||||
PGMPContentParent::Close();
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
|
||||
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
|
||||
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
|
||||
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
nsRefPtr<GMPParent> mParent;
|
||||
nsCString mDisplayName;
|
||||
nsCString mPluginId;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPParent_h_
|
|
@ -18,7 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPDecryptorChild::GMPDecryptorChild(GMPChild* aPlugin,
|
||||
GMPDecryptorChild::GMPDecryptorChild(GMPContentChild* aPlugin,
|
||||
const nsTArray<uint8_t>& aPluginVoucher,
|
||||
const nsTArray<uint8_t>& aSandboxVoucher)
|
||||
: mSession(nullptr)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
class GMPContentChild;
|
||||
|
||||
class GMPDecryptorChild : public GMPDecryptorCallback
|
||||
, public GMPDecryptorHost
|
||||
|
@ -24,7 +24,7 @@ class GMPDecryptorChild : public GMPDecryptorCallback
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPDecryptorChild);
|
||||
|
||||
explicit GMPDecryptorChild(GMPChild* aPlugin,
|
||||
explicit GMPDecryptorChild(GMPContentChild* aPlugin,
|
||||
const nsTArray<uint8_t>& aPluginVoucher,
|
||||
const nsTArray<uint8_t>& aSandboxVoucher);
|
||||
|
||||
|
@ -123,7 +123,7 @@ private:
|
|||
// GMP's GMPDecryptor implementation.
|
||||
// Only call into this on the (GMP process) main thread.
|
||||
GMPDecryptor* mSession;
|
||||
GMPChild* mPlugin;
|
||||
GMPContentChild* mPlugin;
|
||||
|
||||
// Reference to the vouchers owned by the GMPChild.
|
||||
const nsTArray<uint8_t>& mPluginVoucher;
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPDecryptorParent.h"
|
||||
#include "GMPParent.h"
|
||||
#include "GMPContentParent.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPDecryptorParent::GMPDecryptorParent(GMPParent* aPlugin)
|
||||
GMPDecryptorParent::GMPDecryptorParent(GMPContentParent* aPlugin)
|
||||
: mIsOpen(false)
|
||||
, mShuttingDown(false)
|
||||
, mPlugin(aPlugin)
|
||||
|
@ -307,6 +307,13 @@ GMPDecryptorParent::RecvDecrypted(const uint32_t& aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvShutdown()
|
||||
{
|
||||
Shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note: may be called via Terminated()
|
||||
void
|
||||
GMPDecryptorParent::Close()
|
||||
|
|
|
@ -17,7 +17,7 @@ class CryptoSample;
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
class GMPContentParent;
|
||||
|
||||
class GMPDecryptorParent final : public GMPDecryptorProxy
|
||||
, public PGMPDecryptorParent
|
||||
|
@ -25,7 +25,7 @@ class GMPDecryptorParent final : public GMPDecryptorProxy
|
|||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPDecryptorParent)
|
||||
|
||||
explicit GMPDecryptorParent(GMPParent *aPlugin);
|
||||
explicit GMPDecryptorParent(GMPContentParent *aPlugin);
|
||||
|
||||
// GMPDecryptorProxy
|
||||
|
||||
|
@ -104,12 +104,14 @@ private:
|
|||
|
||||
virtual bool RecvSetCaps(const uint64_t& aCaps) override;
|
||||
|
||||
virtual bool RecvShutdown() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
virtual bool Recv__delete__() override;
|
||||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
nsRefPtr<GMPParent> mPlugin;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
nsCString mPluginId;
|
||||
GMPDecryptorProxyCallback* mCallback;
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "GMPTimerParent.h"
|
||||
|
@ -53,6 +54,7 @@ GMPParent::GMPParent()
|
|||
, mProcess(nullptr)
|
||||
, mDeleteProcessOnlyOnUnload(false)
|
||||
, mAbnormalShutdownInProgress(false)
|
||||
, mGMPContentChildCount(0)
|
||||
, mAsyncShutdownRequired(false)
|
||||
, mAsyncShutdownInProgress(false)
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -72,12 +74,6 @@ GMPParent::~GMPParent()
|
|||
LOGD("GMPParent dtor");
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::CloneFrom(const GMPParent* aOther)
|
||||
{
|
||||
|
@ -87,7 +83,7 @@ GMPParent::CloneFrom(const GMPParent* aOther)
|
|||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir)
|
||||
GMPParent::Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir)
|
||||
{
|
||||
MOZ_ASSERT(aPluginDir);
|
||||
MOZ_ASSERT(aService);
|
||||
|
@ -188,8 +184,8 @@ AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
|
|||
{
|
||||
NS_WARNING("Timed out waiting for GMP async shutdown!");
|
||||
GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
if (service) {
|
||||
service->AsyncShutdownComplete(parent);
|
||||
}
|
||||
|
@ -216,8 +212,8 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
|
|||
}
|
||||
|
||||
int32_t timeout = GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT;
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
if (service) {
|
||||
timeout = service->AsyncShutdownTimeoutMs();
|
||||
}
|
||||
|
@ -226,6 +222,16 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
|
|||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::RecvPGMPContentChildDestroyed()
|
||||
{
|
||||
--mGMPContentChildCount;
|
||||
if (!IsUsed()) {
|
||||
CloseIfUnused();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::CloseIfUnused()
|
||||
{
|
||||
|
@ -235,11 +241,7 @@ GMPParent::CloseIfUnused()
|
|||
if ((mDeleteProcessOnlyOnUnload ||
|
||||
mState == GMPStateLoaded ||
|
||||
mState == GMPStateUnloading) &&
|
||||
mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty() &&
|
||||
mDecryptors.IsEmpty() &&
|
||||
mAudioDecoders.IsEmpty()) {
|
||||
|
||||
!IsUsed()) {
|
||||
// Ensure all timers are killed.
|
||||
for (uint32_t i = mTimers.Length(); i > 0; i--) {
|
||||
mTimers[i - 1]->Shutdown();
|
||||
|
@ -286,57 +288,21 @@ GMPParent::AbortAsyncShutdown()
|
|||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mAudioDecoders.RemoveElement(aDecoder));
|
||||
|
||||
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
|
||||
// until after this has completed.
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::CloseActive(bool aDieWhenUnloaded)
|
||||
{
|
||||
LOGD("%s: state %d", __FUNCTION__, mState);
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (aDieWhenUnloaded) {
|
||||
mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
|
||||
}
|
||||
if (mState == GMPStateLoaded) {
|
||||
mState = GMPStateUnloading;
|
||||
}
|
||||
|
||||
// Invalidate and remove any remaining API objects.
|
||||
for (uint32_t i = mVideoDecoders.Length(); i > 0; i--) {
|
||||
mVideoDecoders[i - 1]->Shutdown();
|
||||
if (mState != GMPStateNotLoaded && IsUsed()) {
|
||||
unused << SendCloseActive();
|
||||
}
|
||||
|
||||
for (uint32_t i = mVideoEncoders.Length(); i > 0; i--) {
|
||||
mVideoEncoders[i - 1]->Shutdown();
|
||||
}
|
||||
|
||||
for (uint32_t i = mDecryptors.Length(); i > 0; i--) {
|
||||
mDecryptors[i - 1]->Shutdown();
|
||||
}
|
||||
|
||||
for (uint32_t i = mAudioDecoders.Length(); i > 0; i--) {
|
||||
mAudioDecoders[i - 1]->Shutdown();
|
||||
}
|
||||
|
||||
// Note: we don't shutdown timers here, we do that in CloseIfUnused(),
|
||||
// as there are multiple entry points to CloseIfUnused().
|
||||
|
||||
// Note: We don't shutdown storage API objects here, as they need to
|
||||
// work during async shutdown of GMPs.
|
||||
|
||||
// Note: the shutdown of the codecs is async! don't kill
|
||||
// the plugin-container until they're all safely shut down via
|
||||
// CloseIfUnused();
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -350,7 +316,8 @@ GMPParent::Shutdown()
|
|||
if (mAbnormalShutdownInProgress) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mVideoDecoders.IsEmpty() && mVideoEncoders.IsEmpty());
|
||||
|
||||
MOZ_ASSERT(!IsUsed());
|
||||
if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
|
||||
return;
|
||||
}
|
||||
|
@ -406,78 +373,6 @@ GMPParent::DeleteProcess()
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// If the constructor fails, we'll get called before it's added
|
||||
unused << NS_WARN_IF(!mVideoDecoders.RemoveElement(aDecoder));
|
||||
|
||||
if (mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty()) {
|
||||
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
|
||||
// until after this has completed.
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// If the constructor fails, we'll get called before it's added
|
||||
unused << NS_WARN_IF(!mVideoEncoders.RemoveElement(aEncoder));
|
||||
|
||||
if (mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty()) {
|
||||
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
|
||||
// until after this has completed.
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mDecryptors.RemoveElement(aSession));
|
||||
|
||||
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
|
||||
// until after this has completed.
|
||||
if (mDecryptors.IsEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::GetGMPDecryptor(GMPDecryptorParent** aGMPDP)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PGMPDecryptorParent* pdp = SendPGMPDecryptorConstructor();
|
||||
if (!pdp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPDecryptorParent* dp = static_cast<GMPDecryptorParent*>(pdp);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(dp);
|
||||
mDecryptors.AppendElement(dp);
|
||||
*aGMPDP = dp;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GMPState
|
||||
GMPParent::State() const
|
||||
{
|
||||
|
@ -539,77 +434,6 @@ GMPParent::EnsureProcessLoaded()
|
|||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PGMPAudioDecoderParent* pvap = SendPGMPAudioDecoderConstructor();
|
||||
if (!pvap) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPAudioDecoderParent* vap = static_cast<GMPAudioDecoderParent*>(pvap);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vap);
|
||||
*aGMPAD = vap;
|
||||
mAudioDecoders.AppendElement(vap);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// returned with one anonymous AddRef that locks it until Destroy
|
||||
PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor();
|
||||
if (!pvdp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPVideoDecoderParent *vdp = static_cast<GMPVideoDecoderParent*>(pvdp);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vdp);
|
||||
*aGMPVD = vdp;
|
||||
mVideoDecoders.AppendElement(vdp);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// returned with one anonymous AddRef that locks it until Destroy
|
||||
PGMPVideoEncoderParent* pvep = SendPGMPVideoEncoderConstructor();
|
||||
if (!pvep) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPVideoEncoderParent *vep = static_cast<GMPVideoEncoderParent*>(pvep);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(vep);
|
||||
*aGMPVE = vep;
|
||||
mVideoEncoders.AppendElement(vep);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void
|
||||
GMPParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
|
||||
|
@ -724,70 +548,6 @@ GMPParent::DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter)
|
|||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoDecoderParent*
|
||||
GMPParent::AllocPGMPVideoDecoderParent()
|
||||
{
|
||||
GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
|
||||
NS_ADDREF(vdp);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
|
||||
{
|
||||
GMPVideoDecoderParent* vdp = static_cast<GMPVideoDecoderParent*>(aActor);
|
||||
NS_RELEASE(vdp);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoEncoderParent*
|
||||
GMPParent::AllocPGMPVideoEncoderParent()
|
||||
{
|
||||
GMPVideoEncoderParent* vep = new GMPVideoEncoderParent(this);
|
||||
NS_ADDREF(vep);
|
||||
return vep;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor)
|
||||
{
|
||||
GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(aActor);
|
||||
NS_RELEASE(vep);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorParent*
|
||||
GMPParent::AllocPGMPDecryptorParent()
|
||||
{
|
||||
GMPDecryptorParent* ksp = new GMPDecryptorParent(this);
|
||||
NS_ADDREF(ksp);
|
||||
return ksp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor)
|
||||
{
|
||||
GMPDecryptorParent* ksp = static_cast<GMPDecryptorParent*>(aActor);
|
||||
NS_RELEASE(ksp);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPAudioDecoderParent*
|
||||
GMPParent::AllocPGMPAudioDecoderParent()
|
||||
{
|
||||
GMPAudioDecoderParent* vdp = new GMPAudioDecoderParent(this);
|
||||
NS_ADDREF(vdp);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor)
|
||||
{
|
||||
GMPAudioDecoderParent* vdp = static_cast<GMPAudioDecoderParent*>(aActor);
|
||||
NS_RELEASE(vdp);
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPStorageParent*
|
||||
GMPParent::AllocPGMPStorageParent()
|
||||
{
|
||||
|
@ -1024,7 +784,7 @@ GMPParent::GetVersion() const
|
|||
return mVersion;
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
const nsCString&
|
||||
GMPParent::GetPluginId() const
|
||||
{
|
||||
return mPluginId;
|
||||
|
@ -1053,6 +813,107 @@ GMPParent::RecvAsyncShutdownComplete()
|
|||
return true;
|
||||
}
|
||||
|
||||
class RunCreateContentParentCallbacks : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit RunCreateContentParentCallbacks(GMPContentParent* aGMPContentParent)
|
||||
: mGMPContentParent(aGMPContentParent)
|
||||
{
|
||||
}
|
||||
|
||||
void TakeCallbacks(nsTArray<UniquePtr<GetGMPContentParentCallback>>& aCallbacks)
|
||||
{
|
||||
mCallbacks.SwapElements(aCallbacks);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
for (uint32_t i = 0, length = mCallbacks.Length(); i < length; ++i) {
|
||||
mCallbacks[i]->Done(mGMPContentParent);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPContentParent> mGMPContentParent;
|
||||
nsTArray<UniquePtr<GetGMPContentParentCallback>> mCallbacks;
|
||||
};
|
||||
|
||||
PGMPContentParent*
|
||||
GMPParent::AllocPGMPContentParent(Transport* aTransport, ProcessId aOtherPid)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
MOZ_ASSERT(!mGMPContentParent);
|
||||
|
||||
mGMPContentParent = new GMPContentParent(this);
|
||||
mGMPContentParent->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(),
|
||||
ipc::ParentSide);
|
||||
|
||||
nsRefPtr<RunCreateContentParentCallbacks> runCallbacks =
|
||||
new RunCreateContentParentCallbacks(mGMPContentParent);
|
||||
runCallbacks->TakeCallbacks(mCallbacks);
|
||||
NS_DispatchToCurrentThread(runCallbacks);
|
||||
MOZ_ASSERT(mCallbacks.IsEmpty());
|
||||
|
||||
return mGMPContentParent;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::GetGMPContentParent(UniquePtr<GetGMPContentParentCallback>&& aCallback)
|
||||
{
|
||||
LOGD("%s %p", __FUNCTION__, this);
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (mGMPContentParent) {
|
||||
aCallback->Done(mGMPContentParent);
|
||||
} else {
|
||||
mCallbacks.AppendElement(Move(aCallback));
|
||||
// If we don't have a GMPContentParent and we try to get one for the first
|
||||
// time (mCallbacks.Length() == 1) then call PGMPContent::Open. If more
|
||||
// calls to GetGMPContentParent happen before mGMPContentParent has been
|
||||
// set then we should just store them, so that they get called when we set
|
||||
// mGMPContentParent as a result of the PGMPContent::Open call.
|
||||
if (mCallbacks.Length() == 1) {
|
||||
if (!EnsureProcessLoaded() || !PGMPContent::Open(this)) {
|
||||
return false;
|
||||
}
|
||||
// We want to increment this as soon as possible, to avoid that we'd try
|
||||
// to shut down the GMP process while we're still trying to get a
|
||||
// PGMPContentParent actor.
|
||||
++mGMPContentChildCount;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<GMPContentParent>
|
||||
GMPParent::ForgetGMPContentParent()
|
||||
{
|
||||
MOZ_ASSERT(mCallbacks.IsEmpty());
|
||||
return Move(mGMPContentParent.forget());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::EnsureProcessLoaded(base::ProcessId* aID)
|
||||
{
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return false;
|
||||
}
|
||||
*aID = OtherPid();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::Bridge(GMPServiceParent* aGMPServiceParent)
|
||||
{
|
||||
if (!PGMPContent::Bridge(aGMPServiceParent, this)) {
|
||||
return false;
|
||||
}
|
||||
++mGMPContentChildCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define GMPParent_h_
|
||||
|
||||
#include "GMPProcessParent.h"
|
||||
#include "GMPService.h"
|
||||
#include "GMPServiceParent.h"
|
||||
#include "GMPAudioDecoderParent.h"
|
||||
#include "GMPDecryptorParent.h"
|
||||
#include "GMPVideoDecoderParent.h"
|
||||
|
@ -54,15 +54,30 @@ enum GMPState {
|
|||
GMPStateClosing
|
||||
};
|
||||
|
||||
class GMPParent final : public PGMPParent,
|
||||
public GMPSharedMem
|
||||
class GMPContentParent;
|
||||
|
||||
class GetGMPContentParentCallback
|
||||
{
|
||||
public:
|
||||
GetGMPContentParentCallback()
|
||||
{
|
||||
MOZ_COUNT_CTOR(GetGMPContentParentCallback);
|
||||
};
|
||||
virtual ~GetGMPContentParentCallback()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GetGMPContentParentCallback);
|
||||
};
|
||||
virtual void Done(GMPContentParent* aGMPContentParent) = 0;
|
||||
};
|
||||
|
||||
class GMPParent final : public PGMPParent
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
|
||||
|
||||
GMPParent();
|
||||
|
||||
nsresult Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir);
|
||||
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
||||
nsresult CloneFrom(const GMPParent* aOther);
|
||||
|
||||
void Crash();
|
||||
|
@ -84,18 +99,6 @@ public:
|
|||
|
||||
bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
|
||||
|
||||
nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
|
||||
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
|
||||
|
||||
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
|
||||
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
|
||||
|
||||
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
|
||||
void DecryptorDestroyed(GMPDecryptorParent* aSession);
|
||||
|
||||
nsresult GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD);
|
||||
void AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder);
|
||||
|
||||
GMPState State() const;
|
||||
nsIThread* GMPThread();
|
||||
|
||||
|
@ -117,7 +120,7 @@ public:
|
|||
|
||||
const nsCString& GetDisplayName() const;
|
||||
const nsCString& GetVersion() const;
|
||||
const nsACString& GetPluginId() const;
|
||||
const nsCString& GetPluginId() const;
|
||||
|
||||
// Returns true if a plugin can be or is being used across multiple NodeIds.
|
||||
bool CanBeSharedCrossNodeIds() const;
|
||||
|
@ -131,14 +134,18 @@ public:
|
|||
return nsCOMPtr<nsIFile>(mDirectory).forget();
|
||||
}
|
||||
|
||||
// GMPSharedMem
|
||||
virtual void CheckThread() override;
|
||||
|
||||
void AbortAsyncShutdown();
|
||||
|
||||
bool GetGMPContentParent(UniquePtr<GetGMPContentParentCallback>&& aCallback);
|
||||
already_AddRefed<GMPContentParent> ForgetGMPContentParent();
|
||||
|
||||
bool EnsureProcessLoaded(base::ProcessId* aID);
|
||||
|
||||
bool Bridge(GMPServiceParent* aGMPServiceParent);
|
||||
|
||||
private:
|
||||
~GMPParent();
|
||||
nsRefPtr<GeckoMediaPluginService> mService;
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> mService;
|
||||
bool EnsureProcessLoaded();
|
||||
nsresult ReadGMPMetaData();
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
|
@ -150,22 +157,13 @@ private:
|
|||
virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) override;
|
||||
virtual bool DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter) override;
|
||||
|
||||
virtual PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() override;
|
||||
virtual bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
|
||||
|
||||
virtual PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
|
||||
virtual bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
|
||||
|
||||
virtual PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
|
||||
virtual bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
|
||||
|
||||
virtual PGMPAudioDecoderParent* AllocPGMPAudioDecoderParent() override;
|
||||
virtual bool DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor) override;
|
||||
|
||||
virtual bool RecvPGMPStorageConstructor(PGMPStorageParent* actor) override;
|
||||
virtual PGMPStorageParent* AllocPGMPStorageParent() override;
|
||||
virtual bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
|
||||
|
||||
virtual PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
|
||||
ProcessId aOtherPid) override;
|
||||
|
||||
virtual bool RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
|
||||
virtual PGMPTimerParent* AllocPGMPTimerParent() override;
|
||||
virtual bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
|
||||
|
@ -173,6 +171,13 @@ private:
|
|||
virtual bool RecvAsyncShutdownComplete() override;
|
||||
virtual bool RecvAsyncShutdownRequired() override;
|
||||
|
||||
virtual bool RecvPGMPContentChildDestroyed() override;
|
||||
bool IsUsed()
|
||||
{
|
||||
return mGMPContentChildCount > 0;
|
||||
}
|
||||
|
||||
|
||||
nsresult EnsureAsyncShutdownTimeoutSet();
|
||||
|
||||
GMPState mState;
|
||||
|
@ -187,10 +192,6 @@ private:
|
|||
bool mDeleteProcessOnlyOnUnload;
|
||||
bool mAbnormalShutdownInProgress;
|
||||
|
||||
nsTArray<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
|
||||
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
|
||||
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
|
||||
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
|
||||
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
|
||||
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
|
@ -198,6 +199,11 @@ private:
|
|||
// NodeId the plugin is assigned to, or empty if the the plugin is not
|
||||
// assigned to a NodeId.
|
||||
nsAutoCString mNodeId;
|
||||
// This is used for GMP content in the parent, there may be more of these in
|
||||
// the content processes.
|
||||
nsRefPtr<GMPContentParent> mGMPContentParent;
|
||||
nsTArray<UniquePtr<GetGMPContentParentCallback>> mCallbacks;
|
||||
uint32_t mGMPContentChildCount;
|
||||
|
||||
bool mAsyncShutdownRequired;
|
||||
bool mAsyncShutdownInProgress;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,37 +15,49 @@
|
|||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
extern PRLogModuleInfo* GetGMPLog();
|
||||
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
class GetGMPContentParentCallback;
|
||||
|
||||
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
|
||||
|
||||
class GeckoMediaPluginService final : public mozIGeckoMediaPluginService
|
||||
, public nsIObserver
|
||||
class GeckoMediaPluginService : public mozIGeckoMediaPluginService
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
|
||||
|
||||
GeckoMediaPluginService();
|
||||
nsresult Init();
|
||||
virtual nsresult Init();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_MOZIGECKOMEDIAPLUGINSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void AsyncShutdownNeeded(GMPParent* aParent);
|
||||
void AsyncShutdownComplete(GMPParent* aParent);
|
||||
void AbortAsyncShutdown();
|
||||
// mozIGeckoMediaPluginService
|
||||
NS_IMETHOD GetThread(nsIThread** aThread) override;
|
||||
NS_IMETHOD HasPluginForAPI(const nsACString& aAPI, nsTArray<nsCString>* aTags,
|
||||
bool *aRetVal) override;
|
||||
NS_IMETHOD GetGMPVideoDecoder(nsTArray<nsCString>* aTags,
|
||||
const nsACString& aNodeId,
|
||||
UniquePtr<GetGMPVideoDecoderCallback>&& aCallback)
|
||||
override;
|
||||
NS_IMETHOD GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
|
||||
const nsACString& aNodeId,
|
||||
UniquePtr<GetGMPVideoEncoderCallback>&& aCallback)
|
||||
override;
|
||||
NS_IMETHOD GetGMPAudioDecoder(nsTArray<nsCString>* aTags,
|
||||
const nsACString& aNodeId,
|
||||
UniquePtr<GetGMPAudioDecoderCallback>&& aCallback)
|
||||
override;
|
||||
NS_IMETHOD GetGMPDecryptor(nsTArray<nsCString>* aTags,
|
||||
const nsACString& aNodeId,
|
||||
UniquePtr<GetGMPDecryptorCallback>&& aCallback)
|
||||
override;
|
||||
|
||||
int32_t AsyncShutdownTimeoutMs();
|
||||
|
||||
|
@ -77,120 +89,29 @@ public:
|
|||
const nsACString& aPluginName,
|
||||
const nsAString& aPluginDumpId);
|
||||
|
||||
private:
|
||||
~GeckoMediaPluginService();
|
||||
protected:
|
||||
GeckoMediaPluginService();
|
||||
virtual ~GeckoMediaPluginService();
|
||||
|
||||
virtual void InitializePlugins() = 0;
|
||||
virtual bool GetContentParentFrom(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
UniquePtr<GetGMPContentParentCallback>&& aCallback) = 0;
|
||||
|
||||
nsresult GMPDispatch(nsIRunnable* event, uint32_t flags = NS_DISPATCH_NORMAL);
|
||||
|
||||
void ClearStorage();
|
||||
|
||||
GMPParent* SelectPluginForAPI(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags);
|
||||
GMPParent* FindPluginForAPIFrom(size_t aSearchStartIndex,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
size_t* aOutPluginIndex);
|
||||
|
||||
void UnloadPlugins();
|
||||
void CrashPlugins();
|
||||
void SetAsyncShutdownComplete();
|
||||
|
||||
void LoadFromEnvironment();
|
||||
void ProcessPossiblePlugin(nsIFile* aDir);
|
||||
|
||||
void AddOnGMPThread(const nsAString& aDirectory);
|
||||
void RemoveOnGMPThread(const nsAString& aDirectory,
|
||||
const bool aDeleteFromDisk);
|
||||
|
||||
nsresult SetAsyncShutdownTimeout();
|
||||
|
||||
struct DirectoryFilter {
|
||||
virtual bool operator()(nsIFile* aPath) = 0;
|
||||
~DirectoryFilter() {}
|
||||
};
|
||||
void ClearNodeIdAndPlugin(DirectoryFilter& aFilter);
|
||||
|
||||
void ForgetThisSiteOnGMPThread(const nsACString& aOrigin);
|
||||
void ClearRecentHistoryOnGMPThread(PRTime aSince);
|
||||
void ShutdownGMPThread();
|
||||
|
||||
protected:
|
||||
friend class GMPParent;
|
||||
void ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld);
|
||||
private:
|
||||
GMPParent* ClonePlugin(const GMPParent* aOriginal);
|
||||
nsresult EnsurePluginsOnDiskScanned();
|
||||
nsresult InitStorage();
|
||||
|
||||
class PathRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
enum EOperation {
|
||||
ADD,
|
||||
REMOVE,
|
||||
REMOVE_AND_DELETE_FROM_DISK,
|
||||
};
|
||||
|
||||
PathRunnable(GeckoMediaPluginService* aService, const nsAString& aPath,
|
||||
EOperation aOperation)
|
||||
: mService(aService)
|
||||
, mPath(aPath)
|
||||
, mOperation(aOperation)
|
||||
{ }
|
||||
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
private:
|
||||
nsRefPtr<GeckoMediaPluginService> mService;
|
||||
nsString mPath;
|
||||
EOperation mOperation;
|
||||
};
|
||||
|
||||
Mutex mMutex; // Protects mGMPThread and mShuttingDown and mPlugins
|
||||
nsTArray<nsRefPtr<GMPParent>> mPlugins;
|
||||
Mutex mMutex; // Protects mGMPThread and mGMPThreadShutdown and some members
|
||||
// in derived classes.
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
bool mShuttingDown;
|
||||
bool mGMPThreadShutdown;
|
||||
bool mShuttingDownOnGMPThread;
|
||||
|
||||
nsTArray<nsRefPtr<PluginCrashCallback>> mPluginCrashCallbacks;
|
||||
|
||||
// True if we've inspected MOZ_GMP_PATH on the GMP thread and loaded any
|
||||
// plugins found there into mPlugins.
|
||||
Atomic<bool> mScannedPluginOnDisk;
|
||||
|
||||
template<typename T>
|
||||
class MainThreadOnly {
|
||||
public:
|
||||
MOZ_IMPLICIT MainThreadOnly(T aValue)
|
||||
: mValue(aValue)
|
||||
{}
|
||||
operator T&() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mValue;
|
||||
}
|
||||
|
||||
private:
|
||||
T mValue;
|
||||
};
|
||||
|
||||
MainThreadOnly<bool> mWaitingForPluginsAsyncShutdown;
|
||||
|
||||
nsTArray<nsRefPtr<GMPParent>> mAsyncShutdownPlugins; // GMP Thread only.
|
||||
|
||||
nsCOMPtr<nsIFile> mStorageBaseDir;
|
||||
|
||||
// Hashes of (origin,topLevelOrigin) to the node id for
|
||||
// non-persistent sessions.
|
||||
nsClassHashtable<nsUint32HashKey, nsCString> mTempNodeIds;
|
||||
|
||||
// Hashes node id to whether that node id is allowed to store data
|
||||
// persistently on disk.
|
||||
nsDataHashtable<nsCStringHashKey, bool> mPersistentStorageAllowed;
|
||||
};
|
||||
|
||||
nsresult ReadSalt(nsIFile* aPath, nsACString& aOutData);
|
||||
bool MatchOrigin(nsIFile* aPath, const nsACString& aOrigin);
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -0,0 +1,382 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "GMPService.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#ifdef LOG
|
||||
#undef LOG
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
|
||||
#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
|
||||
#else
|
||||
#define LOGD(msg)
|
||||
#define LOG(leve1, msg)
|
||||
#endif
|
||||
|
||||
#ifdef __CLASS__
|
||||
#undef __CLASS__
|
||||
#endif
|
||||
#define __CLASS__ "GMPService"
|
||||
|
||||
namespace gmp {
|
||||
|
||||
already_AddRefed<GeckoMediaPluginServiceChild>
|
||||
GeckoMediaPluginServiceChild::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
|
||||
nsRefPtr<GeckoMediaPluginService> service(
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService());
|
||||
#ifdef DEBUG
|
||||
if (service) {
|
||||
nsCOMPtr<mozIGeckoMediaPluginChromeService> chromeService;
|
||||
CallQueryInterface(service.get(), getter_AddRefs(chromeService));
|
||||
MOZ_ASSERT(!chromeService);
|
||||
}
|
||||
#endif
|
||||
return service.forget().downcast<GeckoMediaPluginServiceChild>();
|
||||
}
|
||||
|
||||
class GetServiceChildCallback
|
||||
{
|
||||
public:
|
||||
GetServiceChildCallback()
|
||||
{
|
||||
MOZ_COUNT_CTOR(GetServiceChildCallback);
|
||||
}
|
||||
virtual ~GetServiceChildCallback()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GetServiceChildCallback);
|
||||
}
|
||||
virtual void Done(GMPServiceChild* aGMPServiceChild) = 0;
|
||||
};
|
||||
|
||||
class GetContentParentFromDone : public GetServiceChildCallback
|
||||
{
|
||||
public:
|
||||
GetContentParentFromDone(const nsACString& aNodeId, const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
UniquePtr<GetGMPContentParentCallback>&& aCallback)
|
||||
: mNodeId(aNodeId),
|
||||
mAPI(aAPI),
|
||||
mTags(aTags),
|
||||
mCallback(Move(aCallback))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Done(GMPServiceChild* aGMPServiceChild)
|
||||
{
|
||||
if (!aGMPServiceChild) {
|
||||
mCallback->Done(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<base::ProcessId> alreadyBridgedTo;
|
||||
aGMPServiceChild->GetAlreadyBridgedTo(alreadyBridgedTo);
|
||||
|
||||
base::ProcessId otherProcess;
|
||||
nsCString displayName;
|
||||
nsCString pluginId;
|
||||
bool ok = aGMPServiceChild->SendLoadGMP(mNodeId, mAPI, mTags,
|
||||
alreadyBridgedTo, &otherProcess,
|
||||
&displayName, &pluginId);
|
||||
if (!ok) {
|
||||
mCallback->Done(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<GMPContentParent> parent;
|
||||
aGMPServiceChild->GetBridgedGMPContentParent(otherProcess,
|
||||
getter_AddRefs(parent));
|
||||
if (!alreadyBridgedTo.Contains(otherProcess)) {
|
||||
parent->SetDisplayName(displayName);
|
||||
parent->SetPluginId(pluginId);
|
||||
}
|
||||
|
||||
mCallback->Done(parent);
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString mNodeId;
|
||||
nsCString mAPI;
|
||||
const nsTArray<nsCString> mTags;
|
||||
UniquePtr<GetGMPContentParentCallback> mCallback;
|
||||
};
|
||||
|
||||
bool
|
||||
GeckoMediaPluginServiceChild::GetContentParentFrom(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
UniquePtr<GetGMPContentParentCallback>&& aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
|
||||
UniquePtr<GetServiceChildCallback> callback(
|
||||
new GetContentParentFromDone(aNodeId, aAPI, aTags, Move(aCallback)));
|
||||
GetServiceChild(Move(callback));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginServiceChild::GetPluginVersionForAPI(const nsACString& aAPI,
|
||||
nsTArray<nsCString>* aTags,
|
||||
bool* aHasPlugin,
|
||||
nsACString& aOutVersion)
|
||||
{
|
||||
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
|
||||
if (!contentChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCString version;
|
||||
bool ok = contentChild->SendGetGMPPluginVersionForAPI(nsCString(aAPI), *aTags,
|
||||
aHasPlugin, &version);
|
||||
aOutVersion = version;
|
||||
return ok ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
class GetNodeIdDone : public GetServiceChildCallback
|
||||
{
|
||||
public:
|
||||
GetNodeIdDone(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing,
|
||||
UniquePtr<GetNodeIdCallback>&& aCallback)
|
||||
: mOrigin(aOrigin),
|
||||
mTopLevelOrigin(aTopLevelOrigin),
|
||||
mInPrivateBrowsing(aInPrivateBrowsing),
|
||||
mCallback(Move(aCallback))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Done(GMPServiceChild* aGMPServiceChild)
|
||||
{
|
||||
if (!aGMPServiceChild) {
|
||||
mCallback->Done(NS_ERROR_FAILURE, EmptyCString());
|
||||
return;
|
||||
}
|
||||
|
||||
nsCString outId;
|
||||
if (!aGMPServiceChild->SendGetGMPNodeId(mOrigin, mTopLevelOrigin,
|
||||
mInPrivateBrowsing, &outId)) {
|
||||
mCallback->Done(NS_ERROR_FAILURE, EmptyCString());
|
||||
return;
|
||||
}
|
||||
|
||||
mCallback->Done(NS_OK, outId);
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mOrigin;
|
||||
nsString mTopLevelOrigin;
|
||||
bool mInPrivateBrowsing;
|
||||
UniquePtr<GetNodeIdCallback> mCallback;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginServiceChild::GetNodeId(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing,
|
||||
UniquePtr<GetNodeIdCallback>&& aCallback)
|
||||
{
|
||||
UniquePtr<GetServiceChildCallback> callback(
|
||||
new GetNodeIdDone(aOrigin, aTopLevelOrigin, aInPrivateBrowsing,
|
||||
Move(aCallback)));
|
||||
GetServiceChild(Move(callback));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aSomeData)
|
||||
{
|
||||
LOGD(("%s::%s: %s", __CLASS__, __FUNCTION__, aTopic));
|
||||
if (!strcmp(NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, aTopic)) {
|
||||
if (mServiceChild) {
|
||||
mozilla::SyncRunnable::DispatchToThread(mGMPThread,
|
||||
WrapRunnable(mServiceChild.get(),
|
||||
&PGMPServiceChild::Close));
|
||||
mServiceChild = nullptr;
|
||||
}
|
||||
ShutdownGMPThread();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceChild::GetServiceChild(UniquePtr<GetServiceChildCallback>&& aCallback)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (!mServiceChild) {
|
||||
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
|
||||
if (!contentChild) {
|
||||
return;
|
||||
}
|
||||
mGetServiceChildCallbacks.AppendElement(Move(aCallback));
|
||||
if (mGetServiceChildCallbacks.Length() == 1) {
|
||||
NS_DispatchToMainThread(WrapRunnable(contentChild,
|
||||
&dom::ContentChild::SendCreateGMPService));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
aCallback->Done(mServiceChild.get());
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceChild::SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild)
|
||||
{
|
||||
mServiceChild = Move(aServiceChild);
|
||||
nsTArray<UniquePtr<GetServiceChildCallback>> getServiceChildCallbacks;
|
||||
getServiceChildCallbacks.SwapElements(mGetServiceChildCallbacks);
|
||||
for (uint32_t i = 0, length = getServiceChildCallbacks.Length(); i < length; ++i) {
|
||||
getServiceChildCallbacks[i]->Done(mServiceChild.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent)
|
||||
{
|
||||
if (mServiceChild) {
|
||||
mServiceChild->RemoveGMPContentParent(aGMPContentParent);
|
||||
}
|
||||
}
|
||||
|
||||
GMPServiceChild::GMPServiceChild()
|
||||
{
|
||||
}
|
||||
|
||||
GMPServiceChild::~GMPServiceChild()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new DeleteTask<Transport>(GetTransport()));
|
||||
}
|
||||
|
||||
PGMPContentParent*
|
||||
GMPServiceChild::AllocPGMPContentParent(Transport* aTransport,
|
||||
ProcessId aOtherPid)
|
||||
{
|
||||
MOZ_ASSERT(!mContentParents.GetWeak(aOtherPid));
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
MOZ_ASSERT(mainThread);
|
||||
|
||||
nsRefPtr<GMPContentParent> parent = new GMPContentParent();
|
||||
|
||||
DebugOnly<bool> ok = parent->Open(aTransport, aOtherPid,
|
||||
XRE_GetIOMessageLoop(),
|
||||
mozilla::ipc::ParentSide);
|
||||
MOZ_ASSERT(ok);
|
||||
|
||||
mContentParents.Put(aOtherPid, parent);
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid,
|
||||
GMPContentParent** aGMPContentParent)
|
||||
{
|
||||
mContentParents.Get(aOtherPid, aGMPContentParent);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
FindAndRemoveGMPContentParent(const uint64_t& aKey,
|
||||
nsRefPtr<GMPContentParent>& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
return aData == aUserArg ?
|
||||
(PLDHashOperator)(PL_DHASH_STOP | PL_DHASH_REMOVE) :
|
||||
PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
GMPServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent)
|
||||
{
|
||||
mContentParents.Enumerate(FindAndRemoveGMPContentParent, aGMPContentParent);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
FillProcessIDArray(const uint64_t& aKey, GMPContentParent*, void* aUserArg)
|
||||
{
|
||||
static_cast<nsTArray<base::ProcessId>*>(aUserArg)->AppendElement(aKey);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
GMPServiceChild::GetAlreadyBridgedTo(nsTArray<base::ProcessId>& aAlreadyBridgedTo)
|
||||
{
|
||||
aAlreadyBridgedTo.SetCapacity(mContentParents.Count());
|
||||
mContentParents.EnumerateRead(FillProcessIDArray, &aAlreadyBridgedTo);
|
||||
}
|
||||
|
||||
class OpenPGMPServiceChild : public nsRunnable
|
||||
{
|
||||
public:
|
||||
OpenPGMPServiceChild(UniquePtr<GMPServiceChild>&& aGMPServiceChild,
|
||||
mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherPid)
|
||||
: mGMPServiceChild(Move(aGMPServiceChild)),
|
||||
mTransport(aTransport),
|
||||
mOtherPid(aOtherPid)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginServiceChild> gmp =
|
||||
GeckoMediaPluginServiceChild::GetSingleton();
|
||||
MOZ_ASSERT(!gmp->mServiceChild);
|
||||
if (mGMPServiceChild->Open(mTransport, mOtherPid, XRE_GetIOMessageLoop(),
|
||||
ipc::ChildSide)) {
|
||||
gmp->SetServiceChild(Move(mGMPServiceChild));
|
||||
} else {
|
||||
gmp->SetServiceChild(nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
UniquePtr<GMPServiceChild> mGMPServiceChild;
|
||||
mozilla::ipc::Transport* mTransport;
|
||||
base::ProcessId mOtherPid;
|
||||
};
|
||||
|
||||
/* static */
|
||||
PGMPServiceChild*
|
||||
GMPServiceChild::Create(Transport* aTransport, ProcessId aOtherPid)
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginServiceChild> gmp =
|
||||
GeckoMediaPluginServiceChild::GetSingleton();
|
||||
MOZ_ASSERT(!gmp->mServiceChild);
|
||||
|
||||
UniquePtr<GMPServiceChild> serviceChild(new GMPServiceChild());
|
||||
|
||||
nsCOMPtr<nsIThread> gmpThread;
|
||||
nsresult rv = gmp->GetThread(getter_AddRefs(gmpThread));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
GMPServiceChild* result = serviceChild.get();
|
||||
rv = gmpThread->Dispatch(new OpenPGMPServiceChild(Move(serviceChild),
|
||||
aTransport,
|
||||
aOtherPid),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 GMPServiceChild_h_
|
||||
#define GMPServiceChild_h_
|
||||
|
||||
#include "GMPService.h"
|
||||
#include "base/process.h"
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
#include "mozilla/gmp/PGMPServiceChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
|
||||
|
||||
class GMPContentParent;
|
||||
class GMPServiceChild;
|
||||
class GetServiceChildCallback;
|
||||
|
||||
class GeckoMediaPluginServiceChild : public GeckoMediaPluginService
|
||||
{
|
||||
friend class GMPServiceChild;
|
||||
|
||||
public:
|
||||
static already_AddRefed<GeckoMediaPluginServiceChild> GetSingleton();
|
||||
|
||||
NS_IMETHOD GetPluginVersionForAPI(const nsACString& aAPI,
|
||||
nsTArray<nsCString>* aTags,
|
||||
bool* aHasPlugin,
|
||||
nsACString& aOutVersion) override;
|
||||
NS_IMETHOD GetNodeId(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsingMode,
|
||||
UniquePtr<GetNodeIdCallback>&& aCallback) override;
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild);
|
||||
|
||||
void RemoveGMPContentParent(GMPContentParent* aGMPContentParent);
|
||||
|
||||
protected:
|
||||
virtual void InitializePlugins() override
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
virtual bool GetContentParentFrom(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
UniquePtr<GetGMPContentParentCallback>&& aCallback)
|
||||
override;
|
||||
|
||||
private:
|
||||
friend class OpenPGMPServiceChild;
|
||||
|
||||
void GetServiceChild(UniquePtr<GetServiceChildCallback>&& aCallback);
|
||||
|
||||
UniquePtr<GMPServiceChild> mServiceChild;
|
||||
nsTArray<UniquePtr<GetServiceChildCallback>> mGetServiceChildCallbacks;
|
||||
};
|
||||
|
||||
class GMPServiceChild : public PGMPServiceChild
|
||||
{
|
||||
public:
|
||||
explicit GMPServiceChild();
|
||||
virtual ~GMPServiceChild();
|
||||
|
||||
virtual PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
|
||||
ProcessId aOtherPid)
|
||||
override;
|
||||
|
||||
void GetBridgedGMPContentParent(ProcessId aOtherPid,
|
||||
GMPContentParent** aGMPContentParent);
|
||||
void RemoveGMPContentParent(GMPContentParent* aGMPContentParent);
|
||||
|
||||
void GetAlreadyBridgedTo(nsTArray<ProcessId>& aAlreadyBridgedTo);
|
||||
|
||||
static PGMPServiceChild* Create(Transport* aTransport, ProcessId aOtherPid);
|
||||
|
||||
private:
|
||||
nsRefPtrHashtable<nsUint64HashKey, GMPContentParent> mContentParents;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPServiceChild_h_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,211 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 GMPServiceParent_h_
|
||||
#define GMPServiceParent_h_
|
||||
|
||||
#include "GMPService.h"
|
||||
#include "mozilla/gmp/PGMPServiceParent.h"
|
||||
#include "mozIGeckoMediaPluginChromeService.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
|
||||
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
|
||||
|
||||
class GeckoMediaPluginServiceParent final : public GeckoMediaPluginService
|
||||
, public mozIGeckoMediaPluginChromeService
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<GeckoMediaPluginServiceParent> GetSingleton();
|
||||
|
||||
GeckoMediaPluginServiceParent();
|
||||
virtual nsresult Init() override;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// mozIGeckoMediaPluginService
|
||||
NS_IMETHOD GetPluginVersionForAPI(const nsACString& aAPI,
|
||||
nsTArray<nsCString>* aTags,
|
||||
bool* aHasPlugin,
|
||||
nsACString& aOutVersion) override;
|
||||
NS_IMETHOD GetNodeId(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsingMode,
|
||||
UniquePtr<GetNodeIdCallback>&& aCallback) override;
|
||||
|
||||
NS_DECL_MOZIGECKOMEDIAPLUGINCHROMESERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void AsyncShutdownNeeded(GMPParent* aParent);
|
||||
void AsyncShutdownComplete(GMPParent* aParent);
|
||||
void AbortAsyncShutdown();
|
||||
|
||||
int32_t AsyncShutdownTimeoutMs();
|
||||
|
||||
private:
|
||||
friend class GMPServiceParent;
|
||||
|
||||
virtual ~GeckoMediaPluginServiceParent();
|
||||
|
||||
void ClearStorage();
|
||||
|
||||
GMPParent* SelectPluginForAPI(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags);
|
||||
GMPParent* FindPluginForAPIFrom(size_t aSearchStartIndex,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
size_t* aOutPluginIndex);
|
||||
|
||||
nsresult GetNodeId(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
|
||||
bool aInPrivateBrowsing, nsACString& aOutId);
|
||||
|
||||
void UnloadPlugins();
|
||||
void CrashPlugins();
|
||||
void SetAsyncShutdownComplete();
|
||||
|
||||
void LoadFromEnvironment();
|
||||
void ProcessPossiblePlugin(nsIFile* aDir);
|
||||
|
||||
void AddOnGMPThread(const nsAString& aDirectory);
|
||||
void RemoveOnGMPThread(const nsAString& aDirectory,
|
||||
const bool aDeleteFromDisk);
|
||||
|
||||
nsresult SetAsyncShutdownTimeout();
|
||||
|
||||
struct DirectoryFilter {
|
||||
virtual bool operator()(nsIFile* aPath) = 0;
|
||||
~DirectoryFilter() {}
|
||||
};
|
||||
void ClearNodeIdAndPlugin(DirectoryFilter& aFilter);
|
||||
|
||||
void ForgetThisSiteOnGMPThread(const nsACString& aOrigin);
|
||||
void ClearRecentHistoryOnGMPThread(PRTime aSince);
|
||||
|
||||
protected:
|
||||
friend class GMPParent;
|
||||
void ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld);
|
||||
virtual void InitializePlugins() override;
|
||||
virtual bool GetContentParentFrom(const nsACString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
const nsTArray<nsCString>& aTags,
|
||||
UniquePtr<GetGMPContentParentCallback>&& aCallback)
|
||||
override;
|
||||
private:
|
||||
GMPParent* ClonePlugin(const GMPParent* aOriginal);
|
||||
nsresult EnsurePluginsOnDiskScanned();
|
||||
nsresult InitStorage();
|
||||
|
||||
class PathRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
enum EOperation {
|
||||
ADD,
|
||||
REMOVE,
|
||||
REMOVE_AND_DELETE_FROM_DISK,
|
||||
};
|
||||
|
||||
PathRunnable(GeckoMediaPluginServiceParent* aService, const nsAString& aPath,
|
||||
EOperation aOperation)
|
||||
: mService(aService)
|
||||
, mPath(aPath)
|
||||
, mOperation(aOperation)
|
||||
{ }
|
||||
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
private:
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> mService;
|
||||
nsString mPath;
|
||||
EOperation mOperation;
|
||||
};
|
||||
|
||||
// Protected by mMutex from the base class.
|
||||
nsTArray<nsRefPtr<GMPParent>> mPlugins;
|
||||
bool mShuttingDown;
|
||||
|
||||
// True if we've inspected MOZ_GMP_PATH on the GMP thread and loaded any
|
||||
// plugins found there into mPlugins.
|
||||
Atomic<bool> mScannedPluginOnDisk;
|
||||
|
||||
template<typename T>
|
||||
class MainThreadOnly {
|
||||
public:
|
||||
MOZ_IMPLICIT MainThreadOnly(T aValue)
|
||||
: mValue(aValue)
|
||||
{}
|
||||
operator T&() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mValue;
|
||||
}
|
||||
|
||||
private:
|
||||
T mValue;
|
||||
};
|
||||
|
||||
MainThreadOnly<bool> mWaitingForPluginsAsyncShutdown;
|
||||
|
||||
nsTArray<nsRefPtr<GMPParent>> mAsyncShutdownPlugins; // GMP Thread only.
|
||||
|
||||
nsCOMPtr<nsIFile> mStorageBaseDir;
|
||||
|
||||
// Hashes of (origin,topLevelOrigin) to the node id for
|
||||
// non-persistent sessions.
|
||||
nsClassHashtable<nsUint32HashKey, nsCString> mTempNodeIds;
|
||||
|
||||
// Hashes node id to whether that node id is allowed to store data
|
||||
// persistently on disk.
|
||||
nsDataHashtable<nsCStringHashKey, bool> mPersistentStorageAllowed;
|
||||
};
|
||||
|
||||
nsresult ReadSalt(nsIFile* aPath, nsACString& aOutData);
|
||||
bool MatchOrigin(nsIFile* aPath, const nsACString& aOrigin);
|
||||
|
||||
class GMPServiceParent final : public PGMPServiceParent
|
||||
{
|
||||
public:
|
||||
explicit GMPServiceParent(GeckoMediaPluginServiceParent* aService)
|
||||
: mService(aService)
|
||||
{
|
||||
}
|
||||
virtual ~GMPServiceParent();
|
||||
|
||||
virtual bool RecvLoadGMP(const nsCString& aNodeId,
|
||||
const nsCString& aApi,
|
||||
nsTArray<nsCString>&& aTags,
|
||||
nsTArray<ProcessId>&& aAlreadyBridgedTo,
|
||||
base::ProcessId* aID,
|
||||
nsCString* aDisplayName,
|
||||
nsCString* aPluginId) override;
|
||||
virtual bool RecvGetGMPNodeId(const nsString& aOrigin,
|
||||
const nsString& aTopLevelOrigin,
|
||||
const bool& aInPrivateBrowsing,
|
||||
nsCString* aID) override;
|
||||
static bool RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,
|
||||
nsTArray<nsCString>&& aTags,
|
||||
bool* aHasPlugin,
|
||||
nsCString* aVersion);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy);
|
||||
|
||||
static PGMPServiceParent* Create(Transport* aTransport, ProcessId aOtherPid);
|
||||
|
||||
private:
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> mService;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPServiceParent_h_
|
|
@ -52,7 +52,7 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
nsCOMPtr<mozIGeckoMediaPluginChromeService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (NS_WARN_IF(!mps)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -468,7 +468,7 @@ GMPStorageParent::Init()
|
|||
if (NS_WARN_IF(mNodeId.IsEmpty())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
nsCOMPtr<mozIGeckoMediaPluginChromeService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (NS_WARN_IF(!mps)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "GMPVideoDecoderChild.h"
|
||||
#include "GMPVideoi420FrameImpl.h"
|
||||
#include "GMPChild.h"
|
||||
#include "GMPContentChild.h"
|
||||
#include <stdio.h>
|
||||
#include "mozilla/unused.h"
|
||||
#include "GMPVideoEncodedFrameImpl.h"
|
||||
|
@ -13,7 +13,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPChild* aPlugin)
|
||||
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPContentChild* aPlugin)
|
||||
: GMPSharedMemManager(aPlugin),
|
||||
mPlugin(aPlugin),
|
||||
mVideoDecoder(nullptr),
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
class GMPContentChild;
|
||||
|
||||
class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
|
||||
public GMPVideoDecoderCallback,
|
||||
public GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
explicit GMPVideoDecoderChild(GMPChild* aPlugin);
|
||||
explicit GMPVideoDecoderChild(GMPContentChild* aPlugin);
|
||||
virtual ~GMPVideoDecoderChild();
|
||||
|
||||
void Init(GMPVideoDecoder* aDecoder);
|
||||
|
@ -74,7 +74,7 @@ private:
|
|||
virtual bool RecvDrain() override;
|
||||
virtual bool RecvDecodingComplete() override;
|
||||
|
||||
GMPChild* mPlugin;
|
||||
GMPContentChild* mPlugin;
|
||||
GMPVideoDecoder* mVideoDecoder;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "GMPUtils.h"
|
||||
#include "GMPVideoEncodedFrameImpl.h"
|
||||
#include "GMPVideoi420FrameImpl.h"
|
||||
#include "GMPParent.h"
|
||||
#include "GMPContentParent.h"
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace gmp {
|
|||
// on Shutdown -> Dead
|
||||
// Dead: mIsOpen == false
|
||||
|
||||
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPParent* aPlugin)
|
||||
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPContentParent* aPlugin)
|
||||
: GMPSharedMemManager(aPlugin)
|
||||
, mIsOpen(false)
|
||||
, mShuttingDown(false)
|
||||
|
@ -335,6 +335,13 @@ GMPVideoDecoderParent::RecvError(const GMPErr& aError)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvShutdown()
|
||||
{
|
||||
Shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem&& aEncodedBuffer)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
class GMPContentParent;
|
||||
|
||||
class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
|
||||
, public GMPVideoDecoderProxy
|
||||
|
@ -27,7 +27,7 @@ class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
|
|||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
|
||||
|
||||
explicit GMPVideoDecoderParent(GMPParent *aPlugin);
|
||||
explicit GMPVideoDecoderParent(GMPContentParent *aPlugin);
|
||||
|
||||
GMPVideoHostImpl& Host();
|
||||
nsresult Shutdown();
|
||||
|
@ -73,6 +73,7 @@ private:
|
|||
virtual bool RecvDrainComplete() override;
|
||||
virtual bool RecvResetComplete() override;
|
||||
virtual bool RecvError(const GMPErr& aError) override;
|
||||
virtual bool RecvShutdown() override;
|
||||
virtual bool RecvParentShmemForPool(Shmem&& aEncodedBuffer) override;
|
||||
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
|
||||
Shmem* aMem) override;
|
||||
|
@ -80,7 +81,7 @@ private:
|
|||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
nsRefPtr<GMPParent> mPlugin;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
GMPVideoDecoderCallbackProxy* mCallback;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPVideoEncoderChild.h"
|
||||
#include "GMPChild.h"
|
||||
#include "GMPContentChild.h"
|
||||
#include <stdio.h>
|
||||
#include "mozilla/unused.h"
|
||||
#include "GMPVideoEncodedFrameImpl.h"
|
||||
|
@ -13,7 +13,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPChild* aPlugin)
|
||||
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPContentChild* aPlugin)
|
||||
: GMPSharedMemManager(aPlugin),
|
||||
mPlugin(aPlugin),
|
||||
mVideoEncoder(nullptr),
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
class GMPContentChild;
|
||||
|
||||
class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
|
||||
public GMPVideoEncoderCallback,
|
||||
public GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
explicit GMPVideoEncoderChild(GMPChild* aPlugin);
|
||||
explicit GMPVideoEncoderChild(GMPContentChild* aPlugin);
|
||||
virtual ~GMPVideoEncoderChild();
|
||||
|
||||
void Init(GMPVideoEncoder* aEncoder);
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
virtual bool RecvSetPeriodicKeyFrames(const bool& aEnable) override;
|
||||
virtual bool RecvEncodingComplete() override;
|
||||
|
||||
GMPChild* mPlugin;
|
||||
GMPContentChild* mPlugin;
|
||||
GMPVideoEncoder* mVideoEncoder;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "mozilla/unused.h"
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "GMPParent.h"
|
||||
#include "GMPContentParent.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
#include "nsThread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -50,7 +50,7 @@ namespace gmp {
|
|||
// on Shutdown -> Dead
|
||||
// Dead: mIsOpen == false
|
||||
|
||||
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
|
||||
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPContentParent *aPlugin)
|
||||
: GMPSharedMemManager(aPlugin),
|
||||
mIsOpen(false),
|
||||
mShuttingDown(false),
|
||||
|
@ -320,6 +320,13 @@ GMPVideoEncoderParent::RecvError(const GMPErr& aError)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::RecvShutdown()
|
||||
{
|
||||
Shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem&& aFrameBuffer)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
class GMPContentParent;
|
||||
|
||||
class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
||||
public PGMPVideoEncoderParent,
|
||||
|
@ -27,7 +27,7 @@ class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
|||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPVideoEncoderParent)
|
||||
|
||||
explicit GMPVideoEncoderParent(GMPParent *aPlugin);
|
||||
explicit GMPVideoEncoderParent(GMPContentParent *aPlugin);
|
||||
|
||||
GMPVideoHostImpl& Host();
|
||||
void Shutdown();
|
||||
|
@ -69,6 +69,7 @@ private:
|
|||
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||
InfallibleTArray<uint8_t>&& aCodecSpecificInfo) override;
|
||||
virtual bool RecvError(const GMPErr& aError) override;
|
||||
virtual bool RecvShutdown() override;
|
||||
virtual bool RecvParentShmemForPool(Shmem&& aFrameBuffer) override;
|
||||
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
||||
Shmem* aMem) override;
|
||||
|
@ -76,7 +77,7 @@ private:
|
|||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
nsRefPtr<GMPParent> mPlugin;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
GMPVideoEncoderCallbackProxy* mCallback;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
nsCOMPtr<nsIThread> mEncodedThread;
|
||||
|
|
|
@ -3,11 +3,8 @@
|
|||
* 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 protocol PGMPVideoDecoder;
|
||||
include protocol PGMPVideoEncoder;
|
||||
include protocol PCrashReporter;
|
||||
include protocol PGMPDecryptor;
|
||||
include protocol PGMPAudioDecoder;
|
||||
include protocol PGMPContent;
|
||||
include protocol PGMPTimer;
|
||||
include protocol PGMPStorage;
|
||||
|
||||
|
@ -18,10 +15,8 @@ namespace gmp {
|
|||
|
||||
intr protocol PGMP
|
||||
{
|
||||
manages PGMPAudioDecoder;
|
||||
manages PGMPDecryptor;
|
||||
manages PGMPVideoDecoder;
|
||||
manages PGMPVideoEncoder;
|
||||
parent opens PGMPContent;
|
||||
|
||||
manages PCrashReporter;
|
||||
manages PGMPTimer;
|
||||
manages PGMPStorage;
|
||||
|
@ -31,19 +26,17 @@ parent:
|
|||
async PGMPTimer();
|
||||
async PGMPStorage();
|
||||
|
||||
async PGMPContentChildDestroyed();
|
||||
|
||||
async AsyncShutdownComplete();
|
||||
async AsyncShutdownRequired();
|
||||
|
||||
child:
|
||||
async PGMPAudioDecoder();
|
||||
async PGMPDecryptor();
|
||||
async PGMPVideoDecoder();
|
||||
async PGMPVideoEncoder();
|
||||
|
||||
async SetNodeId(nsCString nodeId);
|
||||
async StartPlugin();
|
||||
async BeginAsyncShutdown();
|
||||
async CrashPluginNow();
|
||||
async StartPlugin();
|
||||
async SetNodeId(nsCString nodeId);
|
||||
async CloseActive();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* 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 protocol PGMP;
|
||||
include protocol PGMPContent;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPCodecSpecificInfo from "gmp-audio-codec.h";
|
||||
|
@ -16,7 +16,7 @@ namespace gmp {
|
|||
|
||||
async protocol PGMPAudioDecoder
|
||||
{
|
||||
manager PGMP;
|
||||
manager PGMPContent;
|
||||
child:
|
||||
InitDecode(GMPAudioCodecData aCodecSettings);
|
||||
Decode(GMPAudioEncodedSampleData aInput);
|
||||
|
@ -30,6 +30,7 @@ parent:
|
|||
DrainComplete();
|
||||
ResetComplete();
|
||||
Error(GMPErr aErr);
|
||||
async Shutdown();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 protocol PGMP;
|
||||
include protocol PGMPService;
|
||||
include protocol PGMPVideoDecoder;
|
||||
include protocol PGMPVideoEncoder;
|
||||
include protocol PGMPDecryptor;
|
||||
include protocol PGMPAudioDecoder;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
intr protocol PGMPContent
|
||||
{
|
||||
bridges PGMPService, PGMP;
|
||||
|
||||
manages PGMPAudioDecoder;
|
||||
manages PGMPDecryptor;
|
||||
manages PGMPVideoDecoder;
|
||||
manages PGMPVideoEncoder;
|
||||
|
||||
child:
|
||||
async PGMPAudioDecoder();
|
||||
async PGMPDecryptor();
|
||||
async PGMPVideoDecoder();
|
||||
async PGMPVideoEncoder();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
|
@ -3,7 +3,7 @@
|
|||
* 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 protocol PGMP;
|
||||
include protocol PGMPContent;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPSessionMessageType from "gmp-decryption.h";
|
||||
|
@ -17,7 +17,7 @@ namespace gmp {
|
|||
|
||||
async protocol PGMPDecryptor
|
||||
{
|
||||
manager PGMP;
|
||||
manager PGMPContent;
|
||||
child:
|
||||
|
||||
Init();
|
||||
|
@ -84,6 +84,8 @@ parent:
|
|||
SetCaps(uint64_t aCaps);
|
||||
|
||||
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
|
||||
|
||||
async Shutdown();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 protocol PGMP;
|
||||
|
||||
using base::ProcessId from "base/process.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
sync protocol PGMPService
|
||||
{
|
||||
parent spawns PGMP as child;
|
||||
|
||||
parent:
|
||||
sync LoadGMP(nsCString nodeId, nsCString api, nsCString[] tags,
|
||||
ProcessId[] alreadyBridgedTo)
|
||||
returns (ProcessId id, nsCString displayName, nsCString pluginId);
|
||||
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin,
|
||||
bool inPrivateBrowsing)
|
||||
returns (nsCString id);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
|
@ -3,7 +3,7 @@
|
|||
* 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 protocol PGMP;
|
||||
include protocol PGMPContent;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPVideoCodec from "gmp-video-codec.h";
|
||||
|
@ -16,7 +16,7 @@ namespace gmp {
|
|||
|
||||
intr protocol PGMPVideoDecoder
|
||||
{
|
||||
manager PGMP;
|
||||
manager PGMPContent;
|
||||
child:
|
||||
async InitDecode(GMPVideoCodec aCodecSettings,
|
||||
uint8_t[] aCodecSpecific,
|
||||
|
@ -39,6 +39,7 @@ parent:
|
|||
async DrainComplete();
|
||||
async ResetComplete();
|
||||
async Error(GMPErr aErr);
|
||||
async Shutdown();
|
||||
async ParentShmemForPool(Shmem aEncodedBuffer);
|
||||
// MUST be intr - if sync and we create a new Shmem, when the returned
|
||||
// Shmem is received in the Child it will fail to Deserialize
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* 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 protocol PGMP;
|
||||
include protocol PGMPContent;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPVideoCodec from "gmp-video-codec.h";
|
||||
|
@ -17,7 +17,7 @@ namespace gmp {
|
|||
|
||||
intr protocol PGMPVideoEncoder
|
||||
{
|
||||
manager PGMP;
|
||||
manager PGMPContent;
|
||||
child:
|
||||
async InitEncode(GMPVideoCodec aCodecSettings,
|
||||
uint8_t[] aCodecSpecific,
|
||||
|
@ -37,6 +37,7 @@ parent:
|
|||
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||
uint8_t[] aCodecSpecificInfo);
|
||||
async Error(GMPErr aErr);
|
||||
async Shutdown();
|
||||
async ParentShmemForPool(Shmem aFrameBuffer);
|
||||
// MUST be intr - if sync and we create a new Shmem, when the returned
|
||||
// Shmem is received in the Child it will fail to Deserialize
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
XPIDL_MODULE = 'content_geckomediaplugins'
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'mozIGeckoMediaPluginChromeService.idl',
|
||||
'mozIGeckoMediaPluginService.idl',
|
||||
]
|
||||
|
||||
|
@ -35,6 +36,8 @@ EXPORTS += [
|
|||
'GMPAudioHost.h',
|
||||
'GMPCallbackBase.h',
|
||||
'GMPChild.h',
|
||||
'GMPContentChild.h',
|
||||
'GMPContentParent.h',
|
||||
'GMPDecryptorChild.h',
|
||||
'GMPDecryptorParent.h',
|
||||
'GMPDecryptorProxy.h',
|
||||
|
@ -46,6 +49,8 @@ EXPORTS += [
|
|||
'GMPProcessChild.h',
|
||||
'GMPProcessParent.h',
|
||||
'GMPService.h',
|
||||
'GMPServiceChild.h',
|
||||
'GMPServiceParent.h',
|
||||
'GMPSharedMemManager.h',
|
||||
'GMPStorageChild.h',
|
||||
'GMPStorageParent.h',
|
||||
|
@ -76,6 +81,8 @@ UNIFIED_SOURCES += [
|
|||
'GMPAudioDecoderParent.cpp',
|
||||
'GMPAudioHost.cpp',
|
||||
'GMPChild.cpp',
|
||||
'GMPContentChild.cpp',
|
||||
'GMPContentParent.cpp',
|
||||
'GMPDecryptorChild.cpp',
|
||||
'GMPDecryptorParent.cpp',
|
||||
'GMPEncryptedBufferDataImpl.cpp',
|
||||
|
@ -84,6 +91,8 @@ UNIFIED_SOURCES += [
|
|||
'GMPProcessChild.cpp',
|
||||
'GMPProcessParent.cpp',
|
||||
'GMPService.cpp',
|
||||
'GMPServiceChild.cpp',
|
||||
'GMPServiceParent.cpp',
|
||||
'GMPSharedMemManager.cpp',
|
||||
'GMPStorageChild.cpp',
|
||||
'GMPStorageParent.cpp',
|
||||
|
@ -108,7 +117,9 @@ IPDL_SOURCES += [
|
|||
'GMPTypes.ipdlh',
|
||||
'PGMP.ipdl',
|
||||
'PGMPAudioDecoder.ipdl',
|
||||
'PGMPContent.ipdl',
|
||||
'PGMPDecryptor.ipdl',
|
||||
'PGMPService.ipdl',
|
||||
'PGMPStorage.ipdl',
|
||||
'PGMPTimer.ipdl',
|
||||
'PGMPVideoDecoder.ipdl',
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsISupports.idl"
|
||||
#include "nsIFile.idl"
|
||||
|
||||
[scriptable, uuid(5878366c-73f6-486e-ad2f-9aca602864e4)]
|
||||
interface mozIGeckoMediaPluginChromeService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Add a directory to scan for gecko media plugins.
|
||||
* @note Main-thread API.
|
||||
*/
|
||||
void addPluginDirectory(in AString directory);
|
||||
|
||||
/**
|
||||
* Remove a directory for gecko media plugins.
|
||||
* @note Main-thread API.
|
||||
*/
|
||||
void removePluginDirectory(in AString directory);
|
||||
|
||||
/**
|
||||
* Remove a directory for gecko media plugins and delete it from disk.
|
||||
* @note Main-thread API.
|
||||
*/
|
||||
void removeAndDeletePluginDirectory(in AString directory);
|
||||
|
||||
/**
|
||||
* Clears storage data associated with the origin.
|
||||
*/
|
||||
void forgetThisSite(in AString origin);
|
||||
|
||||
/**
|
||||
* Returns true if the given node id is allowed to store things
|
||||
* persistently on disk. Private Browsing and local content are not
|
||||
* allowed to store persistent data.
|
||||
*/
|
||||
bool isPersistentStorageAllowed(in ACString nodeId);
|
||||
|
||||
/**
|
||||
* Returns the directory to use as the base for storing data about GMPs.
|
||||
*/
|
||||
nsIFile getStorageDir();
|
||||
|
||||
};
|
|
@ -5,10 +5,9 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIThread.idl"
|
||||
#include "nsIPrincipal.idl"
|
||||
#include "nsIFile.idl"
|
||||
|
||||
%{C++
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsStringGlue.h"
|
||||
class GMPAudioDecoderProxy;
|
||||
|
@ -16,17 +15,44 @@ class GMPDecryptorProxy;
|
|||
class GMPVideoDecoderProxy;
|
||||
class GMPVideoEncoderProxy;
|
||||
class GMPVideoHost;
|
||||
|
||||
template<class T>
|
||||
class GMPGetterCallback
|
||||
{
|
||||
public:
|
||||
GMPGetterCallback() { MOZ_COUNT_CTOR(GMPGetterCallback<T>); }
|
||||
virtual ~GMPGetterCallback() { MOZ_COUNT_DTOR(GMPGetterCallback<T>); }
|
||||
virtual void Done(T*) = 0;
|
||||
};
|
||||
template<class T>
|
||||
class GMPVideoGetterCallback
|
||||
{
|
||||
public:
|
||||
GMPVideoGetterCallback() { MOZ_COUNT_CTOR(GMPVideoGetterCallback<T>); }
|
||||
virtual ~GMPVideoGetterCallback() { MOZ_COUNT_DTOR(GMPVideoGetterCallback<T>); }
|
||||
virtual void Done(T*, GMPVideoHost*) = 0;
|
||||
};
|
||||
typedef GMPGetterCallback<GMPDecryptorProxy> GetGMPDecryptorCallback;
|
||||
typedef GMPGetterCallback<GMPAudioDecoderProxy> GetGMPAudioDecoderCallback;
|
||||
typedef GMPVideoGetterCallback<GMPVideoDecoderProxy> GetGMPVideoDecoderCallback;
|
||||
typedef GMPVideoGetterCallback<GMPVideoEncoderProxy> GetGMPVideoEncoderCallback;
|
||||
class GetNodeIdCallback
|
||||
{
|
||||
public:
|
||||
GetNodeIdCallback() { MOZ_COUNT_CTOR(GetNodeIdCallback); }
|
||||
virtual ~GetNodeIdCallback() { MOZ_COUNT_DTOR(GetNodeIdCallback); }
|
||||
virtual void Done(nsresult aResult, const nsACString& aNodeId) = 0;
|
||||
};
|
||||
%}
|
||||
|
||||
[ptr] native GMPVideoDecoderProxy(GMPVideoDecoderProxy);
|
||||
[ptr] native GMPVideoEncoderProxy(GMPVideoEncoderProxy);
|
||||
[ptr] native GMPVideoHost(GMPVideoHost);
|
||||
[ptr] native MessageLoop(MessageLoop);
|
||||
[ptr] native TagArray(nsTArray<nsCString>);
|
||||
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
||||
[ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
|
||||
native GetGMPDecryptorCallback(mozilla::UniquePtr<GetGMPDecryptorCallback>&&);
|
||||
native GetGMPAudioDecoderCallback(mozilla::UniquePtr<GetGMPAudioDecoderCallback>&&);
|
||||
native GetGMPVideoDecoderCallback(mozilla::UniquePtr<GetGMPVideoDecoderCallback>&&);
|
||||
native GetGMPVideoEncoderCallback(mozilla::UniquePtr<GetGMPVideoEncoderCallback>&&);
|
||||
native GetNodeIdCallback(mozilla::UniquePtr<GetNodeIdCallback>&&);
|
||||
|
||||
[scriptable, uuid(f71e6e57-5175-4cf3-8cc2-629273a75b67)]
|
||||
[scriptable, uuid(2b0c90e1-df89-4583-a123-8bdb2f5f7e39)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
{
|
||||
|
||||
|
@ -47,84 +73,78 @@ interface mozIGeckoMediaPluginService : nsISupports
|
|||
* Callable on any thread
|
||||
*/
|
||||
[noscript]
|
||||
ACString getPluginVersionForAPI(in ACString api,
|
||||
in TagArray tags);
|
||||
void getPluginVersionForAPI(in ACString api, in TagArray tags,
|
||||
out boolean hasPlugin, out ACString version);
|
||||
|
||||
/**
|
||||
* Get a video decoder that supports the specified tags.
|
||||
* The array of tags should at least contain a codec tag, and optionally
|
||||
* other tags such as for EME keysystem.
|
||||
* Callable only on GMP thread.
|
||||
* This is an asynchronous operation, the Done method of the callback object
|
||||
* will be called on the GMP thread with the result (which might be null in
|
||||
* the case of failure). This method always takes ownership of the callback
|
||||
* object, but if this method returns an error then the Done method of the
|
||||
* callback object will not be called at all.
|
||||
*/
|
||||
[noscript]
|
||||
GMPVideoDecoderProxy getGMPVideoDecoder(in TagArray tags,
|
||||
[optional] in ACString nodeId,
|
||||
out GMPVideoHost outVideoHost);
|
||||
void getGMPVideoDecoder(in TagArray tags,
|
||||
[optional] in ACString nodeId,
|
||||
in GetGMPVideoDecoderCallback callback);
|
||||
|
||||
/**
|
||||
* Get a video encoder that supports the specified tags.
|
||||
* The array of tags should at least contain a codec tag, and optionally
|
||||
* other tags.
|
||||
* Callable only on GMP thread.
|
||||
* This is an asynchronous operation, the Done method of the callback object
|
||||
* will be called on the GMP thread with the result (which might be null in
|
||||
* the case of failure). This method always takes ownership of the callback
|
||||
* object, but if this method returns an error then the Done method of the
|
||||
* callback object will not be called at all.
|
||||
*/
|
||||
[noscript]
|
||||
GMPVideoEncoderProxy getGMPVideoEncoder(in TagArray tags,
|
||||
[optional] in ACString nodeId,
|
||||
out GMPVideoHost outVideoHost);
|
||||
|
||||
// Returns an audio decoder that supports the specified tags.
|
||||
// The array of tags should at least contain a codec tag, and optionally
|
||||
// other tags such as for EME keysystem.
|
||||
// Callable only on GMP thread.
|
||||
GMPAudioDecoderProxy getGMPAudioDecoder(in TagArray tags,
|
||||
[optional] in ACString nodeId);
|
||||
|
||||
// Returns a decryption session manager that supports the specified tags.
|
||||
// The array of tags should at least contain a key system tag, and optionally
|
||||
// other tags.
|
||||
// Callable only on GMP thread.
|
||||
GMPDecryptorProxy getGMPDecryptor(in TagArray tags, in ACString nodeId);
|
||||
void getGMPVideoEncoder(in TagArray tags,
|
||||
[optional] in ACString nodeId,
|
||||
in GetGMPVideoEncoderCallback callback);
|
||||
|
||||
/**
|
||||
* Add a directory to scan for gecko media plugins.
|
||||
* @note Main-thread API.
|
||||
* Returns an audio decoder that supports the specified tags.
|
||||
* The array of tags should at least contain a codec tag, and optionally
|
||||
* other tags such as for EME keysystem.
|
||||
* Callable only on GMP thread.
|
||||
* This is an asynchronous operation, the Done method of the callback object
|
||||
* will be called on the GMP thread with the result (which might be null in
|
||||
* the case of failure). This method always takes ownership of the callback
|
||||
* object, but if this method returns an error then the Done method of the
|
||||
* callback object will not be called at all.
|
||||
*/
|
||||
void addPluginDirectory(in AString directory);
|
||||
[noscript]
|
||||
void getGMPAudioDecoder(in TagArray tags,
|
||||
[optional] in ACString nodeId,
|
||||
in GetGMPAudioDecoderCallback callback);
|
||||
|
||||
/**
|
||||
* Remove a directory for gecko media plugins.
|
||||
* @note Main-thread API.
|
||||
* Returns a decryption session manager that supports the specified tags.
|
||||
* The array of tags should at least contain a key system tag, and optionally
|
||||
* other tags.
|
||||
* Callable only on GMP thread.
|
||||
* This is an asynchronous operation, the Done method of the callback object
|
||||
* will be called on the GMP thread with the result (which might be null in
|
||||
* the case of failure). This method always takes ownership of the callback
|
||||
* object, but if this method returns an error then the Done method of the
|
||||
* callback object will not be called at all.
|
||||
*/
|
||||
void removePluginDirectory(in AString directory);
|
||||
|
||||
/**
|
||||
* Remove a directory for gecko media plugins and delete it from disk.
|
||||
* @note Main-thread API.
|
||||
*/
|
||||
void removeAndDeletePluginDirectory(in AString directory);
|
||||
[noscript]
|
||||
void getGMPDecryptor(in TagArray tags, in ACString nodeId,
|
||||
in GetGMPDecryptorCallback callback);
|
||||
|
||||
/**
|
||||
* Gets the NodeId for a (origin, urlbarOrigin, isInprivateBrowsing) tuple.
|
||||
*/
|
||||
ACString getNodeId(in AString origin,
|
||||
in AString topLevelOrigin,
|
||||
in bool inPrivateBrowsingMode);
|
||||
|
||||
/**
|
||||
* Clears storage data associated with the origin.
|
||||
*/
|
||||
void forgetThisSite(in AString origin);
|
||||
|
||||
/**
|
||||
* Returns true if the given node id is allowed to store things
|
||||
* persistently on disk. Private Browsing and local content are not
|
||||
* allowed to store persistent data.
|
||||
*/
|
||||
bool isPersistentStorageAllowed(in ACString nodeId);
|
||||
|
||||
/**
|
||||
* Returns the directory to use as the base for storing data about GMPs.
|
||||
*/
|
||||
nsIFile getStorageDir();
|
||||
|
||||
[noscript]
|
||||
void getNodeId(in AString origin,
|
||||
in AString topLevelOrigin,
|
||||
in bool inPrivateBrowsingMode,
|
||||
in GetNodeIdCallback callback);
|
||||
};
|
||||
|
|
|
@ -11,12 +11,13 @@
|
|||
#include "GMPVideoDecoderProxy.h"
|
||||
#include "GMPVideoEncoderProxy.h"
|
||||
#include "GMPDecryptorProxy.h"
|
||||
#include "GMPService.h"
|
||||
#include "GMPServiceParent.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
@ -27,87 +28,234 @@ using namespace std;
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::gmp;
|
||||
|
||||
class GMPTestMonitor
|
||||
{
|
||||
public:
|
||||
GMPTestMonitor()
|
||||
: mFinished(false)
|
||||
{
|
||||
}
|
||||
|
||||
void AwaitFinished()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
while (!mFinished) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
mFinished = false;
|
||||
}
|
||||
|
||||
private:
|
||||
void MarkFinished()
|
||||
{
|
||||
mFinished = true;
|
||||
}
|
||||
|
||||
public:
|
||||
void SetFinished()
|
||||
{
|
||||
NS_DispatchToMainThread(NS_NewNonOwningRunnableMethod(this,
|
||||
&GMPTestMonitor::MarkFinished));
|
||||
}
|
||||
|
||||
private:
|
||||
bool mFinished;
|
||||
};
|
||||
|
||||
struct GMPTestRunner
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner)
|
||||
|
||||
void DoTest(void (GMPTestRunner::*aTestMethod)());
|
||||
void RunTestGMPTestCodec();
|
||||
void RunTestGMPCrossOrigin();
|
||||
void DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&));
|
||||
void RunTestGMPTestCodec1(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPTestCodec2(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPTestCodec3(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPCrossOrigin1(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPCrossOrigin2(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPCrossOrigin3(GMPTestMonitor& aMonitor);
|
||||
void RunTestGMPCrossOrigin4(GMPTestMonitor& aMonitor);
|
||||
|
||||
private:
|
||||
~GMPTestRunner() { }
|
||||
};
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPTestCodec()
|
||||
template<class T, class Base,
|
||||
nsresult (NS_STDCALL GeckoMediaPluginService::*Getter)(nsTArray<nsCString>*,
|
||||
const nsACString&,
|
||||
UniquePtr<Base>&&)>
|
||||
class RunTestGMPVideoCodec : public Base
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
public:
|
||||
virtual void Done(T* aGMP, GMPVideoHost* aHost)
|
||||
{
|
||||
EXPECT_TRUE(aGMP);
|
||||
EXPECT_TRUE(aHost);
|
||||
if (aGMP) {
|
||||
aGMP->Close();
|
||||
}
|
||||
mMonitor.SetFinished();
|
||||
}
|
||||
|
||||
GMPVideoHost* host = nullptr;
|
||||
GMPVideoDecoderProxy* decoder = nullptr;
|
||||
GMPVideoDecoderProxy* decoder2 = nullptr;
|
||||
GMPVideoEncoderProxy* encoder = nullptr;
|
||||
static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin)
|
||||
{
|
||||
UniquePtr<GMPCallbackType> callback(new RunTestGMPVideoCodec(aMonitor));
|
||||
Get(aOrigin, Move(callback));
|
||||
}
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
protected:
|
||||
typedef T GMPCodecType;
|
||||
typedef Base GMPCallbackType;
|
||||
|
||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("o"), &host, &decoder2);
|
||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING(""), &host, &decoder);
|
||||
explicit RunTestGMPVideoCodec(GMPTestMonitor& aMonitor)
|
||||
: mMonitor(aMonitor)
|
||||
{
|
||||
}
|
||||
|
||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING(""), &host, &encoder);
|
||||
static nsresult Get(const nsACString& aNodeId, UniquePtr<Base>&& aCallback)
|
||||
{
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
|
||||
EXPECT_TRUE(host);
|
||||
EXPECT_TRUE(decoder);
|
||||
EXPECT_TRUE(decoder2);
|
||||
EXPECT_TRUE(encoder);
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
return ((*service).*Getter)(&tags, aNodeId, Move(aCallback));
|
||||
}
|
||||
|
||||
if (decoder) decoder->Close();
|
||||
if (decoder2) decoder2->Close();
|
||||
if (encoder) encoder->Close();
|
||||
protected:
|
||||
GMPTestMonitor& mMonitor;
|
||||
};
|
||||
|
||||
typedef RunTestGMPVideoCodec<GMPVideoDecoderProxy,
|
||||
GetGMPVideoDecoderCallback,
|
||||
&GeckoMediaPluginService::GetGMPVideoDecoder>
|
||||
RunTestGMPVideoDecoder;
|
||||
typedef RunTestGMPVideoCodec<GMPVideoEncoderProxy,
|
||||
GetGMPVideoEncoderCallback,
|
||||
&GeckoMediaPluginService::GetGMPVideoEncoder>
|
||||
RunTestGMPVideoEncoder;
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPTestCodec1(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoDecoder::Run(aMonitor, NS_LITERAL_CSTRING("o"));
|
||||
}
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPCrossOrigin()
|
||||
GMPTestRunner::RunTestGMPTestCodec2(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
RunTestGMPVideoDecoder::Run(aMonitor, NS_LITERAL_CSTRING(""));
|
||||
}
|
||||
|
||||
GMPVideoHost* host = nullptr;
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
void
|
||||
GMPTestRunner::RunTestGMPTestCodec3(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoEncoder::Run(aMonitor, NS_LITERAL_CSTRING(""));
|
||||
}
|
||||
|
||||
GMPVideoDecoderProxy* decoder1 = nullptr;
|
||||
GMPVideoDecoderProxy* decoder2 = nullptr;
|
||||
GMPVideoEncoderProxy* encoder1 = nullptr;
|
||||
GMPVideoEncoderProxy* encoder2 = nullptr;
|
||||
template<class Base>
|
||||
class RunTestGMPCrossOrigin : public Base
|
||||
{
|
||||
public:
|
||||
virtual void Done(typename Base::GMPCodecType* aGMP, GMPVideoHost* aHost)
|
||||
{
|
||||
EXPECT_TRUE(aGMP);
|
||||
|
||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &decoder1);
|
||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("origin2"), &host, &decoder2);
|
||||
EXPECT_TRUE(!!decoder1 && !!decoder2 &&
|
||||
decoder1->ParentID() != decoder2->ParentID());
|
||||
UniquePtr<typename Base::GMPCallbackType> callback(
|
||||
new Step2(Base::mMonitor, aGMP, mShouldBeEqual));
|
||||
nsresult rv = Base::Get(mOrigin2, Move(callback));
|
||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
Base::mMonitor.SetFinished();
|
||||
}
|
||||
}
|
||||
|
||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &encoder1);
|
||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING("origin2"), &host, &encoder2);
|
||||
EXPECT_TRUE(!!encoder1 && !!encoder2 &&
|
||||
encoder1->ParentID() != encoder2->ParentID());
|
||||
static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin1,
|
||||
const nsCString& aOrigin2)
|
||||
{
|
||||
UniquePtr<typename Base::GMPCallbackType> callback(
|
||||
new RunTestGMPCrossOrigin<Base>(aMonitor, aOrigin1, aOrigin2));
|
||||
nsresult rv = Base::Get(aOrigin1, Move(callback));
|
||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
aMonitor.SetFinished();
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder2) decoder2->Close();
|
||||
if (encoder2) encoder2->Close();
|
||||
private:
|
||||
RunTestGMPCrossOrigin(GMPTestMonitor& aMonitor, const nsCString& aOrigin1,
|
||||
const nsCString& aOrigin2)
|
||||
: Base(aMonitor),
|
||||
mGMP(nullptr),
|
||||
mOrigin2(aOrigin2),
|
||||
mShouldBeEqual(aOrigin1.Equals(aOrigin2))
|
||||
{
|
||||
}
|
||||
|
||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &decoder2);
|
||||
EXPECT_TRUE(!!decoder1 && !!decoder2 &&
|
||||
decoder1->ParentID() == decoder2->ParentID());
|
||||
class Step2 : public Base
|
||||
{
|
||||
public:
|
||||
Step2(GMPTestMonitor& aMonitor,
|
||||
typename Base::GMPCodecType* aGMP,
|
||||
bool aShouldBeEqual)
|
||||
: Base(aMonitor),
|
||||
mGMP(aGMP),
|
||||
mShouldBeEqual(aShouldBeEqual)
|
||||
{
|
||||
}
|
||||
virtual void Done(typename Base::GMPCodecType* aGMP, GMPVideoHost* aHost)
|
||||
{
|
||||
EXPECT_TRUE(aGMP);
|
||||
if (aGMP) {
|
||||
EXPECT_TRUE(mGMP &&
|
||||
(mGMP->ParentID() == aGMP->ParentID()) == mShouldBeEqual);
|
||||
}
|
||||
if (mGMP) {
|
||||
mGMP->Close();
|
||||
}
|
||||
Base::Done(aGMP, aHost);
|
||||
}
|
||||
|
||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &encoder2);
|
||||
EXPECT_TRUE(!!encoder1 && !!encoder2 &&
|
||||
encoder1->ParentID() == encoder2->ParentID());
|
||||
private:
|
||||
typename Base::GMPCodecType* mGMP;
|
||||
bool mShouldBeEqual;
|
||||
};
|
||||
|
||||
if (decoder1) decoder1->Close();
|
||||
if (decoder2) decoder2->Close();
|
||||
if (encoder1) encoder1->Close();
|
||||
if (encoder2) encoder2->Close();
|
||||
typename Base::GMPCodecType* mGMP;
|
||||
nsCString mOrigin2;
|
||||
bool mShouldBeEqual;
|
||||
};
|
||||
|
||||
typedef RunTestGMPCrossOrigin<RunTestGMPVideoDecoder>
|
||||
RunTestGMPVideoDecoderCrossOrigin;
|
||||
typedef RunTestGMPCrossOrigin<RunTestGMPVideoEncoder>
|
||||
RunTestGMPVideoEncoderCrossOrigin;
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPCrossOrigin1(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoDecoderCrossOrigin::Run(
|
||||
aMonitor, NS_LITERAL_CSTRING("origin1"), NS_LITERAL_CSTRING("origin2"));
|
||||
}
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPCrossOrigin2(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoEncoderCrossOrigin::Run(
|
||||
aMonitor, NS_LITERAL_CSTRING("origin1"), NS_LITERAL_CSTRING("origin2"));
|
||||
}
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPCrossOrigin3(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoDecoderCrossOrigin::Run(
|
||||
aMonitor, NS_LITERAL_CSTRING("origin1"), NS_LITERAL_CSTRING("origin1"));
|
||||
}
|
||||
|
||||
void
|
||||
GMPTestRunner::RunTestGMPCrossOrigin4(GMPTestMonitor& aMonitor)
|
||||
{
|
||||
RunTestGMPVideoEncoderCrossOrigin::Run(
|
||||
aMonitor, NS_LITERAL_CSTRING("origin1"), NS_LITERAL_CSTRING("origin1"));
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIThread>
|
||||
|
@ -158,8 +306,8 @@ template<typename T>
|
|||
static nsresult
|
||||
EnumerateGMPStorageDir(const nsACString& aDir, T&& aDirIter)
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
// $profileDir/gmp/
|
||||
|
@ -312,28 +460,53 @@ SimulatePBModeExit()
|
|||
NS_DispatchToMainThread(new NotifyObserversTask("last-pb-context-exited"), NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
class TestGetNodeIdCallback : public GetNodeIdCallback
|
||||
{
|
||||
public:
|
||||
TestGetNodeIdCallback(nsCString& aNodeId, nsresult& aResult)
|
||||
: mNodeId(aNodeId),
|
||||
mResult(aResult)
|
||||
{
|
||||
}
|
||||
|
||||
void Done(nsresult aResult, const nsACString& aNodeId)
|
||||
{
|
||||
mResult = aResult;
|
||||
mNodeId = aNodeId;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString& mNodeId;
|
||||
nsresult& mResult;
|
||||
};
|
||||
|
||||
static nsCString
|
||||
GetNodeId(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPBMode)
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
EXPECT_TRUE(service);
|
||||
nsCString nodeId;
|
||||
nsresult result;
|
||||
UniquePtr<GetNodeIdCallback> callback(new TestGetNodeIdCallback(nodeId,
|
||||
result));
|
||||
// We rely on the fact that the GetNodeId implementation for
|
||||
// GeckoMediaPluginServiceParent is synchronous.
|
||||
nsresult rv = service->GetNodeId(aOrigin,
|
||||
aTopLevelOrigin,
|
||||
aInPBMode,
|
||||
nodeId);
|
||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||
Move(callback));
|
||||
EXPECT_TRUE(NS_SUCCEEDED(rv) && NS_SUCCEEDED(result));
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsGMPStorageIsEmpty()
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
MOZ_ASSERT(service);
|
||||
nsCOMPtr<nsIFile> storage;
|
||||
nsresult rv = service->GetStorageDir(getter_AddRefs(storage));
|
||||
|
@ -437,9 +610,73 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
SetFinished();
|
||||
}
|
||||
|
||||
class CreateDecryptorDone : public GetGMPDecryptorCallback
|
||||
{
|
||||
public:
|
||||
CreateDecryptorDone(GMPStorageTest* aRunner, nsIRunnable* aContinuation)
|
||||
: mRunner(aRunner),
|
||||
mContinuation(aContinuation)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Done(GMPDecryptorProxy* aDecryptor) override
|
||||
{
|
||||
mRunner->mDecryptor = aDecryptor;
|
||||
EXPECT_TRUE(!!mRunner->mDecryptor);
|
||||
|
||||
if (mRunner->mDecryptor) {
|
||||
mRunner->mDecryptor->Init(mRunner);
|
||||
}
|
||||
nsCOMPtr<nsIThread> thread(GetGMPThread());
|
||||
thread->Dispatch(mContinuation, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPStorageTest> mRunner;
|
||||
nsCOMPtr<nsIRunnable> mContinuation;
|
||||
};
|
||||
|
||||
void CreateDecryptor(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPBMode) {
|
||||
bool aInPBMode,
|
||||
const nsCString& aUpdate)
|
||||
{
|
||||
nsTArray<nsCString> updates;
|
||||
updates.AppendElement(aUpdate);
|
||||
CreateDecryptor(aOrigin, aTopLevelOrigin, aInPBMode, Move(updates));
|
||||
}
|
||||
class Updates : public nsRunnable
|
||||
{
|
||||
public:
|
||||
Updates(GMPStorageTest* aRunner, nsTArray<nsCString>&& aUpdates)
|
||||
: mRunner(aRunner),
|
||||
mUpdates(aUpdates)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
for (auto& update : mUpdates) {
|
||||
mRunner->Update(update);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GMPStorageTest> mRunner;
|
||||
nsTArray<nsCString> mUpdates;
|
||||
};
|
||||
void CreateDecryptor(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPBMode,
|
||||
nsTArray<nsCString>&& aUpdates) {
|
||||
nsCOMPtr<nsIRunnable> updates(new Updates(this, Move(aUpdates)));
|
||||
CreateDecryptor(aOrigin, aTopLevelOrigin, aInPBMode, updates);
|
||||
}
|
||||
void CreateDecryptor(const nsAString& aOrigin,
|
||||
const nsAString& aTopLevelOrigin,
|
||||
bool aInPBMode,
|
||||
nsIRunnable* aContinuation) {
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
EXPECT_TRUE(service);
|
||||
|
@ -450,13 +687,11 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("fake"));
|
||||
|
||||
nsresult rv = service->GetGMPDecryptor(&tags, mNodeId, &mDecryptor);
|
||||
UniquePtr<GetGMPDecryptorCallback> callback(
|
||||
new CreateDecryptorDone(this, aContinuation));
|
||||
nsresult rv =
|
||||
service->GetGMPDecryptor(&tags, mNodeId, Move(callback));
|
||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||
EXPECT_TRUE(!!mDecryptor);
|
||||
|
||||
if (mDecryptor) {
|
||||
mDecryptor->Init(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TestBasicStorage() {
|
||||
|
@ -466,16 +701,16 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false);
|
||||
|
||||
// Send a message to the fake GMP for it to run its own tests internally.
|
||||
// It sends us a "test-storage complete" message when its passed, or
|
||||
// some other message if its tests fail.
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"),
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,28 +724,28 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||
|
||||
// Generate storage data for some site.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &GMPStorageTest::TestForgetThisSite_AnotherSite);
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
void TestForgetThisSite_AnotherSite() {
|
||||
Shutdown();
|
||||
|
||||
// Generate storage data for another site.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example3.com"),
|
||||
NS_LITERAL_STRING("example4.com"),
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &GMPStorageTest::TestForgetThisSite_CollectSiteInfo);
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example3.com"),
|
||||
NS_LITERAL_STRING("example4.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
struct NodeInfo {
|
||||
|
@ -545,8 +780,8 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
}
|
||||
|
||||
void TestForgetThisSite_Forget(nsAutoPtr<NodeInfo> aSiteInfo) {
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
service->ForgetThisSite(NS_ConvertUTF8toUTF16(aSiteInfo->siteToForget));
|
||||
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
|
@ -622,16 +857,15 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||
|
||||
// Generate storage data for some site.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &GMPStorageTest::TestClearRecentHistory1_Clear);
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
}
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Generate some storage data.
|
||||
|
@ -645,15 +879,14 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||
|
||||
// Generate storage data for some site.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &GMPStorageTest::TestClearRecentHistory2_Clear);
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -668,15 +901,14 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||
|
||||
// Generate storage data for some site.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &GMPStorageTest::TestClearRecentHistory3_Clear);
|
||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
||||
Update(NS_LITERAL_CSTRING("test-storage"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
||||
NS_LITERAL_STRING("example2.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-storage"));
|
||||
}
|
||||
|
||||
class MaxMTimeFinder {
|
||||
|
@ -774,12 +1006,6 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
void TestCrossOriginStorage() {
|
||||
EXPECT_TRUE(!mDecryptor);
|
||||
|
||||
// Open decryptor on one, origin, write a record, and test that that
|
||||
// record can't be read on another origin.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example3.com"),
|
||||
NS_LITERAL_STRING("example4.com"),
|
||||
false);
|
||||
|
||||
// Send the decryptor the message "store recordid $time"
|
||||
// Wait for the decrytor to send us "stored recordid $time"
|
||||
auto t = time(0);
|
||||
|
@ -790,7 +1016,13 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
|
||||
nsCString update("store crossOriginTestRecordId ");
|
||||
update.AppendInt((int64_t)t);
|
||||
Update(update);
|
||||
|
||||
// Open decryptor on one, origin, write a record, and test that that
|
||||
// record can't be read on another origin.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example3.com"),
|
||||
NS_LITERAL_STRING("example4.com"),
|
||||
false,
|
||||
update);
|
||||
}
|
||||
|
||||
void TestCrossOriginStorage_RecordStoredContinuation() {
|
||||
|
@ -798,87 +1030,102 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
// and try to read the record.
|
||||
Shutdown();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example5.com"),
|
||||
NS_LITERAL_STRING("example6.com"),
|
||||
false);
|
||||
|
||||
Expect(NS_LITERAL_CSTRING("retrieve crossOriginTestRecordId succeeded (length 0 bytes)"),
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("retrieve crossOriginTestRecordId"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example5.com"),
|
||||
NS_LITERAL_STRING("example6.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("retrieve crossOriginTestRecordId"));
|
||||
}
|
||||
|
||||
void TestPBStorage() {
|
||||
// Open decryptor on one, origin, write a record, close decryptor,
|
||||
// open another, and test that record can be read, close decryptor,
|
||||
// then send pb-last-context-closed notification, then open decryptor
|
||||
// and check that it can't read that data; it should have been purged.
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true);
|
||||
|
||||
// Send the decryptor the message "store recordid $time"
|
||||
// Wait for the decrytor to send us "stored recordid $time"
|
||||
nsCString response("stored pbdata test-pb-data");
|
||||
Expect(response, NS_NewRunnableMethod(this,
|
||||
&GMPStorageTest::TestPBStorage_RecordStoredContinuation));
|
||||
|
||||
nsCString update("store pbdata test-pb-data");
|
||||
Update(update);
|
||||
// Open decryptor on one, origin, write a record, close decryptor,
|
||||
// open another, and test that record can be read, close decryptor,
|
||||
// then send pb-last-context-closed notification, then open decryptor
|
||||
// and check that it can't read that data; it should have been purged.
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true,
|
||||
NS_LITERAL_CSTRING("store pbdata test-pb-data"));
|
||||
}
|
||||
|
||||
void TestPBStorage_RecordStoredContinuation() {
|
||||
Shutdown();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true);
|
||||
|
||||
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 12 bytes)"),
|
||||
NS_NewRunnableMethod(this,
|
||||
&GMPStorageTest::TestPBStorage_RecordRetrievedContinuation));
|
||||
Update(NS_LITERAL_CSTRING("retrieve pbdata"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true,
|
||||
NS_LITERAL_CSTRING("retrieve pbdata"));
|
||||
}
|
||||
|
||||
void TestPBStorage_RecordRetrievedContinuation() {
|
||||
Shutdown();
|
||||
SimulatePBModeExit();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true);
|
||||
|
||||
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 0 bytes)"),
|
||||
NS_NewRunnableMethod(this,
|
||||
&GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("retrieve pbdata"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
||||
NS_LITERAL_STRING("pb2.com"),
|
||||
true,
|
||||
NS_LITERAL_CSTRING("retrieve pbdata"));
|
||||
}
|
||||
|
||||
void NextAsyncShutdownTimeoutTest(nsIRunnable* aContinuation)
|
||||
{
|
||||
if (mDecryptor) {
|
||||
Update(NS_LITERAL_CSTRING("shutdown-mode timeout"));
|
||||
Shutdown();
|
||||
}
|
||||
nsCOMPtr<nsIThread> thread(GetGMPThread());
|
||||
thread->Dispatch(aContinuation, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void CreateAsyncShutdownTimeoutGMP(const nsAString& aOrigin1,
|
||||
const nsAString& aOrigin2) {
|
||||
CreateDecryptor(aOrigin1, aOrigin2, false);
|
||||
Update(NS_LITERAL_CSTRING("shutdown-mode timeout"));
|
||||
Shutdown();
|
||||
const nsAString& aOrigin2,
|
||||
void (GMPStorageTest::*aCallback)()) {
|
||||
nsCOMPtr<nsIRunnable> continuation(
|
||||
NS_NewRunnableMethodWithArg<nsCOMPtr<nsIRunnable>>(
|
||||
this,
|
||||
&GMPStorageTest::NextAsyncShutdownTimeoutTest,
|
||||
NS_NewRunnableMethod(this, aCallback)));
|
||||
|
||||
CreateDecryptor(aOrigin1, aOrigin2, false, continuation);
|
||||
}
|
||||
|
||||
void TestAsyncShutdownTimeout() {
|
||||
// Create decryptors that timeout in their async shutdown.
|
||||
// If the gtest hangs on shutdown, test fails!
|
||||
CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("example7.com"),
|
||||
NS_LITERAL_STRING("example8.com"));
|
||||
NS_LITERAL_STRING("example8.com"),
|
||||
&GMPStorageTest::TestAsyncShutdownTimeout2);
|
||||
};
|
||||
|
||||
void TestAsyncShutdownTimeout2() {
|
||||
CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("example9.com"),
|
||||
NS_LITERAL_STRING("example10.com"));
|
||||
NS_LITERAL_STRING("example10.com"),
|
||||
&GMPStorageTest::TestAsyncShutdownTimeout3);
|
||||
};
|
||||
|
||||
void TestAsyncShutdownTimeout3() {
|
||||
CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("example11.com"),
|
||||
NS_LITERAL_STRING("example12.com"));
|
||||
SetFinished();
|
||||
NS_LITERAL_STRING("example12.com"),
|
||||
&GMPStorageTest::SetFinished);
|
||||
};
|
||||
|
||||
void TestAsyncShutdownStorage() {
|
||||
// Test that a GMP can write to storage during shutdown, and retrieve
|
||||
// that written data in a subsequent session.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example13.com"),
|
||||
NS_LITERAL_STRING("example14.com"),
|
||||
false);
|
||||
|
||||
// Instruct the GMP to write a token (the current timestamp, so it's
|
||||
// unique) during async shutdown, then shutdown the plugin, re-create
|
||||
// it, and check that the token was successfully stored.
|
||||
|
@ -895,7 +1142,12 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
Expect(response, NS_NewRunnableMethodWithArg<nsCString>(this,
|
||||
&GMPStorageTest::TestAsyncShutdownStorage_ReceivedShutdownToken, token));
|
||||
|
||||
Update(update);
|
||||
// Test that a GMP can write to storage during shutdown, and retrieve
|
||||
// that written data in a subsequent session.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example13.com"),
|
||||
NS_LITERAL_STRING("example14.com"),
|
||||
false,
|
||||
update);
|
||||
}
|
||||
|
||||
void TestAsyncShutdownStorage_ReceivedShutdownToken(const nsCString& aToken) {
|
||||
|
@ -906,37 +1158,39 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
void TestAsyncShutdownStorage_AsyncShutdownComplete(const nsCString& aToken) {
|
||||
// Create a new instance of the plugin, retrieve the token written
|
||||
// during shutdown and verify it is correct.
|
||||
CreateDecryptor(NS_LITERAL_STRING("example13.com"),
|
||||
NS_LITERAL_STRING("example14.com"),
|
||||
false);
|
||||
nsCString response("retrieved shutdown-token ");
|
||||
response.Append(aToken);
|
||||
Expect(response,
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("retrieve-shutdown-token"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example13.com"),
|
||||
NS_LITERAL_STRING("example14.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("retrieve-shutdown-token"));
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
void TestOutputProtection() {
|
||||
Shutdown();
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example15.com"),
|
||||
NS_LITERAL_STRING("example16.com"),
|
||||
false);
|
||||
|
||||
Expect(NS_LITERAL_CSTRING("OP tests completed"),
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("test-op-apis"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example15.com"),
|
||||
NS_LITERAL_STRING("example16.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("test-op-apis"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void TestPluginVoucher() {
|
||||
CreateDecryptor(NS_LITERAL_STRING("example17.com"),
|
||||
NS_LITERAL_STRING("example18.com"),
|
||||
false);
|
||||
Expect(NS_LITERAL_CSTRING("retrieved plugin-voucher: gmp-fake placeholder voucher"),
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("retrieve-plugin-voucher"));
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("example17.com"),
|
||||
NS_LITERAL_STRING("example18.com"),
|
||||
false,
|
||||
NS_LITERAL_CSTRING("retrieve-plugin-voucher"));
|
||||
}
|
||||
|
||||
void TestGetRecordNamesInMemoryStorage() {
|
||||
|
@ -953,12 +1207,9 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
}
|
||||
|
||||
void TestGetRecordNames(bool aPrivateBrowsing) {
|
||||
CreateDecryptor(NS_LITERAL_STRING("foo.com"),
|
||||
NS_LITERAL_STRING("bar.com"),
|
||||
aPrivateBrowsing);
|
||||
|
||||
// Create a number of records of different names.
|
||||
const uint32_t num = 100;
|
||||
nsTArray<nsCString> updates(num);
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
nsAutoCString response;
|
||||
response.AppendLiteral("stored data");
|
||||
|
@ -972,7 +1223,7 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
mRecordNames.AppendLiteral("data");
|
||||
AppendIntPadded(mRecordNames, i);
|
||||
|
||||
nsAutoCString update;
|
||||
nsCString& update = *updates.AppendElement();
|
||||
update.AppendLiteral("store data");
|
||||
AppendIntPadded(update, i);
|
||||
update.AppendLiteral(" test-data");
|
||||
|
@ -984,8 +1235,12 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
NS_NewRunnableMethod(this, &GMPStorageTest::TestGetRecordNames_QueryNames);
|
||||
}
|
||||
Expect(response, continuation);
|
||||
Update(update);
|
||||
}
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("foo.com"),
|
||||
NS_LITERAL_STRING("bar.com"),
|
||||
aPrivateBrowsing,
|
||||
Move(updates));
|
||||
}
|
||||
|
||||
void TestGetRecordNames_QueryNames() {
|
||||
|
@ -1025,10 +1280,6 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
MOZ_ASSERT(longRecordName.Length() < GMP_MAX_RECORD_NAME_SIZE);
|
||||
MOZ_ASSERT(longRecordName.Length() > 260); // Windows MAX_PATH
|
||||
|
||||
CreateDecryptor(NS_LITERAL_STRING("fuz.com"),
|
||||
NS_LITERAL_STRING("baz.com"),
|
||||
false);
|
||||
|
||||
nsCString response("stored ");
|
||||
response.Append(longRecordName);
|
||||
response.AppendLiteral(" ");
|
||||
|
@ -1039,7 +1290,10 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
|||
update.Append(longRecordName);
|
||||
update.AppendLiteral(" ");
|
||||
update.Append(data);
|
||||
Update(update);
|
||||
CreateDecryptor(NS_LITERAL_STRING("fuz.com"),
|
||||
NS_LITERAL_STRING("baz.com"),
|
||||
false,
|
||||
update);
|
||||
}
|
||||
|
||||
void Expect(const nsCString& aMessage, nsIRunnable* aContinuation) {
|
||||
|
@ -1146,24 +1400,31 @@ private:
|
|||
};
|
||||
|
||||
void
|
||||
GMPTestRunner::DoTest(void (GMPTestRunner::*aTestMethod)())
|
||||
GMPTestRunner::DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&))
|
||||
{
|
||||
nsRefPtr<GeckoMediaPluginService> service =
|
||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
nsCOMPtr<nsIThread> thread(GetGMPThread());
|
||||
|
||||
service->GetThread(getter_AddRefs(thread));
|
||||
thread->Dispatch(NS_NewRunnableMethod(this, aTestMethod), NS_DISPATCH_SYNC);
|
||||
GMPTestMonitor monitor;
|
||||
thread->Dispatch(NS_NewRunnableMethodWithArg<GMPTestMonitor&>(this,
|
||||
aTestMethod,
|
||||
monitor),
|
||||
NS_DISPATCH_NORMAL);
|
||||
monitor.AwaitFinished();
|
||||
}
|
||||
|
||||
TEST(GeckoMediaPlugins, GMPTestCodec) {
|
||||
nsRefPtr<GMPTestRunner> runner = new GMPTestRunner();
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec1);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec2);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec3);
|
||||
}
|
||||
|
||||
TEST(GeckoMediaPlugins, GMPCrossOrigin) {
|
||||
nsRefPtr<GMPTestRunner> runner = new GMPTestRunner();
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin1);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin2);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin3);
|
||||
runner->DoTest(&GMPTestRunner::RunTestGMPCrossOrigin4);
|
||||
}
|
||||
|
||||
TEST(GeckoMediaPlugins, GMPStorageGetNodeId) {
|
||||
|
|
|
@ -371,22 +371,22 @@ skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
|
|||
[test_dormant_playback.html]
|
||||
skip-if = (os == 'win' && os_version == '5.1') || (os != 'win' && toolkit != 'gonk')
|
||||
[test_eme_canvas_blocked.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s || (os == 'win' && !debug) # bug 1043403, bug 1057908, bug 1140675
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || (os == 'win' && !debug) # bug 1043403, bug 1140675
|
||||
[test_eme_non_mse_fails.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # bug 1043403
|
||||
#[test_eme_obs_notification.html]
|
||||
#skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
#skip-if = buildapp == 'b2g' || toolkit == 'android' # bug 1043403
|
||||
# Disabled (bug 1140778) since this test fails and we don't want to remove the
|
||||
# functionality being tested by this test. We should still test other observers
|
||||
# in future however, so I'm not removing the test, just disabling it.
|
||||
[test_eme_persistent_sessions.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # bug 1043403
|
||||
[test_eme_playback.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # bug 1043403
|
||||
[test_eme_requestKeySystemAccess.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # bug 1043403
|
||||
[test_eme_stream_capture_blocked.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s || (os == 'win' && !debug) # bug 1043403, bug 1057908, bug 1140675
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || (os == 'win' && !debug) # bug 1043403, bug 1140675
|
||||
[test_empty_resource.html]
|
||||
[test_error_in_video_document.html]
|
||||
skip-if = toolkit == 'android' || (os == 'win' && !debug) || (os == 'mac' && !debug) # bug 608634
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount);
|
||||
|
||||
// Focus the window.
|
||||
window.focus();
|
||||
SpecialPowers.focus(window);
|
||||
|
||||
is(plugin1.getFocusState(), true, "(3) Plugin should still have focus.");
|
||||
is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount);
|
||||
|
|
|
@ -38,13 +38,12 @@ NS_NewXBLContentSink(nsIXMLContentSink** aResult,
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsXBLContentSink* it = new nsXBLContentSink();
|
||||
|
||||
nsCOMPtr<nsIXMLContentSink> kungFuDeathGrip = it;
|
||||
nsRefPtr<nsXBLContentSink> it = new nsXBLContentSink();
|
||||
nsresult rv = it->Init(aDoc, aURI, aContainer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(it, aResult);
|
||||
it.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXBLContentSink::nsXBLContentSink()
|
||||
|
|
|
@ -86,13 +86,13 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
|
|||
if (nullptr == aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsXMLContentSink* it = new nsXMLContentSink();
|
||||
nsRefPtr<nsXMLContentSink> it = new nsXMLContentSink();
|
||||
|
||||
nsCOMPtr<nsIXMLContentSink> kungFuDeathGrip = it;
|
||||
nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(it, aResult);
|
||||
|
||||
it.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXMLContentSink::nsXMLContentSink()
|
||||
|
|
|
@ -172,7 +172,7 @@ nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindow** aWindow)
|
|||
if (domdoc && !nsContentUtils::CanCallerAccess(domdoc))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
CallQueryInterface(window, aWindow);
|
||||
window.forget(aWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1314,14 +1314,14 @@ nsXULTemplateQueryProcessorRDF::ParseLiteral(const nsString& aParseType,
|
|||
rv = gRDFService->GetIntLiteral(intValue, getter_AddRefs(intLiteral));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = CallQueryInterface(intLiteral, aResult);
|
||||
intLiteral.forget(aResult);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIRDFLiteral> literal;
|
||||
rv = gRDFService->GetLiteral(aValue.get(), getter_AddRefs(literal));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = CallQueryInterface(literal, aResult);
|
||||
literal.forget(aResult);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -628,6 +628,9 @@ APZCCallbackHelper::SendSetTargetAPZCNotification(nsIWidget* aWidget,
|
|||
uint64_t aInputBlockId,
|
||||
const nsRefPtr<SetTargetAPZCCallback>& aCallback)
|
||||
{
|
||||
if (!aWidget || !aDocument) {
|
||||
return;
|
||||
}
|
||||
if (nsIPresShell* shell = aDocument->GetShell()) {
|
||||
if (nsIFrame* rootFrame = shell->GetRootFrame()) {
|
||||
bool waitForRefresh = false;
|
||||
|
|
|
@ -615,7 +615,7 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread)
|
|||
}
|
||||
sImageBridgeChildSingleton = new ImageBridgeChild();
|
||||
sImageBridgeParentSingleton = new ImageBridgeParent(
|
||||
CompositorParent::CompositorLoop(), nullptr, ipc::kCurrentProcessId);
|
||||
CompositorParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
|
||||
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -943,7 +943,7 @@ void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
|
|||
|
||||
bool ImageBridgeChild::IsSameProcess() const
|
||||
{
|
||||
return OtherPid() == ipc::kCurrentProcessId;
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
void ImageBridgeChild::SendPendingAsyncMessges()
|
||||
|
|
|
@ -340,7 +340,7 @@ ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds
|
|||
|
||||
bool ImageBridgeParent::IsSameProcess() const
|
||||
{
|
||||
return OtherPid() == ipc::kCurrentProcessId;
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -976,7 +976,7 @@ LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
|
|||
|
||||
bool LayerTransactionParent::IsSameProcess() const
|
||||
{
|
||||
return OtherPid() == ipc::kCurrentProcessId;
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -738,7 +738,7 @@ ShadowLayerForwarder::IsSameProcess() const
|
|||
if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
|
||||
return false;
|
||||
}
|
||||
return mShadowManager->OtherPid() == kCurrentProcessId;
|
||||
return mShadowManager->OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,7 +141,8 @@ static nsresult EncodeImageData(DataSourceSurface* aDataSurface,
|
|||
aDataSurface->Unmap();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(encoder, aStream);
|
||||
encoder.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
|
||||
|
|
|
@ -1957,7 +1957,7 @@ ChildImpl::OpenMainProcessActorRunnable::Run()
|
|||
}
|
||||
|
||||
// Make sure the parent knows it is same process.
|
||||
parentActor->SetOtherProcessId(kCurrentProcessId);
|
||||
parentActor->SetOtherProcessId(base::GetCurrentProcId());
|
||||
|
||||
// Now that Open() has succeeded transfer the ownership of the actors to IPDL.
|
||||
unused << parentActor.forget();
|
||||
|
|
|
@ -265,7 +265,7 @@ bool DuplicateHandle(HANDLE aSourceHandle,
|
|||
DWORD aDesiredAccess,
|
||||
DWORD aOptions) {
|
||||
// If our process is the target just duplicate the handle.
|
||||
if (aTargetProcessId == kCurrentProcessId) {
|
||||
if (aTargetProcessId == base::GetCurrentProcId()) {
|
||||
return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
|
||||
::GetCurrentProcess(), aTargetHandle,
|
||||
aDesiredAccess, false, aOptions);
|
||||
|
@ -318,7 +318,7 @@ FatalError(const char* aProtocolName, const char* aMsg,
|
|||
formattedMessage.AppendLiteral("\". Killing child side as a result.");
|
||||
NS_ERROR(formattedMessage.get());
|
||||
|
||||
if (aOtherPid != kInvalidProcessId && aOtherPid != kCurrentProcessId) {
|
||||
if (aOtherPid != kInvalidProcessId && aOtherPid != base::GetCurrentProcId()) {
|
||||
ScopedProcessHandle otherProcessHandle;
|
||||
if (base::OpenProcessHandle(aOtherPid, &otherProcessHandle.rwget())) {
|
||||
if (!base::KillProcess(otherProcessHandle,
|
||||
|
|
|
@ -72,7 +72,6 @@ const base::ProcessId kInvalidProcessId = kuint32max;
|
|||
const base::ProcessHandle kInvalidProcessHandle = -1;
|
||||
const base::ProcessId kInvalidProcessId = -1;
|
||||
#endif
|
||||
const base::ProcessId kCurrentProcessId = base::GetCurrentProcId();
|
||||
|
||||
// Scoped base::ProcessHandle to ensure base::CloseProcessHandle is called.
|
||||
struct ScopedProcessHandleTraits
|
||||
|
|
|
@ -185,7 +185,7 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
|
||||
if md.inline:
|
||||
self.write('inline ')
|
||||
if md.inline:
|
||||
if md.never_inline:
|
||||
self.write('MOZ_NEVER_INLINE ')
|
||||
if md.static:
|
||||
self.write('static ')
|
||||
|
|
|
@ -3005,7 +3005,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
ret=Type.BOOL))
|
||||
|
||||
openmeth.addstmts([
|
||||
StmtExpr(ExprAssn(p.otherPidVar(), ExprVar('ipc::kCurrentProcessId'))),
|
||||
StmtExpr(ExprAssn(p.otherPidVar(), ExprCall(ExprVar('base::GetCurrentProcId')))),
|
||||
StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
|
||||
[ aChannel, aMessageLoop, sidevar ]))
|
||||
])
|
||||
|
|
|
@ -19,7 +19,7 @@ bool
|
|||
IPDLUnitTestProcessChild::Init()
|
||||
{
|
||||
IPDLUnitTestChildInit(IOThreadChild::channel(),
|
||||
ParentId(),
|
||||
ParentPid(),
|
||||
IOThreadChild::message_loop());
|
||||
|
||||
if (NS_FAILED(nsRegion::InitStatic()))
|
||||
|
|
|
@ -181,7 +181,7 @@ ${PARENT_ENABLED_CASES_PROC}
|
|||
if (!transport)
|
||||
fail("no transport");
|
||||
|
||||
base::ProcessHandle child = gSubprocess->GetChildProcessHandle();
|
||||
base::ProcessId child = base::GetProcId(gSubprocess->GetChildProcessHandle());
|
||||
|
||||
switch (test) {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -27,15 +27,10 @@ TestBridgeMainParent::Main()
|
|||
|
||||
PTestBridgeMainSubParent*
|
||||
TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
ProcessId otherPid)
|
||||
{
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
|
||||
if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ParentSide)) {
|
||||
if (!a->Open(transport, otherPid, XRE_GetIOMessageLoop(), ipc::ParentSide)) {
|
||||
return nullptr;
|
||||
}
|
||||
return a.forget();
|
||||
|
@ -110,7 +105,7 @@ TestBridgeMainChild::RecvStart()
|
|||
fail("no transport");
|
||||
|
||||
TestBridgeSubParent* bsp = new TestBridgeSubParent();
|
||||
bsp->Open(transport, mSubprocess->GetChildProcessHandle());
|
||||
bsp->Open(transport, base::GetProcId(mSubprocess->GetChildProcessHandle()));
|
||||
|
||||
bsp->Main();
|
||||
return true;
|
||||
|
@ -178,15 +173,10 @@ TestBridgeSubChild::RecvPing()
|
|||
|
||||
PTestBridgeMainSubChild*
|
||||
TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
ProcessId otherPid)
|
||||
{
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
|
||||
if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
|
||||
if (!a->Open(transport, otherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ TestDataStructuresChild::RecvStart()
|
|||
Test15();
|
||||
Test16();
|
||||
Test17();
|
||||
if (OtherProcess() != 0) {
|
||||
if (OtherPid() != base::GetCurrentProcId()) {
|
||||
//FIXME/bug 703317 allocation of nsIntRegion uses a global
|
||||
//region pool which breaks threads
|
||||
Test18();
|
||||
|
|
|
@ -110,7 +110,7 @@ TestFailedCtorChild::DeallocPTestFailedCtorSubChild(PTestFailedCtorSubChild* act
|
|||
void
|
||||
TestFailedCtorChild::ProcessingError(Result aCode, const char* aReason)
|
||||
{
|
||||
if (OtherProcess() != 0) // thread-mode
|
||||
if (OtherPid() != base::GetCurrentProcId()) // thread-mode
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,14 @@ TestHangsParent::AnswerStackFrame()
|
|||
void
|
||||
TestHangsParent::CleanUp()
|
||||
{
|
||||
if (!KillProcess(OtherProcess(), 0, false))
|
||||
fail("terminating child process");
|
||||
ipc::ScopedProcessHandle otherProcessHandle;
|
||||
if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) {
|
||||
fail("couldn't open child process");
|
||||
} else {
|
||||
if (!KillProcess(otherProcessHandle, 0, false)) {
|
||||
fail("terminating child process");
|
||||
}
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,29 +54,24 @@ TestOpensParent::Main()
|
|||
|
||||
static void
|
||||
OpenParent(TestOpensOpenedParent* aParent,
|
||||
Transport* aTransport, ProcessHandle aOtherProcess)
|
||||
Transport* aTransport, base::ProcessId aOtherPid)
|
||||
{
|
||||
AssertNotMainThread();
|
||||
|
||||
// Open the actor on the off-main thread to park it there.
|
||||
// Messages will be delivered to this thread's message loop
|
||||
// instead of the main thread's.
|
||||
if (!aParent->Open(aTransport, aOtherProcess,
|
||||
if (!aParent->Open(aTransport, aOtherPid,
|
||||
XRE_GetIOMessageLoop(), ipc::ParentSide))
|
||||
fail("opening Parent");
|
||||
}
|
||||
|
||||
PTestOpensOpenedParent*
|
||||
TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
ProcessId otherPid)
|
||||
{
|
||||
gMainThread = MessageLoop::current();
|
||||
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gParentThread = new Thread("ParentThread");
|
||||
if (!gParentThread->Start())
|
||||
fail("starting parent thread");
|
||||
|
@ -84,7 +79,7 @@ TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
|
|||
TestOpensOpenedParent* a = new TestOpensOpenedParent(transport);
|
||||
gParentThread->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(OpenParent, a, transport, h));
|
||||
NewRunnableFunction(OpenParent, a, transport, otherPid));
|
||||
|
||||
return a;
|
||||
}
|
||||
|
@ -174,14 +169,14 @@ TestOpensChild::RecvStart()
|
|||
|
||||
static void
|
||||
OpenChild(TestOpensOpenedChild* aChild,
|
||||
Transport* aTransport, ProcessHandle aOtherProcess)
|
||||
Transport* aTransport, base::ProcessId aOtherPid)
|
||||
{
|
||||
AssertNotMainThread();
|
||||
|
||||
// Open the actor on the off-main thread to park it there.
|
||||
// Messages will be delivered to this thread's message loop
|
||||
// instead of the main thread's.
|
||||
if (!aChild->Open(aTransport, aOtherProcess,
|
||||
if (!aChild->Open(aTransport, aOtherPid,
|
||||
XRE_GetIOMessageLoop(), ipc::ChildSide))
|
||||
fail("opening Child");
|
||||
|
||||
|
@ -192,15 +187,10 @@ OpenChild(TestOpensOpenedChild* aChild,
|
|||
|
||||
PTestOpensOpenedChild*
|
||||
TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
ProcessId otherPid)
|
||||
{
|
||||
gMainThread = MessageLoop::current();
|
||||
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gChildThread = new Thread("ChildThread");
|
||||
if (!gChildThread->Start())
|
||||
fail("starting child thread");
|
||||
|
@ -208,7 +198,7 @@ TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
|
|||
TestOpensOpenedChild* a = new TestOpensOpenedChild(transport);
|
||||
gChildThread->message_loop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(OpenChild, a, transport, h));
|
||||
NewRunnableFunction(OpenChild, a, transport, otherPid));
|
||||
|
||||
return a;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ def main(argv):
|
|||
%sChild** child =
|
||||
reinterpret_cast<%sChild**>(&gChildActor);
|
||||
*child = new %sChild();
|
||||
(*child)->Open(transport, parent, worker);
|
||||
(*child)->Open(transport, parentPid, worker);
|
||||
return;
|
||||
}
|
||||
'''% (t, t, t, t) for t in unittests+extras ])
|
||||
|
|
|
@ -98,7 +98,8 @@ class Logging
|
|||
}
|
||||
|
||||
void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
|
||||
const char* side, *objDesc;
|
||||
const char* side;
|
||||
const char* objDesc;
|
||||
void* ptr;
|
||||
|
||||
if (local == incoming) {
|
||||
|
|
|
@ -870,7 +870,8 @@ class HashTable : private AllocPolicy
|
|||
++cur;
|
||||
}
|
||||
|
||||
Entry* cur, *end;
|
||||
Entry* cur;
|
||||
Entry* end;
|
||||
#ifdef JS_DEBUG
|
||||
const HashTable* table_;
|
||||
uint64_t mutationCount;
|
||||
|
@ -1090,7 +1091,8 @@ class HashTable : private AllocPolicy
|
|||
|
||||
static void destroyTable(AllocPolicy& alloc, Entry* oldTable, uint32_t capacity)
|
||||
{
|
||||
for (Entry* e = oldTable, *end = e + capacity; e < end; ++e)
|
||||
Entry* end = oldTable + capacity;
|
||||
for (Entry* e = oldTable; e < end; ++e)
|
||||
e->destroyIfLive();
|
||||
alloc.free_(oldTable);
|
||||
}
|
||||
|
@ -1346,7 +1348,8 @@ class HashTable : private AllocPolicy
|
|||
table = newTable;
|
||||
|
||||
// Copy only live entries, leaving removed ones behind.
|
||||
for (Entry* src = oldTable, *end = src + oldCap; src < end; ++src) {
|
||||
Entry* end = oldTable + oldCap;
|
||||
for (Entry* src = oldTable; src < end; ++src) {
|
||||
if (src->isLive()) {
|
||||
HashNumber hn = src->getKeyHash();
|
||||
findFreeEntry(hn).setLive(
|
||||
|
@ -1480,7 +1483,8 @@ class HashTable : private AllocPolicy
|
|||
memset(table, 0, sizeof(*table) * capacity());
|
||||
} else {
|
||||
uint32_t tableCapacity = capacity();
|
||||
for (Entry* e = table, *end = table + tableCapacity; e < end; ++e)
|
||||
Entry* end = table + tableCapacity;
|
||||
for (Entry* e = table; e < end; ++e)
|
||||
e->clear();
|
||||
}
|
||||
removedCount = 0;
|
||||
|
|
|
@ -795,7 +795,8 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
|||
* example, Rooted<JSObject> and Rooted<JSFunction>, which use the same
|
||||
* stack head pointer for different classes.
|
||||
*/
|
||||
Rooted<void*>** stack, *prev;
|
||||
Rooted<void*>** stack;
|
||||
Rooted<void*>* prev;
|
||||
|
||||
/*
|
||||
* |ptr| must be the last field in Rooted because the analysis treats all
|
||||
|
|
|
@ -6363,7 +6363,8 @@ CheckConditional(FunctionCompiler& f, ParseNode* ternary, MDefinition** def, Typ
|
|||
if (!condType.isInt())
|
||||
return f.failf(cond, "%s is not a subtype of int", condType.toChars());
|
||||
|
||||
MBasicBlock* thenBlock = nullptr, *elseBlock = nullptr;
|
||||
MBasicBlock* thenBlock = nullptr;
|
||||
MBasicBlock* elseBlock = nullptr;
|
||||
if (!f.branchAndStartThen(condDef, &thenBlock, &elseBlock, thenExpr, elseExpr))
|
||||
return false;
|
||||
|
||||
|
@ -6482,7 +6483,8 @@ CheckAddOrSub(FunctionCompiler& f, ParseNode* expr, MDefinition** def, Type* typ
|
|||
ParseNode* lhs = AddSubLeft(expr);
|
||||
ParseNode* rhs = AddSubRight(expr);
|
||||
|
||||
MDefinition* lhsDef, *rhsDef;
|
||||
MDefinition* lhsDef;
|
||||
MDefinition* rhsDef;
|
||||
Type lhsType, rhsType;
|
||||
unsigned lhsNumAddOrSub, rhsNumAddOrSub;
|
||||
|
||||
|
@ -6545,7 +6547,8 @@ CheckDivOrMod(FunctionCompiler& f, ParseNode* expr, MDefinition** def, Type* typ
|
|||
ParseNode* lhs = DivOrModLeft(expr);
|
||||
ParseNode* rhs = DivOrModRight(expr);
|
||||
|
||||
MDefinition* lhsDef, *rhsDef;
|
||||
MDefinition* lhsDef;
|
||||
MDefinition* rhsDef;
|
||||
Type lhsType, rhsType;
|
||||
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
||||
return false;
|
||||
|
@ -6600,7 +6603,8 @@ CheckComparison(FunctionCompiler& f, ParseNode* comp, MDefinition** def, Type* t
|
|||
ParseNode* lhs = ComparisonLeft(comp);
|
||||
ParseNode* rhs = ComparisonRight(comp);
|
||||
|
||||
MDefinition* lhsDef, *rhsDef;
|
||||
MDefinition* lhsDef;
|
||||
MDefinition* rhsDef;
|
||||
Type lhsType, rhsType;
|
||||
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
||||
return false;
|
||||
|
@ -6947,9 +6951,12 @@ CheckIfConditional(FunctionCompiler& f, ParseNode* conditional, ParseNode* thenS
|
|||
ParseNode* lhs = TernaryKid2(conditional);
|
||||
ParseNode* rhs = TernaryKid3(conditional);
|
||||
|
||||
MBasicBlock* maybeAndTest = nullptr, *maybeOrTest = nullptr;
|
||||
MBasicBlock** ifTrueBlock = &maybeAndTest, **ifFalseBlock = &maybeOrTest;
|
||||
ParseNode* ifTrueBlockNode = lhs, *ifFalseBlockNode = rhs;
|
||||
MBasicBlock* maybeAndTest = nullptr;
|
||||
MBasicBlock* maybeOrTest = nullptr;
|
||||
MBasicBlock** ifTrueBlock = &maybeAndTest;
|
||||
MBasicBlock** ifFalseBlock = &maybeOrTest;
|
||||
ParseNode* ifTrueBlockNode = lhs;
|
||||
ParseNode* ifFalseBlockNode = rhs;
|
||||
|
||||
// Try to spot opportunities for short-circuiting in the AND subpart
|
||||
uint32_t andTestLiteral = 0;
|
||||
|
@ -7071,7 +7078,8 @@ CheckIf(FunctionCompiler& f, ParseNode* ifStmt)
|
|||
ParseNode* thenStmt = TernaryKid2(ifStmt);
|
||||
ParseNode* elseStmt = TernaryKid3(ifStmt);
|
||||
|
||||
MBasicBlock* thenBlock = nullptr, *elseBlock = nullptr;
|
||||
MBasicBlock* thenBlock = nullptr;
|
||||
MBasicBlock* elseBlock = nullptr;
|
||||
ParseNode* elseOrJoinStmt = elseStmt ? elseStmt : nextStmt;
|
||||
|
||||
if (!CheckIfCondition(f, cond, thenStmt, elseOrJoinStmt, &thenBlock, &elseBlock))
|
||||
|
|
|
@ -137,9 +137,10 @@ class OrderedHashTable
|
|||
}
|
||||
|
||||
~OrderedHashTable() {
|
||||
for (Range* r = ranges, *next; r; r = next) {
|
||||
next = r->next;
|
||||
for (Range* r = ranges; r; ) {
|
||||
Range* next = r->next;
|
||||
r->onTableDestroyed();
|
||||
r = next;
|
||||
}
|
||||
alloc.free_(hashTable);
|
||||
freeData(data, dataLength);
|
||||
|
@ -593,7 +594,8 @@ class OrderedHashTable
|
|||
void rehashInPlace() {
|
||||
for (uint32_t i = 0, N = hashBuckets(); i < N; i++)
|
||||
hashTable[i] = nullptr;
|
||||
Data* wp = data, *end = data + dataLength;
|
||||
Data* wp = data;
|
||||
Data* end = data + dataLength;
|
||||
for (Data* rp = data; rp != end; rp++) {
|
||||
if (!Ops::isEmpty(Ops::getKey(rp->element))) {
|
||||
HashNumber h = prepareHash(Ops::getKey(rp->element)) >> hashShift;
|
||||
|
@ -642,7 +644,8 @@ class OrderedHashTable
|
|||
}
|
||||
|
||||
Data* wp = newData;
|
||||
for (Data* p = data, *end = data + dataLength; p != end; p++) {
|
||||
Data* end = data + dataLength;
|
||||
for (Data* p = data; p != end; p++) {
|
||||
if (!Ops::isEmpty(Ops::getKey(p->element))) {
|
||||
HashNumber h = prepareHash(Ops::getKey(p->element)) >> newHashShift;
|
||||
new (wp) Data(Move(p->element), newHashTable[h]);
|
||||
|
|
|
@ -60,7 +60,8 @@ class InlineMap
|
|||
MOZ_ASSERT(map.initialized());
|
||||
}
|
||||
|
||||
for (InlineElem* it = inl, *end = inl + inlNext; it != end; ++it) {
|
||||
InlineElem* end = inl + inlNext;
|
||||
for (InlineElem* it = inl; it != end; ++it) {
|
||||
if (it->key && !map.putNew(it->key, it->value))
|
||||
return false;
|
||||
}
|
||||
|
@ -211,7 +212,8 @@ class InlineMap
|
|||
if (usingMap())
|
||||
return Ptr(map.lookup(key));
|
||||
|
||||
for (InlineElem* it = inl, *end = inl + inlNext; it != end; ++it) {
|
||||
InlineElem* end = inl + inlNext;
|
||||
for (InlineElem* it = inl; it != end; ++it) {
|
||||
if (it->key == key)
|
||||
return Ptr(it);
|
||||
}
|
||||
|
@ -224,7 +226,8 @@ class InlineMap
|
|||
if (usingMap())
|
||||
return AddPtr(map.lookupForAdd(key));
|
||||
|
||||
for (InlineElem* it = inl, *end = inl + inlNext; it != end; ++it) {
|
||||
InlineElem* end = inl + inlNext;
|
||||
for (InlineElem* it = inl; it != end; ++it) {
|
||||
if (it->key == key)
|
||||
return AddPtr(it, true);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ class SplayTree
|
|||
{
|
||||
struct Node {
|
||||
T item;
|
||||
Node* left, *right, *parent;
|
||||
Node* left;
|
||||
Node* right;
|
||||
Node* parent;
|
||||
|
||||
explicit Node(const T& item)
|
||||
: item(item), left(nullptr), right(nullptr), parent(nullptr)
|
||||
|
@ -33,7 +35,8 @@ class SplayTree
|
|||
};
|
||||
|
||||
LifoAlloc* alloc;
|
||||
Node* root, *freeList;
|
||||
Node* root;
|
||||
Node* freeList;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool enableCheckCoherency;
|
||||
|
@ -124,7 +127,8 @@ class SplayTree
|
|||
// Find another node which can be swapped in for the root: either the
|
||||
// rightmost child of the root's left, or the leftmost child of the
|
||||
// root's right.
|
||||
Node* swap, *swapChild;
|
||||
Node* swap;
|
||||
Node* swapChild;
|
||||
if (root->left) {
|
||||
swap = root->left;
|
||||
while (swap->right)
|
||||
|
@ -167,7 +171,8 @@ class SplayTree
|
|||
Node* lookup(const T& v)
|
||||
{
|
||||
MOZ_ASSERT(root);
|
||||
Node* node = root, *parent;
|
||||
Node* node = root;
|
||||
Node* parent;
|
||||
do {
|
||||
parent = node;
|
||||
int c = C::compare(v, node->item);
|
||||
|
|
|
@ -2280,7 +2280,8 @@ BytecodeEmitter::emitPropLHS(ParseNode* pn, JSOp op)
|
|||
*/
|
||||
if (pn2->isKind(PNK_DOT)) {
|
||||
ParseNode* pndot = pn2;
|
||||
ParseNode* pnup = nullptr, *pndown;
|
||||
ParseNode* pnup = nullptr;
|
||||
ParseNode* pndown;
|
||||
ptrdiff_t top = offset();
|
||||
for (;;) {
|
||||
/* Reverse pndot->pn_expr to point up, not down. */
|
||||
|
@ -6673,8 +6674,8 @@ BytecodeEmitter::emitDefaults(ParseNode* pn)
|
|||
{
|
||||
MOZ_ASSERT(pn->isKind(PNK_ARGSBODY));
|
||||
|
||||
ParseNode* arg, *pnlast = pn->last();
|
||||
for (arg = pn->pn_head; arg != pnlast; arg = arg->pn_next) {
|
||||
ParseNode* pnlast = pn->last();
|
||||
for (ParseNode* arg = pn->pn_head; arg != pnlast; arg = arg->pn_next) {
|
||||
if (!(arg->pn_dflags & PND_DEFAULT))
|
||||
continue;
|
||||
if (!bindNameToSlot(arg))
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче