From 570fcda0e2a0c42a82165118a969fcd9cbae5ebc Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Tue, 7 Apr 2020 21:39:12 +0000 Subject: [PATCH] Bug 1616353 - Part 6.1: Implement nsILoadContext on BrowsingContext, r=smaug This also moves nsDocShell's implementation of nsILoadContext to be based on its BrowsingContext. This patch does not, by itself, fix all places which try to mutate `nsILoadContext`. Those are fixed by the other parts of this patch stack. Differential Revision: https://phabricator.services.mozilla.com/D67045 --HG-- extra : moz-landing-system : lando --- docshell/base/BrowsingContext.cpp | 276 ++++++++++++++++++++++++++- docshell/base/BrowsingContext.h | 43 ++++- docshell/base/nsDocShell.cpp | 304 ++++++------------------------ docshell/base/nsDocShell.h | 21 +-- docshell/base/nsIDocShell.idl | 9 - dom/base/nsFrameLoader.cpp | 154 ++++++++------- dom/base/nsFrameLoader.h | 2 + 7 files changed, 466 insertions(+), 343 deletions(-) diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 3f00709f09d4..1d377089ccbf 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -215,6 +215,11 @@ already_AddRefed BrowsingContext::CreateDetached( BrowsingContext* inherit = aParent ? aParent : aOpener; if (inherit) { + context->mPrivateBrowsingId = inherit->mPrivateBrowsingId; + context->mUseRemoteTabs = inherit->mUseRemoteTabs; + context->mUseRemoteSubframes = inherit->mUseRemoteSubframes; + context->mOriginAttributes = inherit->mOriginAttributes; + // CORPP 3.1.3 https://mikewest.github.io/corpp/#integration-html context->mFields.SetWithoutSyncing( inherit->GetEmbedderPolicy()); @@ -320,6 +325,13 @@ already_AddRefed BrowsingContext::CreateFromIPC( context->mWindowless = aInit.mWindowless; + // NOTE: Call through the `Set` methods for these values to ensure that any + // relevant process-local state is also updated. + context->SetOriginAttributes(aInit.mOriginAttributes); + context->SetRemoteTabs(aInit.mUseRemoteTabs); + context->SetRemoteSubframes(aInit.mUseRemoteSubframes); + // NOTE: Private browsing ID is set by `SetOriginAttributes`. + Register(context); // Caller handles attaching us to the tree. @@ -340,13 +352,16 @@ BrowsingContext::BrowsingContext(BrowsingContext* aParent, mBrowsingContextId(aBrowsingContextId), mGroup(aGroup), mParent(aParent), + mPrivateBrowsingId(0), mEverAttached(false), mIsInProcess(false), mIsDiscarded(false), mWindowless(false), mDanglingRemoteOuterProxies(false), mPendingInitialization(false), - mEmbeddedByThisProcess(false) { + mEmbeddedByThisProcess(false), + mUseRemoteTabs(false), + mUseRemoteSubframes(false) { MOZ_RELEASE_ASSERT(!mParent || mParent->Group() == mGroup); MOZ_RELEASE_ASSERT(mBrowsingContextId != 0); MOZ_RELEASE_ASSERT(mGroup); @@ -442,10 +457,16 @@ void BrowsingContext::Attach(bool aFromIPC) { MOZ_DIAGNOSTIC_ASSERT(!mEverAttached); mEverAttached = true; - MOZ_LOG(GetLog(), LogLevel::Debug, - ("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64, - XRE_IsParentProcess() ? "Parent" : "Child", Id(), - mParent ? mParent->Id() : 0)); + if (MOZ_LOG_TEST(GetLog(), LogLevel::Debug)) { + nsAutoCString suffix; + mOriginAttributes.CreateSuffix(suffix); + MOZ_LOG(GetLog(), LogLevel::Debug, + ("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64 + " (private=%d, remote=%d, fission=%d, oa=%s)", + XRE_IsParentProcess() ? "Parent" : "Child", Id(), + mParent ? mParent->Id() : 0, (int)mPrivateBrowsingId, + (int)mUseRemoteTabs, (int)mUseRemoteSubframes, suffix.get())); + } MOZ_DIAGNOSTIC_ASSERT(mGroup); MOZ_DIAGNOSTIC_ASSERT(!mGroup->IsContextCached(this)); @@ -562,6 +583,8 @@ void BrowsingContext::Detach(bool aFromIPC) { mFields.SetWithoutSyncing(false); } + AssertOriginAttributesMatchPrivateBrowsing(); + if (XRE_IsParentProcess()) { Canonical()->CanonicalDiscard(); } @@ -985,6 +1008,239 @@ bool BrowsingContext::ConsumeTransientUserGestureActivation() { return true; } +bool BrowsingContext::CanSetOriginAttributes() { + // A discarded BrowsingContext has already been destroyed, and cannot modify + // its OriginAttributes. + if (NS_WARN_IF(IsDiscarded())) { + return false; + } + + // Before attaching is the safest time to set OriginAttributes, and the only + // allowed time for content BrowsingContexts. + if (!EverAttached()) { + return true; + } + + // Attached content BrowsingContexts may have been synced to other processes. + if (NS_WARN_IF(IsContent())) { + MOZ_CRASH(); + return false; + } + MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); + + // Cannot set OriginAttributes after we've created our child BrowsingContext. + if (NS_WARN_IF(!Children().IsEmpty())) { + return false; + } + + // Only allow setting OriginAttributes if we have no associated document, or + // the document is still `about:blank`. + // TODO: Bug 1273058 - should have no document when setting origin attributes. + if (WindowGlobalParent* window = Canonical()->GetCurrentWindowGlobal()) { + if (nsIURI* uri = window->GetDocumentURI()) { + MOZ_ASSERT(NS_IsAboutBlank(uri)); + return NS_IsAboutBlank(uri); + } + } + return true; +} + +NS_IMETHODIMP BrowsingContext::GetAssociatedWindow( + mozIDOMWindowProxy** aAssociatedWindow) { + nsCOMPtr win = GetDOMWindow(); + win.forget(aAssociatedWindow); + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetTopWindow(mozIDOMWindowProxy** aTopWindow) { + return Top()->GetAssociatedWindow(aTopWindow); +} + +NS_IMETHODIMP BrowsingContext::GetTopFrameElement(Element** aTopFrameElement) { + RefPtr topFrameElement = Top()->GetEmbedderElement(); + topFrameElement.forget(aTopFrameElement); + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetNestedFrameId(uint64_t* aNestedFrameId) { + // FIXME: nestedFrameId should be removed, as it was only used by B2G. + *aNestedFrameId = 0; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetIsContent(bool* aIsContent) { + *aIsContent = IsContent(); + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetUsePrivateBrowsing( + bool* aUsePrivateBrowsing) { + *aUsePrivateBrowsing = mPrivateBrowsingId > 0; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) { + if (!CanSetOriginAttributes()) { + bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0); + if (changed) { + NS_WARNING("SetUsePrivateBrowsing when !CanSetOriginAttributes()"); + } + return changed ? NS_ERROR_FAILURE : NS_OK; + } + + return SetPrivateBrowsing(aUsePrivateBrowsing); +} + +NS_IMETHODIMP BrowsingContext::SetPrivateBrowsing(bool aPrivateBrowsing) { + if (!CanSetOriginAttributes()) { + NS_WARNING("Attempt to set PrivateBrowsing when !CanSetOriginAttributes"); + return NS_ERROR_FAILURE; + } + + bool changed = aPrivateBrowsing != (mPrivateBrowsingId > 0); + if (changed) { + mPrivateBrowsingId = aPrivateBrowsing ? 1 : 0; + if (IsContent()) { + mOriginAttributes.SyncAttributesWithPrivateBrowsing(aPrivateBrowsing); + } + } + AssertOriginAttributesMatchPrivateBrowsing(); + + if (changed && mDocShell) { + nsDocShell::Cast(mDocShell)->NotifyPrivateBrowsingChanged(); + } + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetUseRemoteTabs(bool* aUseRemoteTabs) { + *aUseRemoteTabs = mUseRemoteTabs; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::SetRemoteTabs(bool aUseRemoteTabs) { + if (!CanSetOriginAttributes()) { + NS_WARNING("Attempt to set RemoteTabs when !CanSetOriginAttributes"); + return NS_ERROR_FAILURE; + } + + static bool annotated = false; + if (aUseRemoteTabs && !annotated) { + annotated = true; + CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled, + true); + } + + // Don't allow non-remote tabs with remote subframes. + if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) { + return NS_ERROR_UNEXPECTED; + } + + mUseRemoteTabs = aUseRemoteTabs; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetUseRemoteSubframes( + bool* aUseRemoteSubframes) { + *aUseRemoteSubframes = mUseRemoteSubframes; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::SetRemoteSubframes(bool aUseRemoteSubframes) { + if (!CanSetOriginAttributes()) { + NS_WARNING("Attempt to set RemoteSubframes when !CanSetOriginAttributes"); + return NS_ERROR_FAILURE; + } + + static bool annotated = false; + if (aUseRemoteSubframes && !annotated) { + annotated = true; + CrashReporter::AnnotateCrashReport( + CrashReporter::Annotation::DOMFissionEnabled, true); + } + + // Don't allow non-remote tabs with remote subframes. + if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) { + return NS_ERROR_UNEXPECTED; + } + + mUseRemoteSubframes = aUseRemoteSubframes; + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetUseTrackingProtection( + bool* aUseTrackingProtection) { + *aUseTrackingProtection = false; + + if (GetForceEnableTrackingProtection() || + StaticPrefs::privacy_trackingprotection_enabled() || + (UsePrivateBrowsing() && + StaticPrefs::privacy_trackingprotection_pbmode_enabled())) { + *aUseTrackingProtection = true; + return NS_OK; + } + + if (mParent) { + return mParent->GetUseTrackingProtection(aUseTrackingProtection); + } + + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::SetUseTrackingProtection( + bool aUseTrackingProtection) { + SetForceEnableTrackingProtection(aUseTrackingProtection); + return NS_OK; +} + +NS_IMETHODIMP BrowsingContext::GetScriptableOriginAttributes( + JSContext* aCx, JS::MutableHandle aVal) { + AssertOriginAttributesMatchPrivateBrowsing(); + + bool ok = ToJSValue(aCx, mOriginAttributes, aVal); + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP_(void) +BrowsingContext::GetOriginAttributes(OriginAttributes& aAttrs) { + aAttrs = mOriginAttributes; + AssertOriginAttributesMatchPrivateBrowsing(); +} + +nsresult BrowsingContext::SetOriginAttributes(const OriginAttributes& aAttrs) { + if (!CanSetOriginAttributes()) { + NS_WARNING("Attempt to set OriginAttributes when !CanSetOriginAttributes"); + return NS_ERROR_FAILURE; + } + + AssertOriginAttributesMatchPrivateBrowsing(); + mOriginAttributes = aAttrs; + + bool isPrivate = mOriginAttributes.mPrivateBrowsingId != + nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID; + // Chrome Browsing Context can not contain OriginAttributes.mPrivateBrowsingId + if (IsChrome() && isPrivate) { + mOriginAttributes.mPrivateBrowsingId = + nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID; + } + SetPrivateBrowsing(isPrivate); + AssertOriginAttributesMatchPrivateBrowsing(); + + return NS_OK; +} + +void BrowsingContext::AssertOriginAttributesMatchPrivateBrowsing() { + // Chrome browsing contexts must not have a private browsing OriginAttribute + // Content browsing contexts must maintain the equality: + // mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId + if (IsChrome()) { + MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0); + } else { + MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == + mPrivateBrowsingId); + } +} + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowsingContext) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) @@ -1354,6 +1610,9 @@ BrowsingContext::IPCInitializer BrowsingContext::GetIPCInitializer() { init.mParentId = mParent ? mParent->Id() : 0; init.mCached = IsCached(); init.mWindowless = mWindowless; + init.mUseRemoteTabs = mUseRemoteTabs; + init.mUseRemoteSubframes = mUseRemoteSubframes; + init.mOriginAttributes = mOriginAttributes; init.mFields = mFields.Fields(); return init; } @@ -1734,6 +1993,9 @@ void IPDLParamTraits::Write( WriteIPDLParam(aMessage, aActor, aInit.mParentId); WriteIPDLParam(aMessage, aActor, aInit.mCached); WriteIPDLParam(aMessage, aActor, aInit.mWindowless); + WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteTabs); + WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteSubframes); + WriteIPDLParam(aMessage, aActor, aInit.mOriginAttributes); WriteIPDLParam(aMessage, aActor, aInit.mFields); } @@ -1745,6 +2007,10 @@ bool IPDLParamTraits::Read( !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mParentId) || !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mCached) || !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mWindowless) || + !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mUseRemoteTabs) || + !ReadIPDLParam(aMessage, aIterator, aActor, + &aInit->mUseRemoteSubframes) || + !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mOriginAttributes) || !ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mFields)) { return false; } diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index edac5a2cbedd..eaa253525fe0 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -29,6 +29,7 @@ #include "nsTArray.h" #include "nsWrapperCache.h" #include "nsILoadInfo.h" +#include "nsILoadContext.h" class nsDocShellLoadState; class nsGlobalWindowOuter; @@ -108,6 +109,7 @@ class WindowProxyHolder; FIELD(AllowPlugins, bool) \ FIELD(AllowContentRetargeting, bool) \ FIELD(AllowContentRetargetingOnChildren, bool) \ + FIELD(ForceEnableTrackingProtection, bool) \ /* These field are used to store the states of autoplay media request on \ * GeckoView only, and it would only be modified on the top level browsing \ * context. */ \ @@ -136,7 +138,7 @@ class WindowProxyHolder; // Trees of BrowsingContexts should only ever contain nodes of the // same BrowsingContext::Type. This is enforced by asserts in the // BrowsingContext::Create* methods. -class BrowsingContext : public nsISupports, public nsWrapperCache { +class BrowsingContext : public nsILoadContext, public nsWrapperCache { MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD) public: @@ -436,6 +438,7 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BrowsingContext) + NS_DECL_NSILOADCONTEXT const Children& GetChildren() { return mChildren; } const nsTArray>& GetWindowContexts() { @@ -504,19 +507,22 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { * This object may be serialized over IPC. */ struct IPCInitializer { - uint64_t mId; + uint64_t mId = 0; // IDs are used for Parent and Opener to allow for this object to be // deserialized before other BrowsingContext in the BrowsingContextGroup // have been initialized. - uint64_t mParentId; + uint64_t mParentId = 0; already_AddRefed GetParent(); already_AddRefed GetOpener(); uint64_t GetOpenerId() const { return mozilla::Get(mFields); } - bool mCached; - bool mWindowless; + bool mCached = false; + bool mWindowless = false; + bool mUseRemoteTabs = false; + bool mUseRemoteSubframes = false; + OriginAttributes mOriginAttributes; FieldTuple mFields; }; @@ -542,6 +548,9 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { bool PendingInitialization() const { return mPendingInitialization; }; void SetPendingInitialization(bool aVal) { mPendingInitialization = aVal; }; + const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; } + nsresult SetOriginAttributes(const OriginAttributes& aAttrs); + protected: virtual ~BrowsingContext(); BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup, @@ -554,6 +563,12 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { BrowsingContext* FindWithSpecialName(const nsAString& aName, BrowsingContext& aRequestingContext); + // Is it early enough in the BrowsingContext's lifecycle that it is still + // OK to set OriginAttributes? + bool CanSetOriginAttributes(); + + void AssertOriginAttributesMatchPrivateBrowsing(); + friend class ::nsOuterWindowProxy; friend class ::nsGlobalWindowOuter; friend class WindowContext; @@ -699,6 +714,16 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { JS::Heap mWindowProxy; LocationProxy mLocation; + // OriginAttributes for this BrowsingContext. May not be changed after this + // BrowsingContext is attached. + OriginAttributes mOriginAttributes; + + // Determines if private browsing should be used. May not be changed after + // this BrowsingContext is attached. This field matches mOriginAttributes in + // content Browsing Contexts. Currently treated as a binary value: 1 - in + // private mode, 0 - not private mode. + uint32_t mPrivateBrowsingId; + // True if Attach() has been called on this BrowsingContext already. bool mEverAttached : 1; @@ -727,6 +752,14 @@ class BrowsingContext : public nsISupports, public nsWrapperCache { // process. bool mEmbeddedByThisProcess : 1; + // Determines if remote (out-of-process) tabs should be used. May not be + // changed after this BrowsingContext is attached. + bool mUseRemoteTabs : 1; + + // Determines if out-of-process iframes should be used. May not be changed + // after this BrowsingContext is attached. + bool mUseRemoteSubframes : 1; + // The start time of user gesture, this is only available if the browsing // context is in process. TimeStamp mUserGestureStart; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 2ee7ffbdc9aa..6d69989d9248 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -360,7 +360,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext, mDefaultLoadFlags(nsIRequest::LOAD_NORMAL), mFailedLoadType(0), mFrameType(FRAME_TYPE_REGULAR), - mPrivateBrowsingId(0), mDisplayMode(nsIDocShell::DISPLAY_MODE_BROWSER), mJSRunToCompletionDepth(0), mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE), @@ -387,13 +386,9 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext, mDisableMetaRefreshWhenInactive(false), mIsAppTab(false), mUseGlobalHistory(false), - mUseRemoteTabs(false), - mUseRemoteSubframes(false), - mUseTrackingProtection(false), mDeviceSizeIsPageSize(false), mWindowDraggingAllowed(false), mInFrameSwap(false), - mInheritPrivateBrowsingId(true), mCanExecuteScripts(false), mFiredUnloadEvent(false), mEODForCurrentDocument(false), @@ -412,8 +407,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext, mWillChangeProcess(false), mWatchedByDevtools(false), mIsNavigating(false) { - AssertOriginAttributesMatchPrivateBrowsing(); - // If no outer window ID was provided, generate a new one. if (aContentWindowID == 0) { mContentWindowID = nsContentUtils::GenerateWindowId(); @@ -533,6 +526,12 @@ already_AddRefed nsDocShell::Create( return nullptr; } + // If our BrowsingContext has private browsing enabled, update the number of + // private browsing docshells. + if (aBrowsingContext->UsePrivateBrowsing()) { + ds->NotifyPrivateBrowsingChanged(); + } + // If our parent is present in this process, set up our parent now. RefPtr parent = aBrowsingContext->GetParent(); if (parent && parent->GetDocShell()) { @@ -801,10 +800,12 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { BrowsingContext::Type bcType = mBrowsingContext->GetType(); // Set up the inheriting principal in LoadState. - nsresult rv = aLoadState->SetupInheritingPrincipal(bcType, mOriginAttributes); + nsresult rv = aLoadState->SetupInheritingPrincipal( + bcType, mBrowsingContext->OriginAttributesRef()); NS_ENSURE_SUCCESS(rv, rv); - rv = aLoadState->SetupTriggeringPrincipal(mOriginAttributes); + rv = aLoadState->SetupTriggeringPrincipal( + mBrowsingContext->OriginAttributesRef()); NS_ENSURE_SUCCESS(rv, rv); aLoadState->CalculateLoadURIFlags(); @@ -1523,66 +1524,40 @@ nsDocShell::SetAllowJavascript(bool aAllowJavascript) { NS_IMETHODIMP nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) { NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing); - AssertOriginAttributesMatchPrivateBrowsing(); - *aUsePrivateBrowsing = mPrivateBrowsingId > 0; - return NS_OK; + return mBrowsingContext->GetUsePrivateBrowsing(aUsePrivateBrowsing); +} + +void nsDocShell::NotifyPrivateBrowsingChanged() { + MOZ_ASSERT(!mIsBeingDestroyed); + + if (mAffectPrivateSessionLifetime) { + if (UsePrivateBrowsing()) { + IncreasePrivateDocShellCount(); + } else { + DecreasePrivateDocShellCount(); + } + } + + nsTObserverArray::ForwardIterator iter(mPrivacyObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr obs = do_QueryReferent(ref); + if (!obs) { + mPrivacyObservers.RemoveElement(ref); + } else { + obs->PrivateModeChanged(UsePrivateBrowsing()); + } + } } NS_IMETHODIMP nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) { - if (!CanSetOriginAttributes()) { - bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0); - - return changed ? NS_ERROR_FAILURE : NS_OK; - } - - return SetPrivateBrowsing(aUsePrivateBrowsing); + return mBrowsingContext->SetUsePrivateBrowsing(aUsePrivateBrowsing); } NS_IMETHODIMP nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing) { - MOZ_ASSERT(!mIsBeingDestroyed); - - bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0); - if (changed) { - mPrivateBrowsingId = aUsePrivateBrowsing ? 1 : 0; - - if (mItemType != typeChrome) { - mOriginAttributes.SyncAttributesWithPrivateBrowsing(aUsePrivateBrowsing); - } - - if (mAffectPrivateSessionLifetime) { - if (aUsePrivateBrowsing) { - IncreasePrivateDocShellCount(); - } else { - DecreasePrivateDocShellCount(); - } - } - } - - nsTObserverArray::ForwardIterator iter(mChildList); - while (iter.HasMore()) { - nsCOMPtr shell = do_QueryObject(iter.GetNext()); - if (shell) { - shell->SetPrivateBrowsing(aUsePrivateBrowsing); - } - } - - if (changed) { - nsTObserverArray::ForwardIterator iter(mPrivacyObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr obs = do_QueryReferent(ref); - if (!obs) { - mPrivacyObservers.RemoveElement(ref); - } else { - obs->PrivateModeChanged(aUsePrivateBrowsing); - } - } - } - - AssertOriginAttributesMatchPrivateBrowsing(); - return NS_OK; + return mBrowsingContext->SetPrivateBrowsing(aUsePrivateBrowsing); } NS_IMETHODIMP @@ -1596,52 +1571,23 @@ nsDocShell::GetHasLoadedNonBlankURI(bool* aResult) { NS_IMETHODIMP nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) { NS_ENSURE_ARG_POINTER(aUseRemoteTabs); - - *aUseRemoteTabs = mUseRemoteTabs; - return NS_OK; + return mBrowsingContext->GetUseRemoteTabs(aUseRemoteTabs); } NS_IMETHODIMP nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) { - if (aUseRemoteTabs) { - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled, - true); - } - - // Don't allow non-remote tabs with remote subframes. - if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) { - return NS_ERROR_UNEXPECTED; - } - - mUseRemoteTabs = aUseRemoteTabs; - return NS_OK; + return mBrowsingContext->SetRemoteTabs(aUseRemoteTabs); } NS_IMETHODIMP nsDocShell::GetUseRemoteSubframes(bool* aUseRemoteSubframes) { NS_ENSURE_ARG_POINTER(aUseRemoteSubframes); - - *aUseRemoteSubframes = mUseRemoteSubframes; - return NS_OK; + return mBrowsingContext->GetUseRemoteSubframes(aUseRemoteSubframes); } NS_IMETHODIMP nsDocShell::SetRemoteSubframes(bool aUseRemoteSubframes) { - static bool annotated = false; - - if (aUseRemoteSubframes && !annotated) { - annotated = true; - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::DOMFissionEnabled, true); - } - - // Don't allow non-remote tabs with remote subframes. - if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) { - return NS_ERROR_UNEXPECTED; - } - - mUseRemoteSubframes = aUseRemoteSubframes; - return NS_OK; + return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes); } NS_IMETHODIMP @@ -1650,7 +1596,6 @@ nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime) { bool change = aAffectLifetime != mAffectPrivateSessionLifetime; if (change && UsePrivateBrowsing()) { - AssertOriginAttributesMatchPrivateBrowsing(); if (aAffectLifetime) { IncreasePrivateDocShellCount(); } else { @@ -1839,18 +1784,6 @@ nsDocShell::SetAllowContentRetargetingOnChildren( return NS_OK; } -NS_IMETHODIMP -nsDocShell::GetInheritPrivateBrowsingId(bool* aInheritPrivateBrowsingId) { - *aInheritPrivateBrowsingId = mInheritPrivateBrowsingId; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::SetInheritPrivateBrowsingId(bool aInheritPrivateBrowsingId) { - mInheritPrivateBrowsingId = aInheritPrivateBrowsingId; - return NS_OK; -} - NS_IMETHODIMP nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) { NS_ENSURE_ARG_POINTER(aFullscreenAllowed); @@ -2629,9 +2562,6 @@ void nsDocShell::RecomputeCanExecuteScripts() { nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) { bool wasFrame = IsFrame(); -#ifdef DEBUG - bool wasPrivate = UsePrivateBrowsing(); -#endif nsresult rv = nsDocLoader::SetDocLoaderParent(aParent); NS_ENSURE_SUCCESS(rv, rv); @@ -2678,10 +2608,8 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) { value = false; } SetAllowDNSPrefetch(mAllowDNSPrefetch && value); - if (mInheritPrivateBrowsingId) { - value = parentAsDocShell->GetAffectPrivateSessionLifetime(); - SetAffectPrivateSessionLifetime(value); - } + SetAffectPrivateSessionLifetime( + parentAsDocShell->GetAffectPrivateSessionLifetime()); uint32_t flags; if (NS_SUCCEEDED(parentAsDocShell->GetDefaultLoadFlags(&flags))) { SetDefaultLoadFlags(flags); @@ -2694,12 +2622,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) { // like this that might be embedded within it. } - nsCOMPtr parentAsLoadContext(do_QueryInterface(parent)); - if (parentAsLoadContext && mInheritPrivateBrowsingId && - NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value))) { - SetPrivateBrowsing(value); - } - nsCOMPtr parentURIListener(do_GetInterface(parent)); if (parentURIListener) { mContentListener->SetParentContentListener(parentURIListener); @@ -2713,9 +2635,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) { MaybeClearStorageAccessFlag(); } - NS_ASSERTION(mInheritPrivateBrowsingId || wasPrivate == UsePrivateBrowsing(), - "Private browsing state changed while inheritance was disabled"); - return NS_OK; } @@ -2829,18 +2748,6 @@ nsDocShell::GetSameTypeRootTreeItemIgnoreBrowserBoundaries( return NS_OK; } -void nsDocShell::AssertOriginAttributesMatchPrivateBrowsing() { - // Chrome docshells must not have a private browsing OriginAttribute - // Content docshells must maintain the equality: - // mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId - if (mItemType == typeChrome) { - MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0); - } else { - MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == - mPrivateBrowsingId); - } -} - bool nsDocShell::IsSandboxedFrom(BrowsingContext* aTargetBC) { // If no target then not sandboxed. if (!aTargetBC) { @@ -3059,9 +2966,6 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild) { childDocShell->SetUseGlobalHistory(true); } - Cast(childDocShell)->SetRemoteTabs(mUseRemoteTabs); - Cast(childDocShell)->SetRemoteSubframes(mUseRemoteSubframes); - if (aChild->ItemType() != mItemType) { return NS_OK; } @@ -3678,19 +3582,20 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI, do_GetService(NS_SSSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags, - mOriginAttributes, nullptr, nullptr, &isStsHost); + GetOriginAttributes(), nullptr, nullptr, + &isStsHost); NS_ENSURE_SUCCESS(rv, rv); rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags, - mOriginAttributes, nullptr, nullptr, + GetOriginAttributes(), nullptr, nullptr, &isPinnedHost); NS_ENSURE_SUCCESS(rv, rv); } else { mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags, - mOriginAttributes, &isStsHost); + GetOriginAttributes(), &isStsHost); cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags, - mOriginAttributes, &isPinnedHost); + GetOriginAttributes(), &isPinnedHost); } if (Preferences::GetBool("browser.xul.error_pages.expert_bad_cert", @@ -4449,8 +4354,6 @@ nsDocShell::Destroy() { NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome, "Unexpected item type in docshell"); - AssertOriginAttributesMatchPrivateBrowsing(); - nsCOMPtr serv = services::GetObserverService(); if (serv) { const char* msg = mItemType == typeContent @@ -4558,12 +4461,8 @@ nsDocShell::Destroy() { // to break the cycle between us and the timers. CancelRefreshURITimers(); - if (UsePrivateBrowsing()) { - mPrivateBrowsingId = nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID; - mOriginAttributes.SyncAttributesWithPrivateBrowsing(false); - if (mAffectPrivateSessionLifetime) { - DecreasePrivateDocShellCount(); - } + if (UsePrivateBrowsing() && mAffectPrivateSessionLifetime) { + DecreasePrivateDocShellCount(); } return NS_OK; @@ -5100,7 +4999,6 @@ nsDocShell::SetTitle(const nsAString& aTitle) { } } - AssertOriginAttributesMatchPrivateBrowsing(); if (mCurrentURI && mLoadType != LOAD_ERROR_PAGE) { UpdateGlobalHistoryTitle(mCurrentURI); } @@ -6498,7 +6396,8 @@ nsresult nsDocShell::CreateAboutBlankContentViewer( if (aPrincipal && !aPrincipal->IsSystemPrincipal() && mItemType != typeChrome) { - MOZ_ASSERT(aPrincipal->OriginAttributesRef() == mOriginAttributes); + MOZ_ASSERT(aPrincipal->OriginAttributesRef() == + mBrowsingContext->OriginAttributesRef()); } // Make sure timing is created. But first record whether we had it @@ -11950,63 +11849,27 @@ nsDocShell::GetAssociatedWindow(mozIDOMWindowProxy** aWindow) { NS_IMETHODIMP nsDocShell::GetTopWindow(mozIDOMWindowProxy** aWindow) { - nsCOMPtr win = GetWindow(); - if (win) { - win = win->GetInProcessTop(); - } - win.forget(aWindow); - return NS_OK; + return mBrowsingContext->GetTopWindow(aWindow); } NS_IMETHODIMP nsDocShell::GetTopFrameElement(Element** aElement) { - *aElement = nullptr; - nsCOMPtr win = GetWindow(); - if (!win) { - return NS_OK; - } - - nsCOMPtr top = win->GetInProcessScriptableTop(); - NS_ENSURE_TRUE(top, NS_ERROR_FAILURE); - - // GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is - // inside