Bug 697858 - Save restore state in bundle [r=mfinkle]
authorBrian Nicholson <bnicholson@mozilla.com>
Mon, 09 Jan 2012 11:09:53 -0800
changeset 85275 af32a0da45c9adef1d8e87210d20d6d8a2ec9eba
parent 85274 c2a85ff814c8610749529195916d968a257d04f3
child 85276 05dfaf51fa8369eb04a2f50afd4035f11c04ea70
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs697858
milestone12.0a1
Bug 697858 - Save restore state in bundle [r=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
@@ -97,16 +97,17 @@ 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 SAVED_STATE_URI      = "uri";
     public static final String SAVED_STATE_TITLE    = "title";
     public static final String SAVED_STATE_VIEWPORT = "viewport";
     public static final String SAVED_STATE_SCREEN   = "screen";
+    public static final String SAVED_STATE_SESSION  = "session";
 
     private LinearLayout mMainLayout;
     private RelativeLayout mGeckoLayout;
     public static SurfaceView cameraView;
     public static GeckoApp mAppContext;
     public static boolean mFullScreen = false;
     public static File sGREDir = null;
     public static Menu sMenu;
@@ -136,16 +137,17 @@ abstract public class GeckoApp
     private AboutHomeContent mAboutHomeContent;
     private static AbsoluteLayout mPluginContainer;
 
     public String mLastUri;
     public String mLastTitle;
     public String mLastViewport;
     public byte[] mLastScreen;
     public int mOwnActivityDepth = 0;
+    private boolean mRestoreSession = false;
 
     private Vector<View> mPluginViews = new Vector<View>();
 
     public interface OnTabsChangedListener {
         public void onTabsChanged(Tab tab);
     }
     
     private static ArrayList<OnTabsChangedListener> mTabsChangedListeners;
@@ -570,16 +572,17 @@ abstract public class GeckoApp
             outState = new Bundle();
 
         new SessionSnapshotRunnable(null).run();
 
         outState.putString(SAVED_STATE_URI, mLastUri);
         outState.putString(SAVED_STATE_TITLE, mLastTitle);
         outState.putString(SAVED_STATE_VIEWPORT, mLastViewport);
         outState.putByteArray(SAVED_STATE_SCREEN, mLastScreen);
+        outState.putBoolean(SAVED_STATE_SESSION, true);
     }
 
     public class SessionSnapshotRunnable implements Runnable {
         Tab mThumbnailTab;
         SessionSnapshotRunnable(Tab thumbnailTab) {
             mThumbnailTab = thumbnailTab;
         }
 
@@ -1420,16 +1423,17 @@ abstract public class GeckoApp
         System.loadLibrary("mozutils");
         mMainHandler = new Handler();
         Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - onCreate");
         if (savedInstanceState != null) {
             mLastUri = savedInstanceState.getString(SAVED_STATE_URI);
             mLastTitle = savedInstanceState.getString(SAVED_STATE_TITLE);
             mLastViewport = savedInstanceState.getString(SAVED_STATE_VIEWPORT);
             mLastScreen = savedInstanceState.getByteArray(SAVED_STATE_SCREEN);
+            mRestoreSession = savedInstanceState.getBoolean(SAVED_STATE_SESSION);
         }
 
         Intent intent = getIntent();
         String args = intent.getStringExtra("args");
         if (args != null && args.contains("-profile")) {
             Pattern p = Pattern.compile("(?:-profile\\s*)(\\w*)(\\s*)");
             Matcher m = p.matcher(args);
             if (m.find()) {
@@ -1455,17 +1459,17 @@ abstract public class GeckoApp
 
         mAppContext = this;
 
         if (sGREDir == null)
             sGREDir = new File(this.getApplicationInfo().dataDir);
 
         prefetchDNS(intent.getData());
 
-        sGeckoThread = new GeckoThread(intent, mLastUri, mLastTitle);
+        sGeckoThread = new GeckoThread(intent, mLastUri, mLastTitle, mRestoreSession);
         if (!ACTION_DEBUG.equals(intent.getAction()) &&
             checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched))
             sGeckoThread.start();
 
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.gecko_app);
 
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -412,17 +412,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) {
+    public static void runGecko(String apkPath, String args, String url, boolean restoreSession) {
         // run gecko -- it will spawn its own thread
         GeckoAppShell.nativeInit();
 
         Log.i(LOGTAG, "post native init");
 
         // If we have direct texture available, use it
         if (GeckoAppShell.testDirectTexture()) {
             Log.i(LOGTAG, "Using direct texture for widget layer");
@@ -437,16 +437,18 @@ public class GeckoAppShell
         Log.i(LOGTAG, "setSoftwareLayerClient called");
 
         // First argument is the .apk path
         String combinedArgs = apkPath + " -greomni " + apkPath;
         if (args != null)
             combinedArgs += " " + args;
         if (url != null)
             combinedArgs += " -remote " + url;
+        if (restoreSession)
+            combinedArgs += " -restoresession";
 
         GeckoApp.mAppContext.runOnUiThread(new Runnable() {
                 public void run() {
                     geckoLoaded();
                 }
             });
 
         // and go
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -50,21 +50,23 @@ import java.util.Date;
 import java.util.Locale;
 
 public class GeckoThread extends Thread {
     private static final String LOGTAG = "GeckoThread";
 
     Intent mIntent;
     String mUri;
     String mTitle;
+    boolean mRestoreSession;
 
-    GeckoThread (Intent intent, String uri, String title) {
+    GeckoThread (Intent intent, String uri, String title, boolean restoreSession) {
         mIntent = intent;
         mUri = uri;
         mTitle = title;
+        mRestoreSession = restoreSession;
     }
 
     public void run() {
         final GeckoApp app = GeckoApp.mAppContext;
         File cacheFile = GeckoAppShell.getCacheDir();
         File libxulFile = new File(cacheFile, "libxul.so");
 
         if ((!libxulFile.exists() ||
@@ -101,17 +103,18 @@ public class GeckoThread extends Thread 
                 app.mBrowserToolbar.setTitle(mTitle);
             }
         });
         try {
             Log.w(LOGTAG, "RunGecko - URI = " + mUri);
 
             GeckoAppShell.runGecko(app.getApplication().getPackageResourcePath(),
                                    mIntent.getStringExtra("args"),
-                                   mUri);
+                                   mUri,
+                                   mRestoreSession);
         } catch (Exception e) {
             Log.e(LOGTAG, "top level exception", e);
             StringWriter sw = new StringWriter();
             PrintWriter pw = new PrintWriter(sw);
             e.printStackTrace(pw);
             pw.flush();
             GeckoAppShell.reportJavaCrash(sw.toString());
         }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -257,30 +257,35 @@ var BrowserApp = {
     PermissionsHelper.init();
 
     // Init LoginManager
     Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
     // Init FormHistory
     Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
     let url = "about:home";
-    if ("arguments" in window && window.arguments[0])
-      url = window.arguments[0];
+    let restoreSession = false;
+    if ("arguments" in window) {
+      if (window.arguments[0])
+        uri = window.arguments[0];
+      if (window.arguments[1])
+        restoreSession = window.arguments[1];
+    }
 
     // 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
     let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-    if (ss.shouldRestore()) {
+    if (restoreSession || ss.shouldRestore()) {
       // A restored tab should not be active if we are loading a URL
       let restoreToFront = false;
 
       // Open any commandline URLs, except the homepage
       if (url && url != "about:home") {
         this.addTab(url);
       } else {
         // Let the session make a restored tab active
--- a/mobile/android/components/BrowserCLH.js
+++ b/mobile/android/components/BrowserCLH.js
@@ -6,23 +6,29 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 
 
 function dump(a) {
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
 }
 
 function openWindow(aParent, aURL, aTarget, aFeatures, aArgs) {
-  let argString = null;
-  if (aArgs && !(aArgs instanceof Ci.nsISupportsArray)) {
-    argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
-    argString.data = 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);
+
+  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;
 
-  return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argString || aArgs);
+  argsArray.AppendElement(urlString, false);
+  argsArray.AppendElement(restoreSessionBool, false);
+  return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argsArray);
 }
 
 
 function resolveURIInternal(aCmdLine, aArgument) {
   let uri = aCmdLine.resolveURI(aArgument);
   if (uri)
     return uri;
 
@@ -36,30 +42,38 @@ function resolveURIInternal(aCmdLine, aA
   return uri;
 }
 
 function BrowserCLH() {}
 
 BrowserCLH.prototype = {
   handle: function fs_handle(aCmdLine) {
     let urlParam = "about:home";
+    let restoreSession = false;
     try {
-        urlParam = aCmdLine.handleFlagWithParam("remote", false);
+      urlParam = aCmdLine.handleFlagWithParam("remote", false);
+    } catch (e) { /* Optional */ }
+    try {
+      restoreSession = aCmdLine.handleFlag("restoresession", false);
     } catch (e) { /* Optional */ }
 
     try {
       let uri = resolveURIInternal(aCmdLine, urlParam);
       if (!uri)
         return;
 
       let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
       if (browserWin) {
         browserWin.browserDOMWindow.openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
       } else {
-        browserWin = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", urlParam);
+        let args = {
+          url: urlParam,
+          restoreSession: restoreSession
+        };
+        browserWin = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", args);
       }
 
       aCmdLine.preventDefault = true;
     } catch (x) {
       dump("BrowserCLH.handle: " + x);
     }
   },