Backed out changeset 55f827545de2 (bug 1701303) for causing bustages on ContentParent.cpp. CLOSED TREE

This commit is contained in:
Marian-Vasile Laza 2021-07-05 17:12:13 +03:00
Родитель c64d01a319
Коммит 17d6e262f7
15 изменённых файлов: 146 добавлений и 166 удалений

Просмотреть файл

@ -42,7 +42,6 @@ skip-if = verify
[browser_privatebrowsing_downloadLastDir_toggle.js] [browser_privatebrowsing_downloadLastDir_toggle.js]
[browser_privatebrowsing_favicon.js] [browser_privatebrowsing_favicon.js]
[browser_privatebrowsing_history_shift_click.js] [browser_privatebrowsing_history_shift_click.js]
[browser_privatebrowsing_last_private_browsing_context_exited.js]
[browser_privatebrowsing_lastpbcontextexited.js] [browser_privatebrowsing_lastpbcontextexited.js]
[browser_privatebrowsing_localStorage.js] [browser_privatebrowsing_localStorage.js]
[browser_privatebrowsing_localStorage_before_after.js] [browser_privatebrowsing_localStorage_before_after.js]

Просмотреть файл

@ -1,66 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_no_notification_when_pb_autostart() {
let observedLastPBContext = false;
let observerExited = {
observe(aSubject, aTopic, aData) {
observedLastPBContext = true;
},
};
Services.obs.addObserver(observerExited, "last-pb-context-exited");
await SpecialPowers.pushPrefEnv({
set: [["browser.privatebrowsing.autostart", true]],
});
let win = await BrowserTestUtils.openNewBrowserWindow();
let browser = win.gBrowser.selectedTab.linkedBrowser;
ok(browser.browsingContext.usePrivateBrowsing, "should use private browsing");
await BrowserTestUtils.closeWindow(win);
await SpecialPowers.popPrefEnv();
Services.obs.removeObserver(observerExited, "last-pb-context-exited");
ok(!observedLastPBContext, "No last-pb-context-exited notification seen");
});
add_task(async function test_notification_when_about_preferences() {
let observedLastPBContext = false;
let observerExited = {
observe(aSubject, aTopic, aData) {
observedLastPBContext = true;
},
};
Services.obs.addObserver(observerExited, "last-pb-context-exited");
let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
let browser = win.gBrowser.selectedTab.linkedBrowser;
ok(browser.browsingContext.usePrivateBrowsing, "should use private browsing");
ok(browser.browsingContext.isContent, "should be content browsing context");
let tab = await BrowserTestUtils.addTab(win.gBrowser, "about:preferences");
ok(
tab.linkedBrowser.browsingContext.usePrivateBrowsing,
"should use private browsing"
);
ok(
tab.linkedBrowser.browsingContext.isContent,
"should be content browsing context"
);
let tabClose = BrowserTestUtils.waitForTabClosing(win.gBrowser.selectedTab);
BrowserTestUtils.removeTab(win.gBrowser.selectedTab);
await tabClose;
ok(!observedLastPBContext, "No last-pb-context-exited notification seen");
await BrowserTestUtils.closeWindow(win);
Services.obs.removeObserver(observerExited, "last-pb-context-exited");
ok(observedLastPBContext, "No last-pb-context-exited notification seen");
});

Просмотреть файл

@ -799,10 +799,6 @@ void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
obs->NotifyWhenScriptSafe(ToSupports(this), "browsing-context-attached", obs->NotifyWhenScriptSafe(ToSupports(this), "browsing-context-attached",
nullptr); nullptr);
} }
if (XRE_IsParentProcess()) {
Canonical()->CanonicalAttach();
}
} }
void BrowsingContext::Detach(bool aFromIPC) { void BrowsingContext::Detach(bool aFromIPC) {
@ -1592,10 +1588,6 @@ NS_IMETHODIMP BrowsingContext::SetPrivateBrowsing(bool aPrivateBrowsing) {
if (IsContent()) { if (IsContent()) {
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aPrivateBrowsing); mOriginAttributes.SyncAttributesWithPrivateBrowsing(aPrivateBrowsing);
} }
if (XRE_IsParentProcess()) {
Canonical()->AdjustPrivateBrowsingCount(aPrivateBrowsing);
}
} }
AssertOriginAttributesMatchPrivateBrowsing(); AssertOriginAttributesMatchPrivateBrowsing();

Просмотреть файл

@ -27,7 +27,6 @@
#include "mozilla/NullPrincipal.h" #include "mozilla/NullPrincipal.h"
#include "mozilla/StaticPrefs_docshell.h" #include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/StaticPrefs_fission.h" #include "mozilla/StaticPrefs_fission.h"
#include "mozilla/Telemetry.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "mozilla/MozPromiseInlines.h" #include "mozilla/MozPromiseInlines.h"
#include "nsDocShell.h" #include "nsDocShell.h"
@ -61,49 +60,6 @@ extern mozilla::LazyLogModule gSHIPBFCacheLog;
#define AUTOPLAY_LOG(msg, ...) \ #define AUTOPLAY_LOG(msg, ...) \
MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__)) MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
static mozilla::LazyLogModule sPBContext("PBContext");
// Global count of canonical browsing contexts with the private attribute set
static uint32_t gNumberOfPrivateContexts = 0;
static void IncreasePrivateCount() {
gNumberOfPrivateContexts++;
MOZ_LOG(sPBContext, mozilla::LogLevel::Debug,
("%s: Private browsing context count %d -> %d", __func__,
gNumberOfPrivateContexts - 1, gNumberOfPrivateContexts));
if (gNumberOfPrivateContexts > 1) {
return;
}
static bool sHasSeenPrivateContext = false;
if (!sHasSeenPrivateContext) {
sHasSeenPrivateContext = true;
mozilla::Telemetry::ScalarSet(
mozilla::Telemetry::ScalarID::DOM_PARENTPROCESS_PRIVATE_WINDOW_USED,
true);
}
}
static void DecreasePrivateCount() {
MOZ_ASSERT(gNumberOfPrivateContexts > 0);
gNumberOfPrivateContexts--;
MOZ_LOG(sPBContext, mozilla::LogLevel::Debug,
("%s: Private browsing context count %d -> %d", __func__,
gNumberOfPrivateContexts + 1, gNumberOfPrivateContexts));
if (!gNumberOfPrivateContexts &&
!mozilla::Preferences::GetBool("browser.privatebrowsing.autostart")) {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
MOZ_LOG(sPBContext, mozilla::LogLevel::Debug,
("%s: last-pb-context-exited fired", __func__));
observerService->NotifyObservers(nullptr, "last-pb-context-exited",
nullptr);
}
}
}
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -1133,30 +1089,6 @@ void CanonicalBrowsingContext::CanonicalDiscard() {
} }
CancelSessionStoreUpdate(); CancelSessionStoreUpdate();
if (UsePrivateBrowsing() && EverAttached() && IsContent()) {
DecreasePrivateCount();
}
}
void CanonicalBrowsingContext::CanonicalAttach() {
if (UsePrivateBrowsing() && IsContent()) {
IncreasePrivateCount();
}
}
void CanonicalBrowsingContext::AdjustPrivateBrowsingCount(
bool aPrivateBrowsing) {
if (IsDiscarded() || !EverAttached() || IsChrome()) {
return;
}
MOZ_DIAGNOSTIC_ASSERT(aPrivateBrowsing == UsePrivateBrowsing());
if (aPrivateBrowsing) {
IncreasePrivateCount();
} else {
DecreasePrivateCount();
}
} }
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() { void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
@ -1440,22 +1372,6 @@ nsresult CanonicalBrowsingContext::PendingRemotenessChange::FinishTopContent() {
MOZ_RELEASE_ASSERT(frameLoaderOwner, MOZ_RELEASE_ASSERT(frameLoaderOwner,
"embedder browser must be nsFrameLoaderOwner"); "embedder browser must be nsFrameLoaderOwner");
// If we're process switching a browsing context in private browsing
// mode we might decrease the private browsing count to '0', which
// would make us fire "last-pb-context-exited" and drop the private
// session. To prevent that we artificially increment the number of
// private browsing contexts with '1' until the process switch is done.
bool usePrivateBrowsing = mTarget->UsePrivateBrowsing();
if (usePrivateBrowsing) {
IncreasePrivateCount();
}
auto restorePrivateCount = MakeScopeExit([usePrivateBrowsing]() {
if (usePrivateBrowsing) {
DecreasePrivateCount();
}
});
// Tell frontend code that this browser element is about to change process. // Tell frontend code that this browser element is about to change process.
nsresult rv = browser->BeforeChangeRemoteness(); nsresult rv = browser->BeforeChangeRemoteness();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {

Просмотреть файл

@ -335,13 +335,6 @@ class CanonicalBrowsingContext final : public BrowsingContext {
// Called when the browsing context is being discarded. // Called when the browsing context is being discarded.
void CanonicalDiscard(); void CanonicalDiscard();
// Called when the browsing context is being attached.
void CanonicalAttach();
// Called when the browsing context private mode is changed after
// being attached, but before being discarded.
void AdjustPrivateBrowsingCount(bool aPrivateBrowsing);
using Type = BrowsingContext::Type; using Type = BrowsingContext::Type;
CanonicalBrowsingContext(WindowContext* aParentWindow, CanonicalBrowsingContext(WindowContext* aParentWindow,
BrowsingContextGroup* aGroup, BrowsingContextGroup* aGroup,

Просмотреть файл

@ -273,6 +273,9 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
// Number of documents currently loading // Number of documents currently loading
static int32_t gNumberOfDocumentsLoading = 0; static int32_t gNumberOfDocumentsLoading = 0;
// Global count of docshells with the private attribute set
static uint32_t gNumberOfPrivateDocShells = 0;
static mozilla::LazyLogModule gCharsetMenuLog("CharsetMenu"); static mozilla::LazyLogModule gCharsetMenuLog("CharsetMenu");
#define LOGCHARSETMENU(args) \ #define LOGCHARSETMENU(args) \
@ -304,6 +307,33 @@ static void FavorPerformanceHint(bool aPerfOverStarvation) {
} }
} }
static void IncreasePrivateDocShellCount() {
gNumberOfPrivateDocShells++;
if (gNumberOfPrivateDocShells > 1 || !XRE_IsContentProcess()) {
return;
}
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
cc->SendPrivateDocShellsExist(true);
}
static void DecreasePrivateDocShellCount() {
MOZ_ASSERT(gNumberOfPrivateDocShells > 0);
gNumberOfPrivateDocShells--;
if (!gNumberOfPrivateDocShells) {
if (XRE_IsContentProcess()) {
dom::ContentChild* cc = dom::ContentChild::GetSingleton();
cc->SendPrivateDocShellsExist(false);
return;
}
nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService();
if (obsvc) {
obsvc->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
}
}
}
static bool IsTopLevelDoc(BrowsingContext* aBrowsingContext, static bool IsTopLevelDoc(BrowsingContext* aBrowsingContext,
nsILoadInfo* aLoadInfo) { nsILoadInfo* aLoadInfo) {
MOZ_ASSERT(aBrowsingContext); MOZ_ASSERT(aBrowsingContext);
@ -381,6 +411,7 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mIsBeingDestroyed(false), mIsBeingDestroyed(false),
mIsExecutingOnLoadHandler(false), mIsExecutingOnLoadHandler(false),
mSavingOldViewer(false), mSavingOldViewer(false),
mAffectPrivateSessionLifetime(true),
mInvisible(false), mInvisible(false),
mHasLoadedNonBlankURI(false), mHasLoadedNonBlankURI(false),
mBlankTiming(false), mBlankTiming(false),
@ -1686,6 +1717,14 @@ nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
void nsDocShell::NotifyPrivateBrowsingChanged() { void nsDocShell::NotifyPrivateBrowsingChanged() {
MOZ_ASSERT(!mIsBeingDestroyed); MOZ_ASSERT(!mIsBeingDestroyed);
if (mAffectPrivateSessionLifetime) {
if (UsePrivateBrowsing()) {
IncreasePrivateDocShellCount();
} else {
DecreasePrivateDocShellCount();
}
}
nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers); nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
while (iter.HasMore()) { while (iter.HasMore()) {
nsWeakPtr ref = iter.GetNext(); nsWeakPtr ref = iter.GetNext();
@ -1738,6 +1777,35 @@ nsDocShell::SetRemoteSubframes(bool aUseRemoteSubframes) {
return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes); return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes);
} }
NS_IMETHODIMP
nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime) {
MOZ_ASSERT(!mIsBeingDestroyed);
bool change = aAffectLifetime != mAffectPrivateSessionLifetime;
if (change && UsePrivateBrowsing()) {
if (aAffectLifetime) {
IncreasePrivateDocShellCount();
} else {
DecreasePrivateDocShellCount();
}
}
mAffectPrivateSessionLifetime = aAffectLifetime;
for (auto* child : mChildList.ForwardRange()) {
nsCOMPtr<nsIDocShell> shell = do_QueryObject(child);
if (shell) {
shell->SetAffectPrivateSessionLifetime(aAffectLifetime);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAffectPrivateSessionLifetime(bool* aAffectLifetime) {
*aAffectLifetime = mAffectPrivateSessionLifetime;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::AddWeakPrivacyTransitionObserver( nsDocShell::AddWeakPrivacyTransitionObserver(
nsIPrivacyTransitionObserver* aObserver) { nsIPrivacyTransitionObserver* aObserver) {
@ -2533,6 +2601,8 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
value = false; value = false;
} }
SetAllowDNSPrefetch(mAllowDNSPrefetch && value); SetAllowDNSPrefetch(mAllowDNSPrefetch && value);
SetAffectPrivateSessionLifetime(
parentAsDocShell->GetAffectPrivateSessionLifetime());
// We don't need to inherit metaViewportOverride, because the viewport // We don't need to inherit metaViewportOverride, because the viewport
// is only relevant for the outermost nsDocShell, not for any iframes // is only relevant for the outermost nsDocShell, not for any iframes
@ -4457,6 +4527,10 @@ nsDocShell::Destroy() {
// to break the cycle between us and the timers. // to break the cycle between us and the timers.
CancelRefreshURITimers(); CancelRefreshURITimers();
if (UsePrivateBrowsing() && mAffectPrivateSessionLifetime) {
DecreasePrivateDocShellCount();
}
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -1282,6 +1282,7 @@ class nsDocShell final : public nsDocLoader,
// should be passed a SHEntry to save itself into. // should be passed a SHEntry to save itself into.
bool mSavingOldViewer : 1; bool mSavingOldViewer : 1;
bool mAffectPrivateSessionLifetime : 1;
bool mInvisible : 1; bool mInvisible : 1;
bool mHasLoadedNonBlankURI : 1; bool mHasLoadedNonBlankURI : 1;

Просмотреть файл

@ -605,6 +605,8 @@ interface nsIDocShell : nsIDocShellTreeItem
*/ */
[noscript, notxpcom] bool pluginsAllowedInCurrentDoc(); [noscript, notxpcom] bool pluginsAllowedInCurrentDoc();
[noscript, infallible] attribute boolean affectPrivateSessionLifetime;
/** /**
* Indicates whether the UI may enable the character encoding menu. The UI * Indicates whether the UI may enable the character encoding menu. The UI
* must disable the menu when this property is false. * must disable the menu when this property is false.

Просмотреть файл

@ -495,6 +495,10 @@ nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
docShell->SetAffectPrivateSessionLifetime(
mBrowsingContext->UsePrivateBrowsing() ||
mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME);
#ifdef DEBUG #ifdef DEBUG
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(WebNavigation()); nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(WebNavigation());
MOZ_ASSERT(loadContext); MOZ_ASSERT(loadContext);

Просмотреть файл

@ -1539,6 +1539,9 @@ already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
if (loadContext && loadContext->UseRemoteSubframes()) { if (loadContext && loadContext->UseRemoteSubframes()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW; chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
} }
if (docShell->GetAffectPrivateSessionLifetime()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
}
if (tabId == 0) { if (tabId == 0) {
return nullptr; return nullptr;
@ -4763,6 +4766,35 @@ mozilla::ipc::IPCResult ContentParent::RecvScriptErrorInternal(
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult ContentParent::RecvPrivateDocShellsExist(
const bool& aExist) {
if (!sPrivateContent) {
sPrivateContent = MakeUnique<nsTArray<ContentParent*>>();
if (!sHasSeenPrivateDocShell) {
sHasSeenPrivateDocShell = true;
Telemetry::ScalarSet(
Telemetry::ScalarID::DOM_PARENTPROCESS_PRIVATE_WINDOW_USED, true);
}
}
if (aExist) {
sPrivateContent->AppendElement(this);
} else {
sPrivateContent->RemoveElement(this);
// Only fire the notification if we have private and non-private
// windows: if privatebrowsing.autostart is true, all windows are
// private.
if (!sPrivateContent->Length() &&
!Preferences::GetBool("browser.privatebrowsing.autostart")) {
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
sPrivateContent = nullptr;
}
}
return IPC_OK();
}
bool ContentParent::DoLoadMessageManagerScript(const nsAString& aURL, bool ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
bool aRunInGlobalScope) { bool aRunInGlobalScope) {
MOZ_ASSERT(!aRunInGlobalScope); MOZ_ASSERT(!aRunInGlobalScope);

Просмотреть файл

@ -1118,6 +1118,8 @@ class ContentParent final
const ClonedMessageData* aStack = nullptr); const ClonedMessageData* aStack = nullptr);
public: public:
mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist);
mozilla::ipc::IPCResult RecvCommitBrowsingContextTransaction( mozilla::ipc::IPCResult RecvCommitBrowsingContextTransaction(
const MaybeDiscarded<BrowsingContext>& aContext, const MaybeDiscarded<BrowsingContext>& aContext,
BrowsingContext::BaseTransaction&& aTransaction, uint64_t aEpoch); BrowsingContext::BaseTransaction&& aTransaction, uint64_t aEpoch);

Просмотреть файл

@ -1154,6 +1154,9 @@ parent:
sync GetIconForExtension(nsCString aFileExt, uint32_t aIconSize) sync GetIconForExtension(nsCString aFileExt, uint32_t aIconSize)
returns (uint8_t[] bits); returns (uint8_t[] bits);
// Notify the parent of the presence or absence of private docshells
async PrivateDocShellsExist(bool aExist);
// Tell the parent that the child has gone idle for the first time. // Tell the parent that the child has gone idle for the first time.
async FirstIdle(); async FirstIdle();

Просмотреть файл

@ -162,6 +162,9 @@ void ChromeObserver::AttributeChanged(dom::Element* aElement,
HideWindowChrome(value->Equals(u"true"_ns, eCaseMatters)); HideWindowChrome(value->Equals(u"true"_ns, eCaseMatters));
} else if (aName == nsGkAtoms::chromemargin) { } else if (aName == nsGkAtoms::chromemargin) {
SetChromeMargins(value); SetChromeMargins(value);
} else if (aName == nsGkAtoms::windowtype && aElement->IsXULElement()) {
RefPtr<nsXULElement> xulElement = nsXULElement::FromNodeOrNull(aElement);
xulElement->MaybeUpdatePrivateLifetime();
} }
// title and drawintitlebar are settable on // title and drawintitlebar are settable on
// any root node (windows, dialogs, etc) // any root node (windows, dialogs, etc)

Просмотреть файл

@ -134,6 +134,21 @@ nsXULElement::nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
nsXULElement::~nsXULElement() = default; nsXULElement::~nsXULElement() = default;
void nsXULElement::MaybeUpdatePrivateLifetime() {
if (AttrValueIs(kNameSpaceID_None, nsGkAtoms::windowtype,
u"navigator:browser"_ns, eCaseMatters) ||
AttrValueIs(kNameSpaceID_None, nsGkAtoms::windowtype,
u"navigator:geckoview"_ns, eCaseMatters)) {
return;
}
nsPIDOMWindowOuter* win = OwnerDoc()->GetWindow();
nsCOMPtr<nsIDocShell> docShell = win ? win->GetDocShell() : nullptr;
if (docShell) {
docShell->SetAffectPrivateSessionLifetime(false);
}
}
/* static */ /* static */
nsXULElement* NS_NewBasicXULElement( nsXULElement* NS_NewBasicXULElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) { already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) {
@ -219,6 +234,14 @@ already_AddRefed<nsXULElement> nsXULElement::CreateFromPrototype(
} }
} }
if (aIsRoot && aPrototype->mNodeInfo->Equals(nsGkAtoms::window)) {
for (size_t i = 0; i < aPrototype->mAttributes.Length(); ++i) {
if (aPrototype->mAttributes[i].mName.Equals(nsGkAtoms::windowtype)) {
element->MaybeUpdatePrivateLifetime();
}
}
}
return baseElement.forget().downcast<nsXULElement>(); return baseElement.forget().downcast<nsXULElement>();
} }

Просмотреть файл

@ -504,6 +504,8 @@ class nsXULElement : public nsStyledElement {
bool IsInteractiveHTMLContent() const override; bool IsInteractiveHTMLContent() const override;
void MaybeUpdatePrivateLifetime();
protected: protected:
~nsXULElement(); ~nsXULElement();