--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -62,16 +62,17 @@ SessionStore.prototype = {
_windows: {},
_lastSaveTime: 0,
_lastBackupTime: 0,
_interval: 10000,
_backupInterval: 120000, // 2 minutes
_maxTabsUndo: 5,
_pendingWrite: 0,
+ _pendingWritePrivateOnly: 0,
_scrollSavePending: null,
_writeInProgress: false,
// We only want to start doing backups if we've successfully
// written the session data at least once.
_sessionDataIsGood: false,
// The index where the most recently closed tab was in the tabs array
@@ -346,17 +347,18 @@ SessionStore.prototype = {
case "browser:purge-session-tabs":
case "browser:purge-session-history": // catch sanitization
this._purgeHistory(aTopic);
break;
case "timer-callback":
if (this._loadState == STATE_RUNNING) {
// Timer call back for delayed saving
this._saveTimer = null;
- log("timer-callback, pendingWrite = " + this._pendingWrite);
+ log("timer-callback, pendingWrite = " + this._pendingWritePrivateOnly +
+ "/" + this._pendingWrite);
if (this._pendingWrite) {
this._saveState(true);
}
}
break;
case "Session:NotifyLocationChange": {
let browser = aSubject;
@@ -965,38 +967,47 @@ SessionStore.prototype = {
Ci.nsIDOMWindowUtils).getContentViewerSize(width, height);
displaySize.width = width.value;
displaySize.height = height.value;
return displaySize;
},
- saveStateDelayed: function ss_saveStateDelayed() {
+ saveStateDelayed: function ss_saveStateDelayed(aPrivateTabsOnly = false) {
+ this._pendingWrite++;
+ if (aPrivateTabsOnly) {
+ this._pendingWritePrivateOnly++;
+ }
+ log("incrementing _pendingWrite to " + this._pendingWritePrivateOnly +
+ "/" + this._pendingWrite);
if (!this._saveTimer) {
// Interval until the next disk operation is allowed
let currentDelay = this._lastSaveTime + this._interval - Date.now();
// If we have to wait, set a timer, otherwise saveState directly
let delay = Math.max(currentDelay, MINIMUM_SAVE_DELAY);
if (delay > 0) {
- this._pendingWrite++;
this._createTimer(delay);
} else {
log("saveStateDelayed() no delay");
this.saveState();
}
} else {
log("saveStateDelayed() timer already running, taking no action");
}
},
- saveState: function ss_saveState() {
+ saveState: function ss_saveState(aPrivateTabsOnly = false) {
this._pendingWrite++;
- log("saveState(), incrementing _pendingWrite to " + this._pendingWrite);
+ if (aPrivateTabsOnly) {
+ this._pendingWritePrivateOnly++;
+ }
+ log("saveState(), incrementing _pendingWrite to " + this._pendingWritePrivateOnly +
+ "/" + this._pendingWrite);
this._saveState(true);
},
/**
* Immediately and synchronously writes any pending state to disk.
*
* @return True if data was written, false if no pending file writes were present.
*/
@@ -1007,18 +1018,17 @@ SessionStore.prototype = {
return true;
}
return false;
},
_createTimer: function ss_createTimer(aDelay) {
this._saveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._saveTimer.init(this, aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
- log("saveTimer delay = " + aDelay +
- ", incrementing _pendingWrite to " + this._pendingWrite);
+ log("saveTimer delay = " + aDelay);
},
_killTimer: function ss_killTimer() {
if (this._saveTimer) {
this._saveTimer.cancel();
this._saveTimer = null;
log("killed queued saveTimer");
}
@@ -1081,16 +1091,24 @@ SessionStore.prototype = {
let window = Services.wm.getMostRecentWindow("navigator:browser");
if (window) { // can be null if we're restarting
window.WindowEventDispatcher.sendRequest({
type: "PrivateBrowsing:Data",
session: (privateData.windows.length > 0 && privateData.windows[0].tabs.length > 0) ? JSON.stringify(privateData) : null
});
}
+ // If all queued writes were for private tabs only, we can stop here.
+ if (this._pendingWrite === this._pendingWritePrivateOnly) {
+ this._pendingWrite = 0;
+ this._pendingWritePrivateOnly = 0;
+ this._lastSaveTime = Date.now();
+ return;
+ }
+
// Write only non-private data to disk
if (normalData.windows[0] && normalData.windows[0].tabs) {
log("_saveState() writing normal data, " +
normalData.windows[0].tabs.length + " tabs in window[0]");
} else {
log("_saveState() writing empty normal data");
}
this._writeFile(this._sessionFile, this._sessionFileTemp, normalData, aAsync);
@@ -1194,16 +1212,17 @@ SessionStore.prototype = {
this._write(aFile, aFileTemp, buffer, aAsync).then(() => {
let stopWriteMs = Cu.now();
// Make sure this._pendingWrite is the same value it was before we
// fired off the async write. If the count is different, another write
// is pending, so we shouldn't reset this._pendingWrite yet.
if (pendingWrite === this._pendingWrite) {
this._pendingWrite = 0;
+ this._pendingWritePrivateOnly = 0;
this._writeInProgress = false;
}
log("_writeFile() _write() returned, _pendingWrite = " + this._pendingWrite);
// We don't use a stopwatch here since the calls are async and stopwatches can only manage
// a single timer per histogram.
Services.telemetry.getHistogramById("FX_SESSION_RESTORE_WRITE_FILE_MS").add(Math.round(stopWriteMs - startWriteMs));