Bug 827188 - Initialize the hidden private window lazily; r=bzbarsky
This commit is contained in:
@@ -368,6 +368,9 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
|
|||||||
MarkDocShell(shellTreeNode, cleanupJS, prepareForCC);
|
MarkDocShell(shellTreeNode, cleanupJS, prepareForCC);
|
||||||
}
|
}
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
bool hasHiddenPrivateWindow = false;
|
||||||
|
appShell->GetHasHiddenPrivateWindow(&hasHiddenPrivateWindow);
|
||||||
|
if (hasHiddenPrivateWindow) {
|
||||||
appShell->GetHiddenPrivateWindow(getter_AddRefs(hw));
|
appShell->GetHiddenPrivateWindow(getter_AddRefs(hw));
|
||||||
if (hw) {
|
if (hw) {
|
||||||
nsCOMPtr<nsIDocShell> shell;
|
nsCOMPtr<nsIDocShell> shell;
|
||||||
@@ -375,6 +378,7 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
|
|||||||
nsCOMPtr<nsIDocShellTreeNode> shellTreeNode = do_QueryInterface(shell);
|
nsCOMPtr<nsIDocShellTreeNode> shellTreeNode = do_QueryInterface(shell);
|
||||||
MarkDocShell(shellTreeNode, cleanupJS, prepareForCC);
|
MarkDocShell(shellTreeNode, cleanupJS, prepareForCC);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,10 @@
|
|||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "nsISecurityUITelemetry.h"
|
#include "nsISecurityUITelemetry.h"
|
||||||
|
|
||||||
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
#include "nsIAppShellService.h"
|
||||||
|
#include "nsAppShellCID.h"
|
||||||
|
#else
|
||||||
#include "nsIPrivateBrowsingService.h"
|
#include "nsIPrivateBrowsingService.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -220,9 +223,9 @@ static uint32_t gNumberOfPrivateDocShells = 0;
|
|||||||
|
|
||||||
// Global count of private docshells which will always remain open
|
// Global count of private docshells which will always remain open
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
static const uint32_t kNumberOfAlwaysOpenPrivateDocShells = 1; // the private hidden window
|
static uint32_t gNumberOfAlwaysOpenPrivateDocShells = 0; // the private hidden window
|
||||||
#else
|
#else
|
||||||
static const uint32_t kNumberOfAlwaysOpenPrivateDocShells = 0;
|
static const uint32_t gNumberOfAlwaysOpenPrivateDocShells = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Global reference to the URI fixup service.
|
// Global reference to the URI fixup service.
|
||||||
@@ -688,11 +691,27 @@ ConvertLoadTypeToNavigationType(uint32_t aLoadType)
|
|||||||
|
|
||||||
static nsISHEntry* GetRootSHEntry(nsISHEntry *entry);
|
static nsISHEntry* GetRootSHEntry(nsISHEntry *entry);
|
||||||
|
|
||||||
|
static void
|
||||||
|
AdjustAlwaysOpenPrivateDocShellCount()
|
||||||
|
{
|
||||||
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
nsCOMPtr<nsIAppShellService> appShell
|
||||||
|
(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||||
|
bool hasHiddenPrivateWindow = false;
|
||||||
|
if (appShell) {
|
||||||
|
appShell->GetHasHiddenPrivateWindow(&hasHiddenPrivateWindow);
|
||||||
|
}
|
||||||
|
gNumberOfAlwaysOpenPrivateDocShells = hasHiddenPrivateWindow ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
IncreasePrivateDocShellCount()
|
IncreasePrivateDocShellCount()
|
||||||
{
|
{
|
||||||
|
AdjustAlwaysOpenPrivateDocShellCount();
|
||||||
|
|
||||||
gNumberOfPrivateDocShells++;
|
gNumberOfPrivateDocShells++;
|
||||||
if (gNumberOfPrivateDocShells > kNumberOfAlwaysOpenPrivateDocShells + 1 ||
|
if (gNumberOfPrivateDocShells > gNumberOfAlwaysOpenPrivateDocShells + 1 ||
|
||||||
XRE_GetProcessType() != GeckoProcessType_Content) {
|
XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -704,9 +723,11 @@ IncreasePrivateDocShellCount()
|
|||||||
static void
|
static void
|
||||||
DecreasePrivateDocShellCount()
|
DecreasePrivateDocShellCount()
|
||||||
{
|
{
|
||||||
|
AdjustAlwaysOpenPrivateDocShellCount();
|
||||||
|
|
||||||
MOZ_ASSERT(gNumberOfPrivateDocShells > 0);
|
MOZ_ASSERT(gNumberOfPrivateDocShells > 0);
|
||||||
gNumberOfPrivateDocShells--;
|
gNumberOfPrivateDocShells--;
|
||||||
if (gNumberOfPrivateDocShells == kNumberOfAlwaysOpenPrivateDocShells)
|
if (gNumberOfPrivateDocShells == gNumberOfAlwaysOpenPrivateDocShells)
|
||||||
{
|
{
|
||||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||||
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
|
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
|
||||||
|
|||||||
@@ -314,19 +314,23 @@ nsAppStartup::Quit(uint32_t aMode)
|
|||||||
|
|
||||||
// If we're considering quitting, we will only do so if:
|
// If we're considering quitting, we will only do so if:
|
||||||
if (ferocity == eConsiderQuit) {
|
if (ferocity == eConsiderQuit) {
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
nsCOMPtr<nsIAppShellService> appShell
|
||||||
|
(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
||||||
|
bool hasHiddenPrivateWindow = false;
|
||||||
|
if (appShell) {
|
||||||
|
appShell->GetHasHiddenPrivateWindow(&hasHiddenPrivateWindow);
|
||||||
|
}
|
||||||
|
int32_t suspiciousCount = hasHiddenPrivateWindow ? 2 : 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mConsiderQuitStopper == 0) {
|
if (mConsiderQuitStopper == 0) {
|
||||||
// there are no windows...
|
// there are no windows...
|
||||||
ferocity = eAttemptQuit;
|
ferocity = eAttemptQuit;
|
||||||
}
|
}
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
else if (mConsiderQuitStopper == suspiciousCount) {
|
||||||
else if (mConsiderQuitStopper == 2) {
|
|
||||||
#else
|
|
||||||
else if (mConsiderQuitStopper == 1) {
|
|
||||||
#endif
|
|
||||||
// ... or there is only a hiddenWindow left, and it's useless:
|
// ... or there is only a hiddenWindow left, and it's useless:
|
||||||
nsCOMPtr<nsIAppShellService> appShell
|
|
||||||
(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
|
|
||||||
|
|
||||||
// Failure shouldn't be fatal, but will abort quit attempt:
|
// Failure shouldn't be fatal, but will abort quit attempt:
|
||||||
if (!appShell)
|
if (!appShell)
|
||||||
@@ -337,11 +341,15 @@ nsAppStartup::Quit(uint32_t aMode)
|
|||||||
nsCOMPtr<nsIXULWindow> hiddenWindow;
|
nsCOMPtr<nsIXULWindow> hiddenWindow;
|
||||||
appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow));
|
appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow));
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
nsCOMPtr<nsIXULWindow> hiddenPrivateWindow;
|
|
||||||
appShell->GetHiddenPrivateWindow(getter_AddRefs(hiddenPrivateWindow));
|
|
||||||
// If the remaining windows are useful, we won't quit:
|
// If the remaining windows are useful, we won't quit:
|
||||||
|
nsCOMPtr<nsIXULWindow> hiddenPrivateWindow;
|
||||||
|
if (hasHiddenPrivateWindow) {
|
||||||
|
appShell->GetHiddenPrivateWindow(getter_AddRefs(hiddenPrivateWindow));
|
||||||
if ((!hiddenWindow && !hiddenPrivateWindow) || usefulHiddenWindow)
|
if ((!hiddenWindow && !hiddenPrivateWindow) || usefulHiddenWindow)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
} else if (!hiddenWindow || usefulHiddenWindow) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
// If the one window is useful, we won't quit:
|
// If the one window is useful, we won't quit:
|
||||||
if (!hiddenWindow || usefulHiddenWindow)
|
if (!hiddenWindow || usefulHiddenWindow)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ interface nsIAppShell;
|
|||||||
struct JSContext;
|
struct JSContext;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
[scriptable, uuid(76e6364a-5453-47c7-ad83-8c30eff20a75)]
|
[scriptable, uuid(5c19ab54-67bf-46d0-ac5b-21abd9050c3b)]
|
||||||
interface nsIAppShellService : nsISupports
|
interface nsIAppShellService : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -117,4 +117,10 @@ interface nsIAppShellService : nsISupports
|
|||||||
* @param aWindow you see the pattern
|
* @param aWindow you see the pattern
|
||||||
*/
|
*/
|
||||||
void unregisterTopLevelWindow(in nsIXULWindow aWindow);
|
void unregisterTopLevelWindow(in nsIXULWindow aWindow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the hidden private window has been lazily created.
|
||||||
|
*/
|
||||||
|
[noscript]
|
||||||
|
readonly attribute boolean hasHiddenPrivateWindow;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,6 +82,22 @@ NS_IMPL_ISUPPORTS2(nsAppShellService,
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsAppShellService::CreateHiddenWindow()
|
nsAppShellService::CreateHiddenWindow()
|
||||||
|
{
|
||||||
|
return CreateHiddenWindowHelper(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsAppShellService::EnsurePrivateHiddenWindow()
|
||||||
|
{
|
||||||
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
if (!mHiddenPrivateWindow) {
|
||||||
|
CreateHiddenWindowHelper(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
int32_t initialHeight = 100, initialWidth = 100;
|
int32_t initialHeight = 100, initialWidth = 100;
|
||||||
@@ -91,7 +107,11 @@ nsAppShellService::CreateHiddenWindow()
|
|||||||
nsAdoptingCString prefVal =
|
nsAdoptingCString prefVal =
|
||||||
Preferences::GetCString("browser.hiddenWindowChromeURL");
|
Preferences::GetCString("browser.hiddenWindowChromeURL");
|
||||||
const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
|
const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
|
||||||
|
if (aIsPrivate) {
|
||||||
|
hiddenWindowURL = DEFAULT_HIDDENWINDOW_URL;
|
||||||
|
} else {
|
||||||
mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
|
mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
|
static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
|
||||||
uint32_t chromeMask = nsIWebBrowserChrome::CHROME_ALL;
|
uint32_t chromeMask = nsIWebBrowserChrome::CHROME_ALL;
|
||||||
@@ -102,14 +122,16 @@ nsAppShellService::CreateHiddenWindow()
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsRefPtr<nsWebShellWindow> newWindow;
|
nsRefPtr<nsWebShellWindow> newWindow;
|
||||||
|
if (!aIsPrivate) {
|
||||||
rv = JustCreateTopWindow(nullptr, url,
|
rv = JustCreateTopWindow(nullptr, url,
|
||||||
chromeMask, initialWidth, initialHeight,
|
chromeMask, initialWidth, initialHeight,
|
||||||
true, getter_AddRefs(newWindow));
|
true, getter_AddRefs(newWindow));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mHiddenWindow.swap(newWindow);
|
mHiddenWindow.swap(newWindow);
|
||||||
|
}
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
else {
|
||||||
// Create the hidden private window
|
// Create the hidden private window
|
||||||
chromeMask |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
chromeMask |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
||||||
|
|
||||||
@@ -119,6 +141,7 @@ nsAppShellService::CreateHiddenWindow()
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mHiddenPrivateWindow.swap(newWindow);
|
mHiddenPrivateWindow.swap(newWindow);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// RegisterTopLevelWindow(newWindow); -- Mac only
|
// RegisterTopLevelWindow(newWindow); -- Mac only
|
||||||
@@ -446,6 +469,8 @@ nsAppShellService::GetHiddenPrivateWindow(nsIXULWindow **aWindow)
|
|||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
NS_ENSURE_ARG_POINTER(aWindow);
|
NS_ENSURE_ARG_POINTER(aWindow);
|
||||||
|
|
||||||
|
EnsurePrivateHiddenWindow();
|
||||||
|
|
||||||
*aWindow = mHiddenPrivateWindow;
|
*aWindow = mHiddenPrivateWindow;
|
||||||
NS_IF_ADDREF(*aWindow);
|
NS_IF_ADDREF(*aWindow);
|
||||||
return *aWindow ? NS_OK : NS_ERROR_FAILURE;
|
return *aWindow ? NS_OK : NS_ERROR_FAILURE;
|
||||||
@@ -458,6 +483,8 @@ NS_IMETHODIMP
|
|||||||
nsAppShellService::GetHiddenPrivateDOMWindow(nsIDOMWindow **aWindow)
|
nsAppShellService::GetHiddenPrivateDOMWindow(nsIDOMWindow **aWindow)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
EnsurePrivateHiddenWindow();
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIDocShell> docShell;
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
NS_ENSURE_TRUE(mHiddenPrivateWindow, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mHiddenPrivateWindow, NS_ERROR_FAILURE);
|
||||||
@@ -476,6 +503,19 @@ nsAppShellService::GetHiddenPrivateDOMWindow(nsIDOMWindow **aWindow)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsAppShellService::GetHasHiddenPrivateWindow(bool* aHasPrivateWindow)
|
||||||
|
{
|
||||||
|
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||||
|
NS_ENSURE_ARG_POINTER(aHasPrivateWindow);
|
||||||
|
|
||||||
|
*aHasPrivateWindow = !!mHiddenPrivateWindow;
|
||||||
|
return NS_OK;
|
||||||
|
#else
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsAppShellService::GetHiddenWindowAndJSContext(nsIDOMWindow **aWindow,
|
nsAppShellService::GetHiddenWindowAndJSContext(nsIDOMWindow **aWindow,
|
||||||
JSContext **aJSContext)
|
JSContext **aJSContext)
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
~nsAppShellService();
|
~nsAppShellService();
|
||||||
|
|
||||||
|
nsresult CreateHiddenWindowHelper(bool aIsPrivate);
|
||||||
|
void EnsurePrivateHiddenWindow();
|
||||||
|
|
||||||
nsresult JustCreateTopWindow(nsIXULWindow *aParent,
|
nsresult JustCreateTopWindow(nsIXULWindow *aParent,
|
||||||
nsIURI *aUrl,
|
nsIURI *aUrl,
|
||||||
uint32_t aChromeMask,
|
uint32_t aChromeMask,
|
||||||
|
|||||||
Reference in New Issue
Block a user