Commit a706bb39 authored by Cosmin Sabou's avatar Cosmin Sabou
Browse files

Backed out 16 changesets (bug 827976) for causing bug 1532054. a=backout

Backed out changeset 54c0b12443ed (bug 827976)
Backed out changeset 92b45080d080 (bug 827976)
Backed out changeset 443087a359f9 (bug 827976)
Backed out changeset f976c2d4cebb (bug 827976)
Backed out changeset 66cffb171024 (bug 827976)
Backed out changeset 845e1d0b2402 (bug 827976)
Backed out changeset fd94066a1d76 (bug 827976)
Backed out changeset e253b264e7bd (bug 827976)
Backed out changeset 07ef335770a8 (bug 827976)
Backed out changeset 9d3805d77b99 (bug 827976)
Backed out changeset eed600ceb606 (bug 827976)
Backed out changeset 3b64368cff52 (bug 827976)
Backed out changeset 69d0378e0c09 (bug 827976)
Backed out changeset 9203871a5c6f (bug 827976)
Backed out changeset 96a507c818e2 (bug 827976)
Backed out changeset e254496ff95b (bug 827976)
parent c51046f7
......@@ -240,10 +240,6 @@ pref("browser.startup.blankWindow", true);
pref("browser.startup.blankWindow", false);
#endif
// Don't create the hidden window during startup on
// platforms that don't always need it (Win/Linux).
pref("toolkit.lazyHiddenWindow", true);
pref("browser.slowStartup.notificationDisabled", false);
pref("browser.slowStartup.timeThreshold", 20000);
pref("browser.slowStartup.maxSamples", 5);
......
......@@ -572,12 +572,12 @@ HistoryMenu.prototype = {
},
_getClosedTabCount() {
try {
return SessionStore.getClosedTabCount(window);
} catch (ex) {
// SessionStore doesn't track the hidden window, so just return zero then.
// SessionStore doesn't track the hidden window, so just return zero then.
if (window == Services.appShell.hiddenDOMWindow) {
return 0;
}
return SessionStore.getClosedTabCount(window);
},
toggleHiddenTabs() {
......
......@@ -1516,10 +1516,6 @@ var gBrowserInit = {
this._cancelDelayedStartup();
// Bug 1531854 - The hidden window is force-created here
// until all of its dependencies are handled.
Services.appShell.hiddenDOMWindow;
// We need to set the OfflineApps message listeners up before we
// load homepages, which might need them.
OfflineApps.init();
......
......@@ -17,16 +17,15 @@ function init() {
let gHidden = [];
let gCollapsed = [];
let hiddenDoc = Services.appShell.hiddenDOMWindow.document;
function hideItem(id) {
let hiddenDoc = Services.appShell.hiddenDOMWindow.document;
let element = hiddenDoc.getElementById(id);
element.hidden = true;
gHidden.push(element);
}
function collapseItem(id) {
let hiddenDoc = Services.appShell.hiddenDOMWindow.document;
let element = hiddenDoc.getElementById(id);
element.collapsed = true;
gCollapsed.push(element);
......
......@@ -23,8 +23,6 @@ skip-if = !debug
[browser_startup.js]
[browser_startup_content.js]
skip-if = !e10s
[browser_startup_hiddenwindow.js]
skip-if = os == 'mac'
[browser_startup_flicker.js]
run-if = debug || devedition || nightly_build # Requires startupRecorder.js, which isn't shipped everywhere by default
[browser_tabclose_grow.js]
......
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function() {
if (!AppConstants.NIGHTLY_BUILD && !AppConstants.MOZ_DEV_EDITION && !AppConstants.DEBUG) {
ok(!("@mozilla.org/test/startuprecorder;1" in Cc),
"the startup recorder component shouldn't exist in this non-nightly/non-devedition/" +
"non-debug build.");
return;
}
let startupRecorder = Cc["@mozilla.org/test/startuprecorder;1"].getService().wrappedJSObject;
await startupRecorder.done;
let extras = Cu.cloneInto(startupRecorder.data.extras, {});
let phasesExpectations = {
"before profile selection": false,
"before opening first browser window": false,
"before first paint": !Services.prefs.getBoolPref("toolkit.lazyHiddenWindow"),
// Bug 1531854
"before handling user events": true,
"before becoming idle": true,
};
for (let phase in extras) {
if (!(phase in phasesExpectations)) {
ok(false, `Startup phase '${phase}' should be specified.`);
continue;
}
is(extras[phase].hiddenWindowLoaded, phasesExpectations[phase],
`Hidden window loaded at '${phase}': ${phasesExpectations[phase]}`);
}
});
......@@ -1443,11 +1443,9 @@ BrowserGlue.prototype = {
},
_sendMediaTelemetry() {
let win = Services.wm.getMostRecentWindow("navigator:browser");
if (win) {
let v = win.document.createElementNS("http://www.w3.org/1999/xhtml", "video");
v.reportCanPlayTelemetry();
}
let win = Services.appShell.hiddenDOMWindow;
let v = win.document.createElementNS("http://www.w3.org/1999/xhtml", "video");
v.reportCanPlayTelemetry();
},
/**
......@@ -2807,15 +2805,13 @@ BrowserGlue.prototype = {
* Open preferences even if there are no open windows.
*/
_openPreferences(...args) {
let chromeWindow = BrowserWindowTracker.getTopWindow();
if (chromeWindow) {
chromeWindow.openPreferences(...args);
return;
}
if (Services.appShell.hiddenDOMWindow.openPreferences) {
Services.appShell.hiddenDOMWindow.openPreferences(...args);
return;
}
let chromeWindow = BrowserWindowTracker.getTopWindow();
chromeWindow.openPreferences(...args);
},
_openURLInNewWindow(url) {
......
......@@ -185,9 +185,8 @@ var DownloadsCommon = {
* HistoryDownloadsData objects, depending on the privacy status of the
* specified window and on whether history downloads should be included.
*
* @param [optional] window
* @param window
* The browser window which owns the download button.
* If not given, the privacy status will be assumed as non-private.
* @param [optional] history
* True to include history downloads when the window is public.
* @param [optional] privateAll
......@@ -198,7 +197,7 @@ var DownloadsCommon = {
* `kMaxHistoryResultsForLimitedView`.
*/
getData(window, history = false, privateAll = false, limited = false) {
let isPrivate = window && PrivateBrowsingUtils.isContentWindowPrivate(window);
let isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window);
if (isPrivate && !privateAll) {
return PrivateDownloadsData;
}
......
......@@ -5,7 +5,6 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
const {actionTypes: at} = ChromeUtils.import("resource://activity-stream/common/Actions.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
DownloadsViewUI: "resource:///modules/DownloadsViewUI.jsm",
FileUtils: "resource://gre/modules/FileUtils.jsm",
......@@ -42,8 +41,8 @@ this.DownloadsManager = class DownloadsManager {
init(store) {
this._store = store;
this._downloadData = DownloadsCommon.getData(null /* null for non-private downloads */,
true, false, true);
this._browser = Services.appShell.hiddenDOMWindow;
this._downloadData = DownloadsCommon.getData(this._browser.ownerGlobal, true, false, true);
this._downloadData.addView(this);
}
......@@ -142,7 +141,7 @@ this.DownloadsManager = class DownloadsManager {
doDownloadAction(download => {
DownloadsCommon.openDownloadedFile(
new FileUtils.File(download.target.path), null,
BrowserWindowTracker.getTopWindow());
this._browser.ownerGlobal);
});
break;
case at.UNINIT:
......
......@@ -176,6 +176,8 @@ var SessionSaverInternal = {
// Schedule a state save.
this._wasIdle = this._isIdle;
this._timeoutID = setTimeout(() => {
let hiddenDOMWindow = Services.appShell.hiddenDOMWindow;
// Execute _saveStateAsync when we have enough idle time. Otherwise,
// another idle request is made to schedule _saveStateAsync again.
let saveStateAsyncWhenIdle = (deadline) => {
......@@ -183,13 +185,13 @@ var SessionSaverInternal = {
// _saveStateAsync is around 5.9ms (median). Therefore,
// we'll not execute the function when the idle time is less than 5ms.
if (deadline.timeRemaining() < 5) {
this._idleCallbackID = requestIdleCallback(saveStateAsyncWhenIdle);
this._idleCallbackID = hiddenDOMWindow.requestIdleCallback(saveStateAsyncWhenIdle);
return;
}
this._saveStateAsync();
};
this._idleCallbackID = requestIdleCallback(saveStateAsyncWhenIdle);
this._idleCallbackID = hiddenDOMWindow.requestIdleCallback(saveStateAsyncWhenIdle);
}, delay);
},
......@@ -207,7 +209,7 @@ var SessionSaverInternal = {
cancel() {
clearTimeout(this._timeoutID);
this._timeoutID = null;
cancelIdleCallback(this._idleCallbackID);
Services.appShell.hiddenDOMWindow.cancelIdleCallback(this._idleCallbackID);
this._idleCallbackID = null;
},
......
......@@ -49,7 +49,6 @@ function startupRecorder() {
"image-loading": new Set(),
},
code: {},
extras: {},
prefStats: {},
};
this.done = new Promise(resolve => { this._resolve = resolve; });
......@@ -74,9 +73,6 @@ startupRecorder.prototype = {
}
}),
};
this.data.extras[name] = {
hiddenWindowLoaded: Services.appShell.hasHiddenWindow,
};
},
observe(subject, topic, data) {
......
......@@ -470,7 +470,8 @@ var Sanitizer = {
// Keep track of the time in case we get stuck in la-la-land because of onbeforeunload
// dialogs
let startDate = Date.now();
let existingWindow = Services.appShell.hiddenDOMWindow;
let startDate = existingWindow.performance.now();
// First check if all these windows are OK with being closed:
let windowList = [];
......@@ -486,16 +487,12 @@ var Sanitizer = {
// hit until the prompt has been dismissed. If more than 1 minute has elapsed since we
// started prompting, stop, because the user might not even remember initiating the
// 'forget', and the timespans will be all wrong by now anyway:
if (Date.now() > (startDate + 60 * 1000)) {
if (existingWindow.performance.now() > (startDate + 60 * 1000)) {
this._resetAllWindowClosures(windowList);
throw new Error("Sanitize could not close windows: timeout");
}
}
if (windowList.length == 0) {
return;
}
// If/once we get here, we should actually be able to close all windows.
let refObj = {};
......@@ -506,8 +503,8 @@ var Sanitizer = {
let handler = Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler);
let defaultArgs = handler.defaultArgs;
let features = "chrome,all,dialog=no," + privateStateForNewWindow;
let newWindow = windowList[0].openDialog(AppConstants.BROWSER_CHROME_URL, "_blank",
features, defaultArgs);
let newWindow = existingWindow.openDialog(AppConstants.BROWSER_CHROME_URL, "_blank",
features, defaultArgs);
let onFullScreen = null;
if (AppConstants.platform == "macosx") {
......
......@@ -6,7 +6,7 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const { Cu } = require("chrome");
const Services = require("Services");
const { Pool } = require("devtools/shared/protocol");
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
......@@ -542,13 +542,16 @@ RootActor.prototype = {
// If the request doesn't contains id parameter or id is 0
// (id == 0, based on onListProcesses implementation)
if ((!("id" in request)) || request.id === 0) {
// Check if we are running on xpcshell.
// Check if we are running on xpcshell. hiddenDOMWindow is going to throw on it.
// When running on xpcshell, there is no valid browsing context to attach to
// and so ParentProcessTargetActor doesn't make sense as it inherits from
// BrowsingContextTargetActor. So instead use ContentProcessTargetActor, which
// matches xpcshell needs.
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR");
let isXpcshell = true;
try {
isXpcshell = !Services.wm.getMostRecentWindow(null) &&
!Services.appShell.hiddenDOMWindow;
} catch (e) {}
if (!isXpcshell && this._parentProcessTargetActor &&
(!this._parentProcessTargetActor.docShell ||
......
......@@ -439,23 +439,12 @@ nsDocShell::~nsDocShell() {
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p destroyed\n", this));
#ifdef DEBUG
nsAutoCString url;
if (mLastOpenedURI) {
url = mLastOpenedURI->GetSpecOrDefault();
// Data URLs can be very long, so truncate to avoid flooding the log.
const uint32_t maxURLLength = 1000;
if (url.Length() > maxURLLength) {
url.Truncate(maxURLLength);
}
}
// We're counting the number of |nsDocShells| to help find leaks
--gNumberOfDocShells;
if (!PR_GetEnv("MOZ_QUIET")) {
printf_stderr("--DOCSHELL %p == %ld [pid = %d] [id = %s] [url = %s]\n", (void*)this,
printf_stderr("--DOCSHELL %p == %ld [pid = %d] [id = %s]\n", (void*)this,
gNumberOfDocShells, getpid(),
nsIDToCString(mHistoryID).get(),
url.get());
nsIDToCString(mHistoryID).get());
}
#endif
}
......@@ -1181,10 +1170,6 @@ bool nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
mCurrentURI = aURI;
#ifdef DEBUG
mLastOpenedURI = aURI;
#endif
if (!NS_IsAboutBlank(mCurrentURI)) {
mHasLoadedNonBlankURI = true;
}
......
......@@ -976,10 +976,6 @@ class nsDocShell final : public nsDocLoader,
nsCOMPtr<nsIURI> mCurrentURI;
nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
#ifdef DEBUG
nsCOMPtr<nsIURI> mLastOpenedURI;
#endif
// Reference to the SHEntry for this docshell until the page is destroyed.
// Somebody give me better name
nsCOMPtr<nsISHEntry> mOSHE;
......
......@@ -349,11 +349,9 @@ nsresult nsCCUncollectableMarker::Observe(nsISupports* aSubject,
nsCOMPtr<nsIAppShellService> appShell =
do_GetService(NS_APPSHELLSERVICE_CONTRACTID);
if (appShell) {
bool hasHiddenWindow = false;
appShell->GetHasHiddenWindow(&hasHiddenWindow);
if (hasHiddenWindow) {
nsCOMPtr<nsIXULWindow> hw;
appShell->GetHiddenWindow(getter_AddRefs(hw));
nsCOMPtr<nsIXULWindow> hw;
appShell->GetHiddenWindow(getter_AddRefs(hw));
if (hw) {
nsCOMPtr<nsIDocShell> shell;
hw->GetDocShell(getter_AddRefs(shell));
MarkDocShell(shell, cleanupJS);
......@@ -361,7 +359,6 @@ nsresult nsCCUncollectableMarker::Observe(nsISupports* aSubject,
bool hasHiddenPrivateWindow = false;
appShell->GetHasHiddenPrivateWindow(&hasHiddenPrivateWindow);
if (hasHiddenPrivateWindow) {
nsCOMPtr<nsIXULWindow> hw;
appShell->GetHiddenPrivateWindow(getter_AddRefs(hw));
if (hw) {
nsCOMPtr<nsIDocShell> shell;
......
......@@ -21,9 +21,7 @@ class ShutdownLeaks(object):
self.logger = logger
self.tests = []
self.leakedWindows = {}
self.hiddenWindowsCount = 0
self.leakedDocShells = set()
self.hiddenDocShellsCount = 0
self.currentTest = None
self.seenShutdown = set()
......@@ -81,19 +79,6 @@ class ShutdownLeaks(object):
x for x in test["leakedDocShells"]]
)))
if test["hiddenWindowsCount"] > 0:
# Note: to figure out how many hidden windows were created, we divide
# this number by 2, because 1 hidden window creation implies in
# 1 outer window + 1 inner window.
self.logger.info(
"TEST-INFO | %s | This test created %d hidden window(s)"
% (test["fileName"], test["hiddenWindowsCount"] / 2))
if test["hiddenDocShellsCount"] > 0:
self.logger.info(
"TEST-INFO | %s | This test created %d hidden docshell(s)"
% (test["fileName"], test["hiddenDocShellsCount"]))
return failures
def _logWindow(self, line):
......@@ -116,11 +101,7 @@ class ShutdownLeaks(object):
else:
windows.discard(key)
elif int(pid) in self.seenShutdown and not created:
url = self._parseValue(line, "url")
if not self._isHiddenWindowURL(url):
self.leakedWindows[key] = url
else:
self.hiddenWindowsCount += 1
self.leakedWindows[key] = self._parseValue(line, "url")
def _logDocShell(self, line):
created = line[:2] == "++"
......@@ -142,11 +123,7 @@ class ShutdownLeaks(object):
else:
docShells.discard(key)
elif int(pid) in self.seenShutdown and not created:
url = self._parseValue(line, "url")
if not self._isHiddenWindowURL(url):
self.leakedDocShells.add(key)
else:
self.hiddenDocShellsCount += 1
self.leakedDocShells.add(key)
def _parseValue(self, line, name):
match = re.search("\[%s = (.+?)\]" % name, line)
......@@ -162,16 +139,14 @@ class ShutdownLeaks(object):
id for id in test["windows"] if id in self.leakedWindows]
test["leakedWindows"] = [self.leakedWindows[id]
for id in leakedWindows]
test["hiddenWindowsCount"] = self.hiddenWindowsCount
test["leakedWindowsString"] = ', '.join(
["[pid = %s] [serial = %s]" % x for x in leakedWindows])
test["leakedDocShells"] = [
id for id in test["docShells"] if id in self.leakedDocShells]
test["hiddenDocShellsCount"] = self.hiddenDocShellsCount
test["leakCount"] = len(
test["leakedWindows"]) + len(test["leakedDocShells"])
if test["leakCount"] or test["hiddenWindowsCount"] or test["hiddenDocShellsCount"]:
if test["leakCount"]:
leakingTests.append(test)
return sorted(leakingTests, key=itemgetter("leakCount"), reverse=True)
......@@ -187,10 +162,6 @@ class ShutdownLeaks(object):
return sorted(counts, key=itemgetter(1), reverse=True)
def _isHiddenWindowURL(self, url):
return (url == "resource://gre-resources/hiddenWindow.html" or # Win / Linux
url == "chrome://browser/content/hiddenWindow.xul") # Mac
class LSANLeaks(object):
......
......@@ -9,13 +9,12 @@
*/
var EXPORTED_SYMBOLS = ["setTimeout", "setTimeoutWithTarget", "clearTimeout",
"setInterval", "setIntervalWithTarget", "clearInterval",
"requestIdleCallback", "cancelIdleCallback"];
"setInterval", "setIntervalWithTarget", "clearInterval"];
// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 days.
var gNextId = 1; // setTimeout and setInterval must return a positive integer
var gTimerTable = new Map(); // int -> nsITimer or idleCallback
var gTimerTable = new Map(); // int -> nsITimer
// Don't generate this for every timer.
var setTimeout_timerCallbackQI = ChromeUtils.generateQI([Ci.nsITimerCallback, Ci.nsINamed]);
......@@ -87,27 +86,3 @@ var clearInterval = this.clearTimeout = function clearTimeout(aId) {
gTimerTable.delete(aId);
}
};
function requestIdleCallback(aCallback, aOptions) {
if (typeof aCallback !== "function") {
throw new Error("callback is not a function in requestIdleCallback");
}
let id = gNextId++;
let callback = (...aArgs) => {
if (gTimerTable.has(id)) {
gTimerTable.delete(id);
aCallback(...aArgs);
}
};
ChromeUtils.idleDispatch(callback, aOptions);
gTimerTable.set(id, callback);
return id;
}
function cancelIdleCallback(aId) {
if (gTimerTable.has(aId)) {
gTimerTable.delete(aId);
}
}
......@@ -63,12 +63,11 @@ add_task(async function test_setInterval() {
let calls = 0;
await new Promise((resolve) => {
let interval2 = imported.setInterval((param1, param2) => {
imported.setInterval((param1, param2) => {
Assert.ok(true, "Should be called");
Assert.equal(param1, 15, "first parameter is correct");
Assert.equal(param2, "hola", "second parameter is correct");
if (calls >= EXPECTED_CALLS) {
imported.clearInterval(interval2);
resolve();
}
calls++;
......@@ -89,12 +88,11 @@ add_task(async function test_setIntervalWithTarget() {
let calls = 0;
await new Promise((resolve) => {
let interval2 = imported.setIntervalWithTarget((param1, param2) => {
imported.setIntervalWithTarget((param1, param2) => {
Assert.ok(true, "Should be called");
Assert.equal(param1, 15, "first parameter is correct");
Assert.equal(param2, "hola", "second parameter is correct");
if (calls >= EXPECTED_CALLS) {
imported.clearInterval(interval2);
resolve();
}
calls++;
......@@ -121,24 +119,3 @@ add_task(async function test_setIntervalWithTargetNonFunction() {
Assert.throws(() => { imported.setIntervalWithTarget({}, 0); },
/callback is not a function in setInterval/);
});
add_task(async function test_requestIdleCallback() {
let request1 = imported.requestIdleCallback(() => do_throw("Should not be called"));
Assert.equal(typeof request1, "number", "requestIdleCallback returns a number");
Assert.ok(request1 > 0, "setTimeout returns a positive number");
imported.cancelIdleCallback(request1);
await new Promise((resolve) => {
let request2 = imported.requestIdleCallback((deadline) => {
Assert.ok(true, "Should be called");
Assert.equal(typeof deadline.didTimeout, "boolean", "deadline parameter has .didTimeout property");
Assert.equal(typeof deadline.timeRemaining(), "number", "deadline parameter has .timeRemaining() function");
resolve();
}, {timeout: 100});
Assert.equal(typeof request2, "number", "requestIdleCallback returns a number");
Assert.ok(request2 > 0, "requestIdleCallback returns a positive number");
Assert.notEqual(request1, request2, "Calling requestIdleCallback again returns a different value");
});
});
......@@ -4610,16 +4610,8 @@ nsresult XREMain::XRE_mainRun() {
SaveToEnv("XRE_RESTARTED_BY_PROFILE_MANAGER=");
if (!mShuttingDown) {
#ifdef XP_MACOSX
bool lazyHiddenWindow = false;
#else
bool lazyHiddenWindow = Preferences::GetBool("toolkit.lazyHiddenWindow", false);
#endif
if (!lazyHiddenWindow) {
rv = appStartup->CreateHiddenWindow();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
}
rv = appStartup->CreateHiddenWindow();
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
#ifdef XP_WIN
Preferences::RegisterCallbackAndCall(RegisterApplicationRestartChanged,
......
Markdown is supported
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