Bug 810732 - Ensure that sessionstore-windows-restored is always dispatched. r=mfinkle
authorBrian Nicholson <bnicholson@mozilla.com>
Tue, 27 Nov 2012 16:35:20 -0800
changeset 114312 3f225d53e909d8820c308bf42fc0e07f8d68d2f4
parent 114311 db5b030c100a1a92dbe74cf1fc0d8579b6187259
child 114313 0c18c15c4985db3c4dd9c4492e3959f927c3e564
push id23913
push useremorley@mozilla.com
push dateWed, 28 Nov 2012 17:11:31 +0000
treeherdermozilla-central@17c267a881cf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs810732
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 810732 - Ensure that sessionstore-windows-restored is always dispatched. r=mfinkle
mobile/android/base/GeckoApp.java
mobile/android/chrome/content/browser.js
mobile/android/components/SessionStore.js
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1648,16 +1648,17 @@ abstract public class GeckoApp
                 startupAction = StartupAction.PREFETCH;
                 GeckoAppShell.getHandler().post(new PrefetchRunnable(copy));
             }
         }
 
         Tabs.registerOnTabsChangedListener(this);
 
         // If we are doing a restore, read the session data and send it to Gecko
+        String restoreMessage = null;
         if (mRestoreMode != RESTORE_NONE) {
             try {
                 String sessionString = getProfile().readSessionFile(false);
                 if (sessionString == null) {
                     throw new IOException("could not read from session file");
                 }
 
                 // If we are doing an OOM restore, parse the session data and
@@ -1697,24 +1698,26 @@ abstract public class GeckoApp
                     } else {
                         throw new Exception("No tabs could be read from session file");
                     }
                 }
 
                 JSONObject restoreData = new JSONObject();
                 restoreData.put("restoringOOM", mRestoreMode == RESTORE_OOM);
                 restoreData.put("sessionString", sessionString);
-                GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Session:Restore", restoreData.toString()));
+                restoreMessage = restoreData.toString();
             } catch (Exception e) {
                 // If restore failed, do a normal startup
                 Log.e(LOGTAG, "An error occurred during restore", e);
                 mRestoreMode = RESTORE_NONE;
             }
         }
 
+        GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Session:Restore", restoreMessage));
+
         if (mRestoreMode == RESTORE_OOM) {
             // If we successfully did an OOM restore, we now have tab stubs
             // from the last session. Any future tabs should be animated.
             Tabs.getInstance().notifyListeners(null, Tabs.TabEvents.RESTORED);
         } else {
             // Move the session file if it exists
             getProfile().moveSessionFile();
         }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -170,17 +170,16 @@ var BrowserApp = {
 
     Services.obs.addObserver(this, "Tab:Load", false);
     Services.obs.addObserver(this, "Tab:Selected", false);
     Services.obs.addObserver(this, "Tab:Closed", false);
     Services.obs.addObserver(this, "Session:Back", false);
     Services.obs.addObserver(this, "Session:Forward", false);
     Services.obs.addObserver(this, "Session:Reload", false);
     Services.obs.addObserver(this, "Session:Stop", false);
-    Services.obs.addObserver(this, "Session:Restore", false);
     Services.obs.addObserver(this, "SaveAs:PDF", false);
     Services.obs.addObserver(this, "Browser:Quit", false);
     Services.obs.addObserver(this, "Preferences:Get", false);
     Services.obs.addObserver(this, "Preferences:Set", false);
     Services.obs.addObserver(this, "ScrollTo:FocusedInput", false);
     Services.obs.addObserver(this, "Sanitize:ClearData", false);
     Services.obs.addObserver(this, "FullScreen:Exit", false);
     Services.obs.addObserver(this, "Viewport:Change", false);
@@ -277,21 +276,16 @@ var BrowserApp = {
     // XXX maybe we don't do this if the launch was kicked off from external
     Services.io.offline = false;
 
     // Broadcast a UIReady message so add-ons know we are finished with startup
     let event = document.createEvent("Events");
     event.initEvent("UIReady", true, false);
     window.dispatchEvent(event);
 
-    let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-    if (ss.shouldRestore()) {
-      this.restoreSession(false, null);
-    }
-
     if (updated)
       this.onAppUpdated();
 
     // notify java that gecko has loaded
     sendMessageToJava({
       gecko: {
         type: "Gecko:Ready"
       }
@@ -306,44 +300,16 @@ var BrowserApp = {
     });
 
 #ifdef MOZ_SAFE_BROWSING
     // Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
     setTimeout(function() { SafeBrowsing.init(); }, 5000);
 #endif
   },
 
-  restoreSession: function (restoringOOM, sessionString) {
-    // Be ready to handle any restore failures by making sure we have a valid tab opened
-    let restoreCleanup = {
-      observe: function (aSubject, aTopic, aData) {
-        Services.obs.removeObserver(restoreCleanup, "sessionstore-windows-restored");
-
-        if (this.tabs.length == 0) {
-          this.addTab("about:home", {
-            showProgress: false,
-            selected: true
-          });
-        }
-
-        // Let Java know we're done restoring tabs so tabs added after this can be animated
-        sendMessageToJava({
-          gecko: {
-            type: "Session:RestoreEnd"
-          }
-        });
-      }.bind(this)
-    };
-    Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
-
-    // Start the restore
-    let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-    ss.restoreLastSession(restoringOOM, sessionString);
-  },
-
   isAppUpdated: function() {
     let savedmstone = null;
     try {
       savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
     } catch (e) {
     }
 #expand    let ourmstone = "__MOZ_APP_VERSION__";
     if (ourmstone != savedmstone) {
@@ -1142,19 +1108,16 @@ var BrowserApp = {
                        getService(Ci.nsIProfiler);
       if (profiler.IsActive()) {
         profiler.StopProfiler();
       } else {
         profiler.StartProfiler(100000, 25, ["stackwalk"], 1);
       }
     } else if (aTopic == "gather-telemetry") {
       sendMessageToJava({ gecko: { type: "Telemetry:Gather" }});
-    } else if (aTopic == "Session:Restore") {
-      let data = JSON.parse(aData);
-      this.restoreSession(data.restoringOOM, data.sessionString);
     }
   },
 
   get defaultBrowserWidth() {
     delete this.defaultBrowserWidth;
     let width = Services.prefs.getIntPref("browser.viewport.desktopWidth");
     return this.defaultBrowserWidth = width;
   },
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -94,28 +94,30 @@ SessionStore.prototype = {
         observerService.addObserver(this, "final-ui-startup", true);
         observerService.addObserver(this, "domwindowopened", true);
         observerService.addObserver(this, "domwindowclosed", true);
         observerService.addObserver(this, "browser-lastwindow-close-granted", true);
         observerService.addObserver(this, "browser:purge-session-history", true);
         observerService.addObserver(this, "quit-application-requested", true);
         observerService.addObserver(this, "quit-application-granted", true);
         observerService.addObserver(this, "quit-application", true);
+        observerService.addObserver(this, "Session:Restore", true);
         break;
       case "final-ui-startup":
         observerService.removeObserver(this, "final-ui-startup");
         this.init();
         break;
-      case "domwindowopened":
+      case "domwindowopened": {
         let window = aSubject;
         window.addEventListener("load", function() {
           self.onWindowOpen(window);
           window.removeEventListener("load", arguments.callee, false);
         }, false);
         break;
+      }
       case "domwindowclosed": // catch closed windows
         this.onWindowClose(aSubject);
         break;
       case "browser-lastwindow-close-granted":
         // If a save has been queued, kill the timer and save state now
         if (this._saveTimer) {
           this._saveTimer.cancel();
           this._saveTimer = null;
@@ -159,16 +161,17 @@ SessionStore.prototype = {
           this._sessionFile.moveTo(null, this._sessionFileBackup.leafName);
 
         observerService.removeObserver(this, "domwindowopened");
         observerService.removeObserver(this, "domwindowclosed");
         observerService.removeObserver(this, "browser-lastwindow-close-granted");
         observerService.removeObserver(this, "quit-application-requested");
         observerService.removeObserver(this, "quit-application-granted");
         observerService.removeObserver(this, "quit-application");
+        observerService.removeObserver(this, "Session:Restore");
 
         // If a save has been queued, kill the timer and save state now
         if (this._saveTimer) {
           this._saveTimer.cancel();
           this._saveTimer = null;
           this.saveState();
         }
         break;
@@ -192,16 +195,54 @@ SessionStore.prototype = {
 
         Services.obs.notifyObservers(null, "sessionstore-state-purge-complete", "");
         break;
       case "timer-callback":
         // Timer call back for delayed saving
         this._saveTimer = null;
         this.saveState();
         break;
+      case "Session:Restore": {
+        if (aData) {
+          // Be ready to handle any restore failures by making sure we have a valid tab opened
+          let window = Services.wm.getMostRecentWindow("navigator:browser");
+          let restoreCleanup = {
+            observe: function (aSubject, aTopic, aData) {
+              Services.obs.removeObserver(restoreCleanup, "sessionstore-windows-restored");
+
+              if (window.BrowserApp.tabs.length == 0) {
+                window.BrowserApp.addTab("about:home", {
+                  showProgress: false,
+                  selected: true
+                });
+              }
+
+              // Let Java know we're done restoring tabs so tabs added after this can be animated
+              this._sendMessageToJava({
+                type: "Session:RestoreEnd"
+              });
+            }.bind(this)
+          };
+          Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
+
+          // Do a restore, triggered by Java
+          let data = JSON.parse(aData);
+          this.restoreLastSession(data.restoringOOM, data.sessionString);
+        } else if (this._shouldRestore) {
+          // Do a restore triggered by Gecko (e.g., if
+          // browser.sessionstore.resume_session_once is true). In these cases,
+          // our Java front-end doesn't know we're doing a restore, so it has
+          // already opened an about:home tab.
+          this.restoreLastSession(false, null);
+        } else {
+          // Not doing a restore; just send restore message
+          Services.obs.notifyObservers(null, "sessionstore-windows-restored", "");
+        }
+        break;
+      }
     }
   },
 
   handleEvent: function ss_handleEvent(aEvent) {
     let window = aEvent.currentTarget.ownerDocument.defaultView;
     switch (aEvent.type) {
       case "TabOpen": {
         let browser = aEvent.target;