зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1172870 - Part 1 - Move PBrowser::CreateWindow to PContent. r=smaug
This commit is contained in:
Родитель
55039de64c
Коммит
bad419762d
|
@ -47,6 +47,7 @@
|
||||||
#include "mozilla/layers/ImageBridgeChild.h"
|
#include "mozilla/layers/ImageBridgeChild.h"
|
||||||
#include "mozilla/layers/PCompositorChild.h"
|
#include "mozilla/layers/PCompositorChild.h"
|
||||||
#include "mozilla/layers/SharedBufferManagerChild.h"
|
#include "mozilla/layers/SharedBufferManagerChild.h"
|
||||||
|
#include "mozilla/layout/RenderFrameChild.h"
|
||||||
#include "mozilla/net/NeckoChild.h"
|
#include "mozilla/net/NeckoChild.h"
|
||||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||||
#include "mozilla/plugins/PluginModuleParent.h"
|
#include "mozilla/plugins/PluginModuleParent.h"
|
||||||
|
@ -216,6 +217,7 @@ using namespace mozilla::gmp;
|
||||||
using namespace mozilla::hal_sandbox;
|
using namespace mozilla::hal_sandbox;
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
using namespace mozilla::layout;
|
||||||
using namespace mozilla::net;
|
using namespace mozilla::net;
|
||||||
using namespace mozilla::jsipc;
|
using namespace mozilla::jsipc;
|
||||||
using namespace mozilla::psm;
|
using namespace mozilla::psm;
|
||||||
|
@ -608,7 +610,8 @@ ContentChild::~ContentChild()
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(ContentChild)
|
NS_INTERFACE_MAP_BEGIN(ContentChild)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIContentChild)
|
NS_INTERFACE_MAP_ENTRY(nsIContentChild)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentChild)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -741,6 +744,149 @@ ContentChild::SetProcessName(const nsAString& aName, bool aDontOverride)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
ContentChild::ProvideWindow(nsIDOMWindow* aParent,
|
||||||
|
uint32_t aChromeFlags,
|
||||||
|
bool aCalledFromJS,
|
||||||
|
bool aPositionSpecified,
|
||||||
|
bool aSizeSpecified,
|
||||||
|
nsIURI* aURI,
|
||||||
|
const nsAString& aName,
|
||||||
|
const nsACString& aFeatures,
|
||||||
|
bool* aWindowIsNew,
|
||||||
|
nsIDOMWindow** aReturn)
|
||||||
|
{
|
||||||
|
return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
|
||||||
|
aCalledFromJS, aPositionSpecified,
|
||||||
|
aSizeSpecified, aURI, aName, aFeatures,
|
||||||
|
aWindowIsNew, aReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||||
|
nsIDOMWindow* aParent,
|
||||||
|
bool aIframeMoz,
|
||||||
|
uint32_t aChromeFlags,
|
||||||
|
bool aCalledFromJS,
|
||||||
|
bool aPositionSpecified,
|
||||||
|
bool aSizeSpecified,
|
||||||
|
nsIURI* aURI,
|
||||||
|
const nsAString& aName,
|
||||||
|
const nsACString& aFeatures,
|
||||||
|
bool* aWindowIsNew,
|
||||||
|
nsIDOMWindow** aReturn)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aTabOpener);
|
||||||
|
*aReturn = nullptr;
|
||||||
|
|
||||||
|
const TabId openerTabId = aTabOpener->GetTabId();
|
||||||
|
|
||||||
|
PopupIPCTabContext context;
|
||||||
|
context.opener() = openerTabId;
|
||||||
|
context.isBrowserElement() = aTabOpener->IsBrowserElement();
|
||||||
|
|
||||||
|
IPCTabContext ipcContext(context);
|
||||||
|
|
||||||
|
TabId tabId;
|
||||||
|
SendAllocateTabId(openerTabId,
|
||||||
|
ipcContext,
|
||||||
|
GetID(),
|
||||||
|
&tabId);
|
||||||
|
|
||||||
|
RefPtr<TabChild> newChild = new TabChild(this, tabId,
|
||||||
|
*aTabOpener, aChromeFlags);
|
||||||
|
if (NS_FAILED(newChild->Init())) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.opener() = aTabOpener;
|
||||||
|
unused << SendPBrowserConstructor(
|
||||||
|
// We release this ref in DeallocPBrowserChild
|
||||||
|
RefPtr<TabChild>(newChild).forget().take(),
|
||||||
|
tabId, IPCTabContext(context), aChromeFlags,
|
||||||
|
GetID(), IsForApp(), IsForBrowser());
|
||||||
|
|
||||||
|
nsAutoCString spec;
|
||||||
|
if (aURI) {
|
||||||
|
aURI->GetSpec(spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ConvertUTF8toUTF16 url(spec);
|
||||||
|
nsString name(aName);
|
||||||
|
nsAutoCString features(aFeatures);
|
||||||
|
nsTArray<FrameScriptInfo> frameScripts;
|
||||||
|
nsCString urlToLoad;
|
||||||
|
|
||||||
|
if (aIframeMoz) {
|
||||||
|
MOZ_ASSERT(aTabOpener);
|
||||||
|
newChild->SendBrowserFrameOpenWindow(aTabOpener, url, name,
|
||||||
|
NS_ConvertUTF8toUTF16(features),
|
||||||
|
aWindowIsNew);
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aParent);
|
||||||
|
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
|
||||||
|
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
|
||||||
|
if (!baseURI) {
|
||||||
|
NS_ERROR("nsIDocument didn't return a base URI");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString baseURIString;
|
||||||
|
baseURI->GetSpec(baseURIString);
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
if (!SendCreateWindow(aTabOpener, newChild,
|
||||||
|
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||||
|
aSizeSpecified, url,
|
||||||
|
name, features,
|
||||||
|
NS_ConvertUTF8toUTF16(baseURIString),
|
||||||
|
&rv,
|
||||||
|
aWindowIsNew,
|
||||||
|
&frameScripts,
|
||||||
|
&urlToLoad)) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!*aWindowIsNew) {
|
||||||
|
PBrowserChild::Send__delete__(newChild);
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||||
|
uint64_t layersId = 0;
|
||||||
|
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
|
||||||
|
newChild->SendGetRenderFrameInfo(renderFrame,
|
||||||
|
&textureFactoryIdentifier,
|
||||||
|
&layersId);
|
||||||
|
if (layersId == 0) { // if renderFrame is invalid.
|
||||||
|
PRenderFrameChild::Send__delete__(renderFrame);
|
||||||
|
renderFrame = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unfortunately we don't get a window unless we've shown the frame. That's
|
||||||
|
// pretty bogus; see bug 763602.
|
||||||
|
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < frameScripts.Length(); i++) {
|
||||||
|
FrameScriptInfo& info = frameScripts[i];
|
||||||
|
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
|
||||||
|
MOZ_CRASH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!urlToLoad.IsEmpty()) {
|
||||||
|
newChild->RecvLoadURL(urlToLoad, BrowserConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
|
||||||
|
win.forget(aReturn);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ContentChild::GetProcessName(nsAString& aName)
|
ContentChild::GetProcessName(nsAString& aName)
|
||||||
{
|
{
|
||||||
|
@ -2748,7 +2894,8 @@ ContentChild::RecvShutdown()
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||||
if (os) {
|
if (os) {
|
||||||
os->NotifyObservers(this, "content-child-shutdown", nullptr);
|
os->NotifyObservers(static_cast<nsIContentChild*>(this),
|
||||||
|
"content-child-shutdown", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetIPCChannel()->SetAbortOnError(false);
|
GetIPCChannel()->SetAbortOnError(false);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "nsTHashtable.h"
|
#include "nsTHashtable.h"
|
||||||
|
|
||||||
#include "nsWeakPtr.h"
|
#include "nsWeakPtr.h"
|
||||||
|
#include "nsIWindowProvider.h"
|
||||||
|
|
||||||
|
|
||||||
struct ChromePackage;
|
struct ChromePackage;
|
||||||
|
@ -47,6 +48,7 @@ class ClonedMessageData;
|
||||||
class TabChild;
|
class TabChild;
|
||||||
|
|
||||||
class ContentChild final : public PContentChild
|
class ContentChild final : public PContentChild
|
||||||
|
, public nsIWindowProvider
|
||||||
, public nsIContentChild
|
, public nsIContentChild
|
||||||
{
|
{
|
||||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||||
|
@ -55,6 +57,8 @@ class ContentChild final : public PContentChild
|
||||||
typedef mozilla::ipc::URIParams URIParams;
|
typedef mozilla::ipc::URIParams URIParams;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_NSIWINDOWPROVIDER
|
||||||
|
|
||||||
ContentChild();
|
ContentChild();
|
||||||
virtual ~ContentChild();
|
virtual ~ContentChild();
|
||||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
||||||
|
@ -71,6 +75,20 @@ public:
|
||||||
nsCString vendor;
|
nsCString vendor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
ProvideWindowCommon(TabChild* aTabOpener,
|
||||||
|
nsIDOMWindow* aOpener,
|
||||||
|
bool aIframeMoz,
|
||||||
|
uint32_t aChromeFlags,
|
||||||
|
bool aCalledFromJS,
|
||||||
|
bool aPositionSpecified,
|
||||||
|
bool aSizeSpecified,
|
||||||
|
nsIURI* aURI,
|
||||||
|
const nsAString& aName,
|
||||||
|
const nsACString& aFeatures,
|
||||||
|
bool* aWindowIsNew,
|
||||||
|
nsIDOMWindow** aReturn);
|
||||||
|
|
||||||
bool Init(MessageLoop* aIOLoop,
|
bool Init(MessageLoop* aIOLoop,
|
||||||
base::ProcessId aParentPid,
|
base::ProcessId aParentPid,
|
||||||
IPC::Channel* aChannel);
|
IPC::Channel* aChannel);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
|
|
||||||
#include "ContentParent.h"
|
#include "ContentParent.h"
|
||||||
|
#include "TabParent.h"
|
||||||
|
|
||||||
#if defined(ANDROID) || defined(LINUX)
|
#if defined(ANDROID) || defined(LINUX)
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
|
@ -144,7 +145,13 @@
|
||||||
#include "nsISystemMessagesInternal.h"
|
#include "nsISystemMessagesInternal.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsIURIFixup.h"
|
#include "nsIURIFixup.h"
|
||||||
|
#include "nsIWindowMediator.h"
|
||||||
|
#include "nsIDocShellTreeOwner.h"
|
||||||
|
#include "nsIXULWindow.h"
|
||||||
|
#include "nsIDOMChromeWindow.h"
|
||||||
#include "nsIWindowWatcher.h"
|
#include "nsIWindowWatcher.h"
|
||||||
|
#include "nsPIWindowWatcher.h"
|
||||||
|
#include "nsWindowWatcher.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
#include "gfxDrawable.h"
|
#include "gfxDrawable.h"
|
||||||
#include "ImageOps.h"
|
#include "ImageOps.h"
|
||||||
|
@ -166,6 +173,7 @@
|
||||||
#include "nsIWebBrowserChrome.h"
|
#include "nsIWebBrowserChrome.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsDocShell.h"
|
#include "nsDocShell.h"
|
||||||
|
#include "nsOpenURIInFrameParams.h"
|
||||||
#include "mozilla/net/NeckoMessageUtils.h"
|
#include "mozilla/net/NeckoMessageUtils.h"
|
||||||
#include "gfxPrefs.h"
|
#include "gfxPrefs.h"
|
||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
|
@ -5343,6 +5351,226 @@ ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumen
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<nsPIDOMWindow>
|
||||||
|
FindMostRecentOpenWindow()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIWindowMediator> windowMediator =
|
||||||
|
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
|
||||||
|
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
||||||
|
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
|
||||||
|
getter_AddRefs(windowEnumerator));
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> latest;
|
||||||
|
|
||||||
|
bool hasMore = false;
|
||||||
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||||
|
while (hasMore) {
|
||||||
|
nsCOMPtr<nsISupports> item;
|
||||||
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(item);
|
||||||
|
|
||||||
|
if (window && !window->Closed()) {
|
||||||
|
latest = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return latest.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
||||||
|
PBrowserParent* aNewTab,
|
||||||
|
const uint32_t& aChromeFlags,
|
||||||
|
const bool& aCalledFromJS,
|
||||||
|
const bool& aPositionSpecified,
|
||||||
|
const bool& aSizeSpecified,
|
||||||
|
const nsString& aURI,
|
||||||
|
const nsString& aName,
|
||||||
|
const nsCString& aFeatures,
|
||||||
|
const nsString& aBaseURI,
|
||||||
|
nsresult* aResult,
|
||||||
|
bool* aWindowIsNew,
|
||||||
|
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||||
|
nsCString* aURLToLoad)
|
||||||
|
{
|
||||||
|
// We always expect to open a new window here. If we don't, it's an error.
|
||||||
|
*aWindowIsNew = true;
|
||||||
|
|
||||||
|
// The content process should never be in charge of computing whether or
|
||||||
|
// not a window should be private or remote - the parent will do that.
|
||||||
|
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW));
|
||||||
|
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
|
||||||
|
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
||||||
|
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
||||||
|
|
||||||
|
TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
|
||||||
|
MOZ_ASSERT(thisTabParent);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(thisTabParent->IsBrowserOrApp())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
||||||
|
do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
||||||
|
MOZ_ASSERT(newTab);
|
||||||
|
|
||||||
|
// Content has requested that we open this new content window, so
|
||||||
|
// we must have an opener.
|
||||||
|
newTab->SetHasContentOpener(true);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> frame(do_QueryInterface(thisTabParent->GetOwnerElement()));
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> parent;
|
||||||
|
if (frame) {
|
||||||
|
parent = frame->OwnerDoc()->GetWindow();
|
||||||
|
|
||||||
|
// If our chrome window is in the process of closing, don't try to open a
|
||||||
|
// new tab in it.
|
||||||
|
if (parent && parent->Closed()) {
|
||||||
|
parent = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = thisTabParent->GetBrowserDOMWindow();
|
||||||
|
|
||||||
|
// If we haven't found a chrome window to open in, just use the most recently
|
||||||
|
// opened one.
|
||||||
|
if (!parent) {
|
||||||
|
parent = FindMostRecentOpenWindow();
|
||||||
|
if (NS_WARN_IF(!parent)) {
|
||||||
|
*aResult = NS_ERROR_FAILURE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
|
||||||
|
if (rootChromeWin) {
|
||||||
|
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t openLocation =
|
||||||
|
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
|
||||||
|
aPositionSpecified, aSizeSpecified);
|
||||||
|
|
||||||
|
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
|
||||||
|
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
|
||||||
|
|
||||||
|
// Opening new tabs is the easy case...
|
||||||
|
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
|
||||||
|
if (NS_WARN_IF(!browserDOMWin)) {
|
||||||
|
*aResult = NS_ERROR_FAILURE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPrivate = false;
|
||||||
|
nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
|
||||||
|
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
|
||||||
|
params->SetReferrer(aBaseURI);
|
||||||
|
params->SetIsPrivate(isPrivate);
|
||||||
|
|
||||||
|
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
|
||||||
|
browserDOMWin->OpenURIInFrame(nullptr, params,
|
||||||
|
openLocation,
|
||||||
|
nsIBrowserDOMWindow::OPEN_NEW,
|
||||||
|
getter_AddRefs(frameLoaderOwner));
|
||||||
|
if (!frameLoaderOwner) {
|
||||||
|
*aWindowIsNew = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTab->SwapFrameScriptsFrom(*aFrameScripts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowWatcher is going to expect a valid URI to open a window
|
||||||
|
// to. If it can't find one, it's going to attempt to figure one
|
||||||
|
// out on its own, which is problematic because it can't access
|
||||||
|
// the document for the remote browser we're opening. Luckily,
|
||||||
|
// TabChild has sent us a baseURI with which we can ensure that
|
||||||
|
// the URI we pass to WindowWatcher is valid.
|
||||||
|
nsCOMPtr<nsIURI> baseURI;
|
||||||
|
*aResult = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString finalURIString;
|
||||||
|
if (!aURI.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIURI> finalURI;
|
||||||
|
*aResult = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalURI->GetSpec(finalURIString);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> window;
|
||||||
|
|
||||||
|
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||||
|
|
||||||
|
const char* features = aFeatures.Length() ? aFeatures.get() : nullptr;
|
||||||
|
*aResult = pwwatch->OpenWindow2(parent, finalURIString.get(),
|
||||||
|
NS_ConvertUTF16toUTF8(aName).get(),
|
||||||
|
features, aCalledFromJS,
|
||||||
|
false, false, thisTabParent, nullptr, getter_AddRefs(window));
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
|
||||||
|
if (NS_WARN_IF(!pwindow)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocShell> windowDocShell = pwindow->GetDocShell();
|
||||||
|
if (NS_WARN_IF(!windowDocShell)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||||
|
windowDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(treeOwner);
|
||||||
|
if (NS_WARN_IF(!xulWin)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
||||||
|
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
||||||
|
if (NS_WARN_IF(!xulBrowserWin)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsITabParent> newRemoteTab;
|
||||||
|
*aResult = xulBrowserWin->ForceInitialBrowserRemote(getter_AddRefs(newRemoteTab));
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
||||||
|
|
||||||
|
newTab->SwapFrameScriptsFrom(*aFrameScripts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
ContentParent::PermissionManagerAddref(const ContentParentId& aCpId,
|
ContentParent::PermissionManagerAddref(const ContentParentId& aCpId,
|
||||||
const TabId& aTabId)
|
const TabId& aTabId)
|
||||||
|
|
|
@ -434,6 +434,21 @@ public:
|
||||||
void SetNuwaParent(NuwaParent* aNuwaParent) { mNuwaParent = aNuwaParent; }
|
void SetNuwaParent(NuwaParent* aNuwaParent) { mNuwaParent = aNuwaParent; }
|
||||||
void ForkNewProcess(bool aBlocking);
|
void ForkNewProcess(bool aBlocking);
|
||||||
|
|
||||||
|
virtual bool RecvCreateWindow(PBrowserParent* aThisTabParent,
|
||||||
|
PBrowserParent* aOpener,
|
||||||
|
const uint32_t& aChromeFlags,
|
||||||
|
const bool& aCalledFromJS,
|
||||||
|
const bool& aPositionSpecified,
|
||||||
|
const bool& aSizeSpecified,
|
||||||
|
const nsString& aURI,
|
||||||
|
const nsString& aName,
|
||||||
|
const nsCString& aFeatures,
|
||||||
|
const nsString& aBaseURI,
|
||||||
|
nsresult* aResult,
|
||||||
|
bool* aWindowIsNew,
|
||||||
|
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||||
|
nsCString* aURLToLoad) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnChannelConnected(int32_t pid) override;
|
void OnChannelConnected(int32_t pid) override;
|
||||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||||
|
|
|
@ -94,12 +94,6 @@ struct ShowInfo
|
||||||
double defaultScale;
|
double defaultScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrameScriptInfo
|
|
||||||
{
|
|
||||||
nsString url;
|
|
||||||
bool runInGlobalScope;
|
|
||||||
};
|
|
||||||
|
|
||||||
prio(normal upto urgent) sync protocol PBrowser
|
prio(normal upto urgent) sync protocol PBrowser
|
||||||
{
|
{
|
||||||
manager PContent or PContentBridge;
|
manager PContent or PContentBridge;
|
||||||
|
@ -165,20 +159,6 @@ parent:
|
||||||
|
|
||||||
Event(RemoteDOMEvent aEvent);
|
Event(RemoteDOMEvent aEvent);
|
||||||
|
|
||||||
sync CreateWindow(PBrowser aNewTab,
|
|
||||||
uint32_t aChromeFlags,
|
|
||||||
bool aCalledFromJS,
|
|
||||||
bool aPositionSpecified,
|
|
||||||
bool aSizeSpecified,
|
|
||||||
nsString aURI,
|
|
||||||
nsString aName,
|
|
||||||
nsCString aFeatures,
|
|
||||||
nsString aBaseURI)
|
|
||||||
returns (nsresult rv,
|
|
||||||
bool windowOpened,
|
|
||||||
FrameScriptInfo[] frameScripts,
|
|
||||||
nsCString urlToLoad);
|
|
||||||
|
|
||||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||||
CpowEntry[] aCpows, Principal aPrincipal)
|
CpowEntry[] aCpows, Principal aPrincipal)
|
||||||
returns (StructuredCloneData[] retval);
|
returns (StructuredCloneData[] retval);
|
||||||
|
|
|
@ -410,6 +410,12 @@ union GamepadChangeEvent {
|
||||||
GamepadButtonInformation;
|
GamepadButtonInformation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FrameScriptInfo
|
||||||
|
{
|
||||||
|
nsString url;
|
||||||
|
bool runInGlobalScope;
|
||||||
|
};
|
||||||
|
|
||||||
prio(normal upto urgent) sync protocol PContent
|
prio(normal upto urgent) sync protocol PContent
|
||||||
{
|
{
|
||||||
parent spawns PPluginModule;
|
parent spawns PPluginModule;
|
||||||
|
@ -1112,6 +1118,21 @@ parent:
|
||||||
sync GetGraphicsDeviceInitData()
|
sync GetGraphicsDeviceInitData()
|
||||||
returns (DeviceInitData aData);
|
returns (DeviceInitData aData);
|
||||||
|
|
||||||
|
sync CreateWindow(PBrowser aThisTab,
|
||||||
|
PBrowser aNewTab,
|
||||||
|
uint32_t aChromeFlags,
|
||||||
|
bool aCalledFromJS,
|
||||||
|
bool aPositionSpecified,
|
||||||
|
bool aSizeSpecified,
|
||||||
|
nsString aURI,
|
||||||
|
nsString aName,
|
||||||
|
nsCString aFeatures,
|
||||||
|
nsString aBaseURI)
|
||||||
|
returns (nsresult rv,
|
||||||
|
bool windowOpened,
|
||||||
|
FrameScriptInfo[] frameScripts,
|
||||||
|
nsCString urlToLoad);
|
||||||
|
|
||||||
sync GetDeviceStorageLocation(nsString type)
|
sync GetDeviceStorageLocation(nsString type)
|
||||||
returns (nsString path);
|
returns (nsString path);
|
||||||
|
|
||||||
|
|
|
@ -1115,145 +1115,19 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
|
||||||
// Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
|
// Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
|
||||||
// open window call was canceled. It's important that we pass this error
|
// open window call was canceled. It's important that we pass this error
|
||||||
// code back to our caller.
|
// code back to our caller.
|
||||||
return ProvideWindowCommon(aParent,
|
ContentChild* cc = ContentChild::GetSingleton();
|
||||||
iframeMoz,
|
return cc->ProvideWindowCommon(this,
|
||||||
aChromeFlags,
|
aParent,
|
||||||
aCalledFromJS,
|
iframeMoz,
|
||||||
aPositionSpecified,
|
aChromeFlags,
|
||||||
aSizeSpecified,
|
aCalledFromJS,
|
||||||
aURI,
|
aPositionSpecified,
|
||||||
aName,
|
aSizeSpecified,
|
||||||
aFeatures,
|
aURI,
|
||||||
aWindowIsNew,
|
aName,
|
||||||
aReturn);
|
aFeatures,
|
||||||
}
|
aWindowIsNew,
|
||||||
|
aReturn);
|
||||||
nsresult
|
|
||||||
TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
|
|
||||||
bool aIframeMoz,
|
|
||||||
uint32_t aChromeFlags,
|
|
||||||
bool aCalledFromJS,
|
|
||||||
bool aPositionSpecified,
|
|
||||||
bool aSizeSpecified,
|
|
||||||
nsIURI* aURI,
|
|
||||||
const nsAString& aName,
|
|
||||||
const nsACString& aFeatures,
|
|
||||||
bool* aWindowIsNew,
|
|
||||||
nsIDOMWindow** aReturn)
|
|
||||||
{
|
|
||||||
*aReturn = nullptr;
|
|
||||||
|
|
||||||
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.opener() = openerTabId;
|
|
||||||
context.isBrowserElement() = IsBrowserElement();
|
|
||||||
|
|
||||||
IPCTabContext ipcContext(context);
|
|
||||||
|
|
||||||
TabId tabId;
|
|
||||||
cc->SendAllocateTabId(openerTabId,
|
|
||||||
ipcContext,
|
|
||||||
cc->GetID(),
|
|
||||||
&tabId);
|
|
||||||
|
|
||||||
RefPtr<TabChild> newChild = new TabChild(ContentChild::GetSingleton(), tabId,
|
|
||||||
/* TabContext */ *this, aChromeFlags);
|
|
||||||
if (NS_FAILED(newChild->Init())) {
|
|
||||||
return NS_ERROR_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.opener() = this;
|
|
||||||
unused << Manager()->SendPBrowserConstructor(
|
|
||||||
// We release this ref in DeallocPBrowserChild
|
|
||||||
RefPtr<TabChild>(newChild).forget().take(),
|
|
||||||
tabId, IPCTabContext(context), aChromeFlags,
|
|
||||||
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
|
|
||||||
|
|
||||||
nsAutoCString spec;
|
|
||||||
if (aURI) {
|
|
||||||
aURI->GetSpec(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ConvertUTF8toUTF16 url(spec);
|
|
||||||
nsString name(aName);
|
|
||||||
nsAutoCString features(aFeatures);
|
|
||||||
nsTArray<FrameScriptInfo> frameScripts;
|
|
||||||
nsCString urlToLoad;
|
|
||||||
|
|
||||||
if (aIframeMoz) {
|
|
||||||
newChild->SendBrowserFrameOpenWindow(this, url, name,
|
|
||||||
NS_ConvertUTF8toUTF16(features),
|
|
||||||
aWindowIsNew);
|
|
||||||
} else {
|
|
||||||
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aOpener);
|
|
||||||
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
|
|
||||||
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
|
|
||||||
if (!baseURI) {
|
|
||||||
NS_ERROR("nsIDocument didn't return a base URI");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString baseURIString;
|
|
||||||
baseURI->GetSpec(baseURIString);
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (!SendCreateWindow(newChild,
|
|
||||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
|
||||||
aSizeSpecified, url,
|
|
||||||
name, features,
|
|
||||||
NS_ConvertUTF8toUTF16(baseURIString),
|
|
||||||
&rv,
|
|
||||||
aWindowIsNew,
|
|
||||||
&frameScripts,
|
|
||||||
&urlToLoad)) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!*aWindowIsNew) {
|
|
||||||
PBrowserChild::Send__delete__(newChild);
|
|
||||||
return NS_ERROR_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
|
||||||
uint64_t layersId = 0;
|
|
||||||
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
|
|
||||||
newChild->SendGetRenderFrameInfo(renderFrame,
|
|
||||||
&textureFactoryIdentifier,
|
|
||||||
&layersId);
|
|
||||||
if (layersId == 0) { // if renderFrame is invalid.
|
|
||||||
PRenderFrameChild::Send__delete__(renderFrame);
|
|
||||||
renderFrame = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unfortunately we don't get a window unless we've shown the frame. That's
|
|
||||||
// pretty bogus; see bug 763602.
|
|
||||||
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < frameScripts.Length(); i++) {
|
|
||||||
FrameScriptInfo& info = frameScripts[i];
|
|
||||||
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
|
|
||||||
MOZ_CRASH();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!urlToLoad.IsEmpty()) {
|
|
||||||
newChild->RecvLoadURL(urlToLoad, BrowserConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
|
|
||||||
win.forget(aReturn);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -240,6 +240,16 @@ public:
|
||||||
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
|
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Create a new TabChild object.
|
||||||
|
*/
|
||||||
|
TabChild(nsIContentChild* aManager,
|
||||||
|
const TabId& aTabId,
|
||||||
|
const TabContext& aContext,
|
||||||
|
uint32_t aChromeFlags);
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is expected to be called off the critical path to content
|
* This is expected to be called off the critical path to content
|
||||||
* startup. This is an opportunity to load things that are slow
|
* startup. This is an opportunity to load things that are slow
|
||||||
|
@ -510,6 +520,11 @@ public:
|
||||||
|
|
||||||
virtual ScreenIntSize GetInnerSize() override;
|
virtual ScreenIntSize GetInnerSize() override;
|
||||||
|
|
||||||
|
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||||
|
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||||
|
const uint64_t& aLayersId,
|
||||||
|
PRenderFrameChild* aRenderFrame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~TabChild();
|
virtual ~TabChild();
|
||||||
|
|
||||||
|
@ -535,16 +550,6 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* Create a new TabChild object.
|
|
||||||
*/
|
|
||||||
TabChild(nsIContentChild* aManager,
|
|
||||||
const TabId& aTabId,
|
|
||||||
const TabContext& aContext,
|
|
||||||
uint32_t aChromeFlags);
|
|
||||||
|
|
||||||
nsresult Init();
|
|
||||||
|
|
||||||
class DelayedFireContextMenuEvent;
|
class DelayedFireContextMenuEvent;
|
||||||
|
|
||||||
// Notify others that our TabContext has been updated. (At the moment, this
|
// Notify others that our TabContext has been updated. (At the moment, this
|
||||||
|
@ -564,11 +569,6 @@ private:
|
||||||
void DestroyWindow();
|
void DestroyWindow();
|
||||||
void SetProcessNameToAppName();
|
void SetProcessNameToAppName();
|
||||||
|
|
||||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
|
||||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
|
||||||
const uint64_t& aLayersId,
|
|
||||||
PRenderFrameChild* aRenderFrame);
|
|
||||||
|
|
||||||
void ApplyShowInfo(const ShowInfo& aInfo);
|
void ApplyShowInfo(const ShowInfo& aInfo);
|
||||||
|
|
||||||
// These methods are used for tracking synthetic mouse events
|
// These methods are used for tracking synthetic mouse events
|
||||||
|
@ -581,19 +581,6 @@ private:
|
||||||
void CancelTapTracking();
|
void CancelTapTracking();
|
||||||
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
|
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
|
||||||
|
|
||||||
nsresult
|
|
||||||
ProvideWindowCommon(nsIDOMWindow* aOpener,
|
|
||||||
bool aIframeMoz,
|
|
||||||
uint32_t aChromeFlags,
|
|
||||||
bool aCalledFromJS,
|
|
||||||
bool aPositionSpecified,
|
|
||||||
bool aSizeSpecified,
|
|
||||||
nsIURI* aURI,
|
|
||||||
const nsAString& aName,
|
|
||||||
const nsACString& aFeatures,
|
|
||||||
bool* aWindowIsNew,
|
|
||||||
nsIDOMWindow** aReturn);
|
|
||||||
|
|
||||||
bool HasValidInnerSize();
|
bool HasValidInnerSize();
|
||||||
|
|
||||||
void SetTabId(const TabId& aTabId);
|
void SetTabId(const TabId& aTabId);
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIDocShellTreeOwner.h"
|
#include "nsIDocShellTreeOwner.h"
|
||||||
#include "nsIDOMChromeWindow.h"
|
|
||||||
#include "nsIDOMElement.h"
|
#include "nsIDOMElement.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
|
@ -61,26 +60,20 @@
|
||||||
#include "nsIPromptFactory.h"
|
#include "nsIPromptFactory.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIWebBrowserChrome.h"
|
#include "nsIWebBrowserChrome.h"
|
||||||
#include "nsIWindowCreator2.h"
|
|
||||||
#include "nsIXULBrowserWindow.h"
|
#include "nsIXULBrowserWindow.h"
|
||||||
#include "nsIXULWindow.h"
|
#include "nsIXULWindow.h"
|
||||||
#include "nsIRemoteBrowser.h"
|
#include "nsIRemoteBrowser.h"
|
||||||
#include "nsViewManager.h"
|
#include "nsViewManager.h"
|
||||||
#include "nsVariant.h"
|
#include "nsVariant.h"
|
||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "nsIWindowMediator.h"
|
|
||||||
#include "nsIWindowWatcher.h"
|
|
||||||
#ifndef XP_WIN
|
#ifndef XP_WIN
|
||||||
#include "nsJARProtocolHandler.h"
|
#include "nsJARProtocolHandler.h"
|
||||||
#endif
|
#endif
|
||||||
#include "nsOpenURIInFrameParams.h"
|
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsPIWindowWatcher.h"
|
|
||||||
#include "nsPresShell.h"
|
#include "nsPresShell.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsWindowWatcher.h"
|
|
||||||
#include "private/pprio.h"
|
#include "private/pprio.h"
|
||||||
#include "PermissionMessageUtils.h"
|
#include "PermissionMessageUtils.h"
|
||||||
#include "StructuredCloneData.h"
|
#include "StructuredCloneData.h"
|
||||||
|
@ -723,249 +716,6 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew, nsCString* aURLToLoad)
|
|
||||||
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew), mURLToLoad(aURLToLoad)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!TabParent::sNextTabParent);
|
|
||||||
MOZ_ASSERT(!aNewTab->mCreatingWindow);
|
|
||||||
|
|
||||||
TabParent::sNextTabParent = aNewTab;
|
|
||||||
aNewTab->mCreatingWindow = true;
|
|
||||||
aNewTab->mDelayedURL.Truncate();
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoUseNewTab()
|
|
||||||
{
|
|
||||||
mNewTab->mCreatingWindow = false;
|
|
||||||
*mURLToLoad = mNewTab->mDelayedURL;
|
|
||||||
|
|
||||||
if (TabParent::sNextTabParent) {
|
|
||||||
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
|
|
||||||
TabParent::sNextTabParent = nullptr;
|
|
||||||
*mWindowIsNew = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
TabParent* mNewTab;
|
|
||||||
bool* mWindowIsNew;
|
|
||||||
nsCString* mURLToLoad;
|
|
||||||
};
|
|
||||||
|
|
||||||
static already_AddRefed<nsPIDOMWindow>
|
|
||||||
FindMostRecentOpenWindow()
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIWindowMediator> windowMediator =
|
|
||||||
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
|
||||||
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
|
|
||||||
getter_AddRefs(windowEnumerator));
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> latest;
|
|
||||||
|
|
||||||
bool hasMore = false;
|
|
||||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
|
||||||
while (hasMore) {
|
|
||||||
nsCOMPtr<nsISupports> item;
|
|
||||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
|
|
||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(item);
|
|
||||||
|
|
||||||
if (window && !window->Closed()) {
|
|
||||||
latest = window;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return latest.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
|
|
||||||
const uint32_t& aChromeFlags,
|
|
||||||
const bool& aCalledFromJS,
|
|
||||||
const bool& aPositionSpecified,
|
|
||||||
const bool& aSizeSpecified,
|
|
||||||
const nsString& aURI,
|
|
||||||
const nsString& aName,
|
|
||||||
const nsCString& aFeatures,
|
|
||||||
const nsString& aBaseURI,
|
|
||||||
nsresult* aResult,
|
|
||||||
bool* aWindowIsNew,
|
|
||||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
|
||||||
nsCString* aURLToLoad)
|
|
||||||
{
|
|
||||||
// We always expect to open a new window here. If we don't, it's an error.
|
|
||||||
*aWindowIsNew = true;
|
|
||||||
|
|
||||||
// The content process should never be in charge of computing whether or
|
|
||||||
// not a window should be private or remote - the parent will do that.
|
|
||||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW));
|
|
||||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
|
|
||||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
|
||||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
|
||||||
|
|
||||||
if (NS_WARN_IF(IsBrowserOrApp()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
|
||||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
|
||||||
MOZ_ASSERT(newTab);
|
|
||||||
|
|
||||||
// Content has requested that we open this new content window, so
|
|
||||||
// we must have an opener.
|
|
||||||
newTab->SetHasContentOpener(true);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> parent;
|
|
||||||
if (frame) {
|
|
||||||
parent = frame->OwnerDoc()->GetWindow();
|
|
||||||
|
|
||||||
// If our chrome window is in the process of closing, don't try to open a
|
|
||||||
// new tab in it.
|
|
||||||
if (parent && parent->Closed()) {
|
|
||||||
parent = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = mBrowserDOMWindow;
|
|
||||||
|
|
||||||
// If we haven't found a chrome window to open in, just use the most recently
|
|
||||||
// opened one.
|
|
||||||
if (!parent) {
|
|
||||||
parent = FindMostRecentOpenWindow();
|
|
||||||
if (NS_WARN_IF(!parent)) {
|
|
||||||
*aResult = NS_ERROR_FAILURE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
|
|
||||||
if (rootChromeWin) {
|
|
||||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t openLocation =
|
|
||||||
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
|
|
||||||
aPositionSpecified, aSizeSpecified);
|
|
||||||
|
|
||||||
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
|
|
||||||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
|
|
||||||
|
|
||||||
// Opening new tabs is the easy case...
|
|
||||||
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
|
|
||||||
if (NS_WARN_IF(!browserDOMWin)) {
|
|
||||||
*aResult = NS_ERROR_FAILURE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPrivate;
|
|
||||||
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext();
|
|
||||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
|
|
||||||
params->SetReferrer(aBaseURI);
|
|
||||||
params->SetIsPrivate(isPrivate);
|
|
||||||
|
|
||||||
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
|
|
||||||
browserDOMWin->OpenURIInFrame(nullptr, params,
|
|
||||||
openLocation,
|
|
||||||
nsIBrowserDOMWindow::OPEN_NEW,
|
|
||||||
getter_AddRefs(frameLoaderOwner));
|
|
||||||
if (!frameLoaderOwner) {
|
|
||||||
*aWindowIsNew = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WindowWatcher is going to expect a valid URI to open a window
|
|
||||||
// to. If it can't find one, it's going to attempt to figure one
|
|
||||||
// out on its own, which is problematic because it can't access
|
|
||||||
// the document for the remote browser we're opening. Luckily,
|
|
||||||
// TabChild has sent us a baseURI with which we can ensure that
|
|
||||||
// the URI we pass to WindowWatcher is valid.
|
|
||||||
nsCOMPtr<nsIURI> baseURI;
|
|
||||||
*aResult = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
nsAutoCString finalURIString;
|
|
||||||
if (!aURI.IsEmpty()) {
|
|
||||||
nsCOMPtr<nsIURI> finalURI;
|
|
||||||
*aResult = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
finalURI->GetSpec(finalURIString);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> window;
|
|
||||||
|
|
||||||
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
|
||||||
|
|
||||||
const char* features = aFeatures.Length() ? aFeatures.get() : nullptr;
|
|
||||||
|
|
||||||
*aResult = pwwatch->OpenWindow2(parent, finalURIString.get(),
|
|
||||||
NS_ConvertUTF16toUTF8(aName).get(),
|
|
||||||
features, aCalledFromJS,
|
|
||||||
false, false, this, nullptr, getter_AddRefs(window));
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*aResult = NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
|
|
||||||
if (NS_WARN_IF(!pwindow)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> windowDocShell = pwindow->GetDocShell();
|
|
||||||
if (NS_WARN_IF(!windowDocShell)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
|
||||||
windowDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(treeOwner);
|
|
||||||
if (NS_WARN_IF(!xulWin)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
|
||||||
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
|
||||||
if (NS_WARN_IF(!xulBrowserWin)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsITabParent> newRemoteTab;
|
|
||||||
*aResult = xulBrowserWin->ForceInitialBrowserRemote(getter_AddRefs(newRemoteTab));
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
|
||||||
|
|
||||||
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TabParent* TabParent::sNextTabParent;
|
TabParent* TabParent::sNextTabParent;
|
||||||
|
|
||||||
/* static */ TabParent*
|
/* static */ TabParent*
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/ContentCache.h"
|
#include "mozilla/ContentCache.h"
|
||||||
#include "mozilla/dom/ipc/IdType.h"
|
#include "mozilla/dom/ipc/IdType.h"
|
||||||
#include "mozilla/dom/PBrowserParent.h"
|
#include "mozilla/dom/PBrowserParent.h"
|
||||||
|
#include "mozilla/dom/PContent.h"
|
||||||
#include "mozilla/dom/PFilePickerParent.h"
|
#include "mozilla/dom/PFilePickerParent.h"
|
||||||
#include "mozilla/dom/TabContext.h"
|
#include "mozilla/dom/TabContext.h"
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
|
@ -93,6 +94,9 @@ class TabParent final : public PBrowserParent
|
||||||
virtual ~TabParent();
|
virtual ~TabParent();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Helper class for ContentParent::RecvCreateWindow.
|
||||||
|
struct AutoUseNewTab;
|
||||||
|
|
||||||
// nsITabParent
|
// nsITabParent
|
||||||
NS_DECL_NSITABPARENT
|
NS_DECL_NSITABPARENT
|
||||||
// nsIDOMEventListener interfaces
|
// nsIDOMEventListener interfaces
|
||||||
|
@ -125,6 +129,12 @@ public:
|
||||||
mBrowserDOMWindow = aBrowserDOMWindow;
|
mBrowserDOMWindow = aBrowserDOMWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetHasContentOpener(bool aHasContentOpener);
|
||||||
|
|
||||||
|
void SwapFrameScriptsFrom(nsTArray<FrameScriptInfo>& aFrameScripts) {
|
||||||
|
aFrameScripts.SwapElements(mDelayedFrameScripts);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<nsILoadContext> GetLoadContext();
|
already_AddRefed<nsILoadContext> GetLoadContext();
|
||||||
already_AddRefed<nsIWidget> GetTopLevelWidget();
|
already_AddRefed<nsIWidget> GetTopLevelWidget();
|
||||||
nsIXULBrowserWindow* GetXULBrowserWindow();
|
nsIXULBrowserWindow* GetXULBrowserWindow();
|
||||||
|
@ -147,19 +157,6 @@ public:
|
||||||
const nsString& aName,
|
const nsString& aName,
|
||||||
const nsString& aFeatures,
|
const nsString& aFeatures,
|
||||||
bool* aOutWindowOpened) override;
|
bool* aOutWindowOpened) override;
|
||||||
virtual bool RecvCreateWindow(PBrowserParent* aOpener,
|
|
||||||
const uint32_t& aChromeFlags,
|
|
||||||
const bool& aCalledFromJS,
|
|
||||||
const bool& aPositionSpecified,
|
|
||||||
const bool& aSizeSpecified,
|
|
||||||
const nsString& aURI,
|
|
||||||
const nsString& aName,
|
|
||||||
const nsCString& aFeatures,
|
|
||||||
const nsString& aBaseURI,
|
|
||||||
nsresult* aResult,
|
|
||||||
bool* aWindowIsNew,
|
|
||||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
|
||||||
nsCString* aURLToLoad) override;
|
|
||||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
InfallibleTArray<CpowEntry>&& aCpows,
|
InfallibleTArray<CpowEntry>&& aCpows,
|
||||||
|
@ -497,8 +494,6 @@ protected:
|
||||||
bool InitBrowserConfiguration(const nsCString& aURI,
|
bool InitBrowserConfiguration(const nsCString& aURI,
|
||||||
BrowserConfiguration& aConfiguration);
|
BrowserConfiguration& aConfiguration);
|
||||||
|
|
||||||
void SetHasContentOpener(bool aHasContentOpener);
|
|
||||||
|
|
||||||
// Decide whether we have to use a new process to reload the URI associated
|
// Decide whether we have to use a new process to reload the URI associated
|
||||||
// with the given channel.
|
// with the given channel.
|
||||||
bool ShouldSwitchProcess(nsIChannel* aChannel);
|
bool ShouldSwitchProcess(nsIChannel* aChannel);
|
||||||
|
@ -584,9 +579,6 @@ private:
|
||||||
|
|
||||||
TabId mTabId;
|
TabId mTabId;
|
||||||
|
|
||||||
// Helper class for RecvCreateWindow.
|
|
||||||
struct AutoUseNewTab;
|
|
||||||
|
|
||||||
// When loading a new tab or window via window.open, the child process sends
|
// When loading a new tab or window via window.open, the child process sends
|
||||||
// a new PBrowser to use. We store that tab in sNextTabParent and then
|
// a new PBrowser to use. We store that tab in sNextTabParent and then
|
||||||
// proceed through the browser's normal paths to create a new
|
// proceed through the browser's normal paths to create a new
|
||||||
|
@ -655,6 +647,38 @@ public:
|
||||||
static TabParent* GetTabParentFromLayersId(uint64_t aLayersId);
|
static TabParent* GetTabParentFromLayersId(uint64_t aLayersId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew, nsCString* aURLToLoad)
|
||||||
|
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew), mURLToLoad(aURLToLoad)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!TabParent::sNextTabParent);
|
||||||
|
MOZ_ASSERT(!aNewTab->mCreatingWindow);
|
||||||
|
|
||||||
|
TabParent::sNextTabParent = aNewTab;
|
||||||
|
aNewTab->mCreatingWindow = true;
|
||||||
|
aNewTab->mDelayedURL.Truncate();
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoUseNewTab()
|
||||||
|
{
|
||||||
|
mNewTab->mCreatingWindow = false;
|
||||||
|
*mURLToLoad = mNewTab->mDelayedURL;
|
||||||
|
|
||||||
|
if (TabParent::sNextTabParent) {
|
||||||
|
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
|
||||||
|
TabParent::sNextTabParent = nullptr;
|
||||||
|
*mWindowIsNew = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TabParent* mNewTab;
|
||||||
|
bool* mWindowIsNew;
|
||||||
|
nsCString* mURLToLoad;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче