Commit 82c0f498 authored by Brindusan Cristian's avatar Brindusan Cristian
Browse files

Merge mozilla-central to autoland. a=merge CLOSED TREE

parents d1ef75d4 ebd68897
......@@ -1606,6 +1606,7 @@ window._gBrowser = {
remoteType,
sameProcessAsFrameLoader,
recordExecution,
replaceBrowsingContext,
} = {}) {
let isRemote = aBrowser.getAttribute("remote") == "true";
......@@ -1726,7 +1727,7 @@ window._gBrowser = {
// This call actually switches out our frameloaders. Do this as late as
// possible before rebuilding the browser, as we'll need the new browser
// state set up completely first.
aBrowser.changeRemoteness({ remoteType });
aBrowser.changeRemoteness({ remoteType, replaceBrowsingContext });
// Once we have new frameloaders, this call sets the browser back up.
//
// FIXME(emilio): Shouldn't we call destroy() first? What hides the
......
......@@ -2296,7 +2296,7 @@ var SessionStoreInternal = {
}
},
async _doTabProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId) {
async _doTabProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext) {
debug(`[process-switch]: performing switch from ${aBrowser.remoteType} to ${aRemoteType}`);
// Don't try to switch tabs before delayed startup is completed.
......@@ -2310,6 +2310,10 @@ var SessionStoreInternal = {
// Information about which channel should be performing the load.
redirectLoadSwitchId: aSwitchId,
// True if this is a process switch due to a policy mismatch, means we
// shouldn't preserve our browsing context.
replaceBrowsingContext: aReplaceBrowsingContext,
};
await SessionStore.navigateAndRestore(tab, loadArguments, -1);
......@@ -2332,7 +2336,7 @@ var SessionStoreInternal = {
* This method is asynchronous, as it requires multiple calls into content
* processes.
*/
async _doProcessSwitch(aBrowsingContext, aRemoteType, aChannel, aSwitchId) {
async _doProcessSwitch(aBrowsingContext, aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext) {
// There are two relevant cases when performing a process switch for a
// browsing context: in-process and out-of-process embedders.
......@@ -2341,7 +2345,7 @@ var SessionStoreInternal = {
// traditional mechanism.
if (aBrowsingContext.embedderElement) {
return this._doTabProcessSwitch(aBrowsingContext.embedderElement,
aRemoteType, aChannel, aSwitchId);
aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext);
}
let wg = aBrowsingContext.embedderWindowGlobal;
......@@ -2443,13 +2447,17 @@ var SessionStoreInternal = {
return;
}
const isCOOPSwitch = E10SUtils.useCrossOriginOpenerPolicy() &&
aChannel.hasCrossOriginOpenerPolicyMismatch();
// ------------------------------------------------------------------------
// DANGER ZONE: Perform a process switch into the new process. This is
// destructive.
// ------------------------------------------------------------------------
let identifier = ++this._switchIdMonotonic;
let tabPromise = this._doProcessSwitch(browsingContext, remoteType,
aChannel, identifier);
aChannel, identifier,
isCOOPSwitch);
aChannel.switchProcessTo(tabPromise, identifier);
},
......@@ -3296,6 +3304,7 @@ var SessionStoreInternal = {
// the loadArguments.
newFrameloader: loadArguments.newFrameloader,
remoteType: loadArguments.remoteType,
replaceBrowsingContext: loadArguments.replaceBrowsingContext,
// Make sure that SessionStore knows that this restoration is due
// to a navigation, as opposed to us restoring a closed window or tab.
restoreContentReason: RESTORE_TAB_CONTENT_REASON.NAVIGATE_AND_RESTORE,
......@@ -4258,18 +4267,21 @@ var SessionStoreInternal = {
this.markTabAsRestoring(aTab);
let newFrameloader = aOptions.newFrameloader;
let replaceBrowsingContext = aOptions.replaceBrowsingContext;
let isRemotenessUpdate;
if (aOptions.remoteType !== undefined) {
// We already have a selected remote type so we update to that.
isRemotenessUpdate =
tabbrowser.updateBrowserRemoteness(browser,
{ remoteType: aOptions.remoteType,
newFrameloader });
newFrameloader,
replaceBrowsingContext,
});
} else {
isRemotenessUpdate =
tabbrowser.updateBrowserRemotenessByURL(browser, uri, {
newFrameloader,
replaceBrowsingContext,
});
}
......
......@@ -813,6 +813,21 @@ void BrowsingContext::Transaction::Apply(BrowsingContext* aBrowsingContext,
#include "mozilla/dom/BrowsingContextFieldList.h"
}
BrowsingContext::IPCInitializer BrowsingContext::GetIPCInitializer() {
MOZ_ASSERT(
!mozilla::Preferences::GetBool("fission.preserve_browsing_contexts", false) ||
IsContent());
IPCInitializer init;
init.mId = Id();
init.mParentId = mParent ? mParent->Id() : 0;
init.mCached = IsCached();
#define MOZ_BC_FIELD(name, type) init.m##name = m##name;
#include "mozilla/dom/BrowsingContextFieldList.h"
return init;
}
already_AddRefed<BrowsingContext> BrowsingContext::IPCInitializer::GetParent() {
RefPtr<BrowsingContext> parent;
if (mParentId != 0) {
......
......@@ -347,16 +347,7 @@ class BrowsingContext : public nsWrapperCache,
};
// Create an IPCInitializer object for this BrowsingContext.
IPCInitializer GetIPCInitializer() {
IPCInitializer init;
init.mId = Id();
init.mParentId = mParent ? mParent->Id() : 0;
init.mCached = IsCached();
#define MOZ_BC_FIELD(name, type) init.m##name = m##name;
#include "mozilla/dom/BrowsingContextFieldList.h"
return init;
}
IPCInitializer GetIPCInitializer();
// Create a BrowsingContext object from over IPC.
static already_AddRefed<BrowsingContext> CreateFromIPC(
......
......@@ -11,6 +11,12 @@
namespace mozilla {
namespace dom {
BrowsingContextGroup::BrowsingContextGroup() {
if (XRE_IsContentProcess()) {
ContentChild::GetSingleton()->HoldBrowsingContextGroup(this);
}
}
bool BrowsingContextGroup::Contains(BrowsingContext* aBrowsingContext) {
return aBrowsingContext->Group() == this;
}
......
......@@ -62,7 +62,7 @@ class BrowsingContextGroup final : public nsWrapperCache {
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
BrowsingContextGroup() = default;
BrowsingContextGroup();
static already_AddRefed<BrowsingContextGroup> Select(
BrowsingContext* aParent, BrowsingContext* aOpener) {
......
......@@ -385,7 +385,8 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)
mHasLoadedNonBlankURI(false),
mBlankTiming(false),
mTitleValidForCurrentURI(false),
mIsFrame(false) {
mIsFrame(false),
mSkipBrowsingContextDetachOnDestroy(false) {
mHistoryID.m0 = 0;
mHistoryID.m1 = 0;
mHistoryID.m2 = 0;
......@@ -5036,7 +5037,11 @@ nsDocShell::Destroy() {
mSessionHistory = nullptr;
}
mBrowsingContext->Detach();
// This will be skipped in cases where we want to preserve the browsing
// context between loads.
if (!mSkipBrowsingContextDetachOnDestroy) {
mBrowsingContext->Detach();
}
SetTreeOwner(nullptr);
......@@ -12905,10 +12910,8 @@ nsresult nsDocShell::CharsetChangeStopDocumentLoad() {
return NS_ERROR_DOCSHELL_REQUEST_REJECTED;
}
NS_IMETHODIMP
nsDocShell::SetIsPrinting(bool aIsPrinting) {
void nsDocShell::SetIsPrinting(bool aIsPrinting) {
mIsPrintingOrPP = aIsPrinting;
return NS_OK;
}
NS_IMETHODIMP
......
......@@ -405,6 +405,10 @@ class nsDocShell final : public nsDocLoader,
// Clear the document's storage access flag if needed.
void MaybeClearStorageAccessFlag();
void SkipBrowsingContextDetach() {
mSkipBrowsingContextDetachOnDestroy = true;
}
private: // member functions
friend class nsDSURIContentListener;
friend class FramingChecker;
......@@ -1236,6 +1240,11 @@ class nsDocShell final : public nsDocLoader,
bool mTitleValidForCurrentURI : 1;
bool mIsFrame : 1;
// If mSkipBrowsingContextDetachOnDestroy is set to true, then when the
// docshell is destroyed, the browsing context will not be detached. This is
// for cases where we want to preserve the BC for future use.
bool mSkipBrowsingContextDetachOnDestroy : 1;
};
#endif /* nsDocShell_h__ */
......@@ -546,7 +546,7 @@ interface nsIDocShell : nsIDocShellTreeItem
* Allows nsDocumentViewer to tell the top-level same-type docshell that
* one of the documents under it is printing.
*/
void setIsPrinting(in boolean aIsPrinting);
[noscript, notxpcom] void setIsPrinting(in boolean aIsPrinting);
/**
* If the current content viewer isn't initialized for print preview,
......
......@@ -364,7 +364,7 @@ nsFrameLoader* nsFrameLoader::Create(Element* aOwner, BrowsingContext* aOpener,
/* static */
nsFrameLoader* nsFrameLoader::Create(
mozilla::dom::Element* aOwner,
mozilla::dom::Element* aOwner, BrowsingContext* aPreservedBrowsingContext,
const mozilla::dom::RemotenessOptions& aOptions) {
NS_ENSURE_TRUE(aOwner, nullptr);
// This version of Create is only called for Remoteness updates, so we can
......@@ -381,7 +381,12 @@ nsFrameLoader* nsFrameLoader::Create(
if (hasOpener) {
opener = aOptions.mOpener.Value().Value().get();
}
RefPtr<BrowsingContext> context = CreateBrowsingContext(aOwner, opener);
RefPtr<BrowsingContext> context;
if (aPreservedBrowsingContext) {
context = aPreservedBrowsingContext;
} else {
context = CreateBrowsingContext(aOwner, opener);
}
NS_ENSURE_TRUE(context, nullptr);
return new nsFrameLoader(aOwner, context, aOptions);
}
......@@ -3490,3 +3495,22 @@ JSObject* nsFrameLoader::WrapObject(JSContext* cx,
FrameLoader_Binding::Wrap(cx, this, this, aGivenProto, &result);
return result;
}
void nsFrameLoader::SkipBrowsingContextDetach() {
if (IsRemoteFrame()) {
// OOP Browser - Go directly over Browser Parent
if (mBrowserParent) {
Unused << mBrowserParent->SendSkipBrowsingContextDetach();
}
// OOP IFrame - Through Browser Bridge Parent, set on browser child
else if (mBrowserBridgeChild) {
Unused << mBrowserBridgeChild->SendSkipBrowsingContextDetach();
}
return;
}
// In process
RefPtr<nsDocShell> docshell = GetDocShell();
MOZ_ASSERT(docshell);
docshell->SkipBrowsingContextDetach();
}
......@@ -95,6 +95,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
typedef mozilla::dom::PBrowserParent PBrowserParent;
typedef mozilla::dom::Document Document;
typedef mozilla::dom::BrowserParent BrowserParent;
typedef mozilla::dom::BrowsingContext BrowsingContext;
typedef mozilla::layout::RenderFrame RenderFrame;
public:
......@@ -106,6 +107,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
// Called by nsFrameLoaderOwner::ChangeRemoteness when switching out
// FrameLoaders.
static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
BrowsingContext* aPreservedBrowsingContext,
const mozilla::dom::RemotenessOptions& aOptions);
NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)
......@@ -385,6 +387,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> aGivenProto) override;
void SkipBrowsingContextDetach();
private:
nsFrameLoader(mozilla::dom::Element* aOwner,
mozilla::dom::BrowsingContext* aBrowsingContext,
......
......@@ -32,8 +32,26 @@ nsFrameLoaderOwner::GetBrowsingContext() {
void nsFrameLoaderOwner::ChangeRemoteness(
const mozilla::dom::RemotenessOptions& aOptions, mozilla::ErrorResult& rv) {
// If we already have a Frameloader, destroy it.
RefPtr<mozilla::dom::BrowsingContext> bc;
// If we already have a Frameloader, destroy it, possibly preserving its
// browsing context.
if (mFrameLoader) {
// Don't preserve contexts if this is a chrome (parent process) window that
// is changing from remote to local.
bool isChromeRemoteToLocal =
XRE_IsParentProcess() && (!aOptions.mRemoteType.WasPassed() ||
aOptions.mRemoteType.Value().IsVoid());
// If this is a process switch due to a difference in Cross Origin Opener
// Policy, do not preserve the browsing context. Otherwise, save off the
// browsing context and use it when creating our new FrameLoader.
if (!aOptions.mReplaceBrowsingContext && !isChromeRemoteToLocal &&
mozilla::Preferences::GetBool("fission.preserve_browsing_contexts", false)) {
bc = mFrameLoader->GetBrowsingContext();
mFrameLoader->SkipBrowsingContextDetach();
}
mFrameLoader->Destroy();
mFrameLoader = nullptr;
}
......@@ -43,7 +61,8 @@ void nsFrameLoaderOwner::ChangeRemoteness(
// owner.
RefPtr<Element> owner = do_QueryObject(this);
MOZ_ASSERT(owner);
mFrameLoader = nsFrameLoader::Create(owner, aOptions);
mFrameLoader = nsFrameLoader::Create(owner, bc, aOptions);
if (NS_WARN_IF(!mFrameLoader)) {
return;
}
......@@ -70,9 +89,8 @@ void nsFrameLoaderOwner::ChangeRemoteness(
// FrameLoader, fire an event to act like we've recreated ourselves, similar
// to what XULFrameElement does after rebinding to the tree.
// ChromeOnlyDispatch is turns on to make sure this isn't fired into content.
(new mozilla::AsyncEventDispatcher(owner,
NS_LITERAL_STRING("XULFrameLoaderCreated"),
mozilla::CanBubble::eYes,
mozilla::ChromeOnlyDispatch::eYes))
(new mozilla::AsyncEventDispatcher(
owner, NS_LITERAL_STRING("XULFrameLoaderCreated"),
mozilla::CanBubble::eYes, mozilla::ChromeOnlyDispatch::eYes))
->RunDOMEventWhenSafe();
}
......@@ -182,6 +182,11 @@ IPCResult BrowserBridgeParent::RecvDispatchSynthesizedMouseEvent(
return IPC_OK();
}
IPCResult BrowserBridgeParent::RecvSkipBrowsingContextDetach() {
mBrowserParent->SkipBrowsingContextDetach();
return IPC_OK();
}
IPCResult BrowserBridgeParent::RecvActivate() {
mBrowserParent->Activate();
return IPC_OK();
......
......@@ -59,6 +59,8 @@ class BrowserBridgeParent : public PBrowserBridgeParent {
mozilla::ipc::IPCResult RecvDispatchSynthesizedMouseEvent(
const WidgetMouseEvent& aEvent);
mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach();
mozilla::ipc::IPCResult RecvActivate();
mozilla::ipc::IPCResult RecvDeactivate();
......
......@@ -1052,6 +1052,17 @@ BrowserChild::~BrowserChild() {
mozilla::DropJSObjects(this);
}
mozilla::ipc::IPCResult BrowserChild::RecvSkipBrowsingContextDetach() {
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (!docShell) {
return IPC_OK();
}
RefPtr<nsDocShell> docshell = nsDocShell::Cast(docShell);
MOZ_ASSERT(docshell);
docshell->SkipBrowsingContextDetach();
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserChild::RecvLoadURL(const nsCString& aURI,
const ShowInfo& aInfo) {
if (!mDidLoadURLInit) {
......
......@@ -555,6 +555,7 @@ class BrowserChild final : public BrowserChildBase,
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
const uintptr_t& aNewHandle);
mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach();
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
......
......@@ -536,7 +536,7 @@ void BrowserParent::SetOwnerElement(Element* aElement) {
// Set our BrowsingContext's embedder if we're not embedded within a
// BrowserBridgeParent.
if (!GetBrowserBridgeParent() && mBrowsingContext) {
if (!GetBrowserBridgeParent() && mBrowsingContext && mFrameElement) {
mBrowsingContext->SetEmbedderElement(mFrameElement);
}
......@@ -3744,6 +3744,12 @@ BrowserParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId) {
return NS_OK;
}
void BrowserParent::SkipBrowsingContextDetach() {
RefPtr<nsFrameLoader> fl = GetFrameLoader();
MOZ_ASSERT(fl);
fl->SkipBrowsingContextDetach();
}
mozilla::ipc::IPCResult BrowserParent::RecvLookUpDictionary(
const nsString& aText, nsTArray<FontRange>&& aFontRangeArray,
const bool& aIsVertical, const LayoutDeviceIntPoint& aPoint) {
......
......@@ -678,6 +678,8 @@ class BrowserParent final : public PBrowserParent,
void NavigateByKey(bool aForward, bool aForDocumentNavigation);
void SkipBrowsingContextDetach();
protected:
bool ReceiveMessage(
const nsString& aMessage, bool aSync, ipc::StructuredCloneData* aData,
......
......@@ -2298,6 +2298,8 @@ void ContentChild::ActorDestroy(ActorDestroyReason why) {
mIdleObservers.Clear();
mBrowsingContextGroupHolder.Clear();
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (svc) {
svc->UnregisterListener(mConsoleListener);
......@@ -3798,7 +3800,6 @@ mozilla::ipc::IPCResult ContentChild::RecvRestoreBrowsingContextChildren(
mozilla::ipc::IPCResult ContentChild::RecvRegisterBrowsingContextGroup(
nsTArray<BrowsingContext::IPCInitializer>&& aInits) {
RefPtr<BrowsingContextGroup> group = new BrowsingContextGroup();
// Each of the initializers in aInits is sorted in pre-order, so our parent
// should always be available before the element itself.
for (auto& init : aInits) {
......@@ -3911,6 +3912,11 @@ mozilla::ipc::IPCResult ContentChild::RecvCommitBrowsingContextTransaction(
return IPC_OK();
}
void ContentChild::HoldBrowsingContextGroup(BrowsingContextGroup* aBCG) {
RefPtr<BrowsingContextGroup> bcgPtr(aBCG);
mBrowsingContextGroupHolder.AppendElement(bcgPtr);
}
} // namespace dom
#if defined(__OpenBSD__) && defined(MOZ_SANDBOX)
......
......@@ -674,6 +674,8 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvStartDelayedAutoplayMediaComponents(
BrowsingContext* aContext);
void HoldBrowsingContextGroup(BrowsingContextGroup* aBCG);
#ifdef NIGHTLY_BUILD
// Fetch the current number of pending input events.
//
......@@ -814,6 +816,8 @@ class ContentChild final : public PContentChild,
uint32_t mNetworkLinkType = 0;
nsTArray<RefPtr<BrowsingContextGroup>> mBrowsingContextGroupHolder;
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment