--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -81,16 +81,21 @@ SessionStore.prototype = {
// The index where the most recently closed tab was in the tabs array
// when it was closed.
_lastClosedTabIndex: -1,
// Whether or not to send notifications for changes to the closed tabs.
_notifyClosedTabs: false,
+ // If we're simultaneously closing both a tab and Firefox, we don't want
+ // to bother reloading the newly selected tab if it is zombified.
+ // The Java UI will tell us which tab to watch out for.
+ _keepAsZombieTabId: -1,
+
init: function ss_init() {
loggingEnabled = Services.prefs.getBoolPref("browser.sessionstore.debug_logging");
// Get file references
this._sessionFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
this._sessionFileBackup = this._sessionFile.clone();
this._sessionFilePrevious = this._sessionFile.clone();
this._sessionFileTemp = this._sessionFile.clone();
@@ -136,16 +141,17 @@ SessionStore.prototype = {
observerService.addObserver(this, "domwindowopened", true);
observerService.addObserver(this, "domwindowclosed", true);
observerService.addObserver(this, "browser:purge-session-history", true);
observerService.addObserver(this, "quit-application-requested", true);
observerService.addObserver(this, "quit-application-proceeding", true);
observerService.addObserver(this, "quit-application", true);
observerService.addObserver(this, "Session:Restore", true);
observerService.addObserver(this, "Session:NotifyLocationChange", true);
+ observerService.addObserver(this, "Tab:KeepZombified", true);
observerService.addObserver(this, "application-background", true);
observerService.addObserver(this, "application-foreground", true);
observerService.addObserver(this, "ClosedTabs:StartNotifications", true);
observerService.addObserver(this, "ClosedTabs:StopNotifications", true);
observerService.addObserver(this, "last-pb-context-exited", true);
observerService.addObserver(this, "Session:RestoreRecentTabs", true);
observerService.addObserver(this, "Tabs:OpenMultiple", true);
break;
@@ -279,16 +285,23 @@ SessionStore.prototype = {
if (data.shouldNotifyTabsOpenedToJava) {
Messaging.sendRequest({
type: "Tabs:TabsOpened"
});
}
break;
}
+ case "Tab:KeepZombified": {
+ if (aData >= 0) {
+ this._keepAsZombieTabId = aData;
+ log("Tab:KeepZombified " + aData);
+ }
+ break;
+ }
case "application-background":
// We receive this notification when Android's onPause callback is
// executed. After onPause, the application may be terminated at any
// point without notice; therefore, we must synchronously write out any
// pending save state to ensure that this data does not get lost.
log("application-background");
// Tab events dispatched immediately before the application was backgrounded
// might actually arrive after this point, therefore save them without delay.
@@ -296,16 +309,25 @@ SessionStore.prototype = {
this._minSaveDelay = MINIMUM_SAVE_DELAY_BACKGROUND; // A small delay allows successive tab events to be batched together.
this.flushPendingState();
break;
case "application-foreground":
// Reset minimum interval between session store writes back to default.
log("application-foreground");
this._interval = Services.prefs.getIntPref("browser.sessionstore.interval");
this._minSaveDelay = MINIMUM_SAVE_DELAY;
+
+ // If we skipped restoring a zombified tab before backgrounding,
+ // we might have to do it now instead.
+ let window = Services.wm.getMostRecentWindow("navigator:browser");
+ let tab = window.BrowserApp.selectedTab;
+
+ if (tab.browser.__SS_restore) {
+ this._restoreZombieTab(tab.browser, tab.id);
+ }
break;
case "ClosedTabs:StartNotifications":
this._notifyClosedTabs = true;
log("ClosedTabs:StartNotifications");
this._sendClosedTabsToJava(Services.wm.getMostRecentWindow("navigator:browser"));
break;
case "ClosedTabs:StopNotifications":
this._notifyClosedTabs = false;
@@ -652,36 +674,46 @@ SessionStore.prototype = {
let browsers = aWindow.document.getElementById("browsers");
let index = browsers.selectedIndex;
this._windows[aWindow.__SSID].selected = parseInt(index) + 1; // 1-based
let tabId = aWindow.BrowserApp.getTabForBrowser(aBrowser).id;
// Restore the resurrected browser
if (aBrowser.__SS_restore) {
- let data = aBrowser.__SS_data;
- this._restoreTab(data, aBrowser);
-
- delete aBrowser.__SS_restore;
- aBrowser.removeAttribute("pending");
- log("onTabSelect() restored zombie tab " + tabId);
+ if (tabId != this._keepAsZombieTabId) {
+ this._restoreZombieTab(aBrowser, tabId);
+ } else {
+ log("keeping as zombie tab " + tabId);
+ }
}
+ // The tab id passed through Tab:KeepZombified is valid for one TabSelect only.
+ this._keepAsZombieTabId = -1;
log("onTabSelect() ran for tab " + tabId);
this.saveStateDelayed();
this._updateCrashReportURL(aWindow);
// If the selected tab has changed while listening for closed tab
// notifications, we may have switched between different private browsing
// modes.
if (this._notifyClosedTabs) {
this._sendClosedTabsToJava(aWindow);
}
},
+ _restoreZombieTab: function ss_restoreZombieTab(aBrowser, aTabId) {
+ let data = aBrowser.__SS_data;
+ this._restoreTab(data, aBrowser);
+
+ delete aBrowser.__SS_restore;
+ aBrowser.removeAttribute("pending");
+ log("restoring zombie tab " + aTabId);
+ },
+
onTabInput: function ss_onTabInput(aWindow, aBrowser) {
// If this browser belongs to a zombie tab or the initial restore hasn't yet finished,
// skip any session save activity.
if (aBrowser.__SS_restore || !this._startupRestoreFinished || aBrowser.__SS_restoreReloadPending) {
return;
}
// Don't bother trying to save text data if we don't have history yet