Bug 1388145 - Add SessionStore.promiseAllWindowsRestored. r=mikedeboer
MozReview-Commit-ID: 6FvkAdDnRPa
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -227,16 +227,20 @@ function debug(aMsg) {
*/
var gResistFingerprintingEnabled = false;
this.SessionStore = {
get promiseInitialized() {
return SessionStoreInternal.promiseInitialized;
},
+ get promiseAllWindowsRestored() {
+ return SessionStoreInternal.promiseAllWindowsRestored;
+ },
+
get canRestoreLastSession() {
return SessionStoreInternal.canRestoreLastSession;
},
set canRestoreLastSession(val) {
SessionStoreInternal.canRestoreLastSession = val;
},
@@ -545,16 +549,32 @@ var SessionStoreInternal = {
});
return deferred;
})(),
// Whether session has been initialized
_sessionInitialized: false,
+ // A promise resolved once all windows are restored.
+ _deferredAllWindowsRestored: (function() {
+ let deferred = {};
+
+ deferred.promise = new Promise((resolve, reject) => {
+ deferred.resolve = resolve;
+ deferred.reject = reject;
+ });
+
+ return deferred;
+ })(),
+
+ get promiseAllWindowsRestored() {
+ return this._deferredAllWindowsRestored.promise;
+ },
+
// Promise that is resolved when we're ready to initialize
// and restore the session.
_promiseReadyForInitialization: null,
// Keep busy state counters per window.
_windowBusyStates: new WeakMap(),
/**
@@ -1142,16 +1162,17 @@ var SessionStoreInternal = {
if (isPrivateWindow) {
// We're starting with a single private window. Save the state we
// actually wanted to restore so that we can do it later in case
// the user opens another, non-private window.
this._deferredInitialState = gSessionStartup.state;
// Nothing to restore now, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED);
+ this._deferredAllWindowsRestored.resolve();
} else {
TelemetryTimestamps.add("sessionRestoreRestoring");
this._restoreCount = aInitialState.windows ? aInitialState.windows.length : 0;
// global data must be restored before restoreWindow is called so that
// it happens before observers are notified
this._globalState.setFromState(aInitialState);
@@ -1160,16 +1181,17 @@ var SessionStoreInternal = {
let overwrite = this._isCmdLineEmpty(aWindow, aInitialState);
let options = {firstWindow: true, overwriteTabs: overwrite};
this.restoreWindows(aWindow, aInitialState, options);
}
} else {
// Nothing to restore, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED);
+ this._deferredAllWindowsRestored.resolve();
}
// this window was opened by _openWindowWithState
} else if (!this._isWindowLoaded(aWindow)) {
let state = this._statesToRestore[aWindow.__SS_restoreID];
let options = {overwriteTabs: true, isFollowUp: state.windows.length == 1};
this.restoreWindow(aWindow, state.windows[0], options);
// The user opened another, non-private window after starting up with
// a single private one. Let's restore the session we actually wanted to
@@ -4463,18 +4485,25 @@ var SessionStoreInternal = {
return;
}
// observers were already notified
if (this._restoreCount == -1)
return;
// This was the last window restored at startup, notify observers.
- Services.obs.notifyObservers(null,
- this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED);
+ if (!this._browserSetState) {
+ Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED);
+ this._deferredAllWindowsRestored.resolve();
+ } else {
+ // _browserSetState is used only by tests, and it uses an alternate
+ // notification in order not to retrigger startup observers that
+ // are listening for NOTIFY_WINDOWS_RESTORED.
+ Services.obs.notifyObservers(null, NOTIFY_BROWSER_STATE_RESTORED);
+ }
this._browserSetState = false;
this._restoreCount = -1;
},
/**
* Set the given window's busy state
* @param aWindow the window