зеркало из 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);
|
pref("dom.ipc.plugins.enabled", true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pref("dom.ipc.shims.enabledWarnings", false);
|
||||||
|
|
||||||
// Start the browser in e10s mode
|
// Start the browser in e10s mode
|
||||||
pref("browser.tabs.remote.autostart", false);
|
pref("browser.tabs.remote.autostart", false);
|
||||||
pref("browser.tabs.remote.desktopbehavior", true);
|
pref("browser.tabs.remote.desktopbehavior", true);
|
||||||
|
|
|
@ -1801,13 +1801,10 @@ nsSHistory::SetRootDocShell(nsIDocShell * aDocShell)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator)
|
nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator)
|
||||||
{
|
{
|
||||||
nsresult status = NS_OK;
|
|
||||||
|
|
||||||
NS_ENSURE_ARG_POINTER(aEnumerator);
|
NS_ENSURE_ARG_POINTER(aEnumerator);
|
||||||
nsSHEnumerator * iterator = new nsSHEnumerator(this);
|
nsRefPtr<nsSHEnumerator> iterator = new nsSHEnumerator(this);
|
||||||
if (iterator && NS_FAILED(status = CallQueryInterface(iterator, aEnumerator)))
|
iterator.forget(aEnumerator);
|
||||||
delete iterator;
|
return NS_OK;
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@ MultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(stream, aStream);
|
stream.forget(aStream);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<FileImpl>
|
already_AddRefed<FileImpl>
|
||||||
|
|
|
@ -2499,7 +2499,9 @@ nsFrameLoader::GetMessageManager(nsIMessageSender** aManager)
|
||||||
{
|
{
|
||||||
EnsureMessageManager();
|
EnsureMessageManager();
|
||||||
if (mMessageManager) {
|
if (mMessageManager) {
|
||||||
CallQueryInterface(mMessageManager, aManager);
|
nsRefPtr<nsFrameMessageManager> mm(mMessageManager);
|
||||||
|
mm.forget(aManager);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1490,11 +1490,12 @@ NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||||
NS_ERROR_NOT_AVAILABLE);
|
NS_ERROR_NOT_AVAILABLE);
|
||||||
nsFrameMessageManager* mm = new nsFrameMessageManager(nullptr,
|
nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
|
MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
|
||||||
RegisterStrongMemoryReporter(new MessageManagerReporter());
|
RegisterStrongMemoryReporter(new MessageManagerReporter());
|
||||||
return CallQueryInterface(mm, aResult);
|
mm.forget(aResult);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>*
|
nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>*
|
||||||
|
@ -2008,7 +2009,8 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
|
||||||
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
|
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
|
||||||
nsFrameMessageManager::sParentProcessManager = mm;
|
nsFrameMessageManager::sParentProcessManager = mm;
|
||||||
nsFrameMessageManager::NewProcessMessageManager(false); // Create same process message manager.
|
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,
|
nullptr,
|
||||||
MM_PROCESSMANAGER | MM_OWNSCALLBACK);
|
MM_PROCESSMANAGER | MM_OWNSCALLBACK);
|
||||||
nsFrameMessageManager::SetChildProcessManager(mm);
|
nsFrameMessageManager::SetChildProcessManager(mm);
|
||||||
ProcessGlobal* global = new ProcessGlobal(mm);
|
nsRefPtr<ProcessGlobal> global = new ProcessGlobal(mm);
|
||||||
NS_ENSURE_TRUE(global->Init(), NS_ERROR_UNEXPECTED);
|
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;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
nsresult
|
||||||
|
NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||||
{
|
{
|
||||||
nsHTMLContentSerializer* it = new nsHTMLContentSerializer();
|
nsRefPtr<nsHTMLContentSerializer> it = new nsHTMLContentSerializer();
|
||||||
if (!it) {
|
it.forget(aSerializer);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(it, aSerializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLContentSerializer::nsHTMLContentSerializer()
|
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 TagStackSize = 500;
|
||||||
static const uint32_t OLStackSize = 100;
|
static const uint32_t OLStackSize = 100;
|
||||||
|
|
||||||
nsresult NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
|
nsresult
|
||||||
|
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
|
||||||
{
|
{
|
||||||
nsPlainTextSerializer* it = new nsPlainTextSerializer();
|
nsRefPtr<nsPlainTextSerializer> it = new nsPlainTextSerializer();
|
||||||
if (!it) {
|
it.forget(aSerializer);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(it, aSerializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPlainTextSerializer::nsPlainTextSerializer()
|
nsPlainTextSerializer::nsPlainTextSerializer()
|
||||||
|
|
|
@ -40,14 +40,12 @@ static const int32_t kLongLineLen = 128;
|
||||||
|
|
||||||
#define kXMLNS "xmlns"
|
#define kXMLNS "xmlns"
|
||||||
|
|
||||||
nsresult NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
nsresult
|
||||||
|
NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||||
{
|
{
|
||||||
nsXHTMLContentSerializer* it = new nsXHTMLContentSerializer();
|
nsRefPtr<nsXHTMLContentSerializer> it = new nsXHTMLContentSerializer();
|
||||||
if (!it) {
|
it.forget(aSerializer);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(it, aSerializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXHTMLContentSerializer::nsXHTMLContentSerializer()
|
nsXHTMLContentSerializer::nsXHTMLContentSerializer()
|
||||||
|
|
|
@ -43,14 +43,12 @@ using namespace mozilla::dom;
|
||||||
#define INDENT_STRING " "
|
#define INDENT_STRING " "
|
||||||
#define INDENT_STRING_LENGTH 2
|
#define INDENT_STRING_LENGTH 2
|
||||||
|
|
||||||
nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer)
|
nsresult
|
||||||
|
NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||||
{
|
{
|
||||||
nsXMLContentSerializer* it = new nsXMLContentSerializer();
|
nsRefPtr<nsXMLContentSerializer> it = new nsXMLContentSerializer();
|
||||||
if (!it) {
|
it.forget(aSerializer);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(it, aSerializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXMLContentSerializer::nsXMLContentSerializer()
|
nsXMLContentSerializer::nsXMLContentSerializer()
|
||||||
|
|
|
@ -23,6 +23,7 @@ skip-if = debug == false
|
||||||
[test_bug963382.html]
|
[test_bug963382.html]
|
||||||
skip-if = debug == false
|
skip-if = debug == false
|
||||||
[test_bug1041646.html]
|
[test_bug1041646.html]
|
||||||
|
[test_bug1123875.html]
|
||||||
[test_barewordGetsWindow.html]
|
[test_barewordGetsWindow.html]
|
||||||
[test_callback_default_thisval.html]
|
[test_callback_default_thisval.html]
|
||||||
[test_cloneAndImportNode.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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallQueryInterface(element, aValue);
|
element.forget(aValue);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@
|
||||||
#include "mozilla/dom/voicemail/VoicemailIPCService.h"
|
#include "mozilla/dom/voicemail/VoicemailIPCService.h"
|
||||||
#include "mozilla/net/NeckoMessageUtils.h"
|
#include "mozilla/net/NeckoMessageUtils.h"
|
||||||
#include "mozilla/RemoteSpellCheckEngineChild.h"
|
#include "mozilla/RemoteSpellCheckEngineChild.h"
|
||||||
|
#include "GMPServiceChild.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::docshell;
|
using namespace mozilla::docshell;
|
||||||
|
@ -191,6 +192,7 @@ using namespace mozilla::dom::mobilemessage;
|
||||||
using namespace mozilla::dom::telephony;
|
using namespace mozilla::dom::telephony;
|
||||||
using namespace mozilla::dom::voicemail;
|
using namespace mozilla::dom::voicemail;
|
||||||
using namespace mozilla::embedding;
|
using namespace mozilla::embedding;
|
||||||
|
using namespace mozilla::gmp;
|
||||||
using namespace mozilla::hal_sandbox;
|
using namespace mozilla::hal_sandbox;
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
@ -1036,6 +1038,13 @@ ContentChild::AllocPContentBridgeParent(mozilla::ipc::Transport* aTransport,
|
||||||
return mLastBridge;
|
return mLastBridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGMPServiceChild*
|
||||||
|
ContentChild::AllocPGMPServiceChild(mozilla::ipc::Transport* aTransport,
|
||||||
|
base::ProcessId aOtherProcess)
|
||||||
|
{
|
||||||
|
return GMPServiceChild::Create(aTransport, aOtherProcess);
|
||||||
|
}
|
||||||
|
|
||||||
PCompositorChild*
|
PCompositorChild*
|
||||||
ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||||
base::ProcessId aOtherProcess)
|
base::ProcessId aOtherProcess)
|
||||||
|
|
|
@ -115,6 +115,10 @@ public:
|
||||||
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
|
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
|
||||||
base::ProcessId otherProcess) override;
|
base::ProcessId otherProcess) override;
|
||||||
|
|
||||||
|
PGMPServiceChild*
|
||||||
|
AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
|
||||||
|
base::ProcessId otherProcess) override;
|
||||||
|
|
||||||
PCompositorChild*
|
PCompositorChild*
|
||||||
AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||||
base::ProcessId aOtherProcess) override;
|
base::ProcessId aOtherProcess) override;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "AudioChannelService.h"
|
#include "AudioChannelService.h"
|
||||||
#include "BlobParent.h"
|
#include "BlobParent.h"
|
||||||
#include "CrashReporterParent.h"
|
#include "CrashReporterParent.h"
|
||||||
|
#include "GMPServiceParent.h"
|
||||||
#include "IHistory.h"
|
#include "IHistory.h"
|
||||||
#include "mozIApplication.h"
|
#include "mozIApplication.h"
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
|
@ -233,6 +234,7 @@ using namespace mozilla::dom::mobilemessage;
|
||||||
using namespace mozilla::dom::telephony;
|
using namespace mozilla::dom::telephony;
|
||||||
using namespace mozilla::dom::voicemail;
|
using namespace mozilla::dom::voicemail;
|
||||||
using namespace mozilla::embedding;
|
using namespace mozilla::embedding;
|
||||||
|
using namespace mozilla::gmp;
|
||||||
using namespace mozilla::hal;
|
using namespace mozilla::hal;
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
@ -981,6 +983,23 @@ static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
|
||||||
return docShell;
|
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
|
bool
|
||||||
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv)
|
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv)
|
||||||
{
|
{
|
||||||
|
@ -3062,6 +3081,13 @@ ContentParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc, PDocAcc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGMPServiceParent*
|
||||||
|
ContentParent::AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
|
||||||
|
base::ProcessId aOtherProcess)
|
||||||
|
{
|
||||||
|
return GMPServiceParent::Create(aTransport, aOtherProcess);
|
||||||
|
}
|
||||||
|
|
||||||
PCompositorParent*
|
PCompositorParent*
|
||||||
ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
||||||
base::ProcessId aOtherProcess)
|
base::ProcessId aOtherProcess)
|
||||||
|
|
|
@ -153,6 +153,12 @@ public:
|
||||||
TabId* aTabId) override;
|
TabId* aTabId) override;
|
||||||
virtual bool RecvBridgeToChildProcess(const ContentParentId& aCpId) 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 RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||||
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override;
|
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||||
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
|
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
|
||||||
|
@ -488,6 +494,9 @@ private:
|
||||||
|
|
||||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||||
|
|
||||||
|
PGMPServiceParent*
|
||||||
|
AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
|
||||||
|
base::ProcessId aOtherProcess) override;
|
||||||
PCompositorParent*
|
PCompositorParent*
|
||||||
AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
||||||
base::ProcessId aOtherProcess) override;
|
base::ProcessId aOtherProcess) override;
|
||||||
|
|
|
@ -27,7 +27,15 @@ include protocol PImageBridge;
|
||||||
include protocol PMemoryReportRequest;
|
include protocol PMemoryReportRequest;
|
||||||
include protocol PMobileConnection;
|
include protocol PMobileConnection;
|
||||||
include protocol PNecko;
|
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 PPluginModule;
|
||||||
|
include protocol PGMP;
|
||||||
include protocol PPrinting;
|
include protocol PPrinting;
|
||||||
include protocol POfflineCacheUpdate;
|
include protocol POfflineCacheUpdate;
|
||||||
include protocol PScreenManager;
|
include protocol PScreenManager;
|
||||||
|
@ -364,6 +372,7 @@ prio(normal upto urgent) sync protocol PContent
|
||||||
parent opens PProcessHangMonitor;
|
parent opens PProcessHangMonitor;
|
||||||
parent opens PSharedBufferManager;
|
parent opens PSharedBufferManager;
|
||||||
parent opens PImageBridge;
|
parent opens PImageBridge;
|
||||||
|
parent opens PGMPService;
|
||||||
child opens PBackground;
|
child opens PBackground;
|
||||||
|
|
||||||
manages PAsmJSCacheEntry;
|
manages PAsmJSCacheEntry;
|
||||||
|
@ -608,6 +617,10 @@ parent:
|
||||||
returns (ContentParentId cpId, bool isForApp, bool isForBrowser, TabId tabId);
|
returns (ContentParentId cpId, bool isForApp, bool isForBrowser, TabId tabId);
|
||||||
sync BridgeToChildProcess(ContentParentId cpId);
|
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
|
* This call connects the content process to a plugin process. While this
|
||||||
* call runs, a new PluginModuleParent will be created in the ContentChild
|
* 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)
|
, mKeySystem(aKeySystem)
|
||||||
, mCDM(nullptr)
|
, mCDM(nullptr)
|
||||||
, mDecryptionJobCount(0)
|
, mDecryptionJobCount(0)
|
||||||
|
, mShutdownCalled(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_COUNT_CTOR(CDMProxy);
|
MOZ_COUNT_CTOR(CDMProxy);
|
||||||
|
@ -70,7 +71,7 @@ CDMProxy::Init(PromiseId aPromiseId,
|
||||||
nsCOMPtr<nsIRunnable> task(
|
nsCOMPtr<nsIRunnable> task(
|
||||||
NS_NewRunnableMethodWithArg<nsAutoPtr<InitData>>(this,
|
NS_NewRunnableMethodWithArg<nsAutoPtr<InitData>>(this,
|
||||||
&CDMProxy::gmp_Init,
|
&CDMProxy::gmp_Init,
|
||||||
data));
|
Move(data)));
|
||||||
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +84,69 @@ CDMProxy::IsOnGMPThread()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
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());
|
MOZ_ASSERT(IsOnGMPThread());
|
||||||
|
|
||||||
|
@ -94,13 +157,38 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = mps->GetNodeId(aData->mOrigin,
|
// Make a copy before we transfer ownership of aData to the
|
||||||
aData->mTopLevelOrigin,
|
// gmp_InitGetGMPDecryptorCallback.
|
||||||
aData->mInPrivateBrowsing,
|
InitData data(*aData);
|
||||||
mNodeId);
|
UniquePtr<GetNodeIdCallback> callback(
|
||||||
MOZ_ASSERT(!GetNodeId().IsEmpty());
|
new gmp_InitGetGMPDecryptorCallback(this, Move(aData)));
|
||||||
|
nsresult rv = mps->GetNodeId(data.mOrigin,
|
||||||
|
data.mTopLevelOrigin,
|
||||||
|
data.mInPrivateBrowsing,
|
||||||
|
Move(callback));
|
||||||
if (NS_FAILED(rv)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,17 +200,12 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData> aData)
|
||||||
|
|
||||||
nsTArray<nsCString> tags;
|
nsTArray<nsCString> tags;
|
||||||
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
|
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
|
||||||
rv = mps->GetGMPDecryptor(&tags, GetNodeId(), &mCDM);
|
|
||||||
if (NS_FAILED(rv) || !mCDM) {
|
UniquePtr<GetGMPDecryptorCallback> callback(new gmp_InitDoneCallback(this,
|
||||||
RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
Move(aData)));
|
||||||
} else {
|
nsresult rv = mps->GetGMPDecryptor(&tags, GetNodeId(), Move(callback));
|
||||||
mCallback = new CDMCallbackProxy(this);
|
if (NS_FAILED(rv)) {
|
||||||
mCDM->Init(mCallback);
|
RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
nsCOMPtr<nsIRunnable> task(
|
|
||||||
NS_NewRunnableMethodWithArg<uint32_t>(this,
|
|
||||||
&CDMProxy::OnCDMCreated,
|
|
||||||
aData->mPromiseId));
|
|
||||||
NS_DispatchToMainThread(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +424,8 @@ CDMProxy::gmp_Shutdown()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsOnGMPThread());
|
MOZ_ASSERT(IsOnGMPThread());
|
||||||
|
|
||||||
|
mShutdownCalled = true;
|
||||||
|
|
||||||
// Abort any pending decrypt jobs, to awaken any clients waiting on a job.
|
// Abort any pending decrypt jobs, to awaken any clients waiting on a job.
|
||||||
for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
|
for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
|
||||||
DecryptJob* job = mDecryptionJobs[i];
|
DecryptJob* job = mDecryptionJobs[i];
|
||||||
|
|
|
@ -174,6 +174,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class gmp_InitDoneCallback;
|
||||||
|
friend class gmp_InitGetGMPDecryptorCallback;
|
||||||
|
|
||||||
struct InitData {
|
struct InitData {
|
||||||
uint32_t mPromiseId;
|
uint32_t mPromiseId;
|
||||||
|
@ -183,7 +185,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// GMP thread only.
|
// 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.
|
// GMP thread only.
|
||||||
void gmp_Shutdown();
|
void gmp_Shutdown();
|
||||||
|
@ -320,6 +326,10 @@ private:
|
||||||
// from it.
|
// from it.
|
||||||
// GMP thread only.
|
// GMP thread only.
|
||||||
uint32_t mDecryptionJobCount;
|
uint32_t mDecryptionJobCount;
|
||||||
|
|
||||||
|
// True if CDMProxy::gmp_Shutdown was called.
|
||||||
|
// GMP thread only.
|
||||||
|
bool mShutdownCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,25 +93,34 @@ HaveGMPFor(mozIGeckoMediaPluginService* aGMPService,
|
||||||
static MediaKeySystemStatus
|
static MediaKeySystemStatus
|
||||||
EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
|
EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
|
||||||
const nsAString& aKeySystem,
|
const nsAString& aKeySystem,
|
||||||
int32_t aMinCdmVersion)
|
int32_t aMinCdmVersion,
|
||||||
|
bool aCheckForV6=false)
|
||||||
{
|
{
|
||||||
if (aMinCdmVersion == NO_CDM_VERSION) {
|
|
||||||
return MediaKeySystemStatus::Available;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsTArray<nsCString> tags;
|
nsTArray<nsCString> tags;
|
||||||
tags.AppendElement(NS_ConvertUTF16toUTF8(aKeySystem));
|
tags.AppendElement(NS_ConvertUTF16toUTF8(aKeySystem));
|
||||||
|
bool hasPlugin;
|
||||||
nsAutoCString versionStr;
|
nsAutoCString versionStr;
|
||||||
if (NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
|
if (NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
|
||||||
&tags,
|
&tags,
|
||||||
versionStr)) &&
|
&hasPlugin,
|
||||||
|
versionStr)) ||
|
||||||
// XXX to be removed later in bug 1147692
|
// XXX to be removed later in bug 1147692
|
||||||
NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT),
|
(aCheckForV6 && !hasPlugin &&
|
||||||
&tags,
|
NS_FAILED(aGMPService->GetPluginVersionForAPI(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR_COMPAT),
|
||||||
versionStr))) {
|
&tags,
|
||||||
|
&hasPlugin,
|
||||||
|
versionStr)))) {
|
||||||
return MediaKeySystemStatus::Error;
|
return MediaKeySystemStatus::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasPlugin) {
|
||||||
|
return MediaKeySystemStatus::Cdm_not_installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aMinCdmVersion == NO_CDM_VERSION) {
|
||||||
|
return MediaKeySystemStatus::Available;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
int32_t version = versionStr.ToInteger(&rv);
|
int32_t version = versionStr.ToInteger(&rv);
|
||||||
if (NS_FAILED(rv) || version < 0 || aMinCdmVersion > version) {
|
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)) {
|
if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
|
||||||
return MediaKeySystemStatus::Cdm_disabled;
|
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);
|
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,16 +159,7 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
||||||
if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
|
if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
|
||||||
return MediaKeySystemStatus::Cdm_disabled;
|
return MediaKeySystemStatus::Cdm_disabled;
|
||||||
}
|
}
|
||||||
if (!HaveGMPFor(mps,
|
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPAudioDecoder.h"
|
#include "GMPAudioDecoder.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -132,6 +133,39 @@ GMPAudioDecoder::GetNodeId()
|
||||||
return NS_LITERAL_CSTRING("");
|
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
|
nsresult
|
||||||
GMPAudioDecoder::Init()
|
GMPAudioDecoder::Init()
|
||||||
{
|
{
|
||||||
|
@ -140,25 +174,20 @@ GMPAudioDecoder::Init()
|
||||||
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||||
MOZ_ASSERT(mMPS);
|
MOZ_ASSERT(mMPS);
|
||||||
|
|
||||||
nsTArray<nsCString> tags;
|
nsCOMPtr<nsIThread> gmpThread = NS_GetCurrentThread();
|
||||||
InitTags(tags);
|
|
||||||
nsresult rv = mMPS->GetGMPAudioDecoder(&tags, GetNodeId(), &mGMP);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
MOZ_ASSERT(mGMP);
|
|
||||||
|
|
||||||
nsTArray<uint8_t> codecSpecific;
|
nsRefPtr<GMPInitDoneRunnable> initDone(new GMPInitDoneRunnable());
|
||||||
codecSpecific.AppendElements(mConfig.audio_specific_config->Elements(),
|
gmpThread->Dispatch(
|
||||||
mConfig.audio_specific_config->Length());
|
NS_NewRunnableMethodWithArg<GMPInitDoneRunnable*>(this,
|
||||||
|
&GMPAudioDecoder::GetGMPAPI,
|
||||||
|
initDone),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
rv = mGMP->InitDecode(kGMPAudioCodecAAC,
|
while (!initDone->IsDone()) {
|
||||||
mConfig.channel_count,
|
NS_ProcessNextEvent(gmpThread, true);
|
||||||
mConfig.bits_per_sample,
|
}
|
||||||
mConfig.samples_per_second,
|
|
||||||
codecSpecific,
|
|
||||||
mAdapter);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
return mGMP ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -80,6 +80,63 @@ protected:
|
||||||
virtual nsCString GetNodeId();
|
virtual nsCString GetNodeId();
|
||||||
|
|
||||||
private:
|
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;
|
const mp4_demuxer::AudioDecoderConfig& mConfig;
|
||||||
MediaDataDecoderCallbackProxy* mCallback;
|
MediaDataDecoderCallbackProxy* mCallback;
|
||||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||||
|
|
|
@ -157,29 +157,24 @@ GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample)
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
void
|
||||||
GMPVideoDecoder::Init()
|
GMPVideoDecoder::GetGMPAPI(GMPInitDoneRunnable* aInitDone)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsOnGMPThread());
|
MOZ_ASSERT(IsOnGMPThread());
|
||||||
|
|
||||||
mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
|
||||||
MOZ_ASSERT(mMPS);
|
|
||||||
|
|
||||||
nsTArray<nsCString> tags;
|
nsTArray<nsCString> tags;
|
||||||
InitTags(tags);
|
InitTags(tags);
|
||||||
nsresult rv = mMPS->GetGMPVideoDecoder(&tags, GetNodeId(), &mHost, &mGMP);
|
UniquePtr<GetGMPVideoDecoderCallback> callback(
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
new GMPInitDoneCallback(this, aInitDone));
|
||||||
MOZ_ASSERT(mHost && mGMP);
|
if (NS_FAILED(mMPS->GetGMPVideoDecoder(&tags, GetNodeId(), Move(callback)))) {
|
||||||
|
aInitDone->Dispatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GMP implementations have interpreted the meaning of GMP_BufferLength32
|
void
|
||||||
// differently. The OpenH264 GMP expects GMP_BufferLength32 to behave as
|
GMPVideoDecoder::GMPInitDone(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost)
|
||||||
// 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
|
MOZ_ASSERT(aHost && aGMP);
|
||||||
// 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");
|
|
||||||
|
|
||||||
GMPVideoCodec codec;
|
GMPVideoCodec codec;
|
||||||
memset(&codec, 0, sizeof(codec));
|
memset(&codec, 0, sizeof(codec));
|
||||||
|
@ -195,13 +190,48 @@ GMPVideoDecoder::Init()
|
||||||
codecSpecific.AppendElements(mConfig.extra_data->Elements(),
|
codecSpecific.AppendElements(mConfig.extra_data->Elements(),
|
||||||
mConfig.extra_data->Length());
|
mConfig.extra_data->Length());
|
||||||
|
|
||||||
rv = mGMP->InitDecode(codec,
|
nsresult rv = aGMP->InitDecode(codec,
|
||||||
codecSpecific,
|
codecSpecific,
|
||||||
mAdapter,
|
mAdapter,
|
||||||
PR_GetNumberOfProcessors());
|
PR_GetNumberOfProcessors());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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
|
nsresult
|
||||||
|
|
|
@ -96,6 +96,63 @@ protected:
|
||||||
virtual GMPUnique<GMPVideoEncodedFrame>::Ptr CreateFrame(mp4_demuxer::MP4Sample* aSample);
|
virtual GMPUnique<GMPVideoEncodedFrame>::Ptr CreateFrame(mp4_demuxer::MP4Sample* aSample);
|
||||||
|
|
||||||
private:
|
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;
|
const mp4_demuxer::VideoDecoderConfig& mConfig;
|
||||||
MediaDataDecoderCallbackProxy* mCallback;
|
MediaDataDecoderCallbackProxy* mCallback;
|
||||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "WMFMediaDataDecoder.h"
|
#include "WMFMediaDataDecoder.h"
|
||||||
#include "nsIWindowsRegKey.h"
|
#include "nsIWindowsRegKey.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIGfxInfo.h"
|
#include "nsIGfxInfo.h"
|
||||||
#include "GfxDriverInfo.h"
|
#include "GfxDriverInfo.h"
|
||||||
#include "gfxWindowsPlatform.h"
|
#include "gfxWindowsPlatform.h"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPAudioDecoderChild.h"
|
#include "GMPAudioDecoderChild.h"
|
||||||
#include "GMPChild.h"
|
#include "GMPContentChild.h"
|
||||||
#include "GMPAudioHost.h"
|
#include "GMPAudioHost.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPChild* aPlugin)
|
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPContentChild* aPlugin)
|
||||||
: mPlugin(aPlugin)
|
: mPlugin(aPlugin)
|
||||||
, mAudioDecoder(nullptr)
|
, mAudioDecoder(nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPChild;
|
class GMPContentChild;
|
||||||
|
|
||||||
class GMPAudioDecoderChild : public PGMPAudioDecoderChild,
|
class GMPAudioDecoderChild : public PGMPAudioDecoderChild,
|
||||||
public GMPAudioDecoderCallback
|
public GMPAudioDecoderCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit GMPAudioDecoderChild(GMPChild* aPlugin);
|
explicit GMPAudioDecoderChild(GMPContentChild* aPlugin);
|
||||||
virtual ~GMPAudioDecoderChild();
|
virtual ~GMPAudioDecoderChild();
|
||||||
|
|
||||||
void Init(GMPAudioDecoder* aDecoder);
|
void Init(GMPAudioDecoder* aDecoder);
|
||||||
|
@ -40,7 +40,7 @@ private:
|
||||||
virtual bool RecvDrain() override;
|
virtual bool RecvDrain() override;
|
||||||
virtual bool RecvDecodingComplete() override;
|
virtual bool RecvDecodingComplete() override;
|
||||||
|
|
||||||
GMPChild* mPlugin;
|
GMPContentChild* mPlugin;
|
||||||
GMPAudioDecoder* mAudioDecoder;
|
GMPAudioDecoder* mAudioDecoder;
|
||||||
GMPAudioHostImpl mAudioHost;
|
GMPAudioHostImpl mAudioHost;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPAudioDecoderParent.h"
|
#include "GMPAudioDecoderParent.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPContentParent.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "GMPMessageUtils.h"
|
#include "GMPMessageUtils.h"
|
||||||
|
@ -29,7 +29,7 @@ extern PRLogModuleInfo* GetGMPLog();
|
||||||
|
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPParent* aPlugin)
|
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPContentParent* aPlugin)
|
||||||
: mIsOpen(false)
|
: mIsOpen(false)
|
||||||
, mShuttingDown(false)
|
, mShuttingDown(false)
|
||||||
, mPlugin(aPlugin)
|
, mPlugin(aPlugin)
|
||||||
|
@ -263,6 +263,13 @@ GMPAudioDecoderParent::RecvError(const GMPErr& aError)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPAudioDecoderParent::RecvShutdown()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPAudioDecoderParent::Recv__delete__()
|
GMPAudioDecoderParent::Recv__delete__()
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPParent;
|
class GMPContentParent;
|
||||||
|
|
||||||
class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
|
class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
|
||||||
, public PGMPAudioDecoderParent
|
, public PGMPAudioDecoderParent
|
||||||
|
@ -24,7 +24,7 @@ class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(GMPAudioDecoderParent)
|
NS_INLINE_DECL_REFCOUNTING(GMPAudioDecoderParent)
|
||||||
|
|
||||||
explicit GMPAudioDecoderParent(GMPParent *aPlugin);
|
explicit GMPAudioDecoderParent(GMPContentParent *aPlugin);
|
||||||
|
|
||||||
nsresult Shutdown();
|
nsresult Shutdown();
|
||||||
|
|
||||||
|
@ -50,11 +50,12 @@ private:
|
||||||
virtual bool RecvDrainComplete() override;
|
virtual bool RecvDrainComplete() override;
|
||||||
virtual bool RecvResetComplete() override;
|
virtual bool RecvResetComplete() override;
|
||||||
virtual bool RecvError(const GMPErr& aError) override;
|
virtual bool RecvError(const GMPErr& aError) override;
|
||||||
|
virtual bool RecvShutdown() override;
|
||||||
virtual bool Recv__delete__() override;
|
virtual bool Recv__delete__() override;
|
||||||
|
|
||||||
bool mIsOpen;
|
bool mIsOpen;
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
nsRefPtr<GMPParent> mPlugin;
|
nsRefPtr<GMPContentParent> mPlugin;
|
||||||
GMPAudioDecoderCallbackProxy* mCallback;
|
GMPAudioDecoderCallbackProxy* mCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPChild.h"
|
#include "GMPChild.h"
|
||||||
|
#include "GMPContentChild.h"
|
||||||
#include "GMPProcessChild.h"
|
#include "GMPProcessChild.h"
|
||||||
#include "GMPLoader.h"
|
#include "GMPLoader.h"
|
||||||
#include "GMPVideoDecoderChild.h"
|
#include "GMPVideoDecoderChild.h"
|
||||||
|
@ -256,12 +257,6 @@ GMPChild::StartMacSandbox()
|
||||||
}
|
}
|
||||||
#endif // XP_MACOSX && MOZ_GMP_SANDBOX
|
#endif // XP_MACOSX && MOZ_GMP_SANDBOX
|
||||||
|
|
||||||
void
|
|
||||||
GMPChild::CheckThread()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPChild::Init(const std::string& aPluginPath,
|
GMPChild::Init(const std::string& aPluginPath,
|
||||||
const std::string& aVoucherPath,
|
const std::string& aVoucherPath,
|
||||||
|
@ -467,6 +462,11 @@ GMPChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
{
|
{
|
||||||
LOGD("%s reason=%d", __FUNCTION__, 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) {
|
if (mGMPLoader) {
|
||||||
mGMPLoader->Shutdown();
|
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*
|
mozilla::dom::PCrashReporterChild*
|
||||||
GMPChild::AllocPCrashReporterChild(const NativeThreadId& aThread)
|
GMPChild::AllocPCrashReporterChild(const NativeThreadId& aThread)
|
||||||
{
|
{
|
||||||
|
@ -527,120 +514,6 @@ GMPChild::DeallocPCrashReporterChild(PCrashReporterChild* aCrashReporter)
|
||||||
return true;
|
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*
|
PGMPTimerChild*
|
||||||
GMPChild::AllocPGMPTimerChild()
|
GMPChild::AllocPGMPTimerChild()
|
||||||
{
|
{
|
||||||
|
@ -715,6 +588,15 @@ GMPChild::RecvBeginAsyncShutdown()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPChild::RecvCloseActive()
|
||||||
|
{
|
||||||
|
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
|
||||||
|
mGMPContentChildren[i - 1]->CloseActive();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GMPChild::ShutdownComplete()
|
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 gmp
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#define GMPChild_h_
|
#define GMPChild_h_
|
||||||
|
|
||||||
#include "mozilla/gmp/PGMPChild.h"
|
#include "mozilla/gmp/PGMPChild.h"
|
||||||
#include "GMPSharedMemManager.h"
|
|
||||||
#include "GMPTimerChild.h"
|
#include "GMPTimerChild.h"
|
||||||
#include "GMPStorageChild.h"
|
#include "GMPStorageChild.h"
|
||||||
#include "GMPLoader.h"
|
#include "GMPLoader.h"
|
||||||
|
@ -18,8 +17,9 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
|
class GMPContentChild;
|
||||||
|
|
||||||
class GMPChild : public PGMPChild
|
class GMPChild : public PGMPChild
|
||||||
, public GMPSharedMem
|
|
||||||
, public GMPAsyncShutdownHost
|
, public GMPAsyncShutdownHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -40,9 +40,6 @@ public:
|
||||||
GMPTimerChild* GetGMPTimers();
|
GMPTimerChild* GetGMPTimers();
|
||||||
GMPStorageChild* GetGMPStorage();
|
GMPStorageChild* GetGMPStorage();
|
||||||
|
|
||||||
// GMPSharedMem
|
|
||||||
virtual void CheckThread() override;
|
|
||||||
|
|
||||||
// GMPAsyncShutdownHost
|
// GMPAsyncShutdownHost
|
||||||
void ShutdownComplete() override;
|
void ShutdownComplete() override;
|
||||||
|
|
||||||
|
@ -51,6 +48,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class GMPContentChild;
|
||||||
|
|
||||||
bool PreLoadPluginVoucher(const std::string& aPluginPath);
|
bool PreLoadPluginVoucher(const std::string& aPluginPath);
|
||||||
void PreLoadSandboxVoucher();
|
void PreLoadSandboxVoucher();
|
||||||
|
@ -63,36 +61,27 @@ private:
|
||||||
virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
|
virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
|
||||||
virtual bool DeallocPCrashReporterChild(PCrashReporterChild*) 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 PGMPTimerChild* AllocPGMPTimerChild() override;
|
||||||
virtual bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) override;
|
virtual bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) override;
|
||||||
|
|
||||||
virtual PGMPStorageChild* AllocPGMPStorageChild() override;
|
virtual PGMPStorageChild* AllocPGMPStorageChild() override;
|
||||||
virtual bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) 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 RecvCrashPluginNow() override;
|
||||||
virtual bool RecvBeginAsyncShutdown() override;
|
virtual bool RecvBeginAsyncShutdown() override;
|
||||||
|
virtual bool RecvCloseActive() override;
|
||||||
|
|
||||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
virtual void ProcessingError(Result aCode, const char* aReason) override;
|
virtual void ProcessingError(Result aCode, const char* aReason) override;
|
||||||
|
|
||||||
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI);
|
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI);
|
||||||
|
|
||||||
|
nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
|
||||||
|
|
||||||
GMPAsyncShutdown* mAsyncShutdown;
|
GMPAsyncShutdown* mAsyncShutdown;
|
||||||
nsRefPtr<GMPTimerChild> mTimerChild;
|
nsRefPtr<GMPTimerChild> mTimerChild;
|
||||||
nsRefPtr<GMPStorageChild> mStorage;
|
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 mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPDecryptorChild::GMPDecryptorChild(GMPChild* aPlugin,
|
GMPDecryptorChild::GMPDecryptorChild(GMPContentChild* aPlugin,
|
||||||
const nsTArray<uint8_t>& aPluginVoucher,
|
const nsTArray<uint8_t>& aPluginVoucher,
|
||||||
const nsTArray<uint8_t>& aSandboxVoucher)
|
const nsTArray<uint8_t>& aSandboxVoucher)
|
||||||
: mSession(nullptr)
|
: mSession(nullptr)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPChild;
|
class GMPContentChild;
|
||||||
|
|
||||||
class GMPDecryptorChild : public GMPDecryptorCallback
|
class GMPDecryptorChild : public GMPDecryptorCallback
|
||||||
, public GMPDecryptorHost
|
, public GMPDecryptorHost
|
||||||
|
@ -24,7 +24,7 @@ class GMPDecryptorChild : public GMPDecryptorCallback
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPDecryptorChild);
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPDecryptorChild);
|
||||||
|
|
||||||
explicit GMPDecryptorChild(GMPChild* aPlugin,
|
explicit GMPDecryptorChild(GMPContentChild* aPlugin,
|
||||||
const nsTArray<uint8_t>& aPluginVoucher,
|
const nsTArray<uint8_t>& aPluginVoucher,
|
||||||
const nsTArray<uint8_t>& aSandboxVoucher);
|
const nsTArray<uint8_t>& aSandboxVoucher);
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ private:
|
||||||
// GMP's GMPDecryptor implementation.
|
// GMP's GMPDecryptor implementation.
|
||||||
// Only call into this on the (GMP process) main thread.
|
// Only call into this on the (GMP process) main thread.
|
||||||
GMPDecryptor* mSession;
|
GMPDecryptor* mSession;
|
||||||
GMPChild* mPlugin;
|
GMPContentChild* mPlugin;
|
||||||
|
|
||||||
// Reference to the vouchers owned by the GMPChild.
|
// Reference to the vouchers owned by the GMPChild.
|
||||||
const nsTArray<uint8_t>& mPluginVoucher;
|
const nsTArray<uint8_t>& mPluginVoucher;
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPDecryptorParent.h"
|
#include "GMPDecryptorParent.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPContentParent.h"
|
||||||
#include "mp4_demuxer/DecoderData.h"
|
#include "mp4_demuxer/DecoderData.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPDecryptorParent::GMPDecryptorParent(GMPParent* aPlugin)
|
GMPDecryptorParent::GMPDecryptorParent(GMPContentParent* aPlugin)
|
||||||
: mIsOpen(false)
|
: mIsOpen(false)
|
||||||
, mShuttingDown(false)
|
, mShuttingDown(false)
|
||||||
, mPlugin(aPlugin)
|
, mPlugin(aPlugin)
|
||||||
|
@ -307,6 +307,13 @@ GMPDecryptorParent::RecvDecrypted(const uint32_t& aId,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPDecryptorParent::RecvShutdown()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: may be called via Terminated()
|
// Note: may be called via Terminated()
|
||||||
void
|
void
|
||||||
GMPDecryptorParent::Close()
|
GMPDecryptorParent::Close()
|
||||||
|
|
|
@ -17,7 +17,7 @@ class CryptoSample;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPParent;
|
class GMPContentParent;
|
||||||
|
|
||||||
class GMPDecryptorParent final : public GMPDecryptorProxy
|
class GMPDecryptorParent final : public GMPDecryptorProxy
|
||||||
, public PGMPDecryptorParent
|
, public PGMPDecryptorParent
|
||||||
|
@ -25,7 +25,7 @@ class GMPDecryptorParent final : public GMPDecryptorProxy
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(GMPDecryptorParent)
|
NS_INLINE_DECL_REFCOUNTING(GMPDecryptorParent)
|
||||||
|
|
||||||
explicit GMPDecryptorParent(GMPParent *aPlugin);
|
explicit GMPDecryptorParent(GMPContentParent *aPlugin);
|
||||||
|
|
||||||
// GMPDecryptorProxy
|
// GMPDecryptorProxy
|
||||||
|
|
||||||
|
@ -104,12 +104,14 @@ private:
|
||||||
|
|
||||||
virtual bool RecvSetCaps(const uint64_t& aCaps) override;
|
virtual bool RecvSetCaps(const uint64_t& aCaps) override;
|
||||||
|
|
||||||
|
virtual bool RecvShutdown() override;
|
||||||
|
|
||||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
virtual bool Recv__delete__() override;
|
virtual bool Recv__delete__() override;
|
||||||
|
|
||||||
bool mIsOpen;
|
bool mIsOpen;
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
nsRefPtr<GMPParent> mPlugin;
|
nsRefPtr<GMPContentParent> mPlugin;
|
||||||
nsCString mPluginId;
|
nsCString mPluginId;
|
||||||
GMPDecryptorProxyCallback* mCallback;
|
GMPDecryptorProxyCallback* mCallback;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsIRunnable.h"
|
#include "nsIRunnable.h"
|
||||||
#include "mozIGeckoMediaPluginService.h"
|
#include "mozIGeckoMediaPluginService.h"
|
||||||
|
#include "mozilla/SyncRunnable.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "GMPTimerParent.h"
|
#include "GMPTimerParent.h"
|
||||||
|
@ -53,6 +54,7 @@ GMPParent::GMPParent()
|
||||||
, mProcess(nullptr)
|
, mProcess(nullptr)
|
||||||
, mDeleteProcessOnlyOnUnload(false)
|
, mDeleteProcessOnlyOnUnload(false)
|
||||||
, mAbnormalShutdownInProgress(false)
|
, mAbnormalShutdownInProgress(false)
|
||||||
|
, mGMPContentChildCount(0)
|
||||||
, mAsyncShutdownRequired(false)
|
, mAsyncShutdownRequired(false)
|
||||||
, mAsyncShutdownInProgress(false)
|
, mAsyncShutdownInProgress(false)
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
|
@ -72,12 +74,6 @@ GMPParent::~GMPParent()
|
||||||
LOGD("GMPParent dtor");
|
LOGD("GMPParent dtor");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
GMPParent::CheckThread()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
GMPParent::CloneFrom(const GMPParent* aOther)
|
GMPParent::CloneFrom(const GMPParent* aOther)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +83,7 @@ GMPParent::CloneFrom(const GMPParent* aOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
GMPParent::Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir)
|
GMPParent::Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aPluginDir);
|
MOZ_ASSERT(aPluginDir);
|
||||||
MOZ_ASSERT(aService);
|
MOZ_ASSERT(aService);
|
||||||
|
@ -188,8 +184,8 @@ AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
|
||||||
{
|
{
|
||||||
NS_WARNING("Timed out waiting for GMP async shutdown!");
|
NS_WARNING("Timed out waiting for GMP async shutdown!");
|
||||||
GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
|
GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
if (service) {
|
if (service) {
|
||||||
service->AsyncShutdownComplete(parent);
|
service->AsyncShutdownComplete(parent);
|
||||||
}
|
}
|
||||||
|
@ -216,8 +212,8 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t timeout = GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT;
|
int32_t timeout = GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT;
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
if (service) {
|
if (service) {
|
||||||
timeout = service->AsyncShutdownTimeoutMs();
|
timeout = service->AsyncShutdownTimeoutMs();
|
||||||
}
|
}
|
||||||
|
@ -226,6 +222,16 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPParent::RecvPGMPContentChildDestroyed()
|
||||||
|
{
|
||||||
|
--mGMPContentChildCount;
|
||||||
|
if (!IsUsed()) {
|
||||||
|
CloseIfUnused();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GMPParent::CloseIfUnused()
|
GMPParent::CloseIfUnused()
|
||||||
{
|
{
|
||||||
|
@ -235,11 +241,7 @@ GMPParent::CloseIfUnused()
|
||||||
if ((mDeleteProcessOnlyOnUnload ||
|
if ((mDeleteProcessOnlyOnUnload ||
|
||||||
mState == GMPStateLoaded ||
|
mState == GMPStateLoaded ||
|
||||||
mState == GMPStateUnloading) &&
|
mState == GMPStateUnloading) &&
|
||||||
mVideoDecoders.IsEmpty() &&
|
!IsUsed()) {
|
||||||
mVideoEncoders.IsEmpty() &&
|
|
||||||
mDecryptors.IsEmpty() &&
|
|
||||||
mAudioDecoders.IsEmpty()) {
|
|
||||||
|
|
||||||
// Ensure all timers are killed.
|
// Ensure all timers are killed.
|
||||||
for (uint32_t i = mTimers.Length(); i > 0; i--) {
|
for (uint32_t i = mTimers.Length(); i > 0; i--) {
|
||||||
mTimers[i - 1]->Shutdown();
|
mTimers[i - 1]->Shutdown();
|
||||||
|
@ -286,57 +288,21 @@ GMPParent::AbortAsyncShutdown()
|
||||||
CloseIfUnused();
|
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
|
void
|
||||||
GMPParent::CloseActive(bool aDieWhenUnloaded)
|
GMPParent::CloseActive(bool aDieWhenUnloaded)
|
||||||
{
|
{
|
||||||
LOGD("%s: state %d", __FUNCTION__, mState);
|
LOGD("%s: state %d", __FUNCTION__, mState);
|
||||||
|
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||||
|
|
||||||
if (aDieWhenUnloaded) {
|
if (aDieWhenUnloaded) {
|
||||||
mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
|
mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
|
||||||
}
|
}
|
||||||
if (mState == GMPStateLoaded) {
|
if (mState == GMPStateLoaded) {
|
||||||
mState = GMPStateUnloading;
|
mState = GMPStateUnloading;
|
||||||
}
|
}
|
||||||
|
if (mState != GMPStateNotLoaded && IsUsed()) {
|
||||||
// Invalidate and remove any remaining API objects.
|
unused << SendCloseActive();
|
||||||
for (uint32_t i = mVideoDecoders.Length(); i > 0; i--) {
|
|
||||||
mVideoDecoders[i - 1]->Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
void
|
||||||
|
@ -350,7 +316,8 @@ GMPParent::Shutdown()
|
||||||
if (mAbnormalShutdownInProgress) {
|
if (mAbnormalShutdownInProgress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(mVideoDecoders.IsEmpty() && mVideoEncoders.IsEmpty());
|
|
||||||
|
MOZ_ASSERT(!IsUsed());
|
||||||
if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
|
if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
|
||||||
return;
|
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
|
GMPState
|
||||||
GMPParent::State() const
|
GMPParent::State() const
|
||||||
{
|
{
|
||||||
|
@ -539,77 +434,6 @@ GMPParent::EnsureProcessLoaded()
|
||||||
return NS_SUCCEEDED(rv);
|
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
|
#ifdef MOZ_CRASHREPORTER
|
||||||
void
|
void
|
||||||
GMPParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
|
GMPParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
|
||||||
|
@ -724,70 +548,6 @@ GMPParent::DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter)
|
||||||
return true;
|
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*
|
PGMPStorageParent*
|
||||||
GMPParent::AllocPGMPStorageParent()
|
GMPParent::AllocPGMPStorageParent()
|
||||||
{
|
{
|
||||||
|
@ -1024,7 +784,7 @@ GMPParent::GetVersion() const
|
||||||
return mVersion;
|
return mVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsACString&
|
const nsCString&
|
||||||
GMPParent::GetPluginId() const
|
GMPParent::GetPluginId() const
|
||||||
{
|
{
|
||||||
return mPluginId;
|
return mPluginId;
|
||||||
|
@ -1053,6 +813,107 @@ GMPParent::RecvAsyncShutdownComplete()
|
||||||
return true;
|
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 gmp
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define GMPParent_h_
|
#define GMPParent_h_
|
||||||
|
|
||||||
#include "GMPProcessParent.h"
|
#include "GMPProcessParent.h"
|
||||||
#include "GMPService.h"
|
#include "GMPServiceParent.h"
|
||||||
#include "GMPAudioDecoderParent.h"
|
#include "GMPAudioDecoderParent.h"
|
||||||
#include "GMPDecryptorParent.h"
|
#include "GMPDecryptorParent.h"
|
||||||
#include "GMPVideoDecoderParent.h"
|
#include "GMPVideoDecoderParent.h"
|
||||||
|
@ -54,15 +54,30 @@ enum GMPState {
|
||||||
GMPStateClosing
|
GMPStateClosing
|
||||||
};
|
};
|
||||||
|
|
||||||
class GMPParent final : public PGMPParent,
|
class GMPContentParent;
|
||||||
public GMPSharedMem
|
|
||||||
|
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:
|
public:
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
|
||||||
|
|
||||||
GMPParent();
|
GMPParent();
|
||||||
|
|
||||||
nsresult Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir);
|
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
||||||
nsresult CloneFrom(const GMPParent* aOther);
|
nsresult CloneFrom(const GMPParent* aOther);
|
||||||
|
|
||||||
void Crash();
|
void Crash();
|
||||||
|
@ -84,18 +99,6 @@ public:
|
||||||
|
|
||||||
bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
|
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;
|
GMPState State() const;
|
||||||
nsIThread* GMPThread();
|
nsIThread* GMPThread();
|
||||||
|
|
||||||
|
@ -117,7 +120,7 @@ public:
|
||||||
|
|
||||||
const nsCString& GetDisplayName() const;
|
const nsCString& GetDisplayName() const;
|
||||||
const nsCString& GetVersion() 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.
|
// Returns true if a plugin can be or is being used across multiple NodeIds.
|
||||||
bool CanBeSharedCrossNodeIds() const;
|
bool CanBeSharedCrossNodeIds() const;
|
||||||
|
@ -131,14 +134,18 @@ public:
|
||||||
return nsCOMPtr<nsIFile>(mDirectory).forget();
|
return nsCOMPtr<nsIFile>(mDirectory).forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GMPSharedMem
|
|
||||||
virtual void CheckThread() override;
|
|
||||||
|
|
||||||
void AbortAsyncShutdown();
|
void AbortAsyncShutdown();
|
||||||
|
|
||||||
|
bool GetGMPContentParent(UniquePtr<GetGMPContentParentCallback>&& aCallback);
|
||||||
|
already_AddRefed<GMPContentParent> ForgetGMPContentParent();
|
||||||
|
|
||||||
|
bool EnsureProcessLoaded(base::ProcessId* aID);
|
||||||
|
|
||||||
|
bool Bridge(GMPServiceParent* aGMPServiceParent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~GMPParent();
|
~GMPParent();
|
||||||
nsRefPtr<GeckoMediaPluginService> mService;
|
nsRefPtr<GeckoMediaPluginServiceParent> mService;
|
||||||
bool EnsureProcessLoaded();
|
bool EnsureProcessLoaded();
|
||||||
nsresult ReadGMPMetaData();
|
nsresult ReadGMPMetaData();
|
||||||
#ifdef MOZ_CRASHREPORTER
|
#ifdef MOZ_CRASHREPORTER
|
||||||
|
@ -150,22 +157,13 @@ private:
|
||||||
virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) override;
|
virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) override;
|
||||||
virtual bool DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter) 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 bool RecvPGMPStorageConstructor(PGMPStorageParent* actor) override;
|
||||||
virtual PGMPStorageParent* AllocPGMPStorageParent() override;
|
virtual PGMPStorageParent* AllocPGMPStorageParent() override;
|
||||||
virtual bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
|
virtual bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
|
||||||
|
|
||||||
|
virtual PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
|
||||||
|
ProcessId aOtherPid) override;
|
||||||
|
|
||||||
virtual bool RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
|
virtual bool RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
|
||||||
virtual PGMPTimerParent* AllocPGMPTimerParent() override;
|
virtual PGMPTimerParent* AllocPGMPTimerParent() override;
|
||||||
virtual bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
|
virtual bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
|
||||||
|
@ -173,6 +171,13 @@ private:
|
||||||
virtual bool RecvAsyncShutdownComplete() override;
|
virtual bool RecvAsyncShutdownComplete() override;
|
||||||
virtual bool RecvAsyncShutdownRequired() override;
|
virtual bool RecvAsyncShutdownRequired() override;
|
||||||
|
|
||||||
|
virtual bool RecvPGMPContentChildDestroyed() override;
|
||||||
|
bool IsUsed()
|
||||||
|
{
|
||||||
|
return mGMPContentChildCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult EnsureAsyncShutdownTimeoutSet();
|
nsresult EnsureAsyncShutdownTimeoutSet();
|
||||||
|
|
||||||
GMPState mState;
|
GMPState mState;
|
||||||
|
@ -187,10 +192,6 @@ private:
|
||||||
bool mDeleteProcessOnlyOnUnload;
|
bool mDeleteProcessOnlyOnUnload;
|
||||||
bool mAbnormalShutdownInProgress;
|
bool mAbnormalShutdownInProgress;
|
||||||
|
|
||||||
nsTArray<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
|
|
||||||
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
|
|
||||||
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
|
|
||||||
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
|
|
||||||
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
|
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
|
||||||
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
|
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
|
||||||
nsCOMPtr<nsIThread> mGMPThread;
|
nsCOMPtr<nsIThread> mGMPThread;
|
||||||
|
@ -198,6 +199,11 @@ private:
|
||||||
// NodeId the plugin is assigned to, or empty if the the plugin is not
|
// NodeId the plugin is assigned to, or empty if the the plugin is not
|
||||||
// assigned to a NodeId.
|
// assigned to a NodeId.
|
||||||
nsAutoCString mNodeId;
|
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 mAsyncShutdownRequired;
|
||||||
bool mAsyncShutdownInProgress;
|
bool mAsyncShutdownInProgress;
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,37 +15,49 @@
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIThread.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;
|
template <class> struct already_AddRefed;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
extern PRLogModuleInfo* GetGMPLog();
|
||||||
|
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPParent;
|
class GetGMPContentParentCallback;
|
||||||
|
|
||||||
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
|
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
|
||||||
|
|
||||||
class GeckoMediaPluginService final : public mozIGeckoMediaPluginService
|
class GeckoMediaPluginService : public mozIGeckoMediaPluginService
|
||||||
, public nsIObserver
|
, public nsIObserver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
|
static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
|
||||||
|
|
||||||
GeckoMediaPluginService();
|
virtual nsresult Init();
|
||||||
nsresult Init();
|
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_MOZIGECKOMEDIAPLUGINSERVICE
|
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
void AsyncShutdownNeeded(GMPParent* aParent);
|
// mozIGeckoMediaPluginService
|
||||||
void AsyncShutdownComplete(GMPParent* aParent);
|
NS_IMETHOD GetThread(nsIThread** aThread) override;
|
||||||
void AbortAsyncShutdown();
|
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();
|
int32_t AsyncShutdownTimeoutMs();
|
||||||
|
|
||||||
|
@ -77,120 +89,29 @@ public:
|
||||||
const nsACString& aPluginName,
|
const nsACString& aPluginName,
|
||||||
const nsAString& aPluginDumpId);
|
const nsAString& aPluginDumpId);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
~GeckoMediaPluginService();
|
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);
|
nsresult GMPDispatch(nsIRunnable* event, uint32_t flags = NS_DISPATCH_NORMAL);
|
||||||
|
void ShutdownGMPThread();
|
||||||
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);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class GMPParent;
|
Mutex mMutex; // Protects mGMPThread and mGMPThreadShutdown and some members
|
||||||
void ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld);
|
// in derived classes.
|
||||||
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;
|
|
||||||
nsCOMPtr<nsIThread> mGMPThread;
|
nsCOMPtr<nsIThread> mGMPThread;
|
||||||
bool mShuttingDown;
|
bool mGMPThreadShutdown;
|
||||||
bool mShuttingDownOnGMPThread;
|
bool mShuttingDownOnGMPThread;
|
||||||
|
|
||||||
nsTArray<nsRefPtr<PluginCrashCallback>> mPluginCrashCallbacks;
|
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 gmp
|
||||||
} // namespace mozilla
|
} // 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;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
nsCOMPtr<mozIGeckoMediaPluginChromeService> mps =
|
||||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||||
if (NS_WARN_IF(!mps)) {
|
if (NS_WARN_IF(!mps)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
@ -468,7 +468,7 @@ GMPStorageParent::Init()
|
||||||
if (NS_WARN_IF(mNodeId.IsEmpty())) {
|
if (NS_WARN_IF(mNodeId.IsEmpty())) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
nsCOMPtr<mozIGeckoMediaPluginChromeService> mps =
|
||||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||||
if (NS_WARN_IF(!mps)) {
|
if (NS_WARN_IF(!mps)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "GMPVideoDecoderChild.h"
|
#include "GMPVideoDecoderChild.h"
|
||||||
#include "GMPVideoi420FrameImpl.h"
|
#include "GMPVideoi420FrameImpl.h"
|
||||||
#include "GMPChild.h"
|
#include "GMPContentChild.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "GMPVideoEncodedFrameImpl.h"
|
#include "GMPVideoEncodedFrameImpl.h"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPChild* aPlugin)
|
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPContentChild* aPlugin)
|
||||||
: GMPSharedMemManager(aPlugin),
|
: GMPSharedMemManager(aPlugin),
|
||||||
mPlugin(aPlugin),
|
mPlugin(aPlugin),
|
||||||
mVideoDecoder(nullptr),
|
mVideoDecoder(nullptr),
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPChild;
|
class GMPContentChild;
|
||||||
|
|
||||||
class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
|
class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
|
||||||
public GMPVideoDecoderCallback,
|
public GMPVideoDecoderCallback,
|
||||||
public GMPSharedMemManager
|
public GMPSharedMemManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit GMPVideoDecoderChild(GMPChild* aPlugin);
|
explicit GMPVideoDecoderChild(GMPContentChild* aPlugin);
|
||||||
virtual ~GMPVideoDecoderChild();
|
virtual ~GMPVideoDecoderChild();
|
||||||
|
|
||||||
void Init(GMPVideoDecoder* aDecoder);
|
void Init(GMPVideoDecoder* aDecoder);
|
||||||
|
@ -74,7 +74,7 @@ private:
|
||||||
virtual bool RecvDrain() override;
|
virtual bool RecvDrain() override;
|
||||||
virtual bool RecvDecodingComplete() override;
|
virtual bool RecvDecodingComplete() override;
|
||||||
|
|
||||||
GMPChild* mPlugin;
|
GMPContentChild* mPlugin;
|
||||||
GMPVideoDecoder* mVideoDecoder;
|
GMPVideoDecoder* mVideoDecoder;
|
||||||
GMPVideoHostImpl mVideoHost;
|
GMPVideoHostImpl mVideoHost;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "GMPUtils.h"
|
#include "GMPUtils.h"
|
||||||
#include "GMPVideoEncodedFrameImpl.h"
|
#include "GMPVideoEncodedFrameImpl.h"
|
||||||
#include "GMPVideoi420FrameImpl.h"
|
#include "GMPVideoi420FrameImpl.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPContentParent.h"
|
||||||
#include "GMPMessageUtils.h"
|
#include "GMPMessageUtils.h"
|
||||||
#include "mozilla/gmp/GMPTypes.h"
|
#include "mozilla/gmp/GMPTypes.h"
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace gmp {
|
||||||
// on Shutdown -> Dead
|
// on Shutdown -> Dead
|
||||||
// Dead: mIsOpen == false
|
// Dead: mIsOpen == false
|
||||||
|
|
||||||
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPParent* aPlugin)
|
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPContentParent* aPlugin)
|
||||||
: GMPSharedMemManager(aPlugin)
|
: GMPSharedMemManager(aPlugin)
|
||||||
, mIsOpen(false)
|
, mIsOpen(false)
|
||||||
, mShuttingDown(false)
|
, mShuttingDown(false)
|
||||||
|
@ -335,6 +335,13 @@ GMPVideoDecoderParent::RecvError(const GMPErr& aError)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPVideoDecoderParent::RecvShutdown()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem&& aEncodedBuffer)
|
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem&& aEncodedBuffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPParent;
|
class GMPContentParent;
|
||||||
|
|
||||||
class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
|
class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
|
||||||
, public GMPVideoDecoderProxy
|
, public GMPVideoDecoderProxy
|
||||||
|
@ -27,7 +27,7 @@ class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
|
NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
|
||||||
|
|
||||||
explicit GMPVideoDecoderParent(GMPParent *aPlugin);
|
explicit GMPVideoDecoderParent(GMPContentParent *aPlugin);
|
||||||
|
|
||||||
GMPVideoHostImpl& Host();
|
GMPVideoHostImpl& Host();
|
||||||
nsresult Shutdown();
|
nsresult Shutdown();
|
||||||
|
@ -73,6 +73,7 @@ private:
|
||||||
virtual bool RecvDrainComplete() override;
|
virtual bool RecvDrainComplete() override;
|
||||||
virtual bool RecvResetComplete() override;
|
virtual bool RecvResetComplete() override;
|
||||||
virtual bool RecvError(const GMPErr& aError) override;
|
virtual bool RecvError(const GMPErr& aError) override;
|
||||||
|
virtual bool RecvShutdown() override;
|
||||||
virtual bool RecvParentShmemForPool(Shmem&& aEncodedBuffer) override;
|
virtual bool RecvParentShmemForPool(Shmem&& aEncodedBuffer) override;
|
||||||
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
|
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
|
||||||
Shmem* aMem) override;
|
Shmem* aMem) override;
|
||||||
|
@ -80,7 +81,7 @@ private:
|
||||||
|
|
||||||
bool mIsOpen;
|
bool mIsOpen;
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
nsRefPtr<GMPParent> mPlugin;
|
nsRefPtr<GMPContentParent> mPlugin;
|
||||||
GMPVideoDecoderCallbackProxy* mCallback;
|
GMPVideoDecoderCallbackProxy* mCallback;
|
||||||
GMPVideoHostImpl mVideoHost;
|
GMPVideoHostImpl mVideoHost;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPVideoEncoderChild.h"
|
#include "GMPVideoEncoderChild.h"
|
||||||
#include "GMPChild.h"
|
#include "GMPContentChild.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "GMPVideoEncodedFrameImpl.h"
|
#include "GMPVideoEncodedFrameImpl.h"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPChild* aPlugin)
|
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPContentChild* aPlugin)
|
||||||
: GMPSharedMemManager(aPlugin),
|
: GMPSharedMemManager(aPlugin),
|
||||||
mPlugin(aPlugin),
|
mPlugin(aPlugin),
|
||||||
mVideoEncoder(nullptr),
|
mVideoEncoder(nullptr),
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPChild;
|
class GMPContentChild;
|
||||||
|
|
||||||
class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
|
class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
|
||||||
public GMPVideoEncoderCallback,
|
public GMPVideoEncoderCallback,
|
||||||
public GMPSharedMemManager
|
public GMPSharedMemManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit GMPVideoEncoderChild(GMPChild* aPlugin);
|
explicit GMPVideoEncoderChild(GMPContentChild* aPlugin);
|
||||||
virtual ~GMPVideoEncoderChild();
|
virtual ~GMPVideoEncoderChild();
|
||||||
|
|
||||||
void Init(GMPVideoEncoder* aEncoder);
|
void Init(GMPVideoEncoder* aEncoder);
|
||||||
|
@ -73,7 +73,7 @@ private:
|
||||||
virtual bool RecvSetPeriodicKeyFrames(const bool& aEnable) override;
|
virtual bool RecvSetPeriodicKeyFrames(const bool& aEnable) override;
|
||||||
virtual bool RecvEncodingComplete() override;
|
virtual bool RecvEncodingComplete() override;
|
||||||
|
|
||||||
GMPChild* mPlugin;
|
GMPContentChild* mPlugin;
|
||||||
GMPVideoEncoder* mVideoEncoder;
|
GMPVideoEncoder* mVideoEncoder;
|
||||||
GMPVideoHostImpl mVideoHost;
|
GMPVideoHostImpl mVideoHost;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "GMPMessageUtils.h"
|
#include "GMPMessageUtils.h"
|
||||||
#include "nsAutoRef.h"
|
#include "nsAutoRef.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPContentParent.h"
|
||||||
#include "mozilla/gmp/GMPTypes.h"
|
#include "mozilla/gmp/GMPTypes.h"
|
||||||
#include "nsThread.h"
|
#include "nsThread.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
@ -50,7 +50,7 @@ namespace gmp {
|
||||||
// on Shutdown -> Dead
|
// on Shutdown -> Dead
|
||||||
// Dead: mIsOpen == false
|
// Dead: mIsOpen == false
|
||||||
|
|
||||||
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
|
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPContentParent *aPlugin)
|
||||||
: GMPSharedMemManager(aPlugin),
|
: GMPSharedMemManager(aPlugin),
|
||||||
mIsOpen(false),
|
mIsOpen(false),
|
||||||
mShuttingDown(false),
|
mShuttingDown(false),
|
||||||
|
@ -320,6 +320,13 @@ GMPVideoEncoderParent::RecvError(const GMPErr& aError)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPVideoEncoderParent::RecvShutdown()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem&& aFrameBuffer)
|
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem&& aFrameBuffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GMPParent;
|
class GMPContentParent;
|
||||||
|
|
||||||
class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
||||||
public PGMPVideoEncoderParent,
|
public PGMPVideoEncoderParent,
|
||||||
|
@ -27,7 +27,7 @@ class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(GMPVideoEncoderParent)
|
NS_INLINE_DECL_REFCOUNTING(GMPVideoEncoderParent)
|
||||||
|
|
||||||
explicit GMPVideoEncoderParent(GMPParent *aPlugin);
|
explicit GMPVideoEncoderParent(GMPContentParent *aPlugin);
|
||||||
|
|
||||||
GMPVideoHostImpl& Host();
|
GMPVideoHostImpl& Host();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
@ -69,6 +69,7 @@ private:
|
||||||
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||||
InfallibleTArray<uint8_t>&& aCodecSpecificInfo) override;
|
InfallibleTArray<uint8_t>&& aCodecSpecificInfo) override;
|
||||||
virtual bool RecvError(const GMPErr& aError) override;
|
virtual bool RecvError(const GMPErr& aError) override;
|
||||||
|
virtual bool RecvShutdown() override;
|
||||||
virtual bool RecvParentShmemForPool(Shmem&& aFrameBuffer) override;
|
virtual bool RecvParentShmemForPool(Shmem&& aFrameBuffer) override;
|
||||||
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
||||||
Shmem* aMem) override;
|
Shmem* aMem) override;
|
||||||
|
@ -76,7 +77,7 @@ private:
|
||||||
|
|
||||||
bool mIsOpen;
|
bool mIsOpen;
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
nsRefPtr<GMPParent> mPlugin;
|
nsRefPtr<GMPContentParent> mPlugin;
|
||||||
GMPVideoEncoderCallbackProxy* mCallback;
|
GMPVideoEncoderCallbackProxy* mCallback;
|
||||||
GMPVideoHostImpl mVideoHost;
|
GMPVideoHostImpl mVideoHost;
|
||||||
nsCOMPtr<nsIThread> mEncodedThread;
|
nsCOMPtr<nsIThread> mEncodedThread;
|
||||||
|
|
|
@ -3,11 +3,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PGMPVideoDecoder;
|
|
||||||
include protocol PGMPVideoEncoder;
|
|
||||||
include protocol PCrashReporter;
|
include protocol PCrashReporter;
|
||||||
include protocol PGMPDecryptor;
|
include protocol PGMPContent;
|
||||||
include protocol PGMPAudioDecoder;
|
|
||||||
include protocol PGMPTimer;
|
include protocol PGMPTimer;
|
||||||
include protocol PGMPStorage;
|
include protocol PGMPStorage;
|
||||||
|
|
||||||
|
@ -18,10 +15,8 @@ namespace gmp {
|
||||||
|
|
||||||
intr protocol PGMP
|
intr protocol PGMP
|
||||||
{
|
{
|
||||||
manages PGMPAudioDecoder;
|
parent opens PGMPContent;
|
||||||
manages PGMPDecryptor;
|
|
||||||
manages PGMPVideoDecoder;
|
|
||||||
manages PGMPVideoEncoder;
|
|
||||||
manages PCrashReporter;
|
manages PCrashReporter;
|
||||||
manages PGMPTimer;
|
manages PGMPTimer;
|
||||||
manages PGMPStorage;
|
manages PGMPStorage;
|
||||||
|
@ -31,19 +26,17 @@ parent:
|
||||||
async PGMPTimer();
|
async PGMPTimer();
|
||||||
async PGMPStorage();
|
async PGMPStorage();
|
||||||
|
|
||||||
|
async PGMPContentChildDestroyed();
|
||||||
|
|
||||||
async AsyncShutdownComplete();
|
async AsyncShutdownComplete();
|
||||||
async AsyncShutdownRequired();
|
async AsyncShutdownRequired();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
async PGMPAudioDecoder();
|
|
||||||
async PGMPDecryptor();
|
|
||||||
async PGMPVideoDecoder();
|
|
||||||
async PGMPVideoEncoder();
|
|
||||||
|
|
||||||
async SetNodeId(nsCString nodeId);
|
|
||||||
async StartPlugin();
|
|
||||||
async BeginAsyncShutdown();
|
async BeginAsyncShutdown();
|
||||||
async CrashPluginNow();
|
async CrashPluginNow();
|
||||||
|
async StartPlugin();
|
||||||
|
async SetNodeId(nsCString nodeId);
|
||||||
|
async CloseActive();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gmp
|
} // namespace gmp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PGMP;
|
include protocol PGMPContent;
|
||||||
include GMPTypes;
|
include GMPTypes;
|
||||||
|
|
||||||
using GMPCodecSpecificInfo from "gmp-audio-codec.h";
|
using GMPCodecSpecificInfo from "gmp-audio-codec.h";
|
||||||
|
@ -16,7 +16,7 @@ namespace gmp {
|
||||||
|
|
||||||
async protocol PGMPAudioDecoder
|
async protocol PGMPAudioDecoder
|
||||||
{
|
{
|
||||||
manager PGMP;
|
manager PGMPContent;
|
||||||
child:
|
child:
|
||||||
InitDecode(GMPAudioCodecData aCodecSettings);
|
InitDecode(GMPAudioCodecData aCodecSettings);
|
||||||
Decode(GMPAudioEncodedSampleData aInput);
|
Decode(GMPAudioEncodedSampleData aInput);
|
||||||
|
@ -30,6 +30,7 @@ parent:
|
||||||
DrainComplete();
|
DrainComplete();
|
||||||
ResetComplete();
|
ResetComplete();
|
||||||
Error(GMPErr aErr);
|
Error(GMPErr aErr);
|
||||||
|
async Shutdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gmp
|
} // 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PGMP;
|
include protocol PGMPContent;
|
||||||
include GMPTypes;
|
include GMPTypes;
|
||||||
|
|
||||||
using GMPSessionMessageType from "gmp-decryption.h";
|
using GMPSessionMessageType from "gmp-decryption.h";
|
||||||
|
@ -17,7 +17,7 @@ namespace gmp {
|
||||||
|
|
||||||
async protocol PGMPDecryptor
|
async protocol PGMPDecryptor
|
||||||
{
|
{
|
||||||
manager PGMP;
|
manager PGMPContent;
|
||||||
child:
|
child:
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
@ -84,6 +84,8 @@ parent:
|
||||||
SetCaps(uint64_t aCaps);
|
SetCaps(uint64_t aCaps);
|
||||||
|
|
||||||
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
|
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
|
||||||
|
|
||||||
|
async Shutdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gmp
|
} // 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PGMP;
|
include protocol PGMPContent;
|
||||||
include GMPTypes;
|
include GMPTypes;
|
||||||
|
|
||||||
using GMPVideoCodec from "gmp-video-codec.h";
|
using GMPVideoCodec from "gmp-video-codec.h";
|
||||||
|
@ -16,7 +16,7 @@ namespace gmp {
|
||||||
|
|
||||||
intr protocol PGMPVideoDecoder
|
intr protocol PGMPVideoDecoder
|
||||||
{
|
{
|
||||||
manager PGMP;
|
manager PGMPContent;
|
||||||
child:
|
child:
|
||||||
async InitDecode(GMPVideoCodec aCodecSettings,
|
async InitDecode(GMPVideoCodec aCodecSettings,
|
||||||
uint8_t[] aCodecSpecific,
|
uint8_t[] aCodecSpecific,
|
||||||
|
@ -39,6 +39,7 @@ parent:
|
||||||
async DrainComplete();
|
async DrainComplete();
|
||||||
async ResetComplete();
|
async ResetComplete();
|
||||||
async Error(GMPErr aErr);
|
async Error(GMPErr aErr);
|
||||||
|
async Shutdown();
|
||||||
async ParentShmemForPool(Shmem aEncodedBuffer);
|
async ParentShmemForPool(Shmem aEncodedBuffer);
|
||||||
// MUST be intr - if sync and we create a new Shmem, when the returned
|
// 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
|
// 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PGMP;
|
include protocol PGMPContent;
|
||||||
include GMPTypes;
|
include GMPTypes;
|
||||||
|
|
||||||
using GMPVideoCodec from "gmp-video-codec.h";
|
using GMPVideoCodec from "gmp-video-codec.h";
|
||||||
|
@ -17,7 +17,7 @@ namespace gmp {
|
||||||
|
|
||||||
intr protocol PGMPVideoEncoder
|
intr protocol PGMPVideoEncoder
|
||||||
{
|
{
|
||||||
manager PGMP;
|
manager PGMPContent;
|
||||||
child:
|
child:
|
||||||
async InitEncode(GMPVideoCodec aCodecSettings,
|
async InitEncode(GMPVideoCodec aCodecSettings,
|
||||||
uint8_t[] aCodecSpecific,
|
uint8_t[] aCodecSpecific,
|
||||||
|
@ -37,6 +37,7 @@ parent:
|
||||||
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||||
uint8_t[] aCodecSpecificInfo);
|
uint8_t[] aCodecSpecificInfo);
|
||||||
async Error(GMPErr aErr);
|
async Error(GMPErr aErr);
|
||||||
|
async Shutdown();
|
||||||
async ParentShmemForPool(Shmem aFrameBuffer);
|
async ParentShmemForPool(Shmem aFrameBuffer);
|
||||||
// MUST be intr - if sync and we create a new Shmem, when the returned
|
// 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
|
// Shmem is received in the Child it will fail to Deserialize
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
XPIDL_MODULE = 'content_geckomediaplugins'
|
XPIDL_MODULE = 'content_geckomediaplugins'
|
||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
|
'mozIGeckoMediaPluginChromeService.idl',
|
||||||
'mozIGeckoMediaPluginService.idl',
|
'mozIGeckoMediaPluginService.idl',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -35,6 +36,8 @@ EXPORTS += [
|
||||||
'GMPAudioHost.h',
|
'GMPAudioHost.h',
|
||||||
'GMPCallbackBase.h',
|
'GMPCallbackBase.h',
|
||||||
'GMPChild.h',
|
'GMPChild.h',
|
||||||
|
'GMPContentChild.h',
|
||||||
|
'GMPContentParent.h',
|
||||||
'GMPDecryptorChild.h',
|
'GMPDecryptorChild.h',
|
||||||
'GMPDecryptorParent.h',
|
'GMPDecryptorParent.h',
|
||||||
'GMPDecryptorProxy.h',
|
'GMPDecryptorProxy.h',
|
||||||
|
@ -46,6 +49,8 @@ EXPORTS += [
|
||||||
'GMPProcessChild.h',
|
'GMPProcessChild.h',
|
||||||
'GMPProcessParent.h',
|
'GMPProcessParent.h',
|
||||||
'GMPService.h',
|
'GMPService.h',
|
||||||
|
'GMPServiceChild.h',
|
||||||
|
'GMPServiceParent.h',
|
||||||
'GMPSharedMemManager.h',
|
'GMPSharedMemManager.h',
|
||||||
'GMPStorageChild.h',
|
'GMPStorageChild.h',
|
||||||
'GMPStorageParent.h',
|
'GMPStorageParent.h',
|
||||||
|
@ -76,6 +81,8 @@ UNIFIED_SOURCES += [
|
||||||
'GMPAudioDecoderParent.cpp',
|
'GMPAudioDecoderParent.cpp',
|
||||||
'GMPAudioHost.cpp',
|
'GMPAudioHost.cpp',
|
||||||
'GMPChild.cpp',
|
'GMPChild.cpp',
|
||||||
|
'GMPContentChild.cpp',
|
||||||
|
'GMPContentParent.cpp',
|
||||||
'GMPDecryptorChild.cpp',
|
'GMPDecryptorChild.cpp',
|
||||||
'GMPDecryptorParent.cpp',
|
'GMPDecryptorParent.cpp',
|
||||||
'GMPEncryptedBufferDataImpl.cpp',
|
'GMPEncryptedBufferDataImpl.cpp',
|
||||||
|
@ -84,6 +91,8 @@ UNIFIED_SOURCES += [
|
||||||
'GMPProcessChild.cpp',
|
'GMPProcessChild.cpp',
|
||||||
'GMPProcessParent.cpp',
|
'GMPProcessParent.cpp',
|
||||||
'GMPService.cpp',
|
'GMPService.cpp',
|
||||||
|
'GMPServiceChild.cpp',
|
||||||
|
'GMPServiceParent.cpp',
|
||||||
'GMPSharedMemManager.cpp',
|
'GMPSharedMemManager.cpp',
|
||||||
'GMPStorageChild.cpp',
|
'GMPStorageChild.cpp',
|
||||||
'GMPStorageParent.cpp',
|
'GMPStorageParent.cpp',
|
||||||
|
@ -108,7 +117,9 @@ IPDL_SOURCES += [
|
||||||
'GMPTypes.ipdlh',
|
'GMPTypes.ipdlh',
|
||||||
'PGMP.ipdl',
|
'PGMP.ipdl',
|
||||||
'PGMPAudioDecoder.ipdl',
|
'PGMPAudioDecoder.ipdl',
|
||||||
|
'PGMPContent.ipdl',
|
||||||
'PGMPDecryptor.ipdl',
|
'PGMPDecryptor.ipdl',
|
||||||
|
'PGMPService.ipdl',
|
||||||
'PGMPStorage.ipdl',
|
'PGMPStorage.ipdl',
|
||||||
'PGMPTimer.ipdl',
|
'PGMPTimer.ipdl',
|
||||||
'PGMPVideoDecoder.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 "nsISupports.idl"
|
||||||
#include "nsIThread.idl"
|
#include "nsIThread.idl"
|
||||||
#include "nsIPrincipal.idl"
|
|
||||||
#include "nsIFile.idl"
|
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
class GMPAudioDecoderProxy;
|
class GMPAudioDecoderProxy;
|
||||||
|
@ -16,17 +15,44 @@ class GMPDecryptorProxy;
|
||||||
class GMPVideoDecoderProxy;
|
class GMPVideoDecoderProxy;
|
||||||
class GMPVideoEncoderProxy;
|
class GMPVideoEncoderProxy;
|
||||||
class GMPVideoHost;
|
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 TagArray(nsTArray<nsCString>);
|
||||||
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
native GetGMPDecryptorCallback(mozilla::UniquePtr<GetGMPDecryptorCallback>&&);
|
||||||
[ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
|
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
|
interface mozIGeckoMediaPluginService : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -47,84 +73,78 @@ interface mozIGeckoMediaPluginService : nsISupports
|
||||||
* Callable on any thread
|
* Callable on any thread
|
||||||
*/
|
*/
|
||||||
[noscript]
|
[noscript]
|
||||||
ACString getPluginVersionForAPI(in ACString api,
|
void getPluginVersionForAPI(in ACString api, in TagArray tags,
|
||||||
in TagArray tags);
|
out boolean hasPlugin, out ACString version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a video decoder that supports the specified tags.
|
* Get a video decoder that supports the specified tags.
|
||||||
* The array of tags should at least contain a codec tag, and optionally
|
* The array of tags should at least contain a codec tag, and optionally
|
||||||
* other tags such as for EME keysystem.
|
* other tags such as for EME keysystem.
|
||||||
* Callable only on GMP thread.
|
* 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]
|
[noscript]
|
||||||
GMPVideoDecoderProxy getGMPVideoDecoder(in TagArray tags,
|
void getGMPVideoDecoder(in TagArray tags,
|
||||||
[optional] in ACString nodeId,
|
[optional] in ACString nodeId,
|
||||||
out GMPVideoHost outVideoHost);
|
in GetGMPVideoDecoderCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a video encoder that supports the specified tags.
|
* Get a video encoder that supports the specified tags.
|
||||||
* The array of tags should at least contain a codec tag, and optionally
|
* The array of tags should at least contain a codec tag, and optionally
|
||||||
* other tags.
|
* other tags.
|
||||||
* Callable only on GMP thread.
|
* 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]
|
[noscript]
|
||||||
GMPVideoEncoderProxy getGMPVideoEncoder(in TagArray tags,
|
void getGMPVideoEncoder(in TagArray tags,
|
||||||
[optional] in ACString nodeId,
|
[optional] in ACString nodeId,
|
||||||
out GMPVideoHost outVideoHost);
|
in GetGMPVideoEncoderCallback callback);
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a directory to scan for gecko media plugins.
|
* Returns an audio decoder that supports the specified tags.
|
||||||
* @note Main-thread API.
|
* 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.
|
* Returns a decryption session manager that supports the specified tags.
|
||||||
* @note Main-thread API.
|
* 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);
|
[noscript]
|
||||||
|
void getGMPDecryptor(in TagArray tags, in ACString nodeId,
|
||||||
/**
|
in GetGMPDecryptorCallback callback);
|
||||||
* Remove a directory for gecko media plugins and delete it from disk.
|
|
||||||
* @note Main-thread API.
|
|
||||||
*/
|
|
||||||
void removeAndDeletePluginDirectory(in AString directory);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the NodeId for a (origin, urlbarOrigin, isInprivateBrowsing) tuple.
|
* Gets the NodeId for a (origin, urlbarOrigin, isInprivateBrowsing) tuple.
|
||||||
*/
|
*/
|
||||||
ACString getNodeId(in AString origin,
|
[noscript]
|
||||||
in AString topLevelOrigin,
|
void getNodeId(in AString origin,
|
||||||
in bool inPrivateBrowsingMode);
|
in AString topLevelOrigin,
|
||||||
|
in bool inPrivateBrowsingMode,
|
||||||
/**
|
in GetNodeIdCallback callback);
|
||||||
* 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();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
#include "GMPVideoDecoderProxy.h"
|
#include "GMPVideoDecoderProxy.h"
|
||||||
#include "GMPVideoEncoderProxy.h"
|
#include "GMPVideoEncoderProxy.h"
|
||||||
#include "GMPDecryptorProxy.h"
|
#include "GMPDecryptorProxy.h"
|
||||||
#include "GMPService.h"
|
#include "GMPServiceParent.h"
|
||||||
#include "nsAppDirectoryServiceDefs.h"
|
#include "nsAppDirectoryServiceDefs.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsISimpleEnumerator.h"
|
#include "nsISimpleEnumerator.h"
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "nsNSSComponent.h"
|
#include "nsNSSComponent.h"
|
||||||
|
#include "mozilla/DebugOnly.h"
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
#include "mozilla/WindowsVersion.h"
|
#include "mozilla/WindowsVersion.h"
|
||||||
|
@ -27,87 +28,234 @@ using namespace std;
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::gmp;
|
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
|
struct GMPTestRunner
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner)
|
||||||
|
|
||||||
void DoTest(void (GMPTestRunner::*aTestMethod)());
|
void DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&));
|
||||||
void RunTestGMPTestCodec();
|
void RunTestGMPTestCodec1(GMPTestMonitor& aMonitor);
|
||||||
void RunTestGMPCrossOrigin();
|
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:
|
private:
|
||||||
~GMPTestRunner() { }
|
~GMPTestRunner() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
template<class T, class Base,
|
||||||
GMPTestRunner::RunTestGMPTestCodec()
|
nsresult (NS_STDCALL GeckoMediaPluginService::*Getter)(nsTArray<nsCString>*,
|
||||||
|
const nsACString&,
|
||||||
|
UniquePtr<Base>&&)>
|
||||||
|
class RunTestGMPVideoCodec : public Base
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
public:
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
virtual void Done(T* aGMP, GMPVideoHost* aHost)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(aGMP);
|
||||||
|
EXPECT_TRUE(aHost);
|
||||||
|
if (aGMP) {
|
||||||
|
aGMP->Close();
|
||||||
|
}
|
||||||
|
mMonitor.SetFinished();
|
||||||
|
}
|
||||||
|
|
||||||
GMPVideoHost* host = nullptr;
|
static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin)
|
||||||
GMPVideoDecoderProxy* decoder = nullptr;
|
{
|
||||||
GMPVideoDecoderProxy* decoder2 = nullptr;
|
UniquePtr<GMPCallbackType> callback(new RunTestGMPVideoCodec(aMonitor));
|
||||||
GMPVideoEncoderProxy* encoder = nullptr;
|
Get(aOrigin, Move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
nsTArray<nsCString> tags;
|
protected:
|
||||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
typedef T GMPCodecType;
|
||||||
|
typedef Base GMPCallbackType;
|
||||||
|
|
||||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("o"), &host, &decoder2);
|
explicit RunTestGMPVideoCodec(GMPTestMonitor& aMonitor)
|
||||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING(""), &host, &decoder);
|
: 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);
|
nsRefPtr<GeckoMediaPluginService> service =
|
||||||
EXPECT_TRUE(decoder);
|
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||||
EXPECT_TRUE(decoder2);
|
return ((*service).*Getter)(&tags, aNodeId, Move(aCallback));
|
||||||
EXPECT_TRUE(encoder);
|
}
|
||||||
|
|
||||||
if (decoder) decoder->Close();
|
protected:
|
||||||
if (decoder2) decoder2->Close();
|
GMPTestMonitor& mMonitor;
|
||||||
if (encoder) encoder->Close();
|
};
|
||||||
|
|
||||||
|
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
|
void
|
||||||
GMPTestRunner::RunTestGMPCrossOrigin()
|
GMPTestRunner::RunTestGMPTestCodec2(GMPTestMonitor& aMonitor)
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
RunTestGMPVideoDecoder::Run(aMonitor, NS_LITERAL_CSTRING(""));
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
}
|
||||||
|
|
||||||
GMPVideoHost* host = nullptr;
|
void
|
||||||
nsTArray<nsCString> tags;
|
GMPTestRunner::RunTestGMPTestCodec3(GMPTestMonitor& aMonitor)
|
||||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
{
|
||||||
|
RunTestGMPVideoEncoder::Run(aMonitor, NS_LITERAL_CSTRING(""));
|
||||||
|
}
|
||||||
|
|
||||||
GMPVideoDecoderProxy* decoder1 = nullptr;
|
template<class Base>
|
||||||
GMPVideoDecoderProxy* decoder2 = nullptr;
|
class RunTestGMPCrossOrigin : public Base
|
||||||
GMPVideoEncoderProxy* encoder1 = nullptr;
|
{
|
||||||
GMPVideoEncoderProxy* encoder2 = nullptr;
|
public:
|
||||||
|
virtual void Done(typename Base::GMPCodecType* aGMP, GMPVideoHost* aHost)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(aGMP);
|
||||||
|
|
||||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &decoder1);
|
UniquePtr<typename Base::GMPCallbackType> callback(
|
||||||
service->GetGMPVideoDecoder(&tags, NS_LITERAL_CSTRING("origin2"), &host, &decoder2);
|
new Step2(Base::mMonitor, aGMP, mShouldBeEqual));
|
||||||
EXPECT_TRUE(!!decoder1 && !!decoder2 &&
|
nsresult rv = Base::Get(mOrigin2, Move(callback));
|
||||||
decoder1->ParentID() != decoder2->ParentID());
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
Base::mMonitor.SetFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING("origin1"), &host, &encoder1);
|
static void Run(GMPTestMonitor& aMonitor, const nsCString& aOrigin1,
|
||||||
service->GetGMPVideoEncoder(&tags, NS_LITERAL_CSTRING("origin2"), &host, &encoder2);
|
const nsCString& aOrigin2)
|
||||||
EXPECT_TRUE(!!encoder1 && !!encoder2 &&
|
{
|
||||||
encoder1->ParentID() != encoder2->ParentID());
|
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();
|
private:
|
||||||
if (encoder2) encoder2->Close();
|
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);
|
class Step2 : public Base
|
||||||
EXPECT_TRUE(!!decoder1 && !!decoder2 &&
|
{
|
||||||
decoder1->ParentID() == decoder2->ParentID());
|
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);
|
private:
|
||||||
EXPECT_TRUE(!!encoder1 && !!encoder2 &&
|
typename Base::GMPCodecType* mGMP;
|
||||||
encoder1->ParentID() == encoder2->ParentID());
|
bool mShouldBeEqual;
|
||||||
|
};
|
||||||
|
|
||||||
if (decoder1) decoder1->Close();
|
typename Base::GMPCodecType* mGMP;
|
||||||
if (decoder2) decoder2->Close();
|
nsCString mOrigin2;
|
||||||
if (encoder1) encoder1->Close();
|
bool mShouldBeEqual;
|
||||||
if (encoder2) encoder2->Close();
|
};
|
||||||
|
|
||||||
|
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>
|
static already_AddRefed<nsIThread>
|
||||||
|
@ -158,8 +306,8 @@ template<typename T>
|
||||||
static nsresult
|
static nsresult
|
||||||
EnumerateGMPStorageDir(const nsACString& aDir, T&& aDirIter)
|
EnumerateGMPStorageDir(const nsACString& aDir, T&& aDirIter)
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
MOZ_ASSERT(service);
|
MOZ_ASSERT(service);
|
||||||
|
|
||||||
// $profileDir/gmp/
|
// $profileDir/gmp/
|
||||||
|
@ -312,28 +460,53 @@ SimulatePBModeExit()
|
||||||
NS_DispatchToMainThread(new NotifyObserversTask("last-pb-context-exited"), NS_DISPATCH_SYNC);
|
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
|
static nsCString
|
||||||
GetNodeId(const nsAString& aOrigin,
|
GetNodeId(const nsAString& aOrigin,
|
||||||
const nsAString& aTopLevelOrigin,
|
const nsAString& aTopLevelOrigin,
|
||||||
bool aInPBMode)
|
bool aInPBMode)
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
EXPECT_TRUE(service);
|
EXPECT_TRUE(service);
|
||||||
nsCString nodeId;
|
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,
|
nsresult rv = service->GetNodeId(aOrigin,
|
||||||
aTopLevelOrigin,
|
aTopLevelOrigin,
|
||||||
aInPBMode,
|
aInPBMode,
|
||||||
nodeId);
|
Move(callback));
|
||||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
EXPECT_TRUE(NS_SUCCEEDED(rv) && NS_SUCCEEDED(result));
|
||||||
return nodeId;
|
return nodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsGMPStorageIsEmpty()
|
IsGMPStorageIsEmpty()
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
MOZ_ASSERT(service);
|
MOZ_ASSERT(service);
|
||||||
nsCOMPtr<nsIFile> storage;
|
nsCOMPtr<nsIFile> storage;
|
||||||
nsresult rv = service->GetStorageDir(getter_AddRefs(storage));
|
nsresult rv = service->GetStorageDir(getter_AddRefs(storage));
|
||||||
|
@ -437,9 +610,73 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
SetFinished();
|
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,
|
void CreateDecryptor(const nsAString& aOrigin,
|
||||||
const nsAString& aTopLevelOrigin,
|
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 =
|
nsRefPtr<GeckoMediaPluginService> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
||||||
EXPECT_TRUE(service);
|
EXPECT_TRUE(service);
|
||||||
|
@ -450,13 +687,11 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
nsTArray<nsCString> tags;
|
nsTArray<nsCString> tags;
|
||||||
tags.AppendElement(NS_LITERAL_CSTRING("fake"));
|
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(NS_SUCCEEDED(rv));
|
||||||
EXPECT_TRUE(!!mDecryptor);
|
|
||||||
|
|
||||||
if (mDecryptor) {
|
|
||||||
mDecryptor->Init(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestBasicStorage() {
|
void TestBasicStorage() {
|
||||||
|
@ -466,16 +701,16 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginService> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
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.
|
// 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
|
// It sends us a "test-storage complete" message when its passed, or
|
||||||
// some other message if its tests fail.
|
// some other message if its tests fail.
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"),
|
Expect(NS_LITERAL_CSTRING("test-storage complete"),
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
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());
|
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||||
|
|
||||||
// Generate storage data for some site.
|
// Generate storage data for some site.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
|
||||||
NS_LITERAL_STRING("example2.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||||
this, &GMPStorageTest::TestForgetThisSite_AnotherSite);
|
this, &GMPStorageTest::TestForgetThisSite_AnotherSite);
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
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() {
|
void TestForgetThisSite_AnotherSite() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
// Generate storage data for another site.
|
// Generate storage data for another site.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example3.com"),
|
|
||||||
NS_LITERAL_STRING("example4.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||||
this, &GMPStorageTest::TestForgetThisSite_CollectSiteInfo);
|
this, &GMPStorageTest::TestForgetThisSite_CollectSiteInfo);
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
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 {
|
struct NodeInfo {
|
||||||
|
@ -545,8 +780,8 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestForgetThisSite_Forget(nsAutoPtr<NodeInfo> aSiteInfo) {
|
void TestForgetThisSite_Forget(nsAutoPtr<NodeInfo> aSiteInfo) {
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
GeckoMediaPluginServiceParent::GetSingleton();
|
||||||
service->ForgetThisSite(NS_ConvertUTF8toUTF16(aSiteInfo->siteToForget));
|
service->ForgetThisSite(NS_ConvertUTF8toUTF16(aSiteInfo->siteToForget));
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> thread;
|
nsCOMPtr<nsIThread> thread;
|
||||||
|
@ -622,16 +857,15 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||||
|
|
||||||
// Generate storage data for some site.
|
// Generate storage data for some site.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
|
||||||
NS_LITERAL_STRING("example2.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||||
this, &GMPStorageTest::TestClearRecentHistory1_Clear);
|
this, &GMPStorageTest::TestClearRecentHistory1_Clear);
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
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.
|
* 1. Generate some storage data.
|
||||||
|
@ -645,15 +879,14 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||||
|
|
||||||
// Generate storage data for some site.
|
// Generate storage data for some site.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
|
||||||
NS_LITERAL_STRING("example2.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||||
this, &GMPStorageTest::TestClearRecentHistory2_Clear);
|
this, &GMPStorageTest::TestClearRecentHistory2_Clear);
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
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());
|
EXPECT_TRUE(IsGMPStorageIsEmpty());
|
||||||
|
|
||||||
// Generate storage data for some site.
|
// Generate storage data for some site.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example1.com"),
|
|
||||||
NS_LITERAL_STRING("example2.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||||
this, &GMPStorageTest::TestClearRecentHistory3_Clear);
|
this, &GMPStorageTest::TestClearRecentHistory3_Clear);
|
||||||
Expect(NS_LITERAL_CSTRING("test-storage complete"), r);
|
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 {
|
class MaxMTimeFinder {
|
||||||
|
@ -774,12 +1006,6 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
void TestCrossOriginStorage() {
|
void TestCrossOriginStorage() {
|
||||||
EXPECT_TRUE(!mDecryptor);
|
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"
|
// Send the decryptor the message "store recordid $time"
|
||||||
// Wait for the decrytor to send us "stored recordid $time"
|
// Wait for the decrytor to send us "stored recordid $time"
|
||||||
auto t = time(0);
|
auto t = time(0);
|
||||||
|
@ -790,7 +1016,13 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
|
|
||||||
nsCString update("store crossOriginTestRecordId ");
|
nsCString update("store crossOriginTestRecordId ");
|
||||||
update.AppendInt((int64_t)t);
|
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() {
|
void TestCrossOriginStorage_RecordStoredContinuation() {
|
||||||
|
@ -798,87 +1030,102 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
// and try to read the record.
|
// and try to read the record.
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example5.com"),
|
|
||||||
NS_LITERAL_STRING("example6.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
Expect(NS_LITERAL_CSTRING("retrieve crossOriginTestRecordId succeeded (length 0 bytes)"),
|
Expect(NS_LITERAL_CSTRING("retrieve crossOriginTestRecordId succeeded (length 0 bytes)"),
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
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() {
|
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"
|
// Send the decryptor the message "store recordid $time"
|
||||||
// Wait for the decrytor to send us "stored recordid $time"
|
// Wait for the decrytor to send us "stored recordid $time"
|
||||||
nsCString response("stored pbdata test-pb-data");
|
nsCString response("stored pbdata test-pb-data");
|
||||||
Expect(response, NS_NewRunnableMethod(this,
|
Expect(response, NS_NewRunnableMethod(this,
|
||||||
&GMPStorageTest::TestPBStorage_RecordStoredContinuation));
|
&GMPStorageTest::TestPBStorage_RecordStoredContinuation));
|
||||||
|
|
||||||
nsCString update("store pbdata test-pb-data");
|
// Open decryptor on one, origin, write a record, close decryptor,
|
||||||
Update(update);
|
// 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() {
|
void TestPBStorage_RecordStoredContinuation() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
|
||||||
NS_LITERAL_STRING("pb2.com"),
|
|
||||||
true);
|
|
||||||
|
|
||||||
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 12 bytes)"),
|
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 12 bytes)"),
|
||||||
NS_NewRunnableMethod(this,
|
NS_NewRunnableMethod(this,
|
||||||
&GMPStorageTest::TestPBStorage_RecordRetrievedContinuation));
|
&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() {
|
void TestPBStorage_RecordRetrievedContinuation() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
SimulatePBModeExit();
|
SimulatePBModeExit();
|
||||||
|
|
||||||
CreateDecryptor(NS_LITERAL_STRING("pb1.com"),
|
|
||||||
NS_LITERAL_STRING("pb2.com"),
|
|
||||||
true);
|
|
||||||
|
|
||||||
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 0 bytes)"),
|
Expect(NS_LITERAL_CSTRING("retrieve pbdata succeeded (length 0 bytes)"),
|
||||||
NS_NewRunnableMethod(this,
|
NS_NewRunnableMethod(this,
|
||||||
&GMPStorageTest::SetFinished));
|
&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,
|
void CreateAsyncShutdownTimeoutGMP(const nsAString& aOrigin1,
|
||||||
const nsAString& aOrigin2) {
|
const nsAString& aOrigin2,
|
||||||
CreateDecryptor(aOrigin1, aOrigin2, false);
|
void (GMPStorageTest::*aCallback)()) {
|
||||||
Update(NS_LITERAL_CSTRING("shutdown-mode timeout"));
|
nsCOMPtr<nsIRunnable> continuation(
|
||||||
Shutdown();
|
NS_NewRunnableMethodWithArg<nsCOMPtr<nsIRunnable>>(
|
||||||
|
this,
|
||||||
|
&GMPStorageTest::NextAsyncShutdownTimeoutTest,
|
||||||
|
NS_NewRunnableMethod(this, aCallback)));
|
||||||
|
|
||||||
|
CreateDecryptor(aOrigin1, aOrigin2, false, continuation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestAsyncShutdownTimeout() {
|
void TestAsyncShutdownTimeout() {
|
||||||
// Create decryptors that timeout in their async shutdown.
|
// Create decryptors that timeout in their async shutdown.
|
||||||
// If the gtest hangs on shutdown, test fails!
|
// If the gtest hangs on shutdown, test fails!
|
||||||
CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("example7.com"),
|
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"),
|
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"),
|
CreateAsyncShutdownTimeoutGMP(NS_LITERAL_STRING("example11.com"),
|
||||||
NS_LITERAL_STRING("example12.com"));
|
NS_LITERAL_STRING("example12.com"),
|
||||||
SetFinished();
|
&GMPStorageTest::SetFinished);
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestAsyncShutdownStorage() {
|
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
|
// Instruct the GMP to write a token (the current timestamp, so it's
|
||||||
// unique) during async shutdown, then shutdown the plugin, re-create
|
// unique) during async shutdown, then shutdown the plugin, re-create
|
||||||
// it, and check that the token was successfully stored.
|
// it, and check that the token was successfully stored.
|
||||||
|
@ -895,7 +1142,12 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
Expect(response, NS_NewRunnableMethodWithArg<nsCString>(this,
|
Expect(response, NS_NewRunnableMethodWithArg<nsCString>(this,
|
||||||
&GMPStorageTest::TestAsyncShutdownStorage_ReceivedShutdownToken, token));
|
&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) {
|
void TestAsyncShutdownStorage_ReceivedShutdownToken(const nsCString& aToken) {
|
||||||
|
@ -906,37 +1158,39 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
void TestAsyncShutdownStorage_AsyncShutdownComplete(const nsCString& aToken) {
|
void TestAsyncShutdownStorage_AsyncShutdownComplete(const nsCString& aToken) {
|
||||||
// Create a new instance of the plugin, retrieve the token written
|
// Create a new instance of the plugin, retrieve the token written
|
||||||
// during shutdown and verify it is correct.
|
// during shutdown and verify it is correct.
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example13.com"),
|
|
||||||
NS_LITERAL_STRING("example14.com"),
|
|
||||||
false);
|
|
||||||
nsCString response("retrieved shutdown-token ");
|
nsCString response("retrieved shutdown-token ");
|
||||||
response.Append(aToken);
|
response.Append(aToken);
|
||||||
Expect(response,
|
Expect(response,
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
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)
|
#if defined(XP_WIN)
|
||||||
void TestOutputProtection() {
|
void TestOutputProtection() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
CreateDecryptor(NS_LITERAL_STRING("example15.com"),
|
|
||||||
NS_LITERAL_STRING("example16.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
Expect(NS_LITERAL_CSTRING("OP tests completed"),
|
Expect(NS_LITERAL_CSTRING("OP tests completed"),
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
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
|
#endif
|
||||||
|
|
||||||
void TestPluginVoucher() {
|
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"),
|
Expect(NS_LITERAL_CSTRING("retrieved plugin-voucher: gmp-fake placeholder voucher"),
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
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() {
|
void TestGetRecordNamesInMemoryStorage() {
|
||||||
|
@ -953,12 +1207,9 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGetRecordNames(bool aPrivateBrowsing) {
|
void TestGetRecordNames(bool aPrivateBrowsing) {
|
||||||
CreateDecryptor(NS_LITERAL_STRING("foo.com"),
|
|
||||||
NS_LITERAL_STRING("bar.com"),
|
|
||||||
aPrivateBrowsing);
|
|
||||||
|
|
||||||
// Create a number of records of different names.
|
// Create a number of records of different names.
|
||||||
const uint32_t num = 100;
|
const uint32_t num = 100;
|
||||||
|
nsTArray<nsCString> updates(num);
|
||||||
for (uint32_t i = 0; i < num; i++) {
|
for (uint32_t i = 0; i < num; i++) {
|
||||||
nsAutoCString response;
|
nsAutoCString response;
|
||||||
response.AppendLiteral("stored data");
|
response.AppendLiteral("stored data");
|
||||||
|
@ -972,7 +1223,7 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
mRecordNames.AppendLiteral("data");
|
mRecordNames.AppendLiteral("data");
|
||||||
AppendIntPadded(mRecordNames, i);
|
AppendIntPadded(mRecordNames, i);
|
||||||
|
|
||||||
nsAutoCString update;
|
nsCString& update = *updates.AppendElement();
|
||||||
update.AppendLiteral("store data");
|
update.AppendLiteral("store data");
|
||||||
AppendIntPadded(update, i);
|
AppendIntPadded(update, i);
|
||||||
update.AppendLiteral(" test-data");
|
update.AppendLiteral(" test-data");
|
||||||
|
@ -984,8 +1235,12 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
NS_NewRunnableMethod(this, &GMPStorageTest::TestGetRecordNames_QueryNames);
|
NS_NewRunnableMethod(this, &GMPStorageTest::TestGetRecordNames_QueryNames);
|
||||||
}
|
}
|
||||||
Expect(response, continuation);
|
Expect(response, continuation);
|
||||||
Update(update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateDecryptor(NS_LITERAL_STRING("foo.com"),
|
||||||
|
NS_LITERAL_STRING("bar.com"),
|
||||||
|
aPrivateBrowsing,
|
||||||
|
Move(updates));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGetRecordNames_QueryNames() {
|
void TestGetRecordNames_QueryNames() {
|
||||||
|
@ -1025,10 +1280,6 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
MOZ_ASSERT(longRecordName.Length() < GMP_MAX_RECORD_NAME_SIZE);
|
MOZ_ASSERT(longRecordName.Length() < GMP_MAX_RECORD_NAME_SIZE);
|
||||||
MOZ_ASSERT(longRecordName.Length() > 260); // Windows MAX_PATH
|
MOZ_ASSERT(longRecordName.Length() > 260); // Windows MAX_PATH
|
||||||
|
|
||||||
CreateDecryptor(NS_LITERAL_STRING("fuz.com"),
|
|
||||||
NS_LITERAL_STRING("baz.com"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
nsCString response("stored ");
|
nsCString response("stored ");
|
||||||
response.Append(longRecordName);
|
response.Append(longRecordName);
|
||||||
response.AppendLiteral(" ");
|
response.AppendLiteral(" ");
|
||||||
|
@ -1039,7 +1290,10 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||||
update.Append(longRecordName);
|
update.Append(longRecordName);
|
||||||
update.AppendLiteral(" ");
|
update.AppendLiteral(" ");
|
||||||
update.Append(data);
|
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) {
|
void Expect(const nsCString& aMessage, nsIRunnable* aContinuation) {
|
||||||
|
@ -1146,24 +1400,31 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
GMPTestRunner::DoTest(void (GMPTestRunner::*aTestMethod)())
|
GMPTestRunner::DoTest(void (GMPTestRunner::*aTestMethod)(GMPTestMonitor&))
|
||||||
{
|
{
|
||||||
nsRefPtr<GeckoMediaPluginService> service =
|
nsCOMPtr<nsIThread> thread(GetGMPThread());
|
||||||
GeckoMediaPluginService::GetGeckoMediaPluginService();
|
|
||||||
nsCOMPtr<nsIThread> thread;
|
|
||||||
|
|
||||||
service->GetThread(getter_AddRefs(thread));
|
GMPTestMonitor monitor;
|
||||||
thread->Dispatch(NS_NewRunnableMethod(this, aTestMethod), NS_DISPATCH_SYNC);
|
thread->Dispatch(NS_NewRunnableMethodWithArg<GMPTestMonitor&>(this,
|
||||||
|
aTestMethod,
|
||||||
|
monitor),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
monitor.AwaitFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GeckoMediaPlugins, GMPTestCodec) {
|
TEST(GeckoMediaPlugins, GMPTestCodec) {
|
||||||
nsRefPtr<GMPTestRunner> runner = new GMPTestRunner();
|
nsRefPtr<GMPTestRunner> runner = new GMPTestRunner();
|
||||||
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec);
|
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec1);
|
||||||
|
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec2);
|
||||||
|
runner->DoTest(&GMPTestRunner::RunTestGMPTestCodec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GeckoMediaPlugins, GMPCrossOrigin) {
|
TEST(GeckoMediaPlugins, GMPCrossOrigin) {
|
||||||
nsRefPtr<GMPTestRunner> runner = new GMPTestRunner();
|
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) {
|
TEST(GeckoMediaPlugins, GMPStorageGetNodeId) {
|
||||||
|
|
|
@ -371,22 +371,22 @@ skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
|
||||||
[test_dormant_playback.html]
|
[test_dormant_playback.html]
|
||||||
skip-if = (os == 'win' && os_version == '5.1') || (os != 'win' && toolkit != 'gonk')
|
skip-if = (os == 'win' && os_version == '5.1') || (os != 'win' && toolkit != 'gonk')
|
||||||
[test_eme_canvas_blocked.html]
|
[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]
|
[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]
|
#[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
|
# 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
|
# 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.
|
# in future however, so I'm not removing the test, just disabling it.
|
||||||
[test_eme_persistent_sessions.html]
|
[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]
|
[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]
|
[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]
|
[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_empty_resource.html]
|
||||||
[test_error_in_video_document.html]
|
[test_error_in_video_document.html]
|
||||||
skip-if = toolkit == 'android' || (os == 'win' && !debug) || (os == 'mac' && !debug) # bug 608634
|
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);
|
is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount);
|
||||||
|
|
||||||
// Focus the window.
|
// Focus the window.
|
||||||
window.focus();
|
SpecialPowers.focus(window);
|
||||||
|
|
||||||
is(plugin1.getFocusState(), true, "(3) Plugin should still have focus.");
|
is(plugin1.getFocusState(), true, "(3) Plugin should still have focus.");
|
||||||
is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount);
|
is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount);
|
||||||
|
|
|
@ -38,13 +38,12 @@ NS_NewXBLContentSink(nsIXMLContentSink** aResult,
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aResult);
|
NS_ENSURE_ARG_POINTER(aResult);
|
||||||
|
|
||||||
nsXBLContentSink* it = new nsXBLContentSink();
|
nsRefPtr<nsXBLContentSink> it = new nsXBLContentSink();
|
||||||
|
|
||||||
nsCOMPtr<nsIXMLContentSink> kungFuDeathGrip = it;
|
|
||||||
nsresult rv = it->Init(aDoc, aURI, aContainer);
|
nsresult rv = it->Init(aDoc, aURI, aContainer);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return CallQueryInterface(it, aResult);
|
it.forget(aResult);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXBLContentSink::nsXBLContentSink()
|
nsXBLContentSink::nsXBLContentSink()
|
||||||
|
|
|
@ -86,13 +86,13 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
|
||||||
if (nullptr == aResult) {
|
if (nullptr == aResult) {
|
||||||
return NS_ERROR_NULL_POINTER;
|
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);
|
nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return CallQueryInterface(it, aResult);
|
it.forget(aResult);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXMLContentSink::nsXMLContentSink()
|
nsXMLContentSink::nsXMLContentSink()
|
||||||
|
|
|
@ -172,7 +172,7 @@ nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindow** aWindow)
|
||||||
if (domdoc && !nsContentUtils::CanCallerAccess(domdoc))
|
if (domdoc && !nsContentUtils::CanCallerAccess(domdoc))
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
|
||||||
CallQueryInterface(window, aWindow);
|
window.forget(aWindow);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1314,14 +1314,14 @@ nsXULTemplateQueryProcessorRDF::ParseLiteral(const nsString& aParseType,
|
||||||
rv = gRDFService->GetIntLiteral(intValue, getter_AddRefs(intLiteral));
|
rv = gRDFService->GetIntLiteral(intValue, getter_AddRefs(intLiteral));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
rv = CallQueryInterface(intLiteral, aResult);
|
intLiteral.forget(aResult);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nsCOMPtr<nsIRDFLiteral> literal;
|
nsCOMPtr<nsIRDFLiteral> literal;
|
||||||
rv = gRDFService->GetLiteral(aValue.get(), getter_AddRefs(literal));
|
rv = gRDFService->GetLiteral(aValue.get(), getter_AddRefs(literal));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
rv = CallQueryInterface(literal, aResult);
|
literal.forget(aResult);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -628,6 +628,9 @@ APZCCallbackHelper::SendSetTargetAPZCNotification(nsIWidget* aWidget,
|
||||||
uint64_t aInputBlockId,
|
uint64_t aInputBlockId,
|
||||||
const nsRefPtr<SetTargetAPZCCallback>& aCallback)
|
const nsRefPtr<SetTargetAPZCCallback>& aCallback)
|
||||||
{
|
{
|
||||||
|
if (!aWidget || !aDocument) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (nsIPresShell* shell = aDocument->GetShell()) {
|
if (nsIPresShell* shell = aDocument->GetShell()) {
|
||||||
if (nsIFrame* rootFrame = shell->GetRootFrame()) {
|
if (nsIFrame* rootFrame = shell->GetRootFrame()) {
|
||||||
bool waitForRefresh = false;
|
bool waitForRefresh = false;
|
||||||
|
|
|
@ -615,7 +615,7 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread)
|
||||||
}
|
}
|
||||||
sImageBridgeChildSingleton = new ImageBridgeChild();
|
sImageBridgeChildSingleton = new ImageBridgeChild();
|
||||||
sImageBridgeParentSingleton = new ImageBridgeParent(
|
sImageBridgeParentSingleton = new ImageBridgeParent(
|
||||||
CompositorParent::CompositorLoop(), nullptr, ipc::kCurrentProcessId);
|
CompositorParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
|
||||||
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
|
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -943,7 +943,7 @@ void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
|
||||||
|
|
||||||
bool ImageBridgeChild::IsSameProcess() const
|
bool ImageBridgeChild::IsSameProcess() const
|
||||||
{
|
{
|
||||||
return OtherPid() == ipc::kCurrentProcessId;
|
return OtherPid() == base::GetCurrentProcId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageBridgeChild::SendPendingAsyncMessges()
|
void ImageBridgeChild::SendPendingAsyncMessges()
|
||||||
|
|
|
@ -340,7 +340,7 @@ ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds
|
||||||
|
|
||||||
bool ImageBridgeParent::IsSameProcess() const
|
bool ImageBridgeParent::IsSameProcess() const
|
||||||
{
|
{
|
||||||
return OtherPid() == ipc::kCurrentProcessId;
|
return OtherPid() == base::GetCurrentProcId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -976,7 +976,7 @@ LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
|
||||||
|
|
||||||
bool LayerTransactionParent::IsSameProcess() const
|
bool LayerTransactionParent::IsSameProcess() const
|
||||||
{
|
{
|
||||||
return OtherPid() == ipc::kCurrentProcessId;
|
return OtherPid() == base::GetCurrentProcId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -738,7 +738,7 @@ ShadowLayerForwarder::IsSameProcess() const
|
||||||
if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
|
if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mShadowManager->OtherPid() == kCurrentProcessId;
|
return mShadowManager->OtherPid() == base::GetCurrentProcId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -141,7 +141,8 @@ static nsresult EncodeImageData(DataSourceSurface* aDataSurface,
|
||||||
aDataSurface->Unmap();
|
aDataSurface->Unmap();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return CallQueryInterface(encoder, aStream);
|
encoder.forget(aStream);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
|
NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
|
||||||
|
|
|
@ -1957,7 +1957,7 @@ ChildImpl::OpenMainProcessActorRunnable::Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the parent knows it is same process.
|
// 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.
|
// Now that Open() has succeeded transfer the ownership of the actors to IPDL.
|
||||||
unused << parentActor.forget();
|
unused << parentActor.forget();
|
||||||
|
|
|
@ -265,7 +265,7 @@ bool DuplicateHandle(HANDLE aSourceHandle,
|
||||||
DWORD aDesiredAccess,
|
DWORD aDesiredAccess,
|
||||||
DWORD aOptions) {
|
DWORD aOptions) {
|
||||||
// If our process is the target just duplicate the handle.
|
// If our process is the target just duplicate the handle.
|
||||||
if (aTargetProcessId == kCurrentProcessId) {
|
if (aTargetProcessId == base::GetCurrentProcId()) {
|
||||||
return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
|
return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
|
||||||
::GetCurrentProcess(), aTargetHandle,
|
::GetCurrentProcess(), aTargetHandle,
|
||||||
aDesiredAccess, false, aOptions);
|
aDesiredAccess, false, aOptions);
|
||||||
|
@ -318,7 +318,7 @@ FatalError(const char* aProtocolName, const char* aMsg,
|
||||||
formattedMessage.AppendLiteral("\". Killing child side as a result.");
|
formattedMessage.AppendLiteral("\". Killing child side as a result.");
|
||||||
NS_ERROR(formattedMessage.get());
|
NS_ERROR(formattedMessage.get());
|
||||||
|
|
||||||
if (aOtherPid != kInvalidProcessId && aOtherPid != kCurrentProcessId) {
|
if (aOtherPid != kInvalidProcessId && aOtherPid != base::GetCurrentProcId()) {
|
||||||
ScopedProcessHandle otherProcessHandle;
|
ScopedProcessHandle otherProcessHandle;
|
||||||
if (base::OpenProcessHandle(aOtherPid, &otherProcessHandle.rwget())) {
|
if (base::OpenProcessHandle(aOtherPid, &otherProcessHandle.rwget())) {
|
||||||
if (!base::KillProcess(otherProcessHandle,
|
if (!base::KillProcess(otherProcessHandle,
|
||||||
|
|
|
@ -72,7 +72,6 @@ const base::ProcessId kInvalidProcessId = kuint32max;
|
||||||
const base::ProcessHandle kInvalidProcessHandle = -1;
|
const base::ProcessHandle kInvalidProcessHandle = -1;
|
||||||
const base::ProcessId kInvalidProcessId = -1;
|
const base::ProcessId kInvalidProcessId = -1;
|
||||||
#endif
|
#endif
|
||||||
const base::ProcessId kCurrentProcessId = base::GetCurrentProcId();
|
|
||||||
|
|
||||||
// Scoped base::ProcessHandle to ensure base::CloseProcessHandle is called.
|
// Scoped base::ProcessHandle to ensure base::CloseProcessHandle is called.
|
||||||
struct ScopedProcessHandleTraits
|
struct ScopedProcessHandleTraits
|
||||||
|
|
|
@ -185,7 +185,7 @@ class CxxCodeGen(CodePrinter, Visitor):
|
||||||
|
|
||||||
if md.inline:
|
if md.inline:
|
||||||
self.write('inline ')
|
self.write('inline ')
|
||||||
if md.inline:
|
if md.never_inline:
|
||||||
self.write('MOZ_NEVER_INLINE ')
|
self.write('MOZ_NEVER_INLINE ')
|
||||||
if md.static:
|
if md.static:
|
||||||
self.write('static ')
|
self.write('static ')
|
||||||
|
|
|
@ -3005,7 +3005,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||||
ret=Type.BOOL))
|
ret=Type.BOOL))
|
||||||
|
|
||||||
openmeth.addstmts([
|
openmeth.addstmts([
|
||||||
StmtExpr(ExprAssn(p.otherPidVar(), ExprVar('ipc::kCurrentProcessId'))),
|
StmtExpr(ExprAssn(p.otherPidVar(), ExprCall(ExprVar('base::GetCurrentProcId')))),
|
||||||
StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
|
StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
|
||||||
[ aChannel, aMessageLoop, sidevar ]))
|
[ aChannel, aMessageLoop, sidevar ]))
|
||||||
])
|
])
|
||||||
|
|
|
@ -19,7 +19,7 @@ bool
|
||||||
IPDLUnitTestProcessChild::Init()
|
IPDLUnitTestProcessChild::Init()
|
||||||
{
|
{
|
||||||
IPDLUnitTestChildInit(IOThreadChild::channel(),
|
IPDLUnitTestChildInit(IOThreadChild::channel(),
|
||||||
ParentId(),
|
ParentPid(),
|
||||||
IOThreadChild::message_loop());
|
IOThreadChild::message_loop());
|
||||||
|
|
||||||
if (NS_FAILED(nsRegion::InitStatic()))
|
if (NS_FAILED(nsRegion::InitStatic()))
|
||||||
|
|
|
@ -181,7 +181,7 @@ ${PARENT_ENABLED_CASES_PROC}
|
||||||
if (!transport)
|
if (!transport)
|
||||||
fail("no transport");
|
fail("no transport");
|
||||||
|
|
||||||
base::ProcessHandle child = gSubprocess->GetChildProcessHandle();
|
base::ProcessId child = base::GetProcId(gSubprocess->GetChildProcessHandle());
|
||||||
|
|
||||||
switch (test) {
|
switch (test) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -27,15 +27,10 @@ TestBridgeMainParent::Main()
|
||||||
|
|
||||||
PTestBridgeMainSubParent*
|
PTestBridgeMainSubParent*
|
||||||
TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
|
TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
|
||||||
ProcessId otherProcess)
|
ProcessId otherPid)
|
||||||
{
|
{
|
||||||
ProcessHandle h;
|
|
||||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
|
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 nullptr;
|
||||||
}
|
}
|
||||||
return a.forget();
|
return a.forget();
|
||||||
|
@ -110,7 +105,7 @@ TestBridgeMainChild::RecvStart()
|
||||||
fail("no transport");
|
fail("no transport");
|
||||||
|
|
||||||
TestBridgeSubParent* bsp = new TestBridgeSubParent();
|
TestBridgeSubParent* bsp = new TestBridgeSubParent();
|
||||||
bsp->Open(transport, mSubprocess->GetChildProcessHandle());
|
bsp->Open(transport, base::GetProcId(mSubprocess->GetChildProcessHandle()));
|
||||||
|
|
||||||
bsp->Main();
|
bsp->Main();
|
||||||
return true;
|
return true;
|
||||||
|
@ -178,15 +173,10 @@ TestBridgeSubChild::RecvPing()
|
||||||
|
|
||||||
PTestBridgeMainSubChild*
|
PTestBridgeMainSubChild*
|
||||||
TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
|
TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
|
||||||
ProcessId otherProcess)
|
ProcessId otherPid)
|
||||||
{
|
{
|
||||||
ProcessHandle h;
|
|
||||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -494,7 +494,7 @@ TestDataStructuresChild::RecvStart()
|
||||||
Test15();
|
Test15();
|
||||||
Test16();
|
Test16();
|
||||||
Test17();
|
Test17();
|
||||||
if (OtherProcess() != 0) {
|
if (OtherPid() != base::GetCurrentProcId()) {
|
||||||
//FIXME/bug 703317 allocation of nsIntRegion uses a global
|
//FIXME/bug 703317 allocation of nsIntRegion uses a global
|
||||||
//region pool which breaks threads
|
//region pool which breaks threads
|
||||||
Test18();
|
Test18();
|
||||||
|
|
|
@ -110,7 +110,7 @@ TestFailedCtorChild::DeallocPTestFailedCtorSubChild(PTestFailedCtorSubChild* act
|
||||||
void
|
void
|
||||||
TestFailedCtorChild::ProcessingError(Result aCode, const char* aReason)
|
TestFailedCtorChild::ProcessingError(Result aCode, const char* aReason)
|
||||||
{
|
{
|
||||||
if (OtherProcess() != 0) // thread-mode
|
if (OtherPid() != base::GetCurrentProcId()) // thread-mode
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,14 @@ TestHangsParent::AnswerStackFrame()
|
||||||
void
|
void
|
||||||
TestHangsParent::CleanUp()
|
TestHangsParent::CleanUp()
|
||||||
{
|
{
|
||||||
if (!KillProcess(OtherProcess(), 0, false))
|
ipc::ScopedProcessHandle otherProcessHandle;
|
||||||
fail("terminating child process");
|
if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) {
|
||||||
|
fail("couldn't open child process");
|
||||||
|
} else {
|
||||||
|
if (!KillProcess(otherProcessHandle, 0, false)) {
|
||||||
|
fail("terminating child process");
|
||||||
|
}
|
||||||
|
}
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,29 +54,24 @@ TestOpensParent::Main()
|
||||||
|
|
||||||
static void
|
static void
|
||||||
OpenParent(TestOpensOpenedParent* aParent,
|
OpenParent(TestOpensOpenedParent* aParent,
|
||||||
Transport* aTransport, ProcessHandle aOtherProcess)
|
Transport* aTransport, base::ProcessId aOtherPid)
|
||||||
{
|
{
|
||||||
AssertNotMainThread();
|
AssertNotMainThread();
|
||||||
|
|
||||||
// Open the actor on the off-main thread to park it there.
|
// Open the actor on the off-main thread to park it there.
|
||||||
// Messages will be delivered to this thread's message loop
|
// Messages will be delivered to this thread's message loop
|
||||||
// instead of the main thread's.
|
// instead of the main thread's.
|
||||||
if (!aParent->Open(aTransport, aOtherProcess,
|
if (!aParent->Open(aTransport, aOtherPid,
|
||||||
XRE_GetIOMessageLoop(), ipc::ParentSide))
|
XRE_GetIOMessageLoop(), ipc::ParentSide))
|
||||||
fail("opening Parent");
|
fail("opening Parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
PTestOpensOpenedParent*
|
PTestOpensOpenedParent*
|
||||||
TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
|
TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
|
||||||
ProcessId otherProcess)
|
ProcessId otherPid)
|
||||||
{
|
{
|
||||||
gMainThread = MessageLoop::current();
|
gMainThread = MessageLoop::current();
|
||||||
|
|
||||||
ProcessHandle h;
|
|
||||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
gParentThread = new Thread("ParentThread");
|
gParentThread = new Thread("ParentThread");
|
||||||
if (!gParentThread->Start())
|
if (!gParentThread->Start())
|
||||||
fail("starting parent thread");
|
fail("starting parent thread");
|
||||||
|
@ -84,7 +79,7 @@ TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
|
||||||
TestOpensOpenedParent* a = new TestOpensOpenedParent(transport);
|
TestOpensOpenedParent* a = new TestOpensOpenedParent(transport);
|
||||||
gParentThread->message_loop()->PostTask(
|
gParentThread->message_loop()->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
NewRunnableFunction(OpenParent, a, transport, h));
|
NewRunnableFunction(OpenParent, a, transport, otherPid));
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -174,14 +169,14 @@ TestOpensChild::RecvStart()
|
||||||
|
|
||||||
static void
|
static void
|
||||||
OpenChild(TestOpensOpenedChild* aChild,
|
OpenChild(TestOpensOpenedChild* aChild,
|
||||||
Transport* aTransport, ProcessHandle aOtherProcess)
|
Transport* aTransport, base::ProcessId aOtherPid)
|
||||||
{
|
{
|
||||||
AssertNotMainThread();
|
AssertNotMainThread();
|
||||||
|
|
||||||
// Open the actor on the off-main thread to park it there.
|
// Open the actor on the off-main thread to park it there.
|
||||||
// Messages will be delivered to this thread's message loop
|
// Messages will be delivered to this thread's message loop
|
||||||
// instead of the main thread's.
|
// instead of the main thread's.
|
||||||
if (!aChild->Open(aTransport, aOtherProcess,
|
if (!aChild->Open(aTransport, aOtherPid,
|
||||||
XRE_GetIOMessageLoop(), ipc::ChildSide))
|
XRE_GetIOMessageLoop(), ipc::ChildSide))
|
||||||
fail("opening Child");
|
fail("opening Child");
|
||||||
|
|
||||||
|
@ -192,15 +187,10 @@ OpenChild(TestOpensOpenedChild* aChild,
|
||||||
|
|
||||||
PTestOpensOpenedChild*
|
PTestOpensOpenedChild*
|
||||||
TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
|
TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
|
||||||
ProcessId otherProcess)
|
ProcessId otherPid)
|
||||||
{
|
{
|
||||||
gMainThread = MessageLoop::current();
|
gMainThread = MessageLoop::current();
|
||||||
|
|
||||||
ProcessHandle h;
|
|
||||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
gChildThread = new Thread("ChildThread");
|
gChildThread = new Thread("ChildThread");
|
||||||
if (!gChildThread->Start())
|
if (!gChildThread->Start())
|
||||||
fail("starting child thread");
|
fail("starting child thread");
|
||||||
|
@ -208,7 +198,7 @@ TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
|
||||||
TestOpensOpenedChild* a = new TestOpensOpenedChild(transport);
|
TestOpensOpenedChild* a = new TestOpensOpenedChild(transport);
|
||||||
gChildThread->message_loop()->PostTask(
|
gChildThread->message_loop()->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
NewRunnableFunction(OpenChild, a, transport, h));
|
NewRunnableFunction(OpenChild, a, transport, otherPid));
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ def main(argv):
|
||||||
%sChild** child =
|
%sChild** child =
|
||||||
reinterpret_cast<%sChild**>(&gChildActor);
|
reinterpret_cast<%sChild**>(&gChildActor);
|
||||||
*child = new %sChild();
|
*child = new %sChild();
|
||||||
(*child)->Open(transport, parent, worker);
|
(*child)->Open(transport, parentPid, worker);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
'''% (t, t, t, t) for t in unittests+extras ])
|
'''% (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) {
|
void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
|
||||||
const char* side, *objDesc;
|
const char* side;
|
||||||
|
const char* objDesc;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
|
|
||||||
if (local == incoming) {
|
if (local == incoming) {
|
||||||
|
|
|
@ -870,7 +870,8 @@ class HashTable : private AllocPolicy
|
||||||
++cur;
|
++cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry* cur, *end;
|
Entry* cur;
|
||||||
|
Entry* end;
|
||||||
#ifdef JS_DEBUG
|
#ifdef JS_DEBUG
|
||||||
const HashTable* table_;
|
const HashTable* table_;
|
||||||
uint64_t mutationCount;
|
uint64_t mutationCount;
|
||||||
|
@ -1090,7 +1091,8 @@ class HashTable : private AllocPolicy
|
||||||
|
|
||||||
static void destroyTable(AllocPolicy& alloc, Entry* oldTable, uint32_t capacity)
|
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();
|
e->destroyIfLive();
|
||||||
alloc.free_(oldTable);
|
alloc.free_(oldTable);
|
||||||
}
|
}
|
||||||
|
@ -1346,7 +1348,8 @@ class HashTable : private AllocPolicy
|
||||||
table = newTable;
|
table = newTable;
|
||||||
|
|
||||||
// Copy only live entries, leaving removed ones behind.
|
// 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()) {
|
if (src->isLive()) {
|
||||||
HashNumber hn = src->getKeyHash();
|
HashNumber hn = src->getKeyHash();
|
||||||
findFreeEntry(hn).setLive(
|
findFreeEntry(hn).setLive(
|
||||||
|
@ -1480,7 +1483,8 @@ class HashTable : private AllocPolicy
|
||||||
memset(table, 0, sizeof(*table) * capacity());
|
memset(table, 0, sizeof(*table) * capacity());
|
||||||
} else {
|
} else {
|
||||||
uint32_t tableCapacity = capacity();
|
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();
|
e->clear();
|
||||||
}
|
}
|
||||||
removedCount = 0;
|
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
|
* example, Rooted<JSObject> and Rooted<JSFunction>, which use the same
|
||||||
* stack head pointer for different classes.
|
* 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
|
* |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())
|
if (!condType.isInt())
|
||||||
return f.failf(cond, "%s is not a subtype of int", condType.toChars());
|
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))
|
if (!f.branchAndStartThen(condDef, &thenBlock, &elseBlock, thenExpr, elseExpr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -6482,7 +6483,8 @@ CheckAddOrSub(FunctionCompiler& f, ParseNode* expr, MDefinition** def, Type* typ
|
||||||
ParseNode* lhs = AddSubLeft(expr);
|
ParseNode* lhs = AddSubLeft(expr);
|
||||||
ParseNode* rhs = AddSubRight(expr);
|
ParseNode* rhs = AddSubRight(expr);
|
||||||
|
|
||||||
MDefinition* lhsDef, *rhsDef;
|
MDefinition* lhsDef;
|
||||||
|
MDefinition* rhsDef;
|
||||||
Type lhsType, rhsType;
|
Type lhsType, rhsType;
|
||||||
unsigned lhsNumAddOrSub, rhsNumAddOrSub;
|
unsigned lhsNumAddOrSub, rhsNumAddOrSub;
|
||||||
|
|
||||||
|
@ -6545,7 +6547,8 @@ CheckDivOrMod(FunctionCompiler& f, ParseNode* expr, MDefinition** def, Type* typ
|
||||||
ParseNode* lhs = DivOrModLeft(expr);
|
ParseNode* lhs = DivOrModLeft(expr);
|
||||||
ParseNode* rhs = DivOrModRight(expr);
|
ParseNode* rhs = DivOrModRight(expr);
|
||||||
|
|
||||||
MDefinition* lhsDef, *rhsDef;
|
MDefinition* lhsDef;
|
||||||
|
MDefinition* rhsDef;
|
||||||
Type lhsType, rhsType;
|
Type lhsType, rhsType;
|
||||||
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6600,7 +6603,8 @@ CheckComparison(FunctionCompiler& f, ParseNode* comp, MDefinition** def, Type* t
|
||||||
ParseNode* lhs = ComparisonLeft(comp);
|
ParseNode* lhs = ComparisonLeft(comp);
|
||||||
ParseNode* rhs = ComparisonRight(comp);
|
ParseNode* rhs = ComparisonRight(comp);
|
||||||
|
|
||||||
MDefinition* lhsDef, *rhsDef;
|
MDefinition* lhsDef;
|
||||||
|
MDefinition* rhsDef;
|
||||||
Type lhsType, rhsType;
|
Type lhsType, rhsType;
|
||||||
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6947,9 +6951,12 @@ CheckIfConditional(FunctionCompiler& f, ParseNode* conditional, ParseNode* thenS
|
||||||
ParseNode* lhs = TernaryKid2(conditional);
|
ParseNode* lhs = TernaryKid2(conditional);
|
||||||
ParseNode* rhs = TernaryKid3(conditional);
|
ParseNode* rhs = TernaryKid3(conditional);
|
||||||
|
|
||||||
MBasicBlock* maybeAndTest = nullptr, *maybeOrTest = nullptr;
|
MBasicBlock* maybeAndTest = nullptr;
|
||||||
MBasicBlock** ifTrueBlock = &maybeAndTest, **ifFalseBlock = &maybeOrTest;
|
MBasicBlock* maybeOrTest = nullptr;
|
||||||
ParseNode* ifTrueBlockNode = lhs, *ifFalseBlockNode = rhs;
|
MBasicBlock** ifTrueBlock = &maybeAndTest;
|
||||||
|
MBasicBlock** ifFalseBlock = &maybeOrTest;
|
||||||
|
ParseNode* ifTrueBlockNode = lhs;
|
||||||
|
ParseNode* ifFalseBlockNode = rhs;
|
||||||
|
|
||||||
// Try to spot opportunities for short-circuiting in the AND subpart
|
// Try to spot opportunities for short-circuiting in the AND subpart
|
||||||
uint32_t andTestLiteral = 0;
|
uint32_t andTestLiteral = 0;
|
||||||
|
@ -7071,7 +7078,8 @@ CheckIf(FunctionCompiler& f, ParseNode* ifStmt)
|
||||||
ParseNode* thenStmt = TernaryKid2(ifStmt);
|
ParseNode* thenStmt = TernaryKid2(ifStmt);
|
||||||
ParseNode* elseStmt = TernaryKid3(ifStmt);
|
ParseNode* elseStmt = TernaryKid3(ifStmt);
|
||||||
|
|
||||||
MBasicBlock* thenBlock = nullptr, *elseBlock = nullptr;
|
MBasicBlock* thenBlock = nullptr;
|
||||||
|
MBasicBlock* elseBlock = nullptr;
|
||||||
ParseNode* elseOrJoinStmt = elseStmt ? elseStmt : nextStmt;
|
ParseNode* elseOrJoinStmt = elseStmt ? elseStmt : nextStmt;
|
||||||
|
|
||||||
if (!CheckIfCondition(f, cond, thenStmt, elseOrJoinStmt, &thenBlock, &elseBlock))
|
if (!CheckIfCondition(f, cond, thenStmt, elseOrJoinStmt, &thenBlock, &elseBlock))
|
||||||
|
|
|
@ -137,9 +137,10 @@ class OrderedHashTable
|
||||||
}
|
}
|
||||||
|
|
||||||
~OrderedHashTable() {
|
~OrderedHashTable() {
|
||||||
for (Range* r = ranges, *next; r; r = next) {
|
for (Range* r = ranges; r; ) {
|
||||||
next = r->next;
|
Range* next = r->next;
|
||||||
r->onTableDestroyed();
|
r->onTableDestroyed();
|
||||||
|
r = next;
|
||||||
}
|
}
|
||||||
alloc.free_(hashTable);
|
alloc.free_(hashTable);
|
||||||
freeData(data, dataLength);
|
freeData(data, dataLength);
|
||||||
|
@ -593,7 +594,8 @@ class OrderedHashTable
|
||||||
void rehashInPlace() {
|
void rehashInPlace() {
|
||||||
for (uint32_t i = 0, N = hashBuckets(); i < N; i++)
|
for (uint32_t i = 0, N = hashBuckets(); i < N; i++)
|
||||||
hashTable[i] = nullptr;
|
hashTable[i] = nullptr;
|
||||||
Data* wp = data, *end = data + dataLength;
|
Data* wp = data;
|
||||||
|
Data* end = data + dataLength;
|
||||||
for (Data* rp = data; rp != end; rp++) {
|
for (Data* rp = data; rp != end; rp++) {
|
||||||
if (!Ops::isEmpty(Ops::getKey(rp->element))) {
|
if (!Ops::isEmpty(Ops::getKey(rp->element))) {
|
||||||
HashNumber h = prepareHash(Ops::getKey(rp->element)) >> hashShift;
|
HashNumber h = prepareHash(Ops::getKey(rp->element)) >> hashShift;
|
||||||
|
@ -642,7 +644,8 @@ class OrderedHashTable
|
||||||
}
|
}
|
||||||
|
|
||||||
Data* wp = newData;
|
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))) {
|
if (!Ops::isEmpty(Ops::getKey(p->element))) {
|
||||||
HashNumber h = prepareHash(Ops::getKey(p->element)) >> newHashShift;
|
HashNumber h = prepareHash(Ops::getKey(p->element)) >> newHashShift;
|
||||||
new (wp) Data(Move(p->element), newHashTable[h]);
|
new (wp) Data(Move(p->element), newHashTable[h]);
|
||||||
|
|
|
@ -60,7 +60,8 @@ class InlineMap
|
||||||
MOZ_ASSERT(map.initialized());
|
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))
|
if (it->key && !map.putNew(it->key, it->value))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +212,8 @@ class InlineMap
|
||||||
if (usingMap())
|
if (usingMap())
|
||||||
return Ptr(map.lookup(key));
|
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)
|
if (it->key == key)
|
||||||
return Ptr(it);
|
return Ptr(it);
|
||||||
}
|
}
|
||||||
|
@ -224,7 +226,8 @@ class InlineMap
|
||||||
if (usingMap())
|
if (usingMap())
|
||||||
return AddPtr(map.lookupForAdd(key));
|
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)
|
if (it->key == key)
|
||||||
return AddPtr(it, true);
|
return AddPtr(it, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,9 @@ class SplayTree
|
||||||
{
|
{
|
||||||
struct Node {
|
struct Node {
|
||||||
T item;
|
T item;
|
||||||
Node* left, *right, *parent;
|
Node* left;
|
||||||
|
Node* right;
|
||||||
|
Node* parent;
|
||||||
|
|
||||||
explicit Node(const T& item)
|
explicit Node(const T& item)
|
||||||
: item(item), left(nullptr), right(nullptr), parent(nullptr)
|
: item(item), left(nullptr), right(nullptr), parent(nullptr)
|
||||||
|
@ -33,7 +35,8 @@ class SplayTree
|
||||||
};
|
};
|
||||||
|
|
||||||
LifoAlloc* alloc;
|
LifoAlloc* alloc;
|
||||||
Node* root, *freeList;
|
Node* root;
|
||||||
|
Node* freeList;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool enableCheckCoherency;
|
bool enableCheckCoherency;
|
||||||
|
@ -124,7 +127,8 @@ class SplayTree
|
||||||
// Find another node which can be swapped in for the root: either the
|
// 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
|
// rightmost child of the root's left, or the leftmost child of the
|
||||||
// root's right.
|
// root's right.
|
||||||
Node* swap, *swapChild;
|
Node* swap;
|
||||||
|
Node* swapChild;
|
||||||
if (root->left) {
|
if (root->left) {
|
||||||
swap = root->left;
|
swap = root->left;
|
||||||
while (swap->right)
|
while (swap->right)
|
||||||
|
@ -167,7 +171,8 @@ class SplayTree
|
||||||
Node* lookup(const T& v)
|
Node* lookup(const T& v)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(root);
|
MOZ_ASSERT(root);
|
||||||
Node* node = root, *parent;
|
Node* node = root;
|
||||||
|
Node* parent;
|
||||||
do {
|
do {
|
||||||
parent = node;
|
parent = node;
|
||||||
int c = C::compare(v, node->item);
|
int c = C::compare(v, node->item);
|
||||||
|
|
|
@ -2280,7 +2280,8 @@ BytecodeEmitter::emitPropLHS(ParseNode* pn, JSOp op)
|
||||||
*/
|
*/
|
||||||
if (pn2->isKind(PNK_DOT)) {
|
if (pn2->isKind(PNK_DOT)) {
|
||||||
ParseNode* pndot = pn2;
|
ParseNode* pndot = pn2;
|
||||||
ParseNode* pnup = nullptr, *pndown;
|
ParseNode* pnup = nullptr;
|
||||||
|
ParseNode* pndown;
|
||||||
ptrdiff_t top = offset();
|
ptrdiff_t top = offset();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Reverse pndot->pn_expr to point up, not down. */
|
/* Reverse pndot->pn_expr to point up, not down. */
|
||||||
|
@ -6673,8 +6674,8 @@ BytecodeEmitter::emitDefaults(ParseNode* pn)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(pn->isKind(PNK_ARGSBODY));
|
MOZ_ASSERT(pn->isKind(PNK_ARGSBODY));
|
||||||
|
|
||||||
ParseNode* arg, *pnlast = pn->last();
|
ParseNode* pnlast = pn->last();
|
||||||
for (arg = pn->pn_head; arg != pnlast; arg = arg->pn_next) {
|
for (ParseNode* arg = pn->pn_head; arg != pnlast; arg = arg->pn_next) {
|
||||||
if (!(arg->pn_dflags & PND_DEFAULT))
|
if (!(arg->pn_dflags & PND_DEFAULT))
|
||||||
continue;
|
continue;
|
||||||
if (!bindNameToSlot(arg))
|
if (!bindNameToSlot(arg))
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче