summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/nsSessionStartup.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/nsSessionStartup.js')
-rw-r--r--browser/components/sessionstore/nsSessionStartup.js353
1 files changed, 0 insertions, 353 deletions
diff --git a/browser/components/sessionstore/nsSessionStartup.js b/browser/components/sessionstore/nsSessionStartup.js
deleted file mode 100644
index 7593c48ec..000000000
--- a/browser/components/sessionstore/nsSessionStartup.js
+++ /dev/null
@@ -1,353 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * Session Storage and Restoration
- *
- * Overview
- * This service reads user's session file at startup, and makes a determination
- * as to whether the session should be restored. It will restore the session
- * under the circumstances described below. If the auto-start Private Browsing
- * mode is active, however, the session is never restored.
- *
- * Crash Detection
- * The CrashMonitor is used to check if the final session state was successfully
- * written at shutdown of the last session. If we did not reach
- * 'sessionstore-final-state-write-complete', then it's assumed that the browser
- * has previously crashed and we should restore the session.
- *
- * Forced Restarts
- * In the event that a restart is required due to application update or extension
- * installation, set the browser.sessionstore.resume_session_once pref to true,
- * and the session will be restored the next time the browser starts.
- *
- * Always Resume
- * This service will always resume the session if the integer pref
- * browser.startup.page is set to 3.
- */
-
-/* :::::::: Constants and Helpers ::::::::::::::: */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/TelemetryStopwatch.jsm");
-Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "console",
- "resource://gre/modules/Console.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "SessionFile",
- "resource:///modules/sessionstore/SessionFile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "StartupPerformance",
- "resource:///modules/sessionstore/StartupPerformance.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CrashMonitor",
- "resource://gre/modules/CrashMonitor.jsm");
-
-const STATE_RUNNING_STR = "running";
-
-// 'browser.startup.page' preference value to resume the previous session.
-const BROWSER_STARTUP_RESUME_SESSION = 3;
-
-function debug(aMsg) {
- aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n");
- Services.console.logStringMessage(aMsg);
-}
-function warning(aMsg, aException) {
- let consoleMsg = Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError);
-consoleMsg.init(aMsg, aException.fileName, null, aException.lineNumber, 0, Ci.nsIScriptError.warningFlag, "component javascript");
- Services.console.logMessage(consoleMsg);
-}
-
-var gOnceInitializedDeferred = (function () {
- let deferred = {};
-
- deferred.promise = new Promise((resolve, reject) => {
- deferred.resolve = resolve;
- deferred.reject = reject;
- });
-
- return deferred;
-})();
-
-/* :::::::: The Service ::::::::::::::: */
-
-function SessionStartup() {
-}
-
-SessionStartup.prototype = {
-
- // the state to restore at startup
- _initialState: null,
- _sessionType: Ci.nsISessionStartup.NO_SESSION,
- _initialized: false,
-
- // Stores whether the previous session crashed.
- _previousSessionCrashed: null,
-
-/* ........ Global Event Handlers .............. */
-
- /**
- * Initialize the component
- */
- init: function sss_init() {
- Services.obs.notifyObservers(null, "sessionstore-init-started", null);
- StartupPerformance.init();
-
- // do not need to initialize anything in auto-started private browsing sessions
- if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
- this._initialized = true;
- gOnceInitializedDeferred.resolve();
- return;
- }
-
- SessionFile.read().then(
- this._onSessionFileRead.bind(this),
- console.error
- );
- },
-
- // Wrap a string as a nsISupports
- _createSupportsString: function ssfi_createSupportsString(aData) {
- let string = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- string.data = aData;
- return string;
- },
-
- /**
- * Complete initialization once the Session File has been read
- *
- * @param source The Session State string read from disk.
- * @param parsed The object obtained by parsing |source| as JSON.
- */
- _onSessionFileRead: function ({source, parsed, noFilesFound}) {
- this._initialized = true;
-
- // Let observers modify the state before it is used
- let supportsStateString = this._createSupportsString(source);
- Services.obs.notifyObservers(supportsStateString, "sessionstore-state-read", "");
- let stateString = supportsStateString.data;
-
- if (stateString != source) {
- // The session has been modified by an add-on, reparse.
- try {
- this._initialState = JSON.parse(stateString);
- } catch (ex) {
- // That's not very good, an add-on has rewritten the initial
- // state to something that won't parse.
- warning("Observer rewrote the state to something that won't parse", ex);
- }
- } else {
- // No need to reparse
- this._initialState = parsed;
- }
-
- if (this._initialState == null) {
- // No valid session found.
- this._sessionType = Ci.nsISessionStartup.NO_SESSION;
- Services.obs.notifyObservers(null, "sessionstore-state-finalized", "");
- gOnceInitializedDeferred.resolve();
- return;
- }
-
- let shouldResumeSessionOnce = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
- let shouldResumeSession = shouldResumeSessionOnce ||
- Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION;
-
- // If this is a normal restore then throw away any previous session
- if (!shouldResumeSessionOnce && this._initialState) {
- delete this._initialState.lastSessionState;
- }
-
- let resumeFromCrash = Services.prefs.getBoolPref("browser.sessionstore.resume_from_crash");
-
- CrashMonitor.previousCheckpoints.then(checkpoints => {
- if (checkpoints) {
- // If the previous session finished writing the final state, we'll
- // assume there was no crash.
- this._previousSessionCrashed = !checkpoints["sessionstore-final-state-write-complete"];
-
- } else {
- // If the Crash Monitor could not load a checkpoints file it will
- // provide null. This could occur on the first run after updating to
- // a version including the Crash Monitor, or if the checkpoints file
- // was removed, or on first startup with this profile, or after Firefox Reset.
-
- if (noFilesFound) {
- // There was no checkpoints file and no sessionstore.js or its backups
- // so we will assume that this was a fresh profile.
- this._previousSessionCrashed = false;
-
- } else {
- // If this is the first run after an update, sessionstore.js should
- // still contain the session.state flag to indicate if the session
- // crashed. If it is not present, we will assume this was not the first
- // run after update and the checkpoints file was somehow corrupted or
- // removed by a crash.
- //
- // If the session.state flag is present, we will fallback to using it
- // for crash detection - If the last write of sessionstore.js had it
- // set to "running", we crashed.
- let stateFlagPresent = (this._initialState.session &&
- this._initialState.session.state);
-
-
- this._previousSessionCrashed = !stateFlagPresent ||
- (this._initialState.session.state == STATE_RUNNING_STR);
- }
- }
-
- // Report shutdown success via telemetry. Shortcoming here are
- // being-killed-by-OS-shutdown-logic, shutdown freezing after
- // session restore was written, etc.
- Services.telemetry.getHistogramById("SHUTDOWN_OK").add(!this._previousSessionCrashed);
-
- // set the startup type
- if (this._previousSessionCrashed && resumeFromCrash)
- this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
- else if (!this._previousSessionCrashed && shouldResumeSession)
- this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
- else if (this._initialState)
- this._sessionType = Ci.nsISessionStartup.DEFER_SESSION;
- else
- this._initialState = null; // reset the state
-
- Services.obs.addObserver(this, "sessionstore-windows-restored", true);
-
- if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
- Services.obs.addObserver(this, "browser:purge-session-history", true);
-
- // We're ready. Notify everyone else.
- Services.obs.notifyObservers(null, "sessionstore-state-finalized", "");
- gOnceInitializedDeferred.resolve();
- });
- },
-
- /**
- * Handle notifications
- */
- observe: function sss_observe(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "app-startup":
- Services.obs.addObserver(this, "final-ui-startup", true);
- Services.obs.addObserver(this, "quit-application", true);
- break;
- case "final-ui-startup":
- Services.obs.removeObserver(this, "final-ui-startup");
- Services.obs.removeObserver(this, "quit-application");
- this.init();
- break;
- case "quit-application":
- // no reason for initializing at this point (cf. bug 409115)
- Services.obs.removeObserver(this, "final-ui-startup");
- Services.obs.removeObserver(this, "quit-application");
- if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
- Services.obs.removeObserver(this, "browser:purge-session-history");
- break;
- case "sessionstore-windows-restored":
- Services.obs.removeObserver(this, "sessionstore-windows-restored");
- // free _initialState after nsSessionStore is done with it
- this._initialState = null;
- break;
- case "browser:purge-session-history":
- Services.obs.removeObserver(this, "browser:purge-session-history");
- // reset all state on sanitization
- this._sessionType = Ci.nsISessionStartup.NO_SESSION;
- break;
- }
- },
-
-/* ........ Public API ................*/
-
- get onceInitialized() {
- return gOnceInitializedDeferred.promise;
- },
-
- /**
- * Get the session state as a jsval
- */
- get state() {
- return this._initialState;
- },
-
- /**
- * Determines whether there is a pending session restore. Should only be
- * called after initialization has completed.
- * @returns bool
- */
- doRestore: function sss_doRestore() {
- return this._willRestore();
- },
-
- /**
- * Determines whether automatic session restoration is enabled for this
- * launch of the browser. This does not include crash restoration. In
- * particular, if session restore is configured to restore only in case of
- * crash, this method returns false.
- * @returns bool
- */
- isAutomaticRestoreEnabled: function () {
- return Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") ||
- Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION;
- },
-
- /**
- * Determines whether there is a pending session restore.
- * @returns bool
- */
- _willRestore: function () {
- return this._sessionType == Ci.nsISessionStartup.RECOVER_SESSION ||
- this._sessionType == Ci.nsISessionStartup.RESUME_SESSION;
- },
-
- /**
- * Returns whether we will restore a session that ends up replacing the
- * homepage. The browser uses this to not start loading the homepage if
- * we're going to stop its load anyway shortly after.
- *
- * This is meant to be an optimization for the average case that loading the
- * session file finishes before we may want to start loading the default
- * homepage. Should this be called before the session file has been read it
- * will just return false.
- *
- * @returns bool
- */
- get willOverrideHomepage() {
- if (this._initialState && this._willRestore()) {
- let windows = this._initialState.windows || null;
- // If there are valid windows with not only pinned tabs, signal that we
- // will override the default homepage by restoring a session.
- return windows && windows.some(w => w.tabs.some(t => !t.pinned));
- }
- return false;
- },
-
- /**
- * Get the type of pending session store, if any.
- */
- get sessionType() {
- return this._sessionType;
- },
-
- /**
- * Get whether the previous session crashed.
- */
- get previousSessionCrashed() {
- return this._previousSessionCrashed;
- },
-
- /* ........ QueryInterface .............. */
- QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsISupportsWeakReference,
- Ci.nsISessionStartup]),
- classID: Components.ID("{ec7a6c20-e081-11da-8ad9-0800200c9a66}")
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SessionStartup]);