Bug 1616151 - Port |Bug 670033 - Persist deferred session across a browser restart| and |Bug 1001167 - Don't let invalid sessionstore.js files break sessionstore| to SeaMonkey. r=frg
authorIan Neal <iann_cvs@blueyonder.co.uk>
Mon, 30 Mar 2020 11:49:38 +0200
changeset 38612 6f664f6a69d7b858c02d6f1058538e759f2af04b
parent 38611 e75299a8d3c245240c11a6d7118e5225baa01675
child 38613 d5fc02f311df96287a0c9fc68121fa7b79c7b016
push id400
push userclokep@gmail.com
push dateMon, 04 May 2020 18:56:09 +0000
reviewersfrg
bugs1616151, 670033, 1001167
Bug 1616151 - Port |Bug 670033 - Persist deferred session across a browser restart| and |Bug 1001167 - Don't let invalid sessionstore.js files break sessionstore| to SeaMonkey. r=frg
suite/components/sessionstore/nsSessionStartup.js
suite/components/sessionstore/nsSessionStore.js
--- a/suite/components/sessionstore/nsSessionStartup.js
+++ b/suite/components/sessionstore/nsSessionStartup.js
@@ -52,21 +52,21 @@ SessionStartup.prototype = {
 
 /* ........ Global Event Handlers .............. */
 
   /**
    * Initialize the component
    */
   init: function sss_init() {
     // get file references
-    let sessionFile = Services.dirsvc.get("ProfD",
-                                          Ci.nsIFile);
+    let sessionFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
     sessionFile.append("sessionstore.json");
 
-    let doResumeSession = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") ||
+    let doResumeSessionOnce = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
+    let doResumeSession = doResumeSessionOnce ||
                           Services.prefs.getIntPref("browser.startup.page") == 3;
 
     var resumeFromCrash = Services.prefs.getBoolPref("browser.sessionstore.resume_from_crash");
 
     // only continue if the session file exists
     if (!sessionFile.exists())
       return;
 
@@ -79,16 +79,20 @@ SessionStartup.prototype = {
       // parse the session state into JS objects
       this._initialState = JSON.parse(iniString);
     }
     catch (ex) {
       doResumeSession = false;
       debug("The session file is invalid: " + ex);
     }
 
+    // If this is a normal restore then throw away any previous session
+    if (!doResumeSessionOnce && this._initialState)
+      delete this._initialState.lastSessionState;
+
     let lastSessionCrashed =
       this._initialState && this._initialState.session &&
       this._initialState.session.state &&
       this._initialState.session.state == STATE_RUNNING_STR;
 
     // set the startup type
     if (lastSessionCrashed && resumeFromCrash)
       this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
--- a/suite/components/sessionstore/nsSessionStore.js
+++ b/suite/components/sessionstore/nsSessionStore.js
@@ -164,17 +164,20 @@ SessionStoreService.prototype = {
 
   // tabs to restore in order
   _tabsToRestore: { visible: [], hidden: [] },
   _tabsRestoringCount: 0,
 
   // number of tabs to restore concurrently, pref controlled.
   _maxConcurrentTabRestores: null,
 
-  // The state from the previous session (after restoring pinned tabs)
+  // The state from the previous session (after restoring pinned tabs). This
+  // state is persisted and passed through to the next session during an app
+  // restart to make the third party add-on warning not trash the deferred
+  // session
   _lastSessionState: null,
 
   // Whether we've been initialized
   _initialized: false,
 
   // Mapping from legacy docshellIDs to docshellUUIDs.
   _docshellUUIDMap: new Map(),
 
@@ -245,16 +248,20 @@ SessionStoreService.prototype = {
           if (iniState.windows.length)
             this._initialState = iniState;
           else
             this._initialState = null;
           if (remainingState.windows.length)
             this._lastSessionState = remainingState;
         }
         else {
+          // Get the last deferred session in case the user still wants to
+          // restore it
+          this._lastSessionState = this._initialState.lastSessionState;
+
           let lastSessionCrashed =
             this._initialState.session && this._initialState.session.state &&
             this._initialState.session.state == STATE_RUNNING_STR;
           if (lastSessionCrashed) {
             this._recentCrashes = (this._initialState.session &&
                                    this._initialState.session.recentCrashes || 0) + 1;
 
             if (this._needsRestorePage(this._initialState, this._recentCrashes)) {
@@ -382,16 +389,22 @@ SessionStoreService.prototype = {
         // The browser:purge-session-history notification fires after the
         // quit-application notification so unregister the
         // browser:purge-session-history notification to prevent clearing
         // session data on disk on a restart.  It is also unnecessary to
         // perform any other sanitization processing on a restart as the
         // browser is about to exit anyway.
         Services.obs.removeObserver(this, "browser:purge-session-history");
       }
+
+      if (aData != "restart") {
+        // Throw away the previous session on shutdown
+        this._lastSessionState = null;
+      }
+
       this._loadState = STATE_QUITTING; // just to be sure
       this._uninit();
       break;
     case "browser:purge-session-history": // catch sanitization
       this._clearDisk();
       // 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.
@@ -3358,16 +3371,20 @@ SessionStoreService.prototype = {
     // If crash recovery is disabled, we only want to resume with pinned tabs
     // if we crash.
     let pinnedOnly = this._loadState == STATE_RUNNING && !this._resume_from_crash;
 
     var oState = this._getCurrentState(aUpdateAll);
     if (!oState)
       return;
 
+    // Persist the last session if we deferred restoring it
+    if (this._lastSessionState)
+      oState.lastSessionState = this._lastSessionState;
+
     this._saveStateObject(oState);
   },
 
   /**
    * write a state object to disk
    */
   _saveStateObject: function sss_saveStateObject(aStateObj) {
     var stateString = Cc["@mozilla.org/supports-string;1"]