Bug 697858 - Save restore state in bundle. r=mfinkle
authorBrian Nicholson <bnicholson@mozilla.com>
Mon, 09 Jan 2012 11:09:53 -0800
changeset 84244 03d77ca70f27554ea955e1e2cdd3201a623a2620
parent 84243 cee13e0b2ee4453596c39da411818f2f699d45a9
child 84245 5461d5635ca9258401f96ea856217f00d30fab1d
push id21832
push userbmo@edmorley.co.uk
push dateWed, 11 Jan 2012 17:04:15 +0000
treeherdermozilla-central@40c9f9ff9fd5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs697858
milestone12.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 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;
         }
 
@@ -1422,16 +1425,17 @@ abstract public class GeckoApp
         System.loadLibrary("mozglue");
         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()) {
@@ -1457,17 +1461,17 @@ abstract public class GeckoApp
 
         mAppContext = this;
 
         if (sGREDir == null)
             sGREDir = new File(this.getApplicationInfo().dataDir);
 
         prefetchDNS(intent.getData());
 
-        sGeckoThread = new GeckoThread(intent, mLastUri);
+        sGeckoThread = new GeckoThread(intent, mLastUri, 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
@@ -414,17 +414,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");
@@ -439,16 +439,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
@@ -49,20 +49,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;
 
-    GeckoThread (Intent intent, String uri) {
+    GeckoThread (Intent intent, String uri, boolean restoreSession) {
         mIntent = intent;
         mUri = uri;
+        mRestoreSession = restoreSession;
     }
 
     public void run() {
         final GeckoApp app = GeckoApp.mAppContext;
         File cacheFile = GeckoAppShell.getCacheDir();
         File libxulFile = new File(cacheFile, "libxul.so");
 
         if ((!libxulFile.exists() ||
@@ -93,17 +95,18 @@ public class GeckoThread extends Thread 
         Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - runGecko");
 
         // and then fire us up
         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])
+        url = 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);
     }
   },