mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 879475 - Part 005. Implement ContentBridge r=jlebar
Based on original patch by David Zbarsky <dzbarsky@gmail.com>
This commit is contained in:
parent
8fe78e3629
commit
c9a438a458
@ -88,6 +88,7 @@
|
||||
#include "mozilla/dom/SVGIFrameElement.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "JavaScriptParent.h"
|
||||
#include "CompositorChild.h"
|
||||
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
|
||||
@ -1543,9 +1544,16 @@ nsFrameLoader::ShouldUseRemoteProcess()
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're inside a content process, don't use a remote process for this
|
||||
// frame; it won't work properly until bug 761935 is fixed.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// Don't try to launch nested children if we don't have OMTC.
|
||||
// They won't render!
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content &&
|
||||
!CompositorChild::ChildProcessHasCompositor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content &&
|
||||
!(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
|
||||
Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2093,10 +2101,7 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
if (NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
||||
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2135,11 +2140,12 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
|
||||
nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow();
|
||||
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
|
||||
NS_ABORT_IF_FALSE(rootChromeWin, "How did we not get a chrome window here?");
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
|
||||
if (rootChromeWin) {
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
|
||||
}
|
||||
|
||||
mContentParent = mRemoteBrowser->Manager();
|
||||
|
||||
@ -2424,8 +2430,9 @@ nsFrameLoader::EnsureMessageManager()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool useRemoteProcess = ShouldUseRemoteProcess();
|
||||
if (mMessageManager) {
|
||||
if (ShouldUseRemoteProcess() && mRemoteBrowserShown) {
|
||||
if (useRemoteProcess && mRemoteBrowserShown) {
|
||||
mMessageManager->InitWithCallback(this);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -2449,7 +2456,7 @@ nsFrameLoader::EnsureMessageManager()
|
||||
}
|
||||
}
|
||||
|
||||
if (ShouldUseRemoteProcess()) {
|
||||
if (useRemoteProcess) {
|
||||
mMessageManager = new nsFrameMessageManager(mRemoteBrowserShown ? this : nullptr,
|
||||
static_cast<nsFrameMessageManager*>(parentManager.get()),
|
||||
MM_CHROME);
|
||||
|
@ -1870,8 +1870,6 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
|
||||
{
|
||||
NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager,
|
||||
"Re-creating sParentProcessManager");
|
||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
|
||||
nullptr,
|
||||
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
|
||||
|
@ -283,9 +283,7 @@ nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
|
||||
}
|
||||
|
||||
// Fail if this frame doesn't have the mozbrowser attribute.
|
||||
bool hasMozbrowser = false;
|
||||
GetMozbrowser(&hasMozbrowser);
|
||||
if (!hasMozbrowser) {
|
||||
if (!GetBoolAttr(nsGkAtoms::mozbrowser)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
173
dom/ipc/ContentBridgeChild.cpp
Normal file
173
dom/ipc/ContentBridgeChild.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ContentBridgeChild.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "JavaScriptChild.h"
|
||||
|
||||
using namespace base;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::jsipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(ContentBridgeChild, nsIContentChild)
|
||||
|
||||
ContentBridgeChild::ContentBridgeChild(Transport* aTransport)
|
||||
: mTransport(aTransport)
|
||||
{}
|
||||
|
||||
ContentBridgeChild::~ContentBridgeChild()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
|
||||
}
|
||||
|
||||
void
|
||||
ContentBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &ContentBridgeChild::DeferredDestroy));
|
||||
}
|
||||
|
||||
/*static*/ ContentBridgeChild*
|
||||
ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherProcess)
|
||||
{
|
||||
nsRefPtr<ContentBridgeChild> bridge =
|
||||
new ContentBridgeChild(aTransport);
|
||||
ProcessHandle handle;
|
||||
if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
|
||||
// XXX need to kill |aOtherProcess|, it's boned
|
||||
return nullptr;
|
||||
}
|
||||
bridge->mSelfRef = bridge;
|
||||
|
||||
DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(ok);
|
||||
return bridge;
|
||||
}
|
||||
|
||||
void
|
||||
ContentBridgeChild::DeferredDestroy()
|
||||
{
|
||||
mSelfRef = nullptr;
|
||||
// |this| was just destroyed, hands off
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
return nsIContentChild::RecvAsyncMessage(aMsg, aData, aCpows, aPrincipal);
|
||||
}
|
||||
|
||||
PBlobChild*
|
||||
ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
|
||||
const BlobConstructorParams& params)
|
||||
{
|
||||
return PContentBridgeChild::SendPBlobConstructor(actor, params);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentBridgeChild::SendPBrowserConstructor(aActor,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aID,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
// This implementation is identical to ContentChild::GetCPOWManager but we can't
|
||||
// move it to nsIContentChild because it calls ManagedPJavaScriptChild() which
|
||||
// only exists in PContentChild and PContentBridgeChild.
|
||||
jsipc::JavaScriptChild *
|
||||
ContentBridgeChild::GetCPOWManager()
|
||||
{
|
||||
if (ManagedPJavaScriptChild().Length()) {
|
||||
return static_cast<JavaScriptChild*>(ManagedPJavaScriptChild()[0]);
|
||||
}
|
||||
JavaScriptChild* actor = static_cast<JavaScriptChild*>(SendPJavaScriptConstructor());
|
||||
return actor;
|
||||
}
|
||||
|
||||
mozilla::jsipc::PJavaScriptChild *
|
||||
ContentBridgeChild::AllocPJavaScriptChild()
|
||||
{
|
||||
return nsIContentChild::AllocPJavaScriptChild();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
|
||||
{
|
||||
return nsIContentChild::DeallocPJavaScriptChild(child);
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
ContentBridgeChild::AllocPBrowserChild(const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentChild::AllocPBrowserChild(aContext,
|
||||
aChromeFlags,
|
||||
aID,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::DeallocPBrowserChild(PBrowserChild* aChild)
|
||||
{
|
||||
return nsIContentChild::DeallocPBrowserChild(aChild);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return ContentChild::GetSingleton()->RecvPBrowserConstructor(aActor,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aID,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
PBlobChild*
|
||||
ContentBridgeChild::AllocPBlobChild(const BlobConstructorParams& aParams)
|
||||
{
|
||||
return nsIContentChild::AllocPBlobChild(aParams);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
|
||||
{
|
||||
return nsIContentChild::DeallocPBlobChild(aActor);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
80
dom/ipc/ContentBridgeChild.h
Normal file
80
dom/ipc/ContentBridgeChild.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ContentBridgeChild_h
|
||||
#define mozilla_dom_ContentBridgeChild_h
|
||||
|
||||
#include "mozilla/dom/PContentBridgeChild.h"
|
||||
#include "mozilla/dom/nsIContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentBridgeChild MOZ_FINAL : public PContentBridgeChild
|
||||
, public nsIContentChild
|
||||
{
|
||||
public:
|
||||
ContentBridgeChild(Transport* aTransport);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual ~ContentBridgeChild();
|
||||
|
||||
static ContentBridgeChild*
|
||||
Create(Transport* aTransport, ProcessId aOtherProcess);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
void DeferredDestroy();
|
||||
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBlobChild*
|
||||
SendPBlobConstructor(PBlobChild* actor,
|
||||
const BlobConstructorParams& params);
|
||||
|
||||
jsipc::JavaScriptChild* GetCPOWManager();
|
||||
|
||||
virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPBrowserChild(PBrowserChild*) MOZ_OVERRIDE;
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
|
||||
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPBlobChild(PBlobChild*) MOZ_OVERRIDE;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeChild);
|
||||
|
||||
protected: // members
|
||||
nsRefPtr<ContentBridgeChild> mSelfRef;
|
||||
Transport* mTransport; // owned
|
||||
};
|
||||
|
||||
} // dom
|
||||
} // mozilla
|
||||
|
||||
#endif // mozilla_dom_ContentBridgeChild_h
|
162
dom/ipc/ContentBridgeParent.cpp
Normal file
162
dom/ipc/ContentBridgeParent.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "JavaScriptParent.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace base;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::jsipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(ContentBridgeParent, nsIContentParent)
|
||||
|
||||
ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
|
||||
: mTransport(aTransport)
|
||||
{}
|
||||
|
||||
ContentBridgeParent::~ContentBridgeParent()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
|
||||
}
|
||||
|
||||
void
|
||||
ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
|
||||
}
|
||||
|
||||
/*static*/ ContentBridgeParent*
|
||||
ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
|
||||
{
|
||||
nsRefPtr<ContentBridgeParent> bridge =
|
||||
new ContentBridgeParent(aTransport);
|
||||
ProcessHandle handle;
|
||||
if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
|
||||
// XXX need to kill |aOtherProcess|, it's boned
|
||||
return nullptr;
|
||||
}
|
||||
bridge->mSelfRef = bridge;
|
||||
|
||||
DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(ok);
|
||||
return bridge.get();
|
||||
}
|
||||
|
||||
void
|
||||
ContentBridgeParent::DeferredDestroy()
|
||||
{
|
||||
mSelfRef = nullptr;
|
||||
// |this| was just destroyed, hands off
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeParent::RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
{
|
||||
return nsIContentParent::RecvSyncMessage(aMsg, aData, aCpows, aPrincipal, aRetvals);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeParent::RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
return nsIContentParent::RecvAsyncMessage(aMsg, aData, aCpows, aPrincipal);
|
||||
}
|
||||
|
||||
PBlobParent*
|
||||
ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
|
||||
const BlobConstructorParams& params)
|
||||
{
|
||||
return PContentBridgeParent::SendPBlobConstructor(actor, params);
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentBridgeParent::SendPBrowserConstructor(aActor,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aID,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
PBlobParent*
|
||||
ContentBridgeParent::AllocPBlobParent(const BlobConstructorParams& aParams)
|
||||
{
|
||||
return nsIContentParent::AllocPBlobParent(aParams);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
|
||||
{
|
||||
return nsIContentParent::DeallocPBlobParent(aActor);
|
||||
}
|
||||
|
||||
mozilla::jsipc::PJavaScriptParent *
|
||||
ContentBridgeParent::AllocPJavaScriptParent()
|
||||
{
|
||||
return nsIContentParent::AllocPJavaScriptParent();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
||||
{
|
||||
return nsIContentParent::DeallocPJavaScriptParent(parent);
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentBridgeParent::AllocPBrowserParent(const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentParent::AllocPBrowserParent(aContext,
|
||||
aChromeFlags,
|
||||
aID,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentBridgeParent::DeallocPBrowserParent(PBrowserParent* aParent)
|
||||
{
|
||||
return nsIContentParent::DeallocPBrowserParent(aParent);
|
||||
}
|
||||
|
||||
// This implementation is identical to ContentParent::GetCPOWManager but we can't
|
||||
// move it to nsIContentParent because it calls ManagedPJavaScriptParent() which
|
||||
// only exists in PContentParent and PContentBridgeParent.
|
||||
jsipc::JavaScriptParent*
|
||||
ContentBridgeParent::GetCPOWManager()
|
||||
{
|
||||
if (ManagedPJavaScriptParent().Length()) {
|
||||
return static_cast<JavaScriptParent*>(ManagedPJavaScriptParent()[0]);
|
||||
}
|
||||
JavaScriptParent* actor = static_cast<JavaScriptParent*>(SendPJavaScriptConstructor());
|
||||
return actor;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
117
dom/ipc/ContentBridgeParent.h
Normal file
117
dom/ipc/ContentBridgeParent.h
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ContentBridgeParent_h
|
||||
#define mozilla_dom_ContentBridgeParent_h
|
||||
|
||||
#include "mozilla/dom/PContentBridgeParent.h"
|
||||
#include "mozilla/dom/nsIContentParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentBridgeParent : public PContentBridgeParent
|
||||
, public nsIContentParent
|
||||
{
|
||||
public:
|
||||
ContentBridgeParent(Transport* aTransport);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual ~ContentBridgeParent();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
void DeferredDestroy();
|
||||
|
||||
static ContentBridgeParent*
|
||||
Create(Transport* aTransport, ProcessId aOtherProcess);
|
||||
|
||||
virtual PBlobParent*
|
||||
SendPBlobConstructor(PBlobParent* actor,
|
||||
const BlobConstructorParams& params) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent*
|
||||
SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
|
||||
jsipc::JavaScriptParent* GetCPOWManager();
|
||||
|
||||
virtual uint64_t ChildID() MOZ_OVERRIDE
|
||||
{
|
||||
return mChildID;
|
||||
}
|
||||
virtual bool IsForApp() MOZ_OVERRIDE
|
||||
{
|
||||
return mIsForApp;
|
||||
}
|
||||
virtual bool IsForBrowser() MOZ_OVERRIDE
|
||||
{
|
||||
return mIsForBrowser;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetChildID(uint64_t aId)
|
||||
{
|
||||
mChildID = aId;
|
||||
}
|
||||
void SetIsForApp(bool aIsForApp)
|
||||
{
|
||||
mIsForApp = aIsForApp;
|
||||
}
|
||||
void SetIsForBrowser(bool aIsForBrowser)
|
||||
{
|
||||
mIsForBrowser = aIsForBrowser;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
InfallibleTArray<nsString>* aRetvals) MOZ_OVERRIDE;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
|
||||
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
|
||||
|
||||
virtual jsipc::PJavaScriptParent* AllocPJavaScriptParent() MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
DeallocPJavaScriptParent(jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent*
|
||||
AllocPBrowserParent(const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPBrowserParent(PBrowserParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBlobParent*
|
||||
AllocPBlobParent(const BlobConstructorParams& aParams) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool DeallocPBlobParent(PBlobParent*) MOZ_OVERRIDE;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeParent);
|
||||
|
||||
protected: // members
|
||||
nsRefPtr<ContentBridgeParent> mSelfRef;
|
||||
Transport* mTransport; // owned
|
||||
uint64_t mChildID;
|
||||
bool mIsForApp;
|
||||
bool mIsForBrowser;
|
||||
|
||||
private:
|
||||
friend class ContentParent;
|
||||
};
|
||||
|
||||
} // dom
|
||||
} // mozilla
|
||||
|
||||
#endif // mozilla_dom_ContentBridgeParent_h
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/ContentBridgeChild.h"
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
#include "mozilla/dom/DOMStorageIPC.h"
|
||||
#include "mozilla/dom/ExternalHelperAppChild.h"
|
||||
#include "mozilla/dom/PCrashReporterChild.h"
|
||||
@ -835,6 +837,23 @@ ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* /* a
|
||||
return true;
|
||||
}
|
||||
|
||||
PContentBridgeChild*
|
||||
ContentChild::AllocPContentBridgeChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
{
|
||||
return ContentBridgeChild::Create(aTransport, aOtherProcess);
|
||||
}
|
||||
|
||||
PContentBridgeParent*
|
||||
ContentChild::AllocPContentBridgeParent(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
{
|
||||
MOZ_ASSERT(!mLastBridge);
|
||||
mLastBridge = static_cast<ContentBridgeParent*>(
|
||||
ContentBridgeParent::Create(aTransport, aOtherProcess));
|
||||
return mLastBridge;
|
||||
}
|
||||
|
||||
PCompositorChild*
|
||||
ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess)
|
||||
|
@ -8,9 +8,10 @@
|
||||
#define mozilla_dom_ContentChild_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
#include "mozilla/dom/nsIContentChild.h"
|
||||
#include "mozilla/dom/PContentChild.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsTHashtable.h"
|
||||
@ -89,6 +90,21 @@ public:
|
||||
void GetProcessName(nsACString& aName);
|
||||
static void AppendProcessId(nsACString& aName);
|
||||
|
||||
ContentBridgeParent* GetLastBridge() {
|
||||
MOZ_ASSERT(mLastBridge);
|
||||
ContentBridgeParent* parent = mLastBridge;
|
||||
mLastBridge = nullptr;
|
||||
return parent;
|
||||
}
|
||||
nsRefPtr<ContentBridgeParent> mLastBridge;
|
||||
|
||||
PContentBridgeParent*
|
||||
AllocPContentBridgeParent(mozilla::ipc::Transport* transport,
|
||||
base::ProcessId otherProcess) MOZ_OVERRIDE;
|
||||
PContentBridgeChild*
|
||||
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
|
||||
base::ProcessId otherProcess) MOZ_OVERRIDE;
|
||||
|
||||
PCompositorChild*
|
||||
AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
|
||||
@ -318,7 +334,7 @@ public:
|
||||
const uint64_t& aID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
protected:
|
||||
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "chrome/common/process_watcher.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "AppProcessChecker.h"
|
||||
#include "AudioChannelService.h"
|
||||
#include "CrashReporterParent.h"
|
||||
@ -35,6 +37,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/DataStoreService.h"
|
||||
#include "mozilla/dom/ExternalHelperAppParent.h"
|
||||
#include "mozilla/dom/PContentBridgeParent.h"
|
||||
#include "mozilla/dom/PFileDescriptorSetParent.h"
|
||||
#include "mozilla/dom/PCycleCollectWithLogsParent.h"
|
||||
#include "mozilla/dom/PMemoryReportRequestParent.h"
|
||||
@ -550,6 +553,7 @@ ContentParent::RunNuwaProcess()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsRefPtr<ContentParent> nuwaProcess =
|
||||
new ContentParent(/* aApp = */ nullptr,
|
||||
/* aOpener = */ nullptr,
|
||||
/* aIsForBrowser = */ false,
|
||||
/* aIsForPreallocated = */ true,
|
||||
PROCESS_PRIORITY_BACKGROUND,
|
||||
@ -566,6 +570,7 @@ ContentParent::PreallocateAppProcess()
|
||||
{
|
||||
nsRefPtr<ContentParent> process =
|
||||
new ContentParent(/* app = */ nullptr,
|
||||
/* aOpener = */ nullptr,
|
||||
/* isForBrowserElement = */ false,
|
||||
/* isForPreallocated = */ true,
|
||||
PROCESS_PRIORITY_PREALLOC);
|
||||
@ -596,16 +601,14 @@ ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
||||
/*static*/ void
|
||||
ContentParent::StartUp()
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: This reporter measures all ContentParents.
|
||||
RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
|
||||
|
||||
mozilla::dom::time::InitializeDateCacheCleaner();
|
||||
|
||||
BackgroundChild::Startup();
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
BackgroundChild::Startup();
|
||||
}
|
||||
|
||||
sCanLaunchSubprocesses = true;
|
||||
|
||||
@ -614,7 +617,9 @@ ContentParent::StartUp()
|
||||
|
||||
// Test the PBackground infrastructure on ENABLE_TESTS builds when a special
|
||||
// testing preference is set.
|
||||
MaybeTestPBackground();
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
MaybeTestPBackground();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@ -674,7 +679,9 @@ ContentParent::JoinAllSubprocesses()
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
|
||||
ContentParent::GetNewOrUsed(bool aForBrowserElement,
|
||||
ProcessPriority aPriority,
|
||||
ContentParent* aOpener)
|
||||
{
|
||||
if (!sNonAppContentParents)
|
||||
sNonAppContentParents = new nsTArray<ContentParent*>();
|
||||
@ -684,10 +691,16 @@ ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
|
||||
maxContentProcesses = 1;
|
||||
|
||||
if (sNonAppContentParents->Length() >= uint32_t(maxContentProcesses)) {
|
||||
uint32_t idx = rand() % sNonAppContentParents->Length();
|
||||
nsRefPtr<ContentParent> p = (*sNonAppContentParents)[idx];
|
||||
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sNonAppContentParents?");
|
||||
return p.forget();
|
||||
uint32_t startIdx = rand() % sNonAppContentParents->Length();
|
||||
uint32_t currIdx = startIdx;
|
||||
do {
|
||||
nsRefPtr<ContentParent> p = (*sNonAppContentParents)[currIdx];
|
||||
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sNonAppContntParents?");
|
||||
if (p->mOpener == aOpener) {
|
||||
return p.forget();
|
||||
}
|
||||
currIdx = (currIdx + 1) % sNonAppContentParents->Length();
|
||||
} while (currIdx != startIdx);
|
||||
}
|
||||
|
||||
// Try to take and transform the preallocated process into browser.
|
||||
@ -703,6 +716,7 @@ ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
|
||||
}
|
||||
#endif
|
||||
p = new ContentParent(/* app = */ nullptr,
|
||||
aOpener,
|
||||
aForBrowserElement,
|
||||
/* isForPreallocated = */ false,
|
||||
aPriority);
|
||||
@ -760,6 +774,57 @@ ContentParent::RunAfterPreallocatedProcessReady(nsIRunnable* aRequest)
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef std::map<ContentParent*, std::set<ContentParent*> > GrandchildMap;
|
||||
static GrandchildMap sGrandchildProcessMap;
|
||||
|
||||
std::map<uint64_t, ContentParent*> sContentParentMap;
|
||||
|
||||
bool
|
||||
ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority,
|
||||
uint64_t* aId,
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser)
|
||||
{
|
||||
#if 0
|
||||
if (!CanOpenBrowser(aContext)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsRefPtr<ContentParent> cp = GetNewOrUsed(/* isBrowserElement = */ true,
|
||||
aPriority,
|
||||
this);
|
||||
*aId = cp->ChildID();
|
||||
*aIsForApp = cp->IsForApp();
|
||||
*aIsForBrowser = cp->IsForBrowser();
|
||||
sContentParentMap[*aId] = cp;
|
||||
auto iter = sGrandchildProcessMap.find(this);
|
||||
if (iter == sGrandchildProcessMap.end()) {
|
||||
std::set<ContentParent*> children;
|
||||
children.insert(cp);
|
||||
sGrandchildProcessMap[this] = children;
|
||||
} else {
|
||||
iter->second.insert(cp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::AnswerBridgeToChildProcess(const uint64_t& id)
|
||||
{
|
||||
ContentParent* cp = sContentParentMap[id];
|
||||
auto iter = sGrandchildProcessMap.find(this);
|
||||
if (iter != sGrandchildProcessMap.end() &&
|
||||
iter->second.find(cp) != iter->second.end()) {
|
||||
return PContentBridge::Bridge(this, cp);
|
||||
} else {
|
||||
// You can't bridge to a process you didn't open!
|
||||
KillHard();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ TabParent*
|
||||
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
Element* aFrameElement)
|
||||
@ -771,19 +836,50 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
||||
|
||||
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
|
||||
nsRefPtr<ContentParent> cp = GetNewOrUsed(aContext.IsBrowserElement(),
|
||||
initialPriority);
|
||||
|
||||
if (cp) {
|
||||
nsRefPtr<TabParent> tp;
|
||||
nsRefPtr<nsIContentParent> constructorSender;
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
MOZ_ASSERT(aContext.IsBrowserElement());
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
uint64_t id;
|
||||
bool isForApp;
|
||||
bool isForBrowser;
|
||||
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
||||
initialPriority,
|
||||
&id,
|
||||
&isForApp,
|
||||
&isForBrowser)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!child->CallBridgeToChildProcess(id)) {
|
||||
return nullptr;
|
||||
}
|
||||
ContentBridgeParent* parent = child->GetLastBridge();
|
||||
parent->SetChildID(id);
|
||||
parent->SetIsForApp(isForApp);
|
||||
parent->SetIsForBrowser(isForBrowser);
|
||||
constructorSender = parent;
|
||||
} else if (nsRefPtr<ContentParent> cp =
|
||||
GetNewOrUsed(aContext.IsBrowserElement(), initialPriority)) {
|
||||
constructorSender = cp;
|
||||
}
|
||||
if (constructorSender) {
|
||||
uint32_t chromeFlags = 0;
|
||||
|
||||
// Propagate the private-browsing status of the element's parent
|
||||
// docshell to the remote docshell, via the chrome flags.
|
||||
nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
|
||||
MOZ_ASSERT(frameElement);
|
||||
nsIDocShell* docShell =
|
||||
frameElement->OwnerDoc()->GetWindow()->GetDocShell();
|
||||
MOZ_ASSERT(docShell);
|
||||
nsPIDOMWindow* win = frameElement->OwnerDoc()->GetWindow();
|
||||
if (!win) {
|
||||
NS_WARNING("Remote frame has no window");
|
||||
return nullptr;
|
||||
}
|
||||
nsIDocShell* docShell = win->GetDocShell();
|
||||
if (!docShell) {
|
||||
NS_WARNING("Remote frame has no docshell");
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
||||
if (loadContext && loadContext->UsePrivateBrowsing()) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
||||
@ -794,17 +890,18 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
|
||||
}
|
||||
|
||||
nsRefPtr<TabParent> tp(new TabParent(cp, aContext, chromeFlags));
|
||||
nsRefPtr<TabParent> tp(new TabParent(constructorSender,
|
||||
aContext, chromeFlags));
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
|
||||
PBrowserParent* browser = cp->SendPBrowserConstructor(
|
||||
PBrowserParent* browser = constructorSender->SendPBrowserConstructor(
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
tp.forget().take(),
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags,
|
||||
cp->ChildID(),
|
||||
cp->IsForApp(),
|
||||
cp->IsForBrowser());
|
||||
constructorSender->ChildID(),
|
||||
constructorSender->IsForApp(),
|
||||
constructorSender->IsForBrowser());
|
||||
return static_cast<TabParent*>(browser);
|
||||
}
|
||||
return nullptr;
|
||||
@ -886,6 +983,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
#endif
|
||||
NS_WARNING("Unable to use pre-allocated app process");
|
||||
p = new ContentParent(ownApp,
|
||||
/* aOpener = */ nullptr,
|
||||
/* isForBrowserElement = */ false,
|
||||
/* isForPreallocated = */ false,
|
||||
initialPriority);
|
||||
@ -1230,6 +1328,13 @@ ContentParent::MarkAsDead()
|
||||
}
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
sGrandchildProcessMap.erase(this);
|
||||
for (auto iter = sGrandchildProcessMap.begin();
|
||||
iter != sGrandchildProcessMap.end();
|
||||
iter++) {
|
||||
iter->second.erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1423,6 +1528,19 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
// This runnable ensures that a reference to |this| lives on at
|
||||
// least until after the current task finishes running.
|
||||
NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
|
||||
|
||||
// Destroy any processes created by this ContentParent
|
||||
auto iter = sGrandchildProcessMap.find(this);
|
||||
if (iter != sGrandchildProcessMap.end()) {
|
||||
for(auto child = iter->second.begin();
|
||||
child != iter->second.end();
|
||||
child++) {
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(*child, &ContentParent::ShutDownProcess,
|
||||
/* closeWithError */ false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1519,11 +1637,13 @@ ContentParent::InitializeMembers()
|
||||
}
|
||||
|
||||
ContentParent::ContentParent(mozIApplication* aApp,
|
||||
ContentParent* aOpener,
|
||||
bool aIsForBrowser,
|
||||
bool aIsForPreallocated,
|
||||
ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */,
|
||||
bool aIsNuwaProcess /* = false */)
|
||||
: nsIContentParent()
|
||||
, mOpener(aOpener)
|
||||
, mIsForBrowser(aIsForBrowser)
|
||||
, mIsNuwaProcess(aIsNuwaProcess)
|
||||
{
|
||||
@ -3297,6 +3417,22 @@ ContentParent::RecvSystemMessageHandled()
|
||||
return true;
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentParent::SendPBrowserConstructor(aActor,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aId,
|
||||
aIsForApp,
|
||||
aIsForBrowser);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint)
|
||||
{
|
||||
|
@ -98,7 +98,8 @@ public:
|
||||
static already_AddRefed<ContentParent>
|
||||
GetNewOrUsed(bool aForBrowserElement = false,
|
||||
hal::ProcessPriority aPriority =
|
||||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND);
|
||||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
|
||||
ContentParent* aOpener = nullptr);
|
||||
|
||||
/**
|
||||
* Create a subprocess suitable for use as a preallocated app process.
|
||||
@ -119,6 +120,13 @@ public:
|
||||
static void GetAll(nsTArray<ContentParent*>& aArray);
|
||||
static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
|
||||
|
||||
virtual bool RecvCreateChildProcess(const IPCTabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority,
|
||||
uint64_t* aId,
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool AnswerBridgeToChildProcess(const uint64_t& id) MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
@ -153,8 +161,8 @@ public:
|
||||
bool RequestRunToCompletion();
|
||||
|
||||
bool IsAlive();
|
||||
bool IsForApp();
|
||||
bool IsForBrowser()
|
||||
virtual bool IsForApp() MOZ_OVERRIDE;
|
||||
virtual bool IsForBrowser() MOZ_OVERRIDE
|
||||
{
|
||||
return mIsForBrowser;
|
||||
}
|
||||
@ -168,6 +176,10 @@ public:
|
||||
|
||||
int32_t Pid();
|
||||
|
||||
ContentParent* Opener() {
|
||||
return mOpener;
|
||||
}
|
||||
|
||||
bool NeedsPermissionsUpdate() const {
|
||||
return mSendPermissionUpdates;
|
||||
}
|
||||
@ -273,12 +285,19 @@ private:
|
||||
|
||||
// Hide the raw constructor methods since we don't want client code
|
||||
// using them.
|
||||
using PContentParent::SendPBrowserConstructor;
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
PBrowserParent* actor,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
using PContentParent::SendPTestShellConstructor;
|
||||
|
||||
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
|
||||
// true.
|
||||
ContentParent(mozIApplication* aApp,
|
||||
ContentParent* aOpener,
|
||||
bool aIsForBrowser,
|
||||
bool aIsForPreallocated,
|
||||
hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND,
|
||||
@ -595,6 +614,7 @@ private:
|
||||
// details.
|
||||
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
ContentParent* mOpener;
|
||||
|
||||
uint64_t mChildID;
|
||||
int32_t mGeolocationWatchID;
|
||||
|
@ -113,7 +113,7 @@ FilePickerParent::FileSizeAndDateRunnable::Destroy()
|
||||
void
|
||||
FilePickerParent::SendFiles(const nsCOMArray<nsIDOMFile>& aDomfiles)
|
||||
{
|
||||
ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
|
||||
nsIContentParent* parent = static_cast<TabParent*>(Manager())->Manager();
|
||||
InfallibleTArray<PBlobParent*> files;
|
||||
|
||||
for (unsigned i = 0; i < aDomfiles.Length(); i++) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
include protocol PBlobStream;
|
||||
include protocol PContent;
|
||||
include protocol PContentBridge;
|
||||
|
||||
include DOMTypes;
|
||||
|
||||
@ -18,7 +19,7 @@ union ResolveMysteryParams
|
||||
|
||||
protocol PBlob
|
||||
{
|
||||
manager PContent;
|
||||
manager PContent or PContentBridge;
|
||||
manages PBlobStream;
|
||||
|
||||
both:
|
||||
|
@ -8,6 +8,7 @@
|
||||
include protocol PBlob;
|
||||
include protocol PColorPicker;
|
||||
include protocol PContent;
|
||||
include protocol PContentBridge;
|
||||
include protocol PDocumentRenderer;
|
||||
include protocol PContentPermissionRequest;
|
||||
include protocol PFilePicker;
|
||||
@ -70,7 +71,7 @@ union MaybeNativeKeyBinding
|
||||
|
||||
intr protocol PBrowser
|
||||
{
|
||||
manager PContent;
|
||||
manager PContent or PContentBridge;
|
||||
|
||||
manages PColorPicker;
|
||||
manages PDocumentRenderer;
|
||||
|
@ -10,6 +10,7 @@ include protocol PBlob;
|
||||
include protocol PBluetooth;
|
||||
include protocol PBrowser;
|
||||
include protocol PCompositor;
|
||||
include protocol PContentBridge;
|
||||
include protocol PCycleCollectWithLogs;
|
||||
include protocol PCrashReporter;
|
||||
include protocol PExternalHelperApp;
|
||||
@ -443,6 +444,11 @@ parent:
|
||||
sync GetXPCOMProcessAttributes()
|
||||
returns (bool isOffline);
|
||||
|
||||
sync CreateChildProcess(IPCTabContext context,
|
||||
ProcessPriority priority)
|
||||
returns (uint64_t id, bool isForApp, bool isForBrowser);
|
||||
intr BridgeToChildProcess(uint64_t id);
|
||||
|
||||
async PJavaScript();
|
||||
|
||||
PDeviceStorageRequest(DeviceStorageParams params);
|
||||
|
56
dom/ipc/PContentBridge.ipdl
Normal file
56
dom/ipc/PContentBridge.ipdl
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBlob;
|
||||
include protocol PBrowser;
|
||||
include protocol PContent;
|
||||
include protocol PJavaScript;
|
||||
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
include PTabContext;
|
||||
|
||||
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*
|
||||
* PContentBridge allows us to represent a parent/child relationship between two
|
||||
* child processes. When a child process wants to open its own child, it asks
|
||||
* the root process to create a new process and then bridge them. The first
|
||||
* child will allocate the PContentBridgeParent, and the newly opened child will
|
||||
* allocate the PContentBridgeChild. This protocol allows these processes to
|
||||
* share PBrowsers and send messages to each other.
|
||||
*/
|
||||
intr protocol PContentBridge
|
||||
{
|
||||
bridges PContent, PContent;
|
||||
|
||||
manages PBlob;
|
||||
manages PBrowser;
|
||||
manages PJavaScript;
|
||||
|
||||
parent:
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (nsString[] retval);
|
||||
both:
|
||||
// Both the parent and the child can construct the PBrowser.
|
||||
// See the comment in PContent::PBrowser().
|
||||
async PBrowser(IPCTabContext context, uint32_t chromeFlags,
|
||||
uint64_t id, bool isForApp, bool isForBrowser);
|
||||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
|
||||
async PJavaScript();
|
||||
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@ EXPORTS.mozilla.dom.ipc += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'ContentBridgeChild.h',
|
||||
'ContentBridgeParent.h',
|
||||
'ContentChild.h',
|
||||
'ContentParent.h',
|
||||
'ContentProcess.h',
|
||||
@ -44,6 +46,8 @@ EXPORTS.mozilla += [
|
||||
UNIFIED_SOURCES += [
|
||||
'AppProcessChecker.cpp',
|
||||
'ColorPickerParent.cpp',
|
||||
'ContentBridgeChild.cpp',
|
||||
'ContentBridgeParent.cpp',
|
||||
'ContentParent.cpp',
|
||||
'ContentProcess.cpp',
|
||||
'CrashReporterParent.cpp',
|
||||
@ -79,6 +83,7 @@ IPDL_SOURCES += [
|
||||
'PBrowser.ipdl',
|
||||
'PColorPicker.ipdl',
|
||||
'PContent.ipdl',
|
||||
'PContentBridge.ipdl',
|
||||
'PContentPermission.ipdlh',
|
||||
'PContentPermissionRequest.ipdl',
|
||||
'PCrashReporter.ipdl',
|
||||
|
@ -64,6 +64,46 @@ nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
||||
{
|
||||
const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
|
||||
|
||||
// We don't trust the IPCTabContext we receive from the child, so we'll bail
|
||||
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
|
||||
// (PopupIPCTabContext lets the child process prove that it has access to
|
||||
// the app it's trying to open.)
|
||||
if (appBrowser.type() != IPCTabAppBrowserContext::TPopupIPCTabContext) {
|
||||
NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext();
|
||||
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
|
||||
if (!opener) {
|
||||
NS_ERROR("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Popup windows of isBrowser frames must be isBrowser if the parent
|
||||
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
|
||||
// the content to access data it's not supposed to.
|
||||
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
|
||||
NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
if (!tc.IsValid()) {
|
||||
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
|
||||
"Aborting AllocPBrowserParent.",
|
||||
tc.GetInvalidReason()).get());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
nsIContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
@ -76,40 +116,12 @@ nsIContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
unused << aIsForApp;
|
||||
unused << aIsForBrowser;
|
||||
|
||||
const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
|
||||
|
||||
// We don't trust the IPCTabContext we receive from the child, so we'll bail
|
||||
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
|
||||
// (PopupIPCTabContext lets the child process prove that it has access to
|
||||
// the app it's trying to open.)
|
||||
if (appBrowser.type() != IPCTabAppBrowserContext::TPopupIPCTabContext) {
|
||||
NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext();
|
||||
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
|
||||
if (!opener) {
|
||||
NS_ERROR("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Popup windows of isBrowser frames must be isBrowser if the parent
|
||||
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
|
||||
// the content to access data it's not supposed to.
|
||||
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
|
||||
NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
||||
if (!CanOpenBrowser(aContext)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
if (!tc.IsValid()) {
|
||||
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
|
||||
"Aborting AllocPBrowserParent.",
|
||||
tc.GetInvalidReason()).get());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(tc.IsValid());
|
||||
TabParent* parent = new TabParent(this, tc.GetTabContext(), aChromeFlags);
|
||||
|
||||
// We release this ref in DeallocPBrowserParent()
|
||||
|
@ -44,16 +44,29 @@ public:
|
||||
BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
|
||||
|
||||
virtual uint64_t ChildID() = 0;
|
||||
virtual bool IsForApp() = 0;
|
||||
virtual bool IsForBrowser() = 0;
|
||||
|
||||
virtual PBlobParent* SendPBlobConstructor(
|
||||
PBlobParent* actor,
|
||||
const BlobConstructorParams& params) NS_WARN_UNUSED_RESULT = 0;
|
||||
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
PBrowserParent* actor,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const uint64_t& aId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) NS_WARN_UNUSED_RESULT = 0;
|
||||
|
||||
virtual jsipc::JavaScriptParent *GetCPOWManager() = 0;
|
||||
|
||||
virtual bool IsContentParent() { return false; }
|
||||
ContentParent* AsContentParent();
|
||||
|
||||
protected: // methods
|
||||
bool CanOpenBrowser(const IPCTabContext& aContext);
|
||||
|
||||
protected: // IPDL methods
|
||||
virtual mozilla::jsipc::PJavaScriptParent* AllocPJavaScriptParent();
|
||||
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*);
|
||||
|
@ -4240,7 +4240,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
|
||||
case.addstmts([
|
||||
StmtDecl(Decl(Type('Transport', ptr=1), tvar.name)),
|
||||
StmtDecl(Decl(Type(_actorName(actor.ptype.name(), self.side),
|
||||
StmtDecl(Decl(Type(_actorName(actor.ptype.name(), actor.side),
|
||||
ptr=1), pvar.name)),
|
||||
iffailopen,
|
||||
iffailalloc,
|
||||
|
@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PContent;
|
||||
include protocol PContentBridge;
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
|
||||
@ -16,7 +17,7 @@ namespace jsipc {
|
||||
|
||||
intr protocol PJavaScript
|
||||
{
|
||||
manager PContent;
|
||||
manager PContent or PContentBridge;
|
||||
|
||||
both:
|
||||
// Sent when a CPOW has been finalized and table entries can be freed up.
|
||||
|
Loading…
Reference in New Issue
Block a user