Bug 676780 - Fennec is unable to load webpages and close tabs (corrupt sessionstore) [r=mbrubeck]
--- 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]);