Bug 1388145 - Create global and per-window entry points for scheduling initialization-related idle callbacks. r=florian
MozReview-Commit-ID: LDgTz21gDTL
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1771,20 +1771,52 @@ var gBrowserInit = {
panel.hidePopup();
}
}
});
this.delayedStartupFinished = true;
_resolveDelayedStartup();
+
+ SessionStore.promiseAllWindowsRestored.then(() => {
+ this._schedulePerWindowIdleTasks();
+ });
+
Services.obs.notifyObservers(window, "browser-delayed-startup-finished");
TelemetryTimestamps.add("delayedStartupFinished");
},
+ /**
+ * Use this function as an entry point to schedule tasks that
+ * need to run once per window after startup, and can be scheduled
+ * by using an idle callback.
+ *
+ * The functions scheduled here will fire from idle callbacks
+ * once every window has finished being restored by session
+ * restore, and after the equivalent only-once tasks
+ * have run (from _scheduleStartupIdleTasks in nsBrowserGlue.js).
+ */
+ _schedulePerWindowIdleTasks() {
+ // Bail out if the window has been closed in the meantime.
+ if (window.closed) {
+ return;
+ }
+
+ function scheduleIdleTask(func, options) {
+ requestIdleCallback(function idleTaskRunner() {
+ if (!window.closed) {
+ func();
+ }
+ }, options);
+ }
+
+ // TODO: Functions to be added here using scheduleIdleTask
+ },
+
// Returns the URI(s) to load at startup.
_getUriToLoad() {
// window.arguments[0]: URI to load (string), or an nsIArray of
// nsISupportsStrings to load, or a xul:tab of
// a tabbrowser, which will be replaced by this
// window (for this case, all other arguments are
// ignored).
if (!window.arguments || !window.arguments[0])
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -231,16 +231,18 @@ const BOOKMARKS_BACKUP_IDLE_TIME_SEC = 8
// Minimum interval between backups. We try to not create more than one backup
// per interval.
const BOOKMARKS_BACKUP_MIN_INTERVAL_DAYS = 1;
// Maximum interval between backups. If the last backup is older than these
// days we will try to create a new one more aggressively.
const BOOKMARKS_BACKUP_MAX_INTERVAL_DAYS = 3;
// Seconds of idle time before reporting media telemetry.
const MEDIA_TELEMETRY_IDLE_TIME_SEC = 20;
+// Seconds of idle time before the late idle tasks will be scheduled.
+const LATE_TASKS_IDLE_TIME_SEC = 20;
// Factory object
const BrowserGlueServiceFactory = {
_instance: null,
createInstance: function BGSF_createInstance(outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this._instance == null ?
@@ -571,16 +573,20 @@ BrowserGlue.prototype = {
os.removeObserver(this, "fxaccounts:verify_login");
os.removeObserver(this, "fxaccounts:device_disconnected");
os.removeObserver(this, "weave:engine:clients:display-uris");
os.removeObserver(this, "session-save");
if (this._bookmarksBackupIdleTime) {
this._idleService.removeIdleObserver(this, this._bookmarksBackupIdleTime);
delete this._bookmarksBackupIdleTime;
}
+ if (this._lateTasksIdleObserver) {
+ this._idleService.removeIdleObserver(this._lateTasksIdleObserver, LATE_TASKS_IDLE_TIME_SEC);
+ delete this._lateTasksIdleObserver;
+ }
if (this._mediaTelemetryIdleObserver) {
this._idleService.removeIdleObserver(this._mediaTelemetryIdleObserver, MEDIA_TELEMETRY_IDLE_TIME_SEC);
delete this._mediaTelemetryIdleObserver;
}
try {
os.removeObserver(this, "places-init-complete");
} catch (ex) { /* Could have been removed already */ }
os.removeObserver(this, "handle-xul-text-link");
@@ -1186,16 +1192,68 @@ BrowserGlue.prototype = {
});
Services.tm.idleDispatchToMainThread(() => {
SafeBrowsing.init();
}, 5000);
this._sanitizer.onStartup();
E10SAccessibilityCheck.onWindowsRestored();
+
+ this._scheduleStartupIdleTasks();
+
+ this._lateTasksIdleObserver = (idleService, topic, data) => {
+ if (topic == "idle") {
+ idleService.removeIdleObserver(this._lateTasksIdleObserver,
+ LATE_TASKS_IDLE_TIME_SEC);
+ delete this._lateTasksIdleObserver;
+ this._scheduleArbitrarilyLateIdleTasks();
+ }
+ };
+ this._idleService.addIdleObserver(
+ this._lateTasksIdleObserver, LATE_TASKS_IDLE_TIME_SEC);
+ },
+
+ /**
+ * Use this function as an entry point to schedule tasks that
+ * need to run only once after startup, and can be scheduled
+ * by using an idle callback.
+ *
+ * The functions scheduled here will fire from idle callbacks
+ * once every window has finished being restored by session
+ * restore, and it's guaranteed that they will run before
+ * the equivalent per-window idle tasks
+ * (from _schedulePerWindowIdleTasks in browser.js).
+ *
+ * If you have something that can wait even further than the
+ * per-window initialization, please schedule them using
+ * _scheduleArbitrarilyLateIdleTasks.
+ * Don't be fooled by thinking that the use of the timeout parameter
+ * will delay your function: it will just ensure that it potentially
+ * happens _earlier_ than expected (when the timeout limit has been reached),
+ * but it will not make it happen later (and out of order) compared
+ * to the other ones scheduled together.
+ */
+ _scheduleStartupIdleTasks() {
+ // TODO: Functions to be added here with Services.tm.idleDispatchToMainThread
+ },
+
+ /**
+ * Use this function as an entry point to schedule tasks that need
+ * to run once per session, at any arbitrary point in time.
+ * This function will be called from an idle observer. Check the value of
+ * LATE_TASKS_IDLE_TIME_SEC to see the current value for this idle
+ * observer.
+ *
+ * Note: this function may never be called if the user is never idle for the
+ * full length of the period of time specified. But given a reasonably low
+ * value, this is unlikely.
+ */
+ _scheduleArbitrarilyLateIdleTasks() {
+ // TODO: Functions to be added here with Services.tm.idleDispatchToMainThread
},
_createExtraDefaultProfile() {
if (!AppConstants.MOZ_DEV_EDITION) {
return;
}
// If Developer Edition is the only installed Firefox version and no other
// profiles are present, create a second one for use by other versions.