Bug 1337064 - Remove sync protocol PContent::AllocateTabId. r?kanru
Remove sync protocol AllocateTabId. Instead we generate tabId in
each process with nsContentUtils::GenerateTabId, and register
RemoteFrameInfo in parent process. If the tab id was generated from
a content process, it's sent parent through either PBrowserConstructor
or PContent::CreateChildProcess.
MozReview-Commit-ID: D3W2fK9eCNH
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -10269,9 +10269,34 @@ nsContentUtils::IsLocalRefURL(const nsSt
if (*current > 0x20) {
// if the first non-"C0 controls + space" character is '#', this is a
// local-ref URL.
return *current == '#';
}
}
return false;
-}
\ No newline at end of file
+}
+
+// Tab ID is composed in a similar manner of Window ID.
+static uint64_t gNextTabId = 0;
+static const uint64_t kTabIdProcessBits = 32;
+static const uint64_t kTabIdTabBits = 64 - kTabIdProcessBits;
+
+/* static */ uint64_t
+nsContentUtils::GenerateTabId()
+{
+ uint64_t processId = 0;
+ if (XRE_IsContentProcess()) {
+ ContentChild* cc = ContentChild::GetSingleton();
+ processId = cc->GetID();
+ }
+
+ MOZ_RELEASE_ASSERT(processId < (uint64_t(1) << kTabIdProcessBits));
+ uint64_t processBits = processId & ((uint64_t(1) << kTabIdProcessBits) - 1);
+
+ uint64_t tabId = ++gNextTabId;
+ MOZ_RELEASE_ASSERT(tabId < (uint64_t(1) << kTabIdTabBits));
+ uint64_t tabBits = tabId & ((uint64_t(1) << kTabIdTabBits) - 1);
+
+ return (processBits << kTabIdTabBits) | tabBits;
+
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2868,16 +2868,21 @@ public:
* https://drafts.csswg.org/css-values/#local-urls
*/
static bool
IsLocalRefURL(const nsString& aString);
static bool
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
+ /**
+ * Compose a tab id with process id and a serial number.
+ */
+ static uint64_t GenerateTabId();
+
private:
static bool InitializeEventTable();
static nsresult EnsureStringBundle(PropertiesFile aFile);
static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
nsIPrincipal* aPrincipal);
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -767,21 +767,17 @@ ContentChild::ProvideWindowCommon(TabChi
} else {
// It's possible to not have a TabChild opener in the case
// of ServiceWorker::OpenWindow.
UnsafeIPCTabContext unsafeTabContext;
ipcContext = new IPCTabContext(unsafeTabContext);
}
MOZ_ASSERT(ipcContext);
- TabId tabId;
- SendAllocateTabId(openerTabId,
- *ipcContext,
- GetID(),
- &tabId);
+ TabId tabId(nsContentUtils::GenerateTabId());
// We need to assign a TabGroup to the PBrowser actor before we send it to the
// parent. Otherwise, the parent could send messages to us before we have a
// proper TabGroup for that actor.
RefPtr<TabGroup> tabGroup;
if (aTabOpener && !aForceNoOpener) {
// The new actor will use the same tab group as the opener.
tabGroup = aTabOpener->TabGroup();
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -898,19 +898,19 @@ ContentParent::SendAsyncUpdate(nsIWidget
}
}
#endif // defined(XP_WIN)
mozilla::ipc::IPCResult
ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
const hal::ProcessPriority& aPriority,
const TabId& aOpenerTabId,
+ const TabId& aTabId,
ContentParentId* aCpId,
- bool* aIsForBrowser,
- TabId* aTabId)
+ bool* aIsForBrowser)
{
#if 0
if (!CanOpenBrowser(aContext)) {
return false;
}
#endif
RefPtr<ContentParent> cp;
MaybeInvalidTabContext tc(aContext);
@@ -931,22 +931,18 @@ ContentParent::RecvCreateChildProcess(co
}
*aCpId = cp->ChildID();
*aIsForBrowser = cp->IsForBrowser();
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());
- if (*aTabId == 0) {
- return IPC_FAIL_NO_REASON(this);
- }
+ if (cpm->AddGrandchildProcess(this->ChildID(), cp->ChildID()) &&
+ cpm->RegisterRemoteFrame(aTabId, aOpenerTabId, aContext, cp->ChildID())) {
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
}
mozilla::ipc::IPCResult
ContentParent::RecvBridgeToChildProcess(const ContentParentId& aCpId,
@@ -1162,17 +1158,17 @@ ContentParent::CreateBrowser(const TabCo
if (TabParent* parent = TabParent::GetNextTabParent()) {
parent->SetOwnerElement(aFrameElement);
return parent;
}
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
bool isInContentProcess = !XRE_IsParentProcess();
- TabId tabId;
+ TabId tabId(nsContentUtils::GenerateTabId());
nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
TabId openerTabId;
if (docShell) {
openerTabId = TabParent::GetTabIdFrom(docShell);
}
nsAutoString remoteType;
@@ -1180,30 +1176,32 @@ ContentParent::CreateBrowser(const TabCo
remoteType)) {
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
}
RefPtr<nsIContentParent> constructorSender;
if (isInContentProcess) {
MOZ_ASSERT(aContext.IsMozBrowserElement());
constructorSender = CreateContentBridgeParent(aContext, initialPriority,
- openerTabId, &tabId);
+ openerTabId, tabId);
} else {
if (aOpenerContentParent) {
constructorSender = aOpenerContentParent;
} else {
constructorSender =
GetNewOrUsedBrowserProcess(remoteType, initialPriority, nullptr);
if (!constructorSender) {
return nullptr;
}
}
- tabId = AllocateTabId(openerTabId,
- aContext.AsIPCTabContext(),
- constructorSender->ChildID());
+ ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
+ cpm->RegisterRemoteFrame(tabId,
+ openerTabId,
+ aContext.AsIPCTabContext(),
+ constructorSender->ChildID());
}
if (constructorSender) {
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
if (!treeOwner) {
return nullptr;
}
@@ -1253,29 +1251,29 @@ ContentParent::CreateBrowser(const TabCo
}
return nullptr;
}
/*static*/ ContentBridgeParent*
ContentParent::CreateContentBridgeParent(const TabContext& aContext,
const hal::ProcessPriority& aPriority,
const TabId& aOpenerTabId,
- /*out*/ TabId* aTabId)
+ const TabId& aTabId)
{
MOZ_ASSERT(aTabId);
ContentChild* child = ContentChild::GetSingleton();
ContentParentId cpId;
bool isForBrowser;
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
aPriority,
aOpenerTabId,
+ aTabId,
&cpId,
- &isForBrowser,
- aTabId)) {
+ &isForBrowser)) {
return nullptr;
}
if (cpId == 0) {
return nullptr;
}
Endpoint<PContentBridgeParent> endpoint;
if (!child->SendBridgeToChildProcess(cpId, &endpoint)) {
return nullptr;
@@ -4165,72 +4163,40 @@ ContentParent::NotifyUpdatedDictionaries
InfallibleTArray<nsString> dictionaries;
spellChecker->GetDictionaryList(&dictionaries);
for (auto* cp : AllProcesses(eLive)) {
Unused << cp->SendUpdateDictionaryList(dictionaries);
}
}
-/*static*/ TabId
-ContentParent::AllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId)
-{
- TabId tabId;
- if (XRE_IsParentProcess()) {
- 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,
+ContentParent::UnregisterRemoteFrame(const TabId& aTabId,
const ContentParentId& aCpId,
bool aMarkedDestroying)
{
if (XRE_IsParentProcess()) {
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
ContentParent* cp = cpm->GetContentProcessById(aCpId);
cp->NotifyTabDestroyed(aTabId, aMarkedDestroying);
- ContentProcessManager::GetSingleton()->DeallocateTabId(aCpId, aTabId);
+ ContentProcessManager::GetSingleton()->UnregisterRemoteFrame(aCpId, aTabId);
} else {
- ContentChild::GetSingleton()->SendDeallocateTabId(aTabId, aCpId,
+ ContentChild::GetSingleton()->SendUnregisterRemoteFrame(aTabId, aCpId,
aMarkedDestroying);
}
}
mozilla::ipc::IPCResult
-ContentParent::RecvAllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId,
- TabId* aTabId)
-{
- *aTabId = AllocateTabId(aOpenerTabId, aContext, aCpId);
- if (!(*aTabId)) {
- return IPC_FAIL_NO_REASON(this);
- }
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-ContentParent::RecvDeallocateTabId(const TabId& aTabId,
+ContentParent::RecvUnregisterRemoteFrame(const TabId& aTabId,
const ContentParentId& aCpId,
const bool& aMarkedDestroying)
{
- DeallocateTabId(aTabId, aCpId, aMarkedDestroying);
+ UnregisterRemoteFrame(aTabId, aCpId, aMarkedDestroying);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvNotifyTabDestroying(const TabId& aTabId,
const ContentParentId& aCpId)
{
NotifyTabDestroying(aTabId, aCpId);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -273,19 +273,19 @@ public:
#endif
// Let managees query if it is safe to send messages.
bool IsDestroyed() const { return !mIPCOpen; }
virtual mozilla::ipc::IPCResult RecvCreateChildProcess(const IPCTabContext& aContext,
const hal::ProcessPriority& aPriority,
const TabId& aOpenerTabId,
+ const TabId& aTabId,
ContentParentId* aCpId,
- bool* aIsForBrowser,
- TabId* aTabId) override;
+ bool* aIsForBrowser) override;
virtual mozilla::ipc::IPCResult RecvBridgeToChildProcess(const ContentParentId& aCpId,
Endpoint<PContentBridgeParent>* aEndpoint) override;
virtual mozilla::ipc::IPCResult RecvCreateGMPService() override;
virtual mozilla::ipc::IPCResult RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv,
uint32_t* aRunID,
@@ -344,25 +344,20 @@ public:
TestShellParent* CreateTestShell();
bool DestroyTestShell(TestShellParent* aTestShell);
TestShellParent* GetTestShellSingleton();
jsipc::CPOWManager* GetCPOWManager() override;
- static TabId
- AllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId);
-
static void
- DeallocateTabId(const TabId& aTabId,
- const ContentParentId& aCpId,
- bool aMarkedDestroying);
+ UnregisterRemoteFrame(const TabId& aTabId,
+ const ContentParentId& aCpId,
+ bool aMarkedDestroying);
void ReportChildAlreadyBlocked();
bool RequestRunToCompletion();
bool IsAvailable() const
{
return mIsAvailable;
@@ -483,24 +478,19 @@ public:
bool CycleCollectWithLogs(bool aDumpAllTraces,
nsICycleCollectorLogSink* aSink,
nsIDumpGCAndCCLogsCallback* aCallback);
virtual PBlobParent*
SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams) override;
- virtual mozilla::ipc::IPCResult RecvAllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId,
- TabId* aTabId) override;
-
- virtual mozilla::ipc::IPCResult RecvDeallocateTabId(const TabId& aTabId,
- const ContentParentId& aCpId,
- const bool& aMarkedDestroying) override;
+ virtual mozilla::ipc::IPCResult RecvUnregisterRemoteFrame(const TabId& aTabId,
+ const ContentParentId& aCpId,
+ const bool& aMarkedDestroying) override;
virtual mozilla::ipc::IPCResult RecvNotifyTabDestroying(const TabId& aTabId,
const ContentParentId& aCpId) override;
virtual mozilla::ipc::IPCResult RecvTabChildNotReady(const TabId& aTabId) override;
nsTArray<TabContext> GetManagedTabContext();
@@ -688,17 +678,17 @@ private:
static void JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
Monitor* aMonitor, bool* aDone);
static hal::ProcessPriority GetInitialProcessPriority(Element* aFrameElement);
static ContentBridgeParent* CreateContentBridgeParent(const TabContext& aContext,
const hal::ProcessPriority& aPriority,
const TabId& aOpenerTabId,
- /*out*/ TabId* aTabId);
+ const 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 TabId& aSameTabGroupsAs,
const IPCTabContext& context,
--- a/dom/ipc/ContentProcessManager.cpp
+++ b/dom/ipc/ContentProcessManager.cpp
@@ -19,18 +19,16 @@
#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_IsParentProcess());
@@ -130,74 +128,63 @@ ContentProcessManager::GetAllChildProces
cpIter != iter->second.mChildrenCpId.end();
++cpIter) {
cpIdArray.AppendElement(*cpIter);
}
return Move(cpIdArray);
}
-TabId
-ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aChildCpId)
+bool
+ContentProcessManager::RegisterRemoteFrame(const TabId& aTabId,
+ 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);
+ return false;
}
struct RemoteFrameInfo info;
// 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 (aContext.type() == IPCTabContext::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);
+ return false;
}
info.mOpenerTabId = remoteFrameIter->second.mOpenerTabId;
-
- const PopupIPCTabContext &ipcContext = aContext.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);
+ return false;
}
info.mOpenerTabId = aOpenerTabId;
info.mContext = tc.GetTabContext();
}
- mUniqueId = ++gTabId;
- iter->second.mRemoteFrames[mUniqueId] = info;
-
- return mUniqueId;
+ iter->second.mRemoteFrames[aTabId] = info;
+ return true;
}
void
-ContentProcessManager::DeallocateTabId(const ContentParentId& aChildCpId,
- const TabId& aChildTabId)
+ContentProcessManager::UnregisterRemoteFrame(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;
}
--- a/dom/ipc/ContentProcessManager.h
+++ b/dom/ipc/ContentProcessManager.h
@@ -67,31 +67,33 @@ public:
/**
* 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.
+ * Register RemoteFrameInfo with given tab 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);
+ bool RegisterRemoteFrame(const TabId& aTabId,
+ 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);
+ void UnregisterRemoteFrame(const ContentParentId& aChildCpId,
+ const TabId& aChildTabId);
/**
* Get the TabContext by the given content process and tab id.
*/
bool
GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabContext* aTabContext);
@@ -146,17 +148,16 @@ public:
* is belong to the chrome process.
*/
already_AddRefed<TabParent>
GetTopLevelTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId);
private:
static StaticAutoPtr<ContentProcessManager> sSingleton;
- TabId mUniqueId;
std::map<ContentParentId, ContentProcessInfo> mContentParentMap;
ContentProcessManager() {MOZ_COUNT_CTOR(ContentProcessManager);};
};
} // namespace dom
} // namespace mozilla
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -609,18 +609,19 @@ child:
async RefreshScreens(ScreenDetails[] aScreens);
parent:
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
sync CreateChildProcess(IPCTabContext context,
ProcessPriority priority,
- TabId openerTabId)
- returns (ContentParentId cpId, bool isForBrowser, TabId tabId);
+ TabId openerTabId,
+ TabId tabId)
+ returns (ContentParentId cpId, bool isForBrowser);
sync BridgeToChildProcess(ContentParentId cpId)
returns (Endpoint<PContentBridgeParent> endpoint);
async CreateGMPService();
/**
* This call connects the content process to a plugin process. This call
* returns an endpoint for a new PluginModuleParent. The corresponding
@@ -900,25 +901,20 @@ parent:
returns (nsString newValue);
/**
* Called to provide the options for <keygen> elements.
*/
sync KeygenProvideContent()
returns (nsString aAttribute, nsString[] aContent);
- /**
- * 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,
- ContentParentId cpId,
- bool aMarkedDestroying);
+ /** Clear RemoteFrameInfo of the given tab id. */
+ async UnregisterRemoteFrame(TabId tabId,
+ ContentParentId cpId,
+ bool aMarkedDestroying);
/**
* Tell the chrome process there is a destruction of PBrowser(Tab)
*/
async NotifyTabDestroying(TabId tabId,
ContentParentId cpId);
async TabChildNotReady(TabId tabId);
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -408,25 +408,25 @@ TabParent::RecvEnsureLayersConnected(Com
}
return IPC_OK();
}
mozilla::ipc::IPCResult
TabParent::Recv__delete__()
{
if (XRE_IsParentProcess()) {
- ContentParent::DeallocateTabId(mTabId,
- Manager()->AsContentParent()->ChildID(),
- mMarkedDestroying);
+ ContentParent::UnregisterRemoteFrame(mTabId,
+ Manager()->AsContentParent()->ChildID(),
+ mMarkedDestroying);
}
else {
Manager()->AsContentBridgeParent()->NotifyTabDestroyed();
- ContentParent::DeallocateTabId(mTabId,
- Manager()->ChildID(),
- mMarkedDestroying);
+ ContentParent::UnregisterRemoteFrame(mTabId,
+ Manager()->ChildID(),
+ mMarkedDestroying);
}
return IPC_OK();
}
void
TabParent::ActorDestroy(ActorDestroyReason why)
{
--- a/dom/ipc/nsIContentParent.cpp
+++ b/dom/ipc/nsIContentParent.cpp
@@ -5,16 +5,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIContentParent.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentBridgeParent.h"
+#include "mozilla/dom/ContentProcessManager.h"
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/MemoryStreamParent.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/ipc/FileDescriptorSetParent.h"
@@ -132,36 +133,62 @@ nsIContentParent::AllocPBrowserParent(co
Unused << aCpId;
Unused << aIsForBrowser;
if (!CanOpenBrowser(aContext)) {
return nullptr;
}
uint32_t chromeFlags = aChromeFlags;
+ TabId openerTabId(0);
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
// CanOpenBrowser has ensured that the IPCTabContext is of
// type PopupIPCTabContext, and that the opener TabParent is
// reachable.
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
+ openerTabId = opener->GetTabId();
+
// We must ensure that the private browsing and remoteness flags
// match those of the opener.
nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
if (!loadContext) {
return nullptr;
}
bool isPrivate;
loadContext->GetUsePrivateBrowsing(&isPrivate);
if (isPrivate) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
}
}
+ if (openerTabId > 0 ||
+ aContext.type() == IPCTabContext::TUnsafeIPCTabContext) {
+ // Creation of PBrowser triggered from grandchild process is currently
+ // broken and not supported (i.e. this code path doesn't work in
+ // ContentBridgeParent).
+ //
+ // If you're working on fixing the code path for ContentBridgeParent,
+ // remember to handle the remote frame registration below carefully as it
+ // has to be registered in parent process.
+ MOZ_ASSERT(XRE_IsParentProcess());
+ if (!XRE_IsParentProcess()) {
+ return nullptr;
+ }
+
+ // The creation of PBrowser was triggered from content process through
+ // either window.open() or service worker's openWindow().
+ // We need to register remote frame with the child generated tab id.
+ ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
+ if (!cpm->RegisterRemoteFrame(aTabId, openerTabId, aContext, aCpId)) {
+ return nullptr;
+ }
+ }
+
// And because we're allocating a remote browser, of course the
// window is remote.
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
MaybeInvalidTabContext tc(aContext);
MOZ_ASSERT(tc.IsValid());
TabParent* parent = new TabParent(this, aTabId, tc.GetTabContext(), chromeFlags);
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -912,18 +912,16 @@ description =
[PContent::BeginDriverCrashGuard]
description =
[PContent::EndDriverCrashGuard]
description =
[PContent::KeygenProcessValue]
description =
[PContent::KeygenProvideContent]
description =
-[PContent::AllocateTabId]
-description =
[PContent::GetGraphicsDeviceInitData]
description =
[PContent::CreateWindow]
description =
[PContent::GetAndroidSystemInfo]
description =
[PContent::UngrabPointer]
description =