Bug 1020831 - Make SessionStore.jsm and SessionFile.jsm share the same run state r=yoric

This commit is contained in:
Tim Taubert 2014-09-25 23:26:41 +02:00
parent 0628f512eb
commit f3504d9241
4 changed files with 86 additions and 35 deletions

View File

@ -0,0 +1,66 @@
/* 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";
this.EXPORTED_SYMBOLS = ["RunState"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm", this);
const STATE_STOPPED = 0;
const STATE_RUNNING = 1;
const STATE_QUITTING = 2;
// We're initially stopped.
let state = STATE_STOPPED;
function observer(subj, topic) {
Services.obs.removeObserver(observer, topic);
state = STATE_QUITTING;
}
// Listen for when the application is quitting.
Services.obs.addObserver(observer, "quit-application-granted", false);
/**
* This module keeps track of SessionStore's current run state. We will
* always start out at STATE_STOPPED. After the sessionw as read from disk and
* the initial browser window has loaded we switch to STATE_RUNNING. On the
* first notice that a browser shutdown was granted we switch to STATE_QUITTING.
*/
this.RunState = Object.freeze({
// If we're stopped then SessionStore hasn't been initialized yet. As soon
// as the session is read from disk and the initial browser window has loaded
// the run state will change to STATE_RUNNING.
get isStopped() {
return state == STATE_STOPPED;
},
// STATE_RUNNING is our default mode of operation that we'll spend most of
// the time in. After the session was read from disk and the first browser
// window has loaded we remain running until the browser quits.
get isRunning() {
return state == STATE_RUNNING;
},
// We will enter STATE_QUITTING as soon as we receive notice that a browser
// shutdown was granted. SessionStore will use this information to prevent
// us from collecting partial information while the browser is shutting down
// as well as to allow a last single write to disk and block all writes after
// that.
get isQuitting() {
return state == STATE_QUITTING;
},
// Switch the run state to STATE_RUNNING. This must be called after the
// session was read from, the initial browser window has loaded and we're
// now ready to restore session data.
setRunning() {
if (this.isStopped) {
state = STATE_RUNNING;
}
}
});

View File

@ -38,6 +38,8 @@ Cu.import("resource://gre/modules/AsyncShutdown.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RunState",
"resource:///modules/sessionstore/RunState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
"resource://gre/modules/TelemetryStopwatch.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
@ -267,7 +269,7 @@ let SessionFileInternal = {
}
let isFinalWrite = false;
if (Services.startup.shuttingDown) {
if (RunState.isQuitting) {
// If shutdown has started, we will want to stop receiving
// write instructions.
isFinalWrite = this._isClosed = true;

View File

@ -11,10 +11,6 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const STATE_STOPPED = 0;
const STATE_RUNNING = 1;
const STATE_QUITTING = -1;
const TAB_STATE_NEEDS_RESTORE = 1;
const TAB_STATE_RESTORING = 2;
@ -31,8 +27,7 @@ const MAX_CONCURRENT_TAB_RESTORES = 3;
// global notifications observed
const OBSERVING = [
"browser-window-before-show", "domwindowclosed",
"quit-application-requested", "quit-application-granted",
"browser-lastwindow-close-granted",
"quit-application-requested", "browser-lastwindow-close-granted",
"quit-application", "browser:purge-session-history",
"browser:purge-domain-data",
"gather-telemetry",
@ -112,6 +107,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "GlobalState",
"resource:///modules/sessionstore/GlobalState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyFilter",
"resource:///modules/sessionstore/PrivacyFilter.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RunState",
"resource:///modules/sessionstore/RunState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager",
"resource:///modules/devtools/scratchpad-manager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionSaver",
@ -288,9 +285,6 @@ let SessionStoreInternal = {
Ci.nsISupportsWeakReference
]),
// set default load state
_loadState: STATE_STOPPED,
_globalState: new GlobalState(),
// During the initial restore and setBrowserState calls tracks the number of
@ -472,7 +466,7 @@ let SessionStoreInternal = {
// at this point, we've as good as resumed the session, so we can
// clear the resume_session_once flag, if it's set
if (this._loadState != STATE_QUITTING &&
if (!RunState.isQuitting &&
this._prefBranch.getBoolPref("sessionstore.resume_session_once"))
this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
@ -531,9 +525,6 @@ let SessionStoreInternal = {
case "quit-application-requested":
this.onQuitApplicationRequested();
break;
case "quit-application-granted":
this.onQuitApplicationGranted();
break;
case "browser-lastwindow-close-granted":
this.onLastWindowCloseGranted();
break;
@ -739,7 +730,7 @@ let SessionStoreInternal = {
return;
// ignore windows opened while shutting down
if (this._loadState == STATE_QUITTING)
if (RunState.isQuitting)
return;
// Assign the window a unique identifier we can use to reference
@ -764,8 +755,8 @@ let SessionStoreInternal = {
this._windows[aWindow.__SSi].isPopup = true;
// perform additional initialization when the first window is loading
if (this._loadState == STATE_STOPPED) {
this._loadState = STATE_RUNNING;
if (RunState.isStopped) {
RunState.setRunning();
SessionSaver.updateLastSaveTime();
// restore a crashed session resp. resume the last session if requested
@ -1008,7 +999,7 @@ let SessionStoreInternal = {
let winData = this._windows[aWindow.__SSi];
// Collect window data only when *not* closed during shutdown.
if (this._loadState == STATE_RUNNING) {
if (RunState.isRunning) {
// Flush all data queued in the content script before the window is gone.
TabState.flushWindow(aWindow);
@ -1100,14 +1091,6 @@ let SessionStoreInternal = {
DirtyWindows.clear();
},
/**
* On quit application granted
*/
onQuitApplicationGranted: function ssi_onQuitApplicationGranted() {
// freeze the data at what we've got (ignoring closing windows)
this._loadState = STATE_QUITTING;
},
/**
* On last browser window close
*/
@ -1141,7 +1124,6 @@ let SessionStoreInternal = {
LastSession.clear();
}
this._loadState = STATE_QUITTING; // just to be sure
this._uninit();
},
@ -1153,7 +1135,7 @@ let SessionStoreInternal = {
// If the browser is shutting down, simply return after clearing the
// session data on disk as this notification fires after the
// quit-application notification so the browser is about to exit.
if (this._loadState == STATE_QUITTING)
if (RunState.isQuitting)
return;
LastSession.clear();
let openWindows = {};
@ -1179,7 +1161,7 @@ let SessionStoreInternal = {
var win = this._getMostRecentBrowserWindow();
if (win) {
win.setTimeout(() => SessionSaver.run(), 0);
} else if (this._loadState == STATE_RUNNING) {
} else if (RunState.isRunning) {
SessionSaver.run();
}
@ -1237,7 +1219,7 @@ let SessionStoreInternal = {
}
}
if (this._loadState == STATE_RUNNING) {
if (RunState.isRunning) {
SessionSaver.run();
}
@ -1368,7 +1350,7 @@ let SessionStoreInternal = {
* Window reference
*/
onTabSelect: function ssi_onTabSelect(aWindow) {
if (this._loadState == STATE_RUNNING) {
if (RunState.isRunning) {
this._windows[aWindow.__SSi].selected = aWindow.gBrowser.tabContainer.selectedIndex;
let tab = aWindow.gBrowser.selectedTab;
@ -2033,7 +2015,7 @@ let SessionStoreInternal = {
var activeWindow = this._getMostRecentBrowserWindow();
TelemetryStopwatch.start("FX_SESSION_RESTORE_COLLECT_ALL_WINDOWS_DATA_MS");
if (this._loadState == STATE_RUNNING) {
if (RunState.isRunning) {
// update the data for all windows with activities since the last save operation
this._forEachBrowserWindow(function(aWindow) {
if (!this._isWindowLoaded(aWindow)) // window data is still in _statesToRestore
@ -2090,7 +2072,7 @@ let SessionStoreInternal = {
//XXXzpao We should do this for _restoreLastWindow == true, but that has
// its own check for popups. c.f. bug 597619
if (nonPopupCount == 0 && lastClosedWindowsCopy.length > 0 &&
this._loadState == STATE_QUITTING) {
RunState.isQuitting) {
// prepend the last non-popup browser window, so that if the user loads more tabs
// at startup we don't accidentally add them to a popup window
do {
@ -2155,7 +2137,7 @@ let SessionStoreInternal = {
if (!this._isWindowLoaded(aWindow))
return this._statesToRestore[aWindow.__SS_restoreID];
if (this._loadState == STATE_RUNNING) {
if (RunState.isRunning) {
this._collectWindowData(aWindow);
}
@ -2637,7 +2619,7 @@ let SessionStoreInternal = {
*/
restoreNextTab: function ssi_restoreNextTab() {
// If we call in here while quitting, we don't actually want to do anything
if (this._loadState == STATE_QUITTING)
if (RunState.isQuitting)
return;
// Don't exceed the maximum number of concurrent tab restores.

View File

@ -31,6 +31,7 @@ EXTRA_JS_MODULES.sessionstore = [
'PrivacyFilter.jsm',
'PrivacyLevel.jsm',
'RecentlyClosedTabsAndWindowsMenuUtils.jsm',
'RunState.jsm',
'SessionCookies.jsm',
'SessionFile.jsm',
'SessionHistory.jsm',