зеркало из https://github.com/mozilla/gecko-dev.git
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 --HG-- extra : rebase_source : 1913f8f586537be1c82a70a19cc8c6351671d0df
This commit is contained in:
Родитель
e7a1ec743f
Коммит
d5dd0ed263
|
@ -10273,4 +10273,29 @@ nsContentUtils::IsLocalRefURL(const nsString& aString)
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
|
|
@ -2873,6 +2873,11 @@ public:
|
|||
static bool
|
||||
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
||||
|
||||
/**
|
||||
* Compose a tab id with process id and a serial number.
|
||||
*/
|
||||
static uint64_t GenerateTabId();
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
@ -774,11 +774,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -909,9 +909,9 @@ 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)) {
|
||||
|
@ -942,12 +942,8 @@ ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
|
|||
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();
|
||||
}
|
||||
|
||||
|
@ -1179,7 +1175,7 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
|
||||
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
||||
bool isInContentProcess = !XRE_IsParentProcess();
|
||||
TabId tabId;
|
||||
TabId tabId(nsContentUtils::GenerateTabId());
|
||||
|
||||
nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
|
||||
TabId openerTabId;
|
||||
|
@ -1197,7 +1193,7 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
if (isInContentProcess) {
|
||||
MOZ_ASSERT(aContext.IsMozBrowserElement());
|
||||
constructorSender = CreateContentBridgeParent(aContext, initialPriority,
|
||||
openerTabId, &tabId);
|
||||
openerTabId, tabId);
|
||||
} else {
|
||||
if (aOpenerContentParent) {
|
||||
constructorSender = aOpenerContentParent;
|
||||
|
@ -1208,9 +1204,11 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
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;
|
||||
|
@ -1270,7 +1268,7 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
|||
ContentParent::CreateContentBridgeParent(const TabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority,
|
||||
const TabId& aOpenerTabId,
|
||||
/*out*/ TabId* aTabId)
|
||||
const TabId& aTabId)
|
||||
{
|
||||
MOZ_ASSERT(aTabId);
|
||||
|
||||
|
@ -1280,9 +1278,9 @@ ContentParent::CreateContentBridgeParent(const TabContext& aContext,
|
|||
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
||||
aPriority,
|
||||
aOpenerTabId,
|
||||
aTabId,
|
||||
&cpId,
|
||||
&isForBrowser,
|
||||
aTabId)) {
|
||||
&isForBrowser)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (cpId == 0) {
|
||||
|
@ -4216,27 +4214,8 @@ ContentParent::NotifyUpdatedDictionaries()
|
|||
}
|
||||
}
|
||||
|
||||
/*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)
|
||||
{
|
||||
|
@ -4246,32 +4225,19 @@ ContentParent::DeallocateTabId(const TabId& aTabId,
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -279,9 +279,9 @@ public:
|
|||
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;
|
||||
|
@ -350,15 +350,10 @@ public:
|
|||
|
||||
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();
|
||||
|
||||
|
@ -489,14 +484,9 @@ public:
|
|||
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;
|
||||
|
@ -694,7 +684,7 @@ private:
|
|||
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.
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static uint64_t gTabId = 0;
|
||||
|
||||
/* static */
|
||||
StaticAutoPtr<ContentProcessManager>
|
||||
ContentProcessManager::sSingleton;
|
||||
|
@ -135,17 +133,18 @@ ContentProcessManager::GetAllChildProcessById(const ContentParentId& aParentCpId
|
|||
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;
|
||||
|
@ -156,20 +155,10 @@ ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
|
|||
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 {
|
||||
|
@ -178,21 +167,19 @@ ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
|
|||
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());
|
||||
|
||||
|
|
|
@ -72,21 +72,23 @@ public:
|
|||
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.
|
||||
|
@ -151,7 +153,6 @@ public:
|
|||
|
||||
private:
|
||||
static StaticAutoPtr<ContentProcessManager> sSingleton;
|
||||
TabId mUniqueId;
|
||||
std::map<ContentParentId, ContentProcessInfo> mContentParentMap;
|
||||
|
||||
ContentProcessManager() {MOZ_COUNT_CTOR(ContentProcessManager);};
|
||||
|
|
|
@ -623,8 +623,9 @@ parent:
|
|||
|
||||
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);
|
||||
|
||||
|
@ -914,15 +915,10 @@ parent:
|
|||
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)
|
||||
|
|
|
@ -413,15 +413,15 @@ 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();
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#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"
|
||||
|
@ -138,12 +139,15 @@ nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
|
|||
}
|
||||
|
||||
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();
|
||||
|
@ -158,6 +162,29 @@ nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -917,8 +917,6 @@ description =
|
|||
description =
|
||||
[PContent::KeygenProvideContent]
|
||||
description =
|
||||
[PContent::AllocateTabId]
|
||||
description =
|
||||
[PContent::GetGraphicsDeviceInitData]
|
||||
description =
|
||||
[PContent::CreateWindow]
|
||||
|
|
Загрузка…
Ссылка в новой задаче