Bug 676780 - Fennec is unable to load webpages and close tabs (corrupt sessionstore) [r=mbrubeck]
authorMark Finkle <mfinkle@mozilla.com>
Wed, 10 Aug 2011 15:48:37 -0400
changeset 74222 b7d5fd20d40a5807ef342c458e8cf6bfd40f9115
parent 74221 23a7c8800e3fd358c1af5aa4371e6cbdbf55c846
child 74223 968dee8a144a3e7802a4ba551d912e44f3d3ded0
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersmbrubeck
bugs676780
milestone8.0a1
Bug 676780 - Fennec is unable to load webpages and close tabs (corrupt sessionstore) [r=mbrubeck]
mobile/chrome/content/browser.js
mobile/components/SessionStore.js
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -350,20 +350,22 @@ var Browser = {
       // First open any commandline URLs, except the homepage
       if (commandURL && commandURL != this.getHomePage()) {
         this.addTab(commandURL, true);
       } else {
         bringFront = true;
         // Initial window resizes call functions that assume a tab is in the tab list
         // and restored tabs are added too late. We add a dummy to to satisfy the resize
         // code and then remove the dummy after the session has been restored.
-        let dummy = this.addTab("about:blank");
+        let dummy = this.addTab("about:blank", true);
         let dummyCleanup = {
-          observe: function() {
+          observe: function(aSubject, aTopic, aData) {
             Services.obs.removeObserver(dummyCleanup, "sessionstore-windows-restored");
+            if (aData == "fail")
+              Browser.addTab(commandURL || Browser.getHomePage(), true);
             dummy.chromeTab.ignoreUndo = true;
             Browser.closeTab(dummy, { forceClose: true });
           }
         };
         Services.obs.addObserver(dummyCleanup, "sessionstore-windows-restored", false);
       }
       ss.restoreLastSession(bringFront);
     } else {
--- a/mobile/components/SessionStore.js
+++ b/mobile/components/SessionStore.js
@@ -702,33 +702,35 @@ SessionStore.prototype = {
       throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
   },
 
   shouldRestore: function ss_shouldRestore() {
     return this._shouldRestore;
   },
 
   restoreLastSession: function ss_restoreLastSession(aBringToFront) {
-    // The previous session data has already been renamed to the backup file
-    if (!this._sessionFileBackup.exists())
-      return;
+    let self = this;
+    function notifyObservers(aMessage) {
+      self._clearCache();
+      Services.obs.notifyObservers(null, "sessionstore-windows-restored", aMessage || "");
+    }
 
-    let self = this;
-    function notifyObservers() {
-      self._clearCache();
-      Services.obs.notifyObservers(null, "sessionstore-windows-restored", "");
+    // The previous session data has already been renamed to the backup file
+    if (!this._sessionFileBackup.exists()) {
+      notifyObservers("fail")
+      return;
     }
 
     try {
       let channel = NetUtil.newChannel(this._sessionFileBackup);
       channel.contentType = "application/json";
       NetUtil.asyncFetch(channel, function(aStream, aResult) {
         if (!Components.isSuccessCode(aResult)) {
           Cu.reportError("SessionStore: Could not read from sessionstore.bak file");
-          notifyObservers();
+          notifyObservers("fail");
           return;
         }
 
         // Read session state file into a string and let observers modify the state before it's being used
         let state = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
         state.data = NetUtil.readInputStreamToString(aStream, aStream.available()) || "";
         aStream.close();
 
@@ -737,24 +739,27 @@ SessionStore.prototype = {
         let data = null;
         try {
           data = JSON.parse(state.data);
         } catch (ex) {
           Cu.reportError("SessionStore: Could not parse JSON: " + ex);
         }
 
         if (!data || data.windows.length == 0) {
-          notifyObservers();
+          notifyObservers("fail");
           return;
         }
 
         let window = Services.wm.getMostRecentWindow("navigator:browser");
 
+        let tabs = data.windows[0].tabs;
         let selected = data.windows[0].selected;
-        let tabs = data.windows[0].tabs;
+        if (selected > tabs.length) // Clamp the selected index if it's bogus
+          selected = 1;
+
         for (let i=0; i<tabs.length; i++) {
           let tabData = tabs[i];
 
           // Add a tab, but don't load the URL until we need to
           let params = { getAttention: false, delayLoad: true };
 
           // We must have selected tabs as soon as possible, so we let all tabs be selected
           // until we get the real selected tab. Then we stop selecting tabs. The end result
@@ -790,14 +795,14 @@ SessionStore.prototype = {
 
           tab.browser.__SS_extdata = tabData.extData;
         }
     
         notifyObservers();
       });
     } catch (ex) {
       Cu.reportError("SessionStore: Could not read from sessionstore.bak file: " + ex);
-      notifyObservers();
+      notifyObservers("fail");
     }
   }
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([SessionStore]);