Bug 753625 - Use tri-state session restore flag. r=mfinkle a=mfinkle
authorBrian Nicholson <bnicholson@mozilla.com>
Mon, 14 May 2012 14:48:04 -0700
changeset 95768 912f2f9254690c90ad45f5568bd6ecd5a8614ba2
parent 95767 65bf57670069c94299f2200c639094010e78da3b
child 95769 6fc8256df073e637064b2648689318106f7da1c2
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, mfinkle
bugs753625
milestone14.0a2
Bug 753625 - Use tri-state session restore flag. r=mfinkle a=mfinkle
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoThread.java
mobile/android/chrome/content/browser.js
mobile/android/components/BrowserCLH.js
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -111,17 +111,16 @@ abstract public class GeckoApp
     public static final String ACTION_ALERT_CLEAR   = "org.mozilla.gecko.ACTION_ALERT_CLEAR";
     public static final String ACTION_WEBAPP        = "org.mozilla.gecko.WEBAPP";
     public static final String ACTION_DEBUG         = "org.mozilla.gecko.DEBUG";
     public static final String ACTION_BOOKMARK      = "org.mozilla.gecko.BOOKMARK";
     public static final String ACTION_LOAD          = "org.mozilla.gecko.LOAD";
     public static final String ACTION_UPDATE        = "org.mozilla.gecko.UPDATE";
     public static final String ACTION_INIT_PW       = "org.mozilla.gecko.INIT_PW";
     public static final String SAVED_STATE_TITLE    = "title";
-    public static final String SAVED_STATE_SESSION  = "session";
 
     StartupMode mStartupMode = null;
     private LinearLayout mMainLayout;
     private RelativeLayout mGeckoLayout;
     public static SurfaceView cameraView;
     public static GeckoApp mAppContext;
     public static boolean mDOMFullScreen = false;
     public static Menu sMenu;
@@ -139,17 +138,17 @@ abstract public class GeckoApp
     public static FormAssistPopup mFormAssistPopup;
     public Favicons mFavicons;
 
     private static LayerController mLayerController;
     private static GeckoLayerClient mLayerClient;
     private AboutHomeContent mAboutHomeContent;
     private static AbsoluteLayout mPluginContainer;
 
-    private boolean mRestoreSession = false;
+    private int mRestoreMode = GeckoAppShell.RESTORE_NONE;
     private boolean mInitialized = false;
 
     static class ExtraMenuItem implements MenuItem.OnMenuItemClickListener {
         String label;
         String icon;
         int id;
         public boolean onMenuItemClick(MenuItem item) {
             Log.i(LOGTAG, "menu item clicked");
@@ -539,17 +538,16 @@ abstract public class GeckoApp
         super.onSaveInstanceState(outState);
 
         if (outState == null)
             outState = new Bundle();
 
         Tab tab = Tabs.getInstance().getSelectedTab();
         if (tab != null)
             outState.putString(SAVED_STATE_TITLE, tab.getDisplayTitle());
-        outState.putBoolean(SAVED_STATE_SESSION, true);
     }
 
     void getAndProcessThumbnailForTab(final Tab tab) {
         boolean isSelectedTab = Tabs.getInstance().isSelectedTab(tab);
         final Bitmap bitmap = isSelectedTab ? mLayerClient.getBitmap() : null;
         
         if ("about:home".equals(tab.getURL())) {
             tab.updateThumbnail(null);
@@ -1538,17 +1536,17 @@ abstract public class GeckoApp
         mBrowserToolbar.from(actionBar);
 
         // setup gecko layout
         mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
         mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
 
         if (savedInstanceState != null) {
             mBrowserToolbar.setTitle(savedInstanceState.getString(SAVED_STATE_TITLE));
-            mRestoreSession = savedInstanceState.getBoolean(SAVED_STATE_SESSION);
+            mRestoreMode = GeckoAppShell.RESTORE_OOM;
         }
 
         ((GeckoApplication) getApplication()).addApplicationLifecycleCallbacks(this);
     }
 
     private void initialize() {
         mInitialized = true;
 
@@ -1571,30 +1569,31 @@ abstract public class GeckoApp
 
         String passedUri = null;
         String uri = getURIFromIntent(intent);
         if (uri != null && uri.length() > 0) {
             passedUri = uri;
             mBrowserToolbar.setTitle(uri);
         }
 
-        mRestoreSession |= getProfile().shouldRestoreSession();
+        if (mRestoreMode == GeckoAppShell.RESTORE_NONE && getProfile().shouldRestoreSession())
+            mRestoreMode = GeckoAppShell.RESTORE_CRASH;
 
         boolean isExternalURL = passedUri != null && !passedUri.equals("about:home");
         if (!isExternalURL) {
             // show about:home if we aren't restoring previous session
-            if (!mRestoreSession) {
+            if (mRestoreMode == GeckoAppShell.RESTORE_NONE) {
                 mBrowserToolbar.updateTabCount(1);
                 showAboutHome();
             }
         } else {
             mBrowserToolbar.updateTabCount(1);
         }
 
-        mBrowserToolbar.setProgressVisibility(isExternalURL || mRestoreSession);
+        mBrowserToolbar.setProgressVisibility(isExternalURL || (mRestoreMode != GeckoAppShell.RESTORE_NONE));
 
         // Start migrating as early as possible, can do this in
         // parallel with Gecko load.
         checkMigrateProfile();
 
         Uri data = intent.getData();
         if (data != null && "http".equals(data.getScheme()) &&
             isHostOnPrefetchWhitelist(data.getHost())) {
@@ -1604,17 +1603,17 @@ abstract public class GeckoApp
             // We're going to handle this uri with the redirector, so setting
             // the action to MAIN and clearing the uri data prevents us from
             // loading it twice
             intent.setAction(Intent.ACTION_MAIN);
             intent.setData(null);
             passedUri = "about:empty";
         }
 
-        sGeckoThread = new GeckoThread(intent, passedUri, mRestoreSession);
+        sGeckoThread = new GeckoThread(intent, passedUri, mRestoreMode);
         if (!ACTION_DEBUG.equals(action) &&
             checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched)) {
             sGeckoThread.start();
         } else if (ACTION_DEBUG.equals(action) &&
             checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitForDebugger)) {
             mMainHandler.postDelayed(new Runnable() {
                 public void run() {
                     Log.i(LOGTAG, "Launching from debug intent after 5s wait");
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -116,16 +116,20 @@ public class GeckoAppShell
 
     public static final String SHORTCUT_TYPE_WEBAPP = "webapp";
     public static final String SHORTCUT_TYPE_BOOKMARK = "bookmark";
 
     static public final int SCREENSHOT_THUMBNAIL = 0;
     static public final int SCREENSHOT_WHOLE_PAGE = 1;
     static public final int SCREENSHOT_UPDATE = 2;
 
+    static public final int RESTORE_NONE = 0;
+    static public final int RESTORE_OOM = 1;
+    static public final int RESTORE_CRASH = 2;
+
     static private File sCacheFile = null;
     static private int sFreeSpace = -1;
     static File sHomeDir = null;
     static private int sDensityDpi = 0;
     private static Boolean sSQLiteLibsLoaded = false;
     private static Boolean sNSSLibsLoaded = false;
     private static Boolean sLibsSetup = false;
     private static File sGREDir = null;
@@ -453,17 +457,17 @@ public class GeckoAppShell
             DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
 
             GeckoAppShell.putenv("LOCALE_DECIMAL_POINT=" + dfs.getDecimalSeparator());
             GeckoAppShell.putenv("LOCALE_THOUSANDS_SEP=" + dfs.getGroupingSeparator());
             GeckoAppShell.putenv("LOCALE_GROUPING=" + (char)df.getGroupingSize());
         }
     }
 
-    public static void runGecko(String apkPath, String args, String url, String type, boolean restoreSession) {
+    public static void runGecko(String apkPath, String args, String url, String type, int restoreMode) {
         Looper.prepare();
         sGeckoHandler = new Handler();
         
         // run gecko -- it will spawn its own thread
         GeckoAppShell.nativeInit();
 
         Log.i(LOGTAG, "post native init");
 
@@ -475,18 +479,18 @@ public class GeckoAppShell
         // First argument is the .apk path
         String combinedArgs = apkPath + " -greomni " + apkPath;
         if (args != null)
             combinedArgs += " " + args;
         if (url != null)
             combinedArgs += " -url " + url;
         if (type != null)
             combinedArgs += " " + type;
-        if (restoreSession)
-            combinedArgs += " -restoresession";
+        if (restoreMode != RESTORE_NONE)
+            combinedArgs += " -restoremode " + restoreMode;
 
         DisplayMetrics metrics = new DisplayMetrics();
         GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
         combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels;
 
         GeckoApp.mAppContext.runOnUiThread(new Runnable() {
                 public void run() {
                     geckoLoaded();
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -51,22 +51,22 @@ import java.io.StringWriter;
 import java.util.Date;
 import java.util.Locale;
 
 public class GeckoThread extends Thread {
     private static final String LOGTAG = "GeckoThread";
 
     Intent mIntent;
     String mUri;
-    boolean mRestoreSession;
+    int mRestoreMode;
 
-    GeckoThread (Intent intent, String uri, boolean restoreSession) {
+    GeckoThread(Intent intent, String uri, int restoreMode) {
         mIntent = intent;
         mUri = uri;
-        mRestoreSession = restoreSession;
+        mRestoreMode = restoreMode;
     }
 
     public void run() {
         final GeckoApp app = GeckoApp.mAppContext;
         File cacheFile = GeckoAppShell.getCacheDir(app);
         File libxulFile = new File(cacheFile, "libxul.so");
 
         if ((!libxulFile.exists() ||
@@ -108,11 +108,11 @@ public class GeckoThread extends Thread 
                       null;
 
         // and then fire us up
         Log.i(LOGTAG, "RunGecko - URI = " + mUri);
         GeckoAppShell.runGecko(app.getApplication().getPackageResourcePath(),
                                mIntent.getStringExtra("args"),
                                mUri,
                                type,
-                               mRestoreSession);
+                               mRestoreMode);
     }
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -245,23 +245,23 @@ var BrowserApp = {
 
     // Init LoginManager
     Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
     // Init FormHistory
     Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
     let loadParams = {};
     let url = "about:home";
-    let forceRestore = false;
+    let restoreMode = 0;
     let pinned = false;
     if ("arguments" in window) {
       if (window.arguments[0])
         url = window.arguments[0];
       if (window.arguments[1])
-        forceRestore = window.arguments[1];
+        restoreMode = window.arguments[1];
       if (window.arguments[2])
         gScreenWidth = window.arguments[2];
       if (window.arguments[3])
         gScreenHeight = window.arguments[3];
       if (window.arguments[4])
         pinned = window.arguments[4];
     }
 
@@ -271,19 +271,22 @@ 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);
 
-    // restore the previous session
+    // Restore the previous session
+    // restoreMode = 0 means no restore
+    // restoreMode = 1 means force restore (after an OOM kill)
+    // restoreMode = 2 means restore only if we haven't crashed multiple times
     let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-    if (forceRestore || ss.shouldRestore()) {
+    if (restoreMode || ss.shouldRestore()) {
       // A restored tab should not be active if we are loading a URL
       let restoreToFront = false;
 
       sendMessageToJava({
         gecko: {
           type: "Session:RestoreBegin"
         }
       });
@@ -313,17 +316,17 @@ var BrowserApp = {
               type: "Session:RestoreEnd"
             }
           });
         }
       };
       Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
 
       // Start the restore
-      ss.restoreLastSession(restoreToFront, forceRestore);
+      ss.restoreLastSession(restoreToFront, restoreMode == 1);
     } else {
       loadParams.showProgress = (url != "about:home");
       loadParams.pinned = pinned;
       this.addTab(url, loadParams);
 
       // show telemetry door hanger if we aren't restoring a session
       this._showTelemetryPrompt();
     }
--- a/mobile/android/components/BrowserCLH.js
+++ b/mobile/android/components/BrowserCLH.js
@@ -8,32 +8,32 @@ Cu.import("resource://gre/modules/Servic
 
 function dump(a) {
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
 }
 
 function openWindow(aParent, aURL, aTarget, aFeatures, aArgs) {
   let argsArray = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
   let urlString = null;
-  let restoreSessionBool = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
+  let restoreModeInt = Cc["@mozilla.org/supports-PRInt32;1"].createInstance(Ci.nsISupportsPRInt32);
   let pinnedBool = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
   let widthInt = Cc["@mozilla.org/supports-PRInt32;1"].createInstance(Ci.nsISupportsPRInt32);
   let heightInt = Cc["@mozilla.org/supports-PRInt32;1"].createInstance(Ci.nsISupportsPRInt32);
 
   if ("url" in aArgs) {
     urlString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
     urlString.data = aArgs.url;
   }
-  restoreSessionBool.data = "restoreSession" in aArgs ? aArgs.restoreSession : false;
+  restoreModeInt.data = "restoreMode" in aArgs ? aArgs.restoreMode : 0;
   widthInt.data = "width" in aArgs ? aArgs.width : 1;
   heightInt.data = "height" in aArgs ? aArgs.height : 1;
   pinnedBool.data = "pinned" in aArgs ? aArgs.pinned : false;
 
   argsArray.AppendElement(urlString, false);
-  argsArray.AppendElement(restoreSessionBool, false);
+  argsArray.AppendElement(restoreModeInt, false);
   argsArray.AppendElement(widthInt, false);
   argsArray.AppendElement(heightInt, false);
   argsArray.AppendElement(pinnedBool, false);
   return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argsArray);
 }
 
 
 function resolveURIInternal(aCmdLine, aArgument) {
@@ -53,29 +53,29 @@ function resolveURIInternal(aCmdLine, aA
 
 function BrowserCLH() {}
 
 BrowserCLH.prototype = {
   handle: function fs_handle(aCmdLine) {
     let openURL = "about:home";
     let pinned = false;
 
-    let restoreSession = false;
+    let restoreMode = 0;
     let width = 1;
     let height = 1;
 
     try {
       openURL = aCmdLine.handleFlagWithParam("url", false);
     } catch (e) { /* Optional */ }
     try {
       pinned = aCmdLine.handleFlag("webapp", false);
     } catch (e) { /* Optional */ }
 
     try {
-      restoreSession = aCmdLine.handleFlag("restoresession", false);
+      restoreMode = aCmdLine.handleFlagWithParam("restoremode", false);
     } catch (e) { /* Optional */ }
     try {
       width = aCmdLine.handleFlagWithParam("width", false);
     } catch (e) { /* Optional */ }
     try {
       height = aCmdLine.handleFlagWithParam("height", false);
     } catch (e) { /* Optional */ }
 
@@ -86,17 +86,17 @@ BrowserCLH.prototype = {
 
       let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
       if (browserWin) {
         let whereFlags = pinned ? Ci.nsIBrowserDOMWindow.OPEN_SWITCHTAB : Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
         browserWin.browserDOMWindow.openURI(uri, null, whereFlags, Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
       } else {
         let args = {
           url: openURL,
-          restoreSession: restoreSession,
+          restoreMode: restoreMode,
           pinned: pinned,
           width: width,
           height: height
         };
         browserWin = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", args);
       }
 
       aCmdLine.preventDefault = true;