mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1020172 - Part 2: Manage TabParent in chrome process. r=khuey
This commit is contained in:
parent
8a7316ff02
commit
922d41136b
@ -81,6 +81,7 @@ ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
|
||||
|
||||
bool
|
||||
ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -88,6 +89,7 @@ ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentBridgeChild::SendPBrowserConstructor(aActor,
|
||||
aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
@ -121,13 +123,15 @@ ContentBridgeChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
ContentBridgeChild::AllocPBrowserChild(const IPCTabContext &aContext,
|
||||
ContentBridgeChild::AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentChild::AllocPBrowserChild(aContext,
|
||||
return nsIContentChild::AllocPBrowserChild(aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
aIsForApp,
|
||||
@ -142,6 +146,7 @@ ContentBridgeChild::DeallocPBrowserChild(PBrowserChild* aChild)
|
||||
|
||||
bool
|
||||
ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -149,6 +154,7 @@ ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return ContentChild::GetSingleton()->RecvPBrowserConstructor(aActor,
|
||||
aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
jsipc::JavaScriptShared* GetCPOWManager() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -48,13 +49,15 @@ public:
|
||||
protected:
|
||||
virtual ~ContentBridgeChild();
|
||||
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPBrowserChild(PBrowserChild*) MOZ_OVERRIDE;
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
|
@ -87,6 +87,7 @@ ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
|
||||
|
||||
PBrowserParent*
|
||||
ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -94,6 +95,7 @@ ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentBridgeParent::SendPBrowserConstructor(aActor,
|
||||
aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
@ -126,13 +128,15 @@ ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentBridgeParent::AllocPBrowserParent(const IPCTabContext &aContext,
|
||||
ContentBridgeParent::AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentParent::AllocPBrowserParent(aContext,
|
||||
return nsIContentParent::AllocPBrowserParent(aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
aIsForApp,
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
|
||||
virtual PBrowserParent*
|
||||
SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -87,7 +88,8 @@ protected:
|
||||
DeallocPJavaScriptParent(jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent*
|
||||
AllocPBrowserParent(const IPCTabContext &aContext,
|
||||
AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext &aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
|
@ -1109,13 +1109,15 @@ ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *aChild)
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
ContentChild::AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentChild::AllocPBrowserChild(aContext,
|
||||
return nsIContentChild::AllocPBrowserChild(aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
aIsForApp,
|
||||
@ -1124,6 +1126,7 @@ ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
|
||||
bool
|
||||
ContentChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -1131,6 +1134,7 @@ ContentChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentChild::SendPBrowserConstructor(aActor,
|
||||
aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpID,
|
||||
@ -1140,6 +1144,7 @@ ContentChild::SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
|
||||
bool
|
||||
ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
|
@ -131,7 +131,8 @@ public:
|
||||
AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
@ -370,6 +371,7 @@ public:
|
||||
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SendPBrowserConstructor(PBrowserChild* actor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -377,6 +379,7 @@ public:
|
||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
|
@ -131,6 +131,7 @@
|
||||
#include "gfxPrefs.h"
|
||||
#include "prio.h"
|
||||
#include "private/pprio.h"
|
||||
#include "ContentProcessManager.h"
|
||||
|
||||
#if defined(ANDROID) || defined(LINUX)
|
||||
#include "nsSystemInfo.h"
|
||||
@ -845,17 +846,14 @@ ContentParent::PreallocatedProcessReady()
|
||||
#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,
|
||||
const TabId& aOpenerTabId,
|
||||
ContentParentId* aCpId,
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser)
|
||||
bool* aIsForBrowser,
|
||||
TabId* aTabId)
|
||||
{
|
||||
#if 0
|
||||
if (!CanOpenBrowser(aContext)) {
|
||||
@ -884,40 +882,67 @@ ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
|
||||
}
|
||||
|
||||
if (!cp) {
|
||||
*aId = 0;
|
||||
*aCpId = 0;
|
||||
*aIsForApp = false;
|
||||
*aIsForBrowser = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
*aId = cp->ChildID();
|
||||
*aCpId = 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);
|
||||
|
||||
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
||||
cpm->AddContentProcess(cp, this->ChildID());
|
||||
|
||||
if (cpm->AddGrandchildProcess(this->ChildID(), cp->ChildID())) {
|
||||
// Pre-allocate a TabId here to save one time IPC call at app startup.
|
||||
*aTabId = AllocateTabId(aOpenerTabId,
|
||||
aContext,
|
||||
cp->ChildID());
|
||||
return (*aTabId != 0);
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::AnswerBridgeToChildProcess(const uint64_t& id)
|
||||
ContentParent::AnswerBridgeToChildProcess(const ContentParentId& aCpId)
|
||||
{
|
||||
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;
|
||||
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
||||
ContentParent* cp = cpm->GetContentProcessById(aCpId);
|
||||
|
||||
if (cp) {
|
||||
ContentParentId parentId;
|
||||
if (cpm->GetParentProcessId(cp->ChildID(), &parentId) &&
|
||||
parentId == this->ChildID()) {
|
||||
return PContentBridge::Bridge(this, cp);
|
||||
}
|
||||
}
|
||||
|
||||
// You can't bridge to a process you didn't open!
|
||||
KillHard();
|
||||
return false;
|
||||
}
|
||||
|
||||
static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
|
||||
{
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
return docShell;
|
||||
}
|
||||
|
||||
/*static*/ TabParent*
|
||||
@ -931,40 +956,38 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
|
||||
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
||||
bool isInContentProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
|
||||
TabId tabId;
|
||||
|
||||
nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
|
||||
TabId openerTabId;
|
||||
if (docShell) {
|
||||
openerTabId = TabParent::GetTabIdFrom(docShell);
|
||||
}
|
||||
|
||||
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
|
||||
nsRefPtr<TabParent> tp;
|
||||
nsRefPtr<nsIContentParent> constructorSender;
|
||||
if (isInContentProcess) {
|
||||
MOZ_ASSERT(aContext.IsBrowserElement());
|
||||
constructorSender =
|
||||
CreateContentBridgeParent(aContext, initialPriority);
|
||||
constructorSender = CreateContentBridgeParent(aContext,
|
||||
initialPriority,
|
||||
openerTabId,
|
||||
&tabId);
|
||||
} else {
|
||||
if (aOpenerContentParent) {
|
||||
constructorSender = aOpenerContentParent;
|
||||
} else {
|
||||
constructorSender =
|
||||
GetNewOrUsedBrowserProcess(aContext.IsBrowserElement(),
|
||||
initialPriority);
|
||||
}
|
||||
if (aOpenerContentParent) {
|
||||
constructorSender = aOpenerContentParent;
|
||||
} else {
|
||||
constructorSender =
|
||||
GetNewOrUsedBrowserProcess(aContext.IsBrowserElement(),
|
||||
initialPriority);
|
||||
}
|
||||
tabId = AllocateTabId(openerTabId,
|
||||
aContext.AsIPCTabContext(),
|
||||
constructorSender->ChildID());
|
||||
}
|
||||
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);
|
||||
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;
|
||||
@ -975,13 +998,17 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
|
||||
}
|
||||
|
||||
nsRefPtr<TabParent> tp(new TabParent(constructorSender,
|
||||
if (tabId == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
|
||||
aContext, chromeFlags));
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
|
||||
PBrowserParent* browser = constructorSender->SendPBrowserConstructor(
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
tp.forget().take(),
|
||||
tabId,
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags,
|
||||
constructorSender->ChildID(),
|
||||
@ -1001,7 +1028,10 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
nsAutoString manifestURL;
|
||||
|
||||
if (isInContentProcess) {
|
||||
parent = CreateContentBridgeParent(aContext, initialPriority);
|
||||
parent = CreateContentBridgeParent(aContext,
|
||||
initialPriority,
|
||||
openerTabId,
|
||||
&tabId);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<mozIApplication> ownApp = aContext.GetOwnApp();
|
||||
@ -1049,6 +1079,9 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
parentAppStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
// Check if we can re-use the process of the parent app.
|
||||
p = sAppContentParents->Get(parentAppManifestURL);
|
||||
tabId = AllocateTabId(openerTabId,
|
||||
aContext.AsIPCTabContext(),
|
||||
p->ChildID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1070,21 +1103,25 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
&tookPreallocated);
|
||||
MOZ_ASSERT(p);
|
||||
sAppContentParents->Put(manifestURL, p);
|
||||
tabId = AllocateTabId(openerTabId,
|
||||
aContext.AsIPCTabContext(),
|
||||
p->ChildID());
|
||||
}
|
||||
parent = static_cast<nsIContentParent*>(p);
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
if (!parent || (tabId == 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t chromeFlags = 0;
|
||||
|
||||
nsRefPtr<TabParent> tp = new TabParent(parent, aContext, chromeFlags);
|
||||
nsRefPtr<TabParent> tp = new TabParent(parent, tabId, aContext, chromeFlags);
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
PBrowserParent* browser = parent->SendPBrowserConstructor(
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
nsRefPtr<TabParent>(tp).forget().take(),
|
||||
tabId,
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags,
|
||||
parent->ChildID(),
|
||||
@ -1127,27 +1164,33 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
|
||||
/*static*/ ContentBridgeParent*
|
||||
ContentParent::CreateContentBridgeParent(const TabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority)
|
||||
const hal::ProcessPriority& aPriority,
|
||||
const TabId& aOpenerTabId,
|
||||
/*out*/ TabId* aTabId)
|
||||
{
|
||||
MOZ_ASSERT(aTabId);
|
||||
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
uint64_t id;
|
||||
ContentParentId cpId;
|
||||
bool isForApp;
|
||||
bool isForBrowser;
|
||||
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
||||
aPriority,
|
||||
&id,
|
||||
aOpenerTabId,
|
||||
&cpId,
|
||||
&isForApp,
|
||||
&isForBrowser)) {
|
||||
&isForBrowser,
|
||||
aTabId)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (id == 0) {
|
||||
if (cpId == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!child->CallBridgeToChildProcess(id)) {
|
||||
if (!child->CallBridgeToChildProcess(cpId)) {
|
||||
return nullptr;
|
||||
}
|
||||
ContentBridgeParent* parent = child->GetLastBridge();
|
||||
parent->SetChildID(id);
|
||||
parent->SetChildID(cpId);
|
||||
parent->SetIsForApp(isForApp);
|
||||
parent->SetIsForBrowser(isForBrowser);
|
||||
return parent;
|
||||
@ -1476,13 +1519,6 @@ ContentParent::MarkAsDead()
|
||||
}
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
sGrandchildProcessMap.erase(this);
|
||||
for (auto iter = sGrandchildProcessMap.begin();
|
||||
iter != sGrandchildProcessMap.end();
|
||||
iter++) {
|
||||
iter->second.erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1720,17 +1756,17 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
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));
|
||||
}
|
||||
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
||||
nsTArray<ContentParentId> childIDArray =
|
||||
cpm->GetAllChildProcessById(this->ChildID());
|
||||
for(uint32_t i = 0; i < childIDArray.Length(); i++) {
|
||||
ContentParent* cp = cpm->GetContentProcessById(childIDArray[i]);
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(cp, &ContentParent::ShutDownProcess,
|
||||
/* closeWithError */ false));
|
||||
}
|
||||
cpm->RemoveContentProcess(this->ChildID());
|
||||
}
|
||||
|
||||
void
|
||||
@ -1893,6 +1929,8 @@ ContentParent::ContentParent(mozIApplication* aApp,
|
||||
InitInternal(aInitialPriority,
|
||||
true, /* Setup off-main thread compositing */
|
||||
true /* Send registered chrome */);
|
||||
|
||||
ContentProcessManager::GetSingleton()->AddContentProcess(this);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
@ -1970,6 +2008,8 @@ ContentParent::ContentParent(ContentParent* aTemplate,
|
||||
InitInternal(priority,
|
||||
false, /* Setup Off-main thread compositing */
|
||||
false /* Send registered chrome */);
|
||||
|
||||
ContentProcessManager::GetSingleton()->AddContentProcess(this);
|
||||
}
|
||||
#endif // MOZ_NUWA_PROCESS
|
||||
|
||||
@ -2831,13 +2871,15 @@ ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
ContentParent::AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return nsIContentParent::AllocPBrowserParent(aContext,
|
||||
return nsIContentParent::AllocPBrowserParent(aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpId,
|
||||
aIsForApp,
|
||||
@ -3825,6 +3867,7 @@ ContentParent::RecvSystemMessageHandled()
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
@ -3832,6 +3875,7 @@ ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
||||
const bool& aIsForBrowser)
|
||||
{
|
||||
return PContentParent::SendPBrowserConstructor(aActor,
|
||||
aTabId,
|
||||
aContext,
|
||||
aChromeFlags,
|
||||
aCpId,
|
||||
@ -4133,6 +4177,66 @@ ContentParent::NotifyUpdatedDictionaries()
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ TabId
|
||||
ContentParent::AllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aCpId)
|
||||
{
|
||||
TabId tabId;
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
||||
tabId = cpm->AllocateTabId(aOpenerTabId, aContext, aCpId);
|
||||
}
|
||||
else {
|
||||
ContentChild::GetSingleton()->SendAllocateTabId(aOpenerTabId,
|
||||
aContext,
|
||||
aCpId,
|
||||
&tabId);
|
||||
}
|
||||
return tabId;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::DeallocateTabId(const TabId& aTabId,
|
||||
const ContentParentId& aCpId)
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
ContentProcessManager::GetSingleton()->DeallocateTabId(aCpId,
|
||||
aTabId);
|
||||
}
|
||||
else {
|
||||
ContentChild::GetSingleton()->SendDeallocateTabId(aTabId);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aCpId,
|
||||
TabId* aTabId)
|
||||
{
|
||||
*aTabId = AllocateTabId(aOpenerTabId, aContext, aCpId);
|
||||
if (!(*aTabId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvDeallocateTabId(const TabId& aTabId)
|
||||
{
|
||||
DeallocateTabId(aTabId, this->ChildID());
|
||||
return true;
|
||||
}
|
||||
|
||||
nsTArray<TabContext>
|
||||
ContentParent::GetManagedTabContext()
|
||||
{
|
||||
return Move(ContentProcessManager::GetSingleton()->
|
||||
GetTabContextByContentProcess(this->ChildID()));
|
||||
}
|
||||
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -143,10 +143,12 @@ public:
|
||||
|
||||
virtual bool RecvCreateChildProcess(const IPCTabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority,
|
||||
uint64_t* aId,
|
||||
const TabId& aOpenerTabId,
|
||||
ContentParentId* aCpId,
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser) MOZ_OVERRIDE;
|
||||
virtual bool AnswerBridgeToChildProcess(const uint64_t& id) MOZ_OVERRIDE;
|
||||
bool* aIsForBrowser,
|
||||
TabId* aTabId) MOZ_OVERRIDE;
|
||||
virtual bool AnswerBridgeToChildProcess(const ContentParentId& aCpId) MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
|
||||
|
||||
@ -179,6 +181,13 @@ public:
|
||||
TestShellParent* GetTestShellSingleton();
|
||||
jsipc::JavaScriptShared* GetCPOWManager() MOZ_OVERRIDE;
|
||||
|
||||
static TabId
|
||||
AllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aCpId);
|
||||
static void
|
||||
DeallocateTabId(const TabId& aTabId, const ContentParentId& aCpId);
|
||||
|
||||
void ReportChildAlreadyBlocked();
|
||||
bool RequestRunToCompletion();
|
||||
|
||||
@ -282,6 +291,14 @@ public:
|
||||
PBlobParent* aActor,
|
||||
const BlobConstructorParams& aParams) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvAllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aCpId,
|
||||
TabId* aTabId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDeallocateTabId(const TabId& aTabId) MOZ_OVERRIDE;
|
||||
|
||||
nsTArray<TabContext> GetManagedTabContext();
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
@ -310,12 +327,15 @@ private:
|
||||
static hal::ProcessPriority GetInitialProcessPriority(Element* aFrameElement);
|
||||
|
||||
static ContentBridgeParent* CreateContentBridgeParent(const TabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority);
|
||||
const hal::ProcessPriority& aPriority,
|
||||
const TabId& aOpenerTabId,
|
||||
/*out*/ TabId* aTabId);
|
||||
|
||||
// Hide the raw constructor methods since we don't want client code
|
||||
// using them.
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
PBrowserParent* actor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
@ -420,7 +440,8 @@ private:
|
||||
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*) MOZ_OVERRIDE;
|
||||
virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
virtual PBrowserParent* AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
|
276
dom/ipc/ContentProcessManager.cpp
Normal file
276
dom/ipc/ContentProcessManager.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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 "ContentProcessManager.h"
|
||||
#include "ContentParent.h"
|
||||
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
// XXX need another bug to move this to a common header.
|
||||
#ifdef DISABLE_ASSERTS_FOR_FUZZING
|
||||
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
|
||||
#else
|
||||
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static uint64_t gTabId = 0;
|
||||
|
||||
/* static */
|
||||
StaticAutoPtr<ContentProcessManager>
|
||||
ContentProcessManager::sSingleton;
|
||||
|
||||
/* static */ ContentProcessManager*
|
||||
ContentProcessManager::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (!sSingleton) {
|
||||
sSingleton = new ContentProcessManager();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
void
|
||||
ContentProcessManager::AddContentProcess(ContentParent* aChildCp,
|
||||
const ContentParentId& aParentCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aChildCp);
|
||||
|
||||
ContentProcessInfo info;
|
||||
info.mCp = aChildCp;
|
||||
info.mParentCpId = aParentCpId;
|
||||
mContentParentMap[aChildCp->ChildID()] = info;
|
||||
}
|
||||
|
||||
void
|
||||
ContentProcessManager::RemoveContentProcess(const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mContentParentMap.find(aChildCpId) != mContentParentMap.end());
|
||||
|
||||
mContentParentMap.erase(aChildCpId);
|
||||
for (auto iter = mContentParentMap.begin();
|
||||
iter != mContentParentMap.end();
|
||||
++iter) {
|
||||
if (!iter->second.mChildrenCpId.empty()) {
|
||||
iter->second.mChildrenCpId.erase(aChildCpId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ContentProcessManager::AddGrandchildProcess(const ContentParentId& aParentCpId,
|
||||
const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto iter = mContentParentMap.find(aParentCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING("Parent process should be already in map!");
|
||||
return false;
|
||||
}
|
||||
iter->second.mChildrenCpId.insert(aChildCpId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentProcessManager::GetParentProcessId(const ContentParentId& aChildCpId,
|
||||
/*out*/ ContentParentId* aParentCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
*aParentCpId = iter->second.mParentCpId;
|
||||
return true;
|
||||
}
|
||||
|
||||
ContentParent*
|
||||
ContentProcessManager::GetContentProcessById(const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
return iter->second.mCp;
|
||||
}
|
||||
|
||||
nsTArray<ContentParentId>
|
||||
ContentProcessManager::GetAllChildProcessById(const ContentParentId& aParentCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsTArray<ContentParentId> cpIdArray;
|
||||
auto iter = mContentParentMap.find(aParentCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return Move(cpIdArray);
|
||||
}
|
||||
|
||||
for (auto cpIter = iter->second.mChildrenCpId.begin();
|
||||
cpIter != iter->second.mChildrenCpId.end();
|
||||
++cpIter) {
|
||||
cpIdArray.AppendElement(*cpIter);
|
||||
}
|
||||
|
||||
return Move(cpIdArray);
|
||||
}
|
||||
|
||||
TabId
|
||||
ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return TabId(0);
|
||||
}
|
||||
|
||||
struct RemoteFrameInfo info;
|
||||
|
||||
const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
|
||||
// If it's a PopupIPCTabContext, it's the case that a TabChild want to
|
||||
// open a new tab. aOpenerTabId has to be it's parent frame's opener id.
|
||||
if (appBrowser.type() == IPCTabAppBrowserContext::TPopupIPCTabContext) {
|
||||
auto remoteFrameIter = iter->second.mRemoteFrames.find(aOpenerTabId);
|
||||
if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
|
||||
ASSERT_UNLESS_FUZZING("Failed to find parent frame's opener id.");
|
||||
return TabId(0);
|
||||
}
|
||||
|
||||
info.mOpenerTabId = remoteFrameIter->second.mOpenerTabId;
|
||||
|
||||
const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();
|
||||
MOZ_ASSERT(ipcContext.opener().type() == PBrowserOrId::TTabId);
|
||||
|
||||
remoteFrameIter = iter->second.mRemoteFrames.find(ipcContext.opener().get_TabId());
|
||||
if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
|
||||
ASSERT_UNLESS_FUZZING("Failed to find tab id.");
|
||||
return TabId(0);
|
||||
}
|
||||
|
||||
info.mContext = remoteFrameIter->second.mContext;
|
||||
}
|
||||
else {
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
if (!tc.IsValid()) {
|
||||
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
|
||||
"the child process. (%s)",
|
||||
tc.GetInvalidReason()).get());
|
||||
return TabId(0);
|
||||
}
|
||||
info.mOpenerTabId = aOpenerTabId;
|
||||
info.mContext = tc.GetTabContext();
|
||||
}
|
||||
|
||||
mUniqueId = ++gTabId;
|
||||
iter->second.mRemoteFrames[mUniqueId] = info;
|
||||
|
||||
return mUniqueId;
|
||||
}
|
||||
|
||||
void
|
||||
ContentProcessManager::DeallocateTabId(const ContentParentId& aChildCpId,
|
||||
const TabId& aChildTabId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return;
|
||||
}
|
||||
|
||||
auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
|
||||
if (remoteFrameIter != iter->second.mRemoteFrames.end()) {
|
||||
iter->second.mRemoteFrames.erase(aChildTabId);
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<uint64_t>
|
||||
ContentProcessManager::GetAppIdsByContentProcess(const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsTArray<uint64_t> appIdArray;
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return Move(appIdArray);
|
||||
}
|
||||
|
||||
for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
|
||||
remoteFrameIter != iter->second.mRemoteFrames.end();
|
||||
++remoteFrameIter) {
|
||||
appIdArray.AppendElement(remoteFrameIter->second.mContext.OwnOrContainingAppId());
|
||||
}
|
||||
|
||||
return Move(appIdArray);
|
||||
}
|
||||
|
||||
nsTArray<TabContext>
|
||||
ContentProcessManager::GetTabContextByContentProcess(const ContentParentId& aChildCpId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsTArray<TabContext> tabContextArray;
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return Move(tabContextArray);
|
||||
}
|
||||
|
||||
for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
|
||||
remoteFrameIter != iter->second.mRemoteFrames.end();
|
||||
++remoteFrameIter) {
|
||||
tabContextArray.AppendElement(remoteFrameIter->second.mContext);
|
||||
}
|
||||
|
||||
return Move(tabContextArray);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentProcessManager::GetRemoteFrameOpenerTabId(const ContentParentId& aChildCpId,
|
||||
const TabId& aChildTabId,
|
||||
/*out*/TabId* aOpenerTabId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
auto iter = mContentParentMap.find(aChildCpId);
|
||||
if (NS_WARN_IF(iter == mContentParentMap.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
|
||||
if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
||||
*aOpenerTabId = remoteFrameIter->second.mOpenerTabId;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
122
dom/ipc/ContentProcessManager.h
Normal file
122
dom/ipc/ContentProcessManager.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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_ContentProcessManager_h
|
||||
#define mozilla_dom_ContentProcessManager_h
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/TabContext.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class ContentParent;
|
||||
|
||||
struct RemoteFrameInfo
|
||||
{
|
||||
TabId mOpenerTabId;
|
||||
TabContext mContext;
|
||||
};
|
||||
|
||||
struct ContentProcessInfo
|
||||
{
|
||||
ContentParent* mCp;
|
||||
ContentParentId mParentCpId;
|
||||
std::set<ContentParentId> mChildrenCpId;
|
||||
std::map<TabId, RemoteFrameInfo> mRemoteFrames;
|
||||
};
|
||||
|
||||
class ContentProcessManager MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
static ContentProcessManager* GetSingleton();
|
||||
~ContentProcessManager() {MOZ_COUNT_DTOR(ContentProcessManager);};
|
||||
|
||||
/**
|
||||
* Add a new content process into the map.
|
||||
* If aParentCpId is not 0, it's a nested content process.
|
||||
*/
|
||||
void AddContentProcess(ContentParent* aChildCp,
|
||||
const ContentParentId& aParentCpId = ContentParentId(0));
|
||||
/**
|
||||
* Remove the content process by id.
|
||||
*/
|
||||
void RemoveContentProcess(const ContentParentId& aChildCpId);
|
||||
/**
|
||||
* Add a grandchild content process into the map.
|
||||
* aParentCpId must be already added in the map by AddContentProcess().
|
||||
*/
|
||||
bool AddGrandchildProcess(const ContentParentId& aParentCpId,
|
||||
const ContentParentId& aChildCpId);
|
||||
/**
|
||||
* Get the parent process's id by child process's id.
|
||||
* Used to check if a child really belongs to the parent.
|
||||
*/
|
||||
bool GetParentProcessId(const ContentParentId& aChildCpId,
|
||||
/*out*/ ContentParentId* aParentCpId);
|
||||
/**
|
||||
* Return the ContentParent pointer by id.
|
||||
*/
|
||||
ContentParent* GetContentProcessById(const ContentParentId& aChildCpId);
|
||||
|
||||
/**
|
||||
* Return a list of all child process's id.
|
||||
*/
|
||||
nsTArray<ContentParentId>
|
||||
GetAllChildProcessById(const ContentParentId& aParentCpId);
|
||||
|
||||
/**
|
||||
* Allocate a tab id for the given content process's id.
|
||||
* Used when a content process wants to create a new tab. aOpenerTabId and
|
||||
* aContext are saved in RemoteFrameInfo, which is a part of ContentProcessInfo.
|
||||
* We can use the tab id and process id to locate the TabContext for future use.
|
||||
*/
|
||||
TabId AllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const ContentParentId& aChildCpId);
|
||||
|
||||
/**
|
||||
* Remove the RemoteFrameInfo by the given process and tab id.
|
||||
*/
|
||||
void DeallocateTabId(const ContentParentId& aChildCpId,
|
||||
const TabId& aChildTabId);
|
||||
|
||||
/**
|
||||
* Get all app ids which are inside the given content process.
|
||||
* XXX Currently not used. Plan to be used for bug 1020186.
|
||||
*/
|
||||
nsTArray<uint64_t>
|
||||
GetAppIdsByContentProcess(const ContentParentId& aChildCpId);
|
||||
|
||||
/**
|
||||
* Get all TabContext which are inside the given content process.
|
||||
* Used for AppProcessChecker to cehck app status.
|
||||
*/
|
||||
nsTArray<TabContext>
|
||||
GetTabContextByContentProcess(const ContentParentId& aChildCpId);
|
||||
|
||||
/**
|
||||
* Query a tab's opener id by the given process and tab id.
|
||||
* XXX Currently not used. Plan to be used for bug 1020179.
|
||||
*/
|
||||
bool GetRemoteFrameOpenerTabId(const ContentParentId& aChildCpId,
|
||||
const TabId& aChildTabId,
|
||||
/*out*/ TabId* aOpenerTabId);
|
||||
|
||||
private:
|
||||
static StaticAutoPtr<ContentProcessManager> sSingleton;
|
||||
TabId mUniqueId;
|
||||
std::map<ContentParentId, ContentProcessInfo> mContentParentMap;
|
||||
|
||||
ContentProcessManager() {MOZ_COUNT_CTOR(ContentProcessManager);};
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
#endif
|
@ -7,9 +7,16 @@
|
||||
#ifndef mozilla_dom_IdType_h
|
||||
#define mozilla_dom_IdType_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
namespace IPC {
|
||||
template<typename T> struct ParamTraits;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class ContentParent;
|
||||
class TabParent;
|
||||
|
||||
|
||||
template<typename T>
|
||||
@ -38,6 +45,7 @@ private:
|
||||
uint64_t mId;
|
||||
};
|
||||
|
||||
typedef IdType<TabParent> TabId;
|
||||
typedef IdType<ContentParent> ContentParentId;
|
||||
|
||||
} // namespace dom
|
||||
|
21
dom/ipc/PBrowserOrId.ipdlh
Normal file
21
dom/ipc/PBrowserOrId.ipdlh
Normal file
@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=c: */
|
||||
/* 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 PBrowser;
|
||||
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
union PBrowserOrId
|
||||
{
|
||||
nullable PBrowser;
|
||||
TabId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -67,6 +67,7 @@ using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
using mozilla::dom::quota::PersistenceType from "mozilla/dom/quota/PersistenceType.h";
|
||||
using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h";
|
||||
using gfxIntSize from "nsSize.h";
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
@ -386,7 +387,7 @@ both:
|
||||
// access to (in the form of a TabChild).
|
||||
//
|
||||
// Keep the last 3 attributes in sync with GetProcessAttributes!
|
||||
async PBrowser(IPCTabContext context, uint32_t chromeFlags,
|
||||
async PBrowser(TabId tabId, IPCTabContext context, uint32_t chromeFlags,
|
||||
ContentParentId cpId, bool isForApp, bool isForBrowser);
|
||||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
@ -527,9 +528,10 @@ parent:
|
||||
ClipboardCapabilities clipboardCaps);
|
||||
|
||||
sync CreateChildProcess(IPCTabContext context,
|
||||
ProcessPriority priority)
|
||||
returns (uint64_t id, bool isForApp, bool isForBrowser);
|
||||
intr BridgeToChildProcess(uint64_t id);
|
||||
ProcessPriority priority,
|
||||
TabId openerTabId)
|
||||
returns (ContentParentId cpId, bool isForApp, bool isForBrowser, TabId tabId);
|
||||
intr BridgeToChildProcess(ContentParentId cpId);
|
||||
|
||||
async PJavaScript();
|
||||
|
||||
@ -744,6 +746,14 @@ parent:
|
||||
returns (int32_t refCnt, int32_t dBRefCnt, int32_t sliceRefCnt,
|
||||
bool result);
|
||||
|
||||
/**
|
||||
* Tell the chrome process there is an creation of PBrowser.
|
||||
* return a system-wise unique Id.
|
||||
*/
|
||||
sync AllocateTabId(TabId openerTabId, IPCTabContext context, ContentParentId cpId)
|
||||
returns (TabId tabId);
|
||||
async DeallocateTabId(TabId tabId);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal);
|
||||
|
@ -14,6 +14,7 @@ include JavaScriptTypes;
|
||||
include PTabContext;
|
||||
|
||||
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
namespace mozilla {
|
||||
@ -42,7 +43,7 @@ parent:
|
||||
both:
|
||||
// Both the parent and the child can construct the PBrowser.
|
||||
// See the comment in PContent::PBrowser().
|
||||
async PBrowser(IPCTabContext context, uint32_t chromeFlags,
|
||||
async PBrowser(TabId tabId, IPCTabContext context, uint32_t chromeFlags,
|
||||
ContentParentId cpId, bool isForApp, bool isForBrowser);
|
||||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBrowser;
|
||||
|
||||
include PBrowserOrId;
|
||||
|
||||
using mozilla::layout::ScrollingBehavior from "mozilla/layout/RenderFrameUtils.h";
|
||||
|
||||
@ -27,7 +27,7 @@ namespace dom {
|
||||
// it.
|
||||
struct PopupIPCTabContext
|
||||
{
|
||||
PBrowser opener;
|
||||
PBrowserOrId opener;
|
||||
bool isBrowserElement;
|
||||
};
|
||||
|
||||
|
@ -733,11 +733,11 @@ private:
|
||||
StaticRefPtr<TabChild> sPreallocatedTab;
|
||||
|
||||
/*static*/
|
||||
std::map<uint64_t, nsRefPtr<TabChild> >&
|
||||
std::map<TabId, nsRefPtr<TabChild>>&
|
||||
TabChild::NestedTabChildMap()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
static std::map<uint64_t, nsRefPtr<TabChild> > sNestedTabChildMap;
|
||||
static std::map<TabId, nsRefPtr<TabChild>> sNestedTabChildMap;
|
||||
return sNestedTabChildMap;
|
||||
}
|
||||
|
||||
@ -750,6 +750,7 @@ TabChild::PreloadSlowThings()
|
||||
// not connected to any manager. Any attempt to use the TabChild
|
||||
// in IPC will crash.
|
||||
nsRefPtr<TabChild> tab(new TabChild(nullptr,
|
||||
TabId(0),
|
||||
TabContext(), /* chromeFlags */ 0));
|
||||
if (!NS_SUCCEEDED(tab->Init()) ||
|
||||
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
|
||||
@ -780,6 +781,7 @@ TabChild::PreloadSlowThings()
|
||||
|
||||
/*static*/ already_AddRefed<TabChild>
|
||||
TabChild::Create(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext &aContext,
|
||||
uint32_t aChromeFlags)
|
||||
{
|
||||
@ -793,18 +795,20 @@ TabChild::Create(nsIContentChild* aManager,
|
||||
MOZ_ASSERT(!child->mTriedBrowserInit);
|
||||
|
||||
child->mManager = aManager;
|
||||
child->SetTabId(aTabId);
|
||||
child->SetTabContext(aContext);
|
||||
child->NotifyTabContextUpdated();
|
||||
return child.forget();
|
||||
}
|
||||
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aManager,
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aManager, aTabId,
|
||||
aContext, aChromeFlags);
|
||||
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
TabChild::TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags)
|
||||
: TabContext(aContext)
|
||||
@ -827,8 +831,8 @@ TabChild::TabChild(nsIContentChild* aManager,
|
||||
, mIgnoreKeyPressEvent(false)
|
||||
, mActiveElementManager(new ActiveElementManager())
|
||||
, mHasValidInnerSize(false)
|
||||
, mUniqueId(0)
|
||||
, mDestroyed(false)
|
||||
, mUniqueId(aTabId)
|
||||
{
|
||||
if (!sActiveDurationMsSet) {
|
||||
Preferences::AddIntVarCache(&sActiveDurationMs,
|
||||
@ -836,6 +840,12 @@ TabChild::TabChild(nsIContentChild* aManager,
|
||||
sActiveDurationMs);
|
||||
sActiveDurationMsSet = true;
|
||||
}
|
||||
|
||||
// preloaded TabChild should not be added to child map
|
||||
if (mUniqueId) {
|
||||
MOZ_ASSERT(NestedTabChildMap().find(mUniqueId) == NestedTabChildMap().end());
|
||||
NestedTabChildMap()[mUniqueId] = this;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1433,26 +1443,36 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
{
|
||||
*aReturn = nullptr;
|
||||
|
||||
nsRefPtr<TabChild> newChild =
|
||||
new TabChild(ContentChild::GetSingleton(),
|
||||
/* TabContext */ *this, /* chromeFlags */ 0);
|
||||
if (!NS_SUCCEEDED(newChild->Init())) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
const TabId openerTabId = GetTabId();
|
||||
|
||||
// We must use PopupIPCTabContext here; ContentParent will not accept the
|
||||
// result of this->AsIPCTabContext() (which will be a
|
||||
// BrowserFrameIPCTabContext or an AppFrameIPCTabContext), for security
|
||||
// reasons.
|
||||
PopupIPCTabContext context;
|
||||
context.openerChild() = this;
|
||||
context.opener() = openerTabId;
|
||||
context.isBrowserElement() = IsBrowserElement();
|
||||
|
||||
ContentChild* cc = static_cast<ContentChild*>(Manager());
|
||||
IPCTabContext ipcContext(context, mScrolling);
|
||||
|
||||
TabId tabId;
|
||||
cc->SendAllocateTabId(openerTabId,
|
||||
ipcContext,
|
||||
cc->GetID(),
|
||||
&tabId);
|
||||
|
||||
nsRefPtr<TabChild> newChild = new TabChild(ContentChild::GetSingleton(), tabId,
|
||||
/* TabContext */ *this, /* chromeFlags */ 0);
|
||||
if (NS_FAILED(newChild->Init())) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
context.opener() = this;
|
||||
unused << Manager()->SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
nsRefPtr<TabChild>(newChild).forget().take(),
|
||||
IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
|
||||
tabId, IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
|
||||
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
|
||||
|
||||
nsAutoCString spec;
|
||||
@ -1562,8 +1582,8 @@ TabChild::ActorDestroy(ActorDestroyReason why)
|
||||
CompositorChild* compositorChild = static_cast<CompositorChild*>(CompositorChild::Get());
|
||||
compositorChild->CancelNotifyAfterRemotePaint(this);
|
||||
|
||||
if (Id() != 0) {
|
||||
NestedTabChildMap().erase(Id());
|
||||
if (GetTabId() != 0) {
|
||||
NestedTabChildMap().erase(GetTabId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "nsIWebBrowserChrome3.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
|
||||
class nsICachedFileDescriptorListener;
|
||||
class nsIDOMWindowUtils;
|
||||
@ -254,7 +255,7 @@ class TabChild MOZ_FINAL : public TabChildBase,
|
||||
typedef mozilla::layers::ActiveElementManager ActiveElementManager;
|
||||
|
||||
public:
|
||||
static std::map<uint64_t, nsRefPtr<TabChild> >& NestedTabChildMap();
|
||||
static std::map<TabId, nsRefPtr<TabChild>>& NestedTabChildMap();
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -266,26 +267,13 @@ public:
|
||||
|
||||
/** Return a TabChild with the given attributes. */
|
||||
static already_AddRefed<TabChild>
|
||||
Create(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
Create(nsIContentChild* aManager, const TabId& aTabId, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
|
||||
bool IsRootContentDocument();
|
||||
|
||||
const uint64_t Id() const {
|
||||
return mUniqueId;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
GetTabChildId(TabChild* aTabChild)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (aTabChild->Id() != 0) {
|
||||
return aTabChild->Id();
|
||||
}
|
||||
static uint64_t sId = 0;
|
||||
sId++;
|
||||
aTabChild->mUniqueId = sId;
|
||||
NestedTabChildMap()[sId] = aTabChild;
|
||||
return sId;
|
||||
const TabId GetTabId() const {
|
||||
MOZ_ASSERT(mUniqueId != 0);
|
||||
return mUniqueId;
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -516,7 +504,10 @@ private:
|
||||
*
|
||||
* |aIsBrowserElement| indicates whether we're a browser (but not an app).
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
@ -564,6 +555,14 @@ private:
|
||||
void SendPendingTouchPreventedResponse(bool aPreventDefault,
|
||||
const ScrollableLayerGuid& aGuid);
|
||||
|
||||
void SetTabId(const TabId& aTabId)
|
||||
{
|
||||
MOZ_ASSERT(mUniqueId == 0);
|
||||
|
||||
mUniqueId = aTabId;
|
||||
NestedTabChildMap()[mUniqueId] = this;
|
||||
}
|
||||
|
||||
class CachedFileDescriptorInfo;
|
||||
class CachedFileDescriptorCallbackRunnable;
|
||||
|
||||
@ -606,8 +605,8 @@ private:
|
||||
bool mIgnoreKeyPressEvent;
|
||||
nsRefPtr<ActiveElementManager> mActiveElementManager;
|
||||
bool mHasValidInnerSize;
|
||||
uint64_t mUniqueId;
|
||||
bool mDestroyed;
|
||||
TabId mUniqueId;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
@ -256,8 +256,8 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext();
|
||||
|
||||
TabContext *context;
|
||||
if (ipcContext.openerParent()) {
|
||||
context = static_cast<TabParent*>(ipcContext.openerParent());
|
||||
if (ipcContext.opener().type() == PBrowserOrId::TPBrowserParent) {
|
||||
context = static_cast<TabParent*>(ipcContext.opener().get_PBrowserParent());
|
||||
if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
|
||||
// If the TabParent corresponds to a browser element, then it can only
|
||||
// open other browser elements, for security reasons. We should have
|
||||
@ -267,8 +267,13 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
"open a non-browser tab.";
|
||||
return;
|
||||
}
|
||||
} else if (ipcContext.openerChild()) {
|
||||
context = static_cast<TabChild*>(ipcContext.openerChild());
|
||||
} else if (ipcContext.opener().type() == PBrowserOrId::TPBrowserChild) {
|
||||
context = static_cast<TabChild*>(ipcContext.opener().get_PBrowserChild());
|
||||
} else if (ipcContext.opener().type() == PBrowserOrId::TTabId) {
|
||||
// We should never get here because this PopupIPCTabContext is only
|
||||
// used for allocating a new tab id, not for allocating a PBrowser.
|
||||
mInvalidReason = "Child process tried to open an tab without the opener information.";
|
||||
return;
|
||||
} else {
|
||||
// This should be unreachable because PopupIPCTabContext::opener is not a
|
||||
// nullable field.
|
||||
|
@ -218,7 +218,10 @@ NS_IMPL_ISUPPORTS(TabParent,
|
||||
nsISecureBrowserUI,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
TabParent::TabParent(nsIContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags)
|
||||
TabParent::TabParent(nsIContentParent* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags)
|
||||
: TabContext(aContext)
|
||||
, mFrameElement(nullptr)
|
||||
, mIMESelectionAnchor(0)
|
||||
@ -242,6 +245,7 @@ TabParent::TabParent(nsIContentParent* aManager, const TabContext& aContext, uin
|
||||
, mAppPackageFileDescriptorSent(false)
|
||||
, mSendOfflineStatus(true)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mTabId(aTabId)
|
||||
{
|
||||
MOZ_ASSERT(aManager);
|
||||
}
|
||||
@ -318,7 +322,13 @@ TabParent::Recv__delete__()
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
Manager()->AsContentParent()->NotifyTabDestroyed(this, mMarkedDestroying);
|
||||
ContentParent::DeallocateTabId(mTabId,
|
||||
Manager()->AsContentParent()->ChildID());
|
||||
}
|
||||
else {
|
||||
ContentParent::DeallocateTabId(mTabId, ContentParentId(0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1648,6 +1658,16 @@ TabParent::GetFrom(nsIContent* aContent)
|
||||
return GetFrom(frameLoader);
|
||||
}
|
||||
|
||||
/*static*/ TabId
|
||||
TabParent::GetTabIdFrom(nsIDocShell *docShell)
|
||||
{
|
||||
nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
|
||||
if (tabChild) {
|
||||
return static_cast<TabChild*>(tabChild.get())->GetTabId();
|
||||
}
|
||||
return TabId(0);
|
||||
}
|
||||
|
||||
RenderFrameParent*
|
||||
TabParent::GetRenderFrame()
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/dom/PFilePickerParent.h"
|
||||
#include "mozilla/dom/TabContext.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
@ -28,6 +29,7 @@ class nsIURI;
|
||||
class nsIWidget;
|
||||
class nsILoadContext;
|
||||
class CpowHolder;
|
||||
class nsIDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -67,7 +69,10 @@ public:
|
||||
// nsITabParent
|
||||
NS_DECL_NSITABPARENT
|
||||
|
||||
TabParent(nsIContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
TabParent(nsIContentParent* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
Element* GetOwnerElement() const { return mFrameElement; }
|
||||
void SetOwnerElement(Element* aElement);
|
||||
|
||||
@ -322,6 +327,7 @@ public:
|
||||
|
||||
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
|
||||
static TabParent* GetFrom(nsIContent* aContent);
|
||||
static TabId GetTabIdFrom(nsIDocShell* docshell);
|
||||
|
||||
nsIContentParent* Manager() { return mManager; }
|
||||
|
||||
@ -333,6 +339,11 @@ public:
|
||||
|
||||
already_AddRefed<nsIWidget> GetWidget() const;
|
||||
|
||||
const TabId GetTabId() const
|
||||
{
|
||||
return mTabId;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
@ -435,6 +446,8 @@ private:
|
||||
uint32_t mChromeFlags;
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
||||
TabId mTabId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -21,6 +21,7 @@ EXPORTS.mozilla.dom += [
|
||||
'ContentChild.h',
|
||||
'ContentParent.h',
|
||||
'ContentProcess.h',
|
||||
'ContentProcessManager.h',
|
||||
'CPOWManagerGetter.h',
|
||||
'CrashReporterChild.h',
|
||||
'CrashReporterParent.h',
|
||||
@ -48,6 +49,7 @@ UNIFIED_SOURCES += [
|
||||
'ContentBridgeParent.cpp',
|
||||
'ContentParent.cpp',
|
||||
'ContentProcess.cpp',
|
||||
'ContentProcessManager.cpp',
|
||||
'CrashReporterParent.cpp',
|
||||
'FilePickerParent.cpp',
|
||||
'nsIContentChild.cpp',
|
||||
@ -78,6 +80,7 @@ IPDL_SOURCES += [
|
||||
'PBlob.ipdl',
|
||||
'PBlobStream.ipdl',
|
||||
'PBrowser.ipdl',
|
||||
'PBrowserOrId.ipdlh',
|
||||
'PColorPicker.ipdl',
|
||||
'PContent.ipdl',
|
||||
'PContentBridge.ipdl',
|
||||
|
@ -50,7 +50,8 @@ nsIContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild)
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
nsIContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
nsIContentChild::AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
@ -69,7 +70,7 @@ nsIContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
}
|
||||
|
||||
nsRefPtr<TabChild> child =
|
||||
TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
|
||||
TabChild::Create(this, aTabId, tc.GetTabContext(), aChromeFlags);
|
||||
|
||||
// The ref here is released in DeallocPBrowserChild.
|
||||
return child.forget().take();
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
|
||||
virtual bool
|
||||
SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID,
|
||||
@ -63,7 +64,8 @@ protected:
|
||||
virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild();
|
||||
virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*);
|
||||
|
||||
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
|
||||
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
|
@ -24,6 +24,13 @@
|
||||
|
||||
using namespace mozilla::jsipc;
|
||||
|
||||
// XXX need another bug to move this to a common header.
|
||||
#ifdef DISABLE_ASSERTS_FOR_FUZZING
|
||||
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
|
||||
#else
|
||||
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -74,14 +81,19 @@ nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
||||
// (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.");
|
||||
ASSERT_UNLESS_FUZZING("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext();
|
||||
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
|
||||
if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
|
||||
ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto opener = static_cast<TabParent*>(popupContext.opener().get_PBrowserParent());
|
||||
if (!opener) {
|
||||
NS_ERROR("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -89,7 +101,7 @@ nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
||||
// 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.");
|
||||
ASSERT_UNLESS_FUZZING("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -105,7 +117,8 @@ nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
nsIContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
@ -121,7 +134,7 @@ nsIContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
MOZ_ASSERT(tc.IsValid());
|
||||
TabParent* parent = new TabParent(this, tc.GetTabContext(), aChromeFlags);
|
||||
TabParent* parent = new TabParent(this, aTabId, tc.GetTabContext(), aChromeFlags);
|
||||
|
||||
// We release this ref in DeallocPBrowserParent()
|
||||
NS_ADDREF(parent);
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
PBrowserParent* actor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
@ -77,7 +78,8 @@ protected: // IPDL methods
|
||||
virtual mozilla::jsipc::PJavaScriptParent* AllocPJavaScriptParent();
|
||||
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*);
|
||||
|
||||
virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
|
||||
virtual PBrowserParent* AllocPBrowserParent(const TabId& aTabId,
|
||||
const IPCTabContext& aContext,
|
||||
const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
|
@ -26,18 +26,13 @@ include protocol PRtspChannel;
|
||||
include URIParams;
|
||||
include InputStreamParams;
|
||||
include NeckoChannelParams;
|
||||
|
||||
include PBrowserOrId;
|
||||
|
||||
using class IPC::SerializedLoadContext from "SerializedLoadContext.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
union PBrowserOrId {
|
||||
nullable PBrowser;
|
||||
uint64_t;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
sync protocol PNecko
|
||||
{
|
||||
|
@ -27,12 +27,12 @@ namespace mozilla {
|
||||
|
||||
namespace dom{
|
||||
class TabParent;
|
||||
class PBrowserOrId;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
|
||||
class HttpChannelParentListener;
|
||||
class PBrowserOrId;
|
||||
|
||||
class HttpChannelParent : public PHttpChannelParent
|
||||
, public nsIParentRedirectingChannel
|
||||
@ -54,7 +54,7 @@ public:
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
|
||||
HttpChannelParent(const PBrowserOrId& iframeEmbedding,
|
||||
HttpChannelParent(const dom::PBrowserOrId& iframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
PBOverrideStatus aStatus);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user