Bug 695836 - sync last screen and last uri preference. r=mfinkle
authorDoug Turner <dougt@dougt.org>
Sun, 23 Oct 2011 21:11:29 -0700
changeset 83227 45c91268cfee6f300edfee2b79071492bddcadec
parent 83226 d80bb047fca26926ac8b19e0d87eecc784526a69
child 83228 1b7748fbdf19a6364e4440d8506e8b5fbde2defd
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs695836
milestone10.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 695836 - sync last screen and last uri preference. r=mfinkle
embedding/android/GeckoApp.java
embedding/android/GeckoSurfaceView.java
mobile/chrome/content/browser.js
mobile/components/BrowserCLH.js
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -63,16 +63,17 @@ import android.hardware.*;
 
 import android.util.*;
 import android.net.*;
 import android.database.*;
 import android.database.sqlite.*;
 import android.provider.*;
 import android.content.pm.*;
 import android.content.pm.PackageManager.*;
+import android.content.SharedPreferences.*;
 import dalvik.system.*;
 
 abstract public class GeckoApp
     extends Activity
 {
     private static final String LOG_FILE_NAME     = "GeckoApp";
 
     public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK";
@@ -330,19 +331,34 @@ abstract public class GeckoApp
                 config.locale = locale;
                 res.updateConfiguration(config, res.getDisplayMetrics());
 
                 Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - runGecko");
 
                 // and then fire us up
                 try {
                     String env = intent.getStringExtra("env0");
+                    String uri = intent.getDataString();
+                    if (uri == null || uri.equals(""))
+                        uri = getLastUri();
+                    if (uri == null)
+                        uri = "";
+
+                    final String awesomeURI = uri; 
+                    mMainHandler.post(new Runnable() {
+                      public void run() {
+                        mBrowserToolbar.setTitle(awesomeURI);
+                      }
+                    });
+
+                    Log.w(LOGTAG, "RunGecko - URI = " + uri);
+
                     GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
                                            intent.getStringExtra("args"),
-                                           intent.getDataString());
+                                           uri);
                 } catch (Exception e) {
                     Log.e(LOG_FILE_NAME, "top level exception", e);
                     StringWriter sw = new StringWriter();
                     e.printStackTrace(new PrintWriter(sw));
                     GeckoAppShell.reportJavaCrash(sw.toString());
                 }
                 return null;
             }
@@ -397,20 +413,56 @@ abstract public class GeckoApp
                showTabsIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
                startActivityForResult(showTabsIntent, SHOW_TABS_REQUEST);
                return true;
            default:
                return super.onOptionsItemSelected(item);
         }
     }
 
+    private void rememberLastScreen(boolean sync) {
+        if (surfaceView == null)
+            return;
+        Tab tab = Tabs.getInstance().getSelectedTab();
+        if (!tab.getHistory().empty()) {
+            SharedPreferences prefs = getSharedPreferences("GeckoApp", 0);
+            Editor editor = prefs.edit();
+            
+            String uri = tab.getHistory().peek().mUri;
+            String title = tab.getHistory().peek().mTitle;
+
+            editor.putString("last-uri", uri);
+            editor.putString("last-title", title);
+
+            Log.i(LOG_FILE_NAME, "Saving:: " + uri + " " + title);
+            editor.commit();
+            surfaceView.saveLast(sync);
+        }
+    }
+
+    private String getLastUri() {
+        SharedPreferences prefs = getSharedPreferences("GeckoApp", 0);
+        String lastUri = prefs.getString("last-uri", "");
+        return lastUri;
+    }
+
+    private boolean restoreLastScreen() {
+        SharedPreferences prefs = getSharedPreferences ("GeckoApp", 0);
+        String lastUri = prefs.getString("last-uri", "");
+        String lastTitle = prefs.getString("last-title", "");
+
+        Log.i(LOG_FILE_NAME, "The last uri was: " + lastUri);
+        Log.i(LOG_FILE_NAME, "The last title was: " + lastTitle);
+        
+        return true;
+    }
+
     private void quit() {
         Log.i(LOG_FILE_NAME, "pleaseKillMe");
-        if (surfaceView != null)
-            surfaceView.saveLast(true);
+        rememberLastScreen(true);
         GeckoAppShell.nativeQuit();
         finish();
     }
 
     void handleLocationChange(final int tabId, final String uri) {
         Tab tab = Tabs.getInstance().getTab(tabId);
         if (tab != null)
             tab.updateURL(uri);
--- a/embedding/android/GeckoSurfaceView.java
+++ b/embedding/android/GeckoSurfaceView.java
@@ -108,29 +108,42 @@ class GeckoSurfaceView
 
     public String getStartupBitmapFilePath() {
         File file = new File(Environment.getExternalStorageDirectory(),
                              "lastScreen.png");
         return file.toString();
     }
 
     public void hideStartupBitmap() {
+        Log.e(LOG_FILE_NAME, "!!! hideStartupBitmap !!!");
+        if (mShowingLoadScreen == false)
+            return;
+
+        mStartupBitmap = null;
         mShowingLoadScreen = false;
+
+        surfaceCreated(getHolder());
         surfaceChanged(getHolder(), mFormat, mWidth, mHeight);
     }
 
+    public void showStartupBitmap() {
+        Log.e(LOG_FILE_NAME, "!!! showStartupBitmap !!!");
+        mShowingLoadScreen = true;
+    }
+
     public void loadStartupBitmap() {
-        new Thread(new Runnable() {
-                public void run() {
-                    String filePath = getStartupBitmapFilePath();
-                    mStartupBitmap = BitmapFactory.decodeFile(filePath);
-                }}).start();
+        // This is blocking on the main thread and that is
+        // okay.  we want to get this image in as soon as
+        // possible so that we can paint it to the screen.
+        String filePath = getStartupBitmapFilePath();
+        mStartupBitmap = BitmapFactory.decodeFile(filePath);
     }
 
     public void drawStartupBitmap(SurfaceHolder holder, int width, int height) {
+        Log.e(LOG_FILE_NAME, "!!! drawStartupBitmap !!!");
 
         Canvas c = holder.lockCanvas();
         if (c == null) {
             Log.e(LOG_FILE_NAME, "!!! NO CANVAS !!!");
             return;
         }
 
         if (mStartupBitmap == null) {
@@ -145,51 +158,55 @@ class GeckoSurfaceView
             Drawable drawable = new BitmapDrawable(mStartupBitmap);
             drawable.setBounds(0, 0, width, height);
             drawable.draw(c);
         }
         holder.unlockCanvasAndPost(c);
     }
 
     public void draw(SurfaceHolder holder, ByteBuffer buffer) {
+        Log.e(LOG_FILE_NAME, "!!! draw1 !!!");
+
         if (buffer == null || buffer.capacity() != (mWidth * mHeight * 2))
             return;
 
         synchronized (mSoftwareBuffer) {
             if (buffer != mSoftwareBuffer || mSoftwareBufferCopy == null)
                 return;
 
             Canvas c = holder.lockCanvas();
             if (c == null)
                 return;
             mSoftwareBufferCopy.copyPixelsFromBuffer(buffer);
-            c.drawBitmap(mLastBitmap = mSoftwareBufferCopy, 0, 0, null);
+            c.drawBitmap(mSoftwareBufferCopy, 0, 0, null);
             holder.unlockCanvasAndPost(c);
         }
     }
 
     public void draw(SurfaceHolder holder, Bitmap bitmap) {
+        Log.e(LOG_FILE_NAME, "!!! draw2 !!!");
+
         if (bitmap == null ||
             bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight)
             return;
 
         synchronized (mSoftwareBitmap) {
             if (bitmap != mSoftwareBitmap)
                 return;
 
             Canvas c = holder.lockCanvas();
             if (c == null)
                 return;
-            c.drawBitmap(mLastBitmap = bitmap, 0, 0, null);
+            c.drawBitmap(bitmap, 0, 0, null);
             holder.unlockCanvasAndPost(c);
         }
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
+        Log.i(LOG_FILE_NAME, "!!! surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
 
         mFormat = format;
         mWidth = width;
         mHeight = height;
 
         if (mShowingLoadScreen) {
             drawStartupBitmap(holder, width, height);
             return;
@@ -215,17 +232,17 @@ class GeckoSurfaceView
             GeckoAppShell.geckoEventSync();
             mDrawSingleFrame = false;
             mAbortDraw = false;
         }
 
         mSurfaceLock.lock();
 
         if (mInDrawing) {
-            Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!");
+            Log.w(LOG_FILE_NAME, "!! surfaceChanged while mInDrawing is true!");
         }
 
         boolean invalidSize;
 
         if (width == 0 || height == 0) {
             mSoftwareBitmap = null;
             mSoftwareBuffer = null;
             mSoftwareBufferCopy = null;
@@ -237,17 +254,17 @@ class GeckoSurfaceView
         boolean doSyncDraw =
             mDrawMode == DRAW_2D &&
             !invalidSize &&
             GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
         mSyncDraw = doSyncDraw;
 
         mSurfaceValid = true;
 
-        Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
+        Log.i(LOG_FILE_NAME, "!! surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
 
         try {
             DisplayMetrics metrics = new DisplayMetrics();
             GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
 
             GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height,
                                           metrics.widthPixels, metrics.heightPixels);
             GeckoAppShell.sendEventToGecko(e);
@@ -257,61 +274,64 @@ class GeckoSurfaceView
 
         if (doSyncDraw) {
             GeckoAppShell.scheduleRedraw();
 
             Object syncDrawObject = null;
             try {
                 syncDrawObject = mSyncDraws.take();
             } catch (InterruptedException ie) {
-                Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie);
+                Log.e(LOG_FILE_NAME, "!! Threw exception while getting sync draw bitmap/buffer: ", ie);
             }
             if (syncDrawObject != null) {
                 if (syncDrawObject instanceof Bitmap)
                     draw(holder, (Bitmap)syncDrawObject);
                 else
                     draw(holder, (ByteBuffer)syncDrawObject);
             } else {
-                Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null");
+                Log.e(LOG_FILE_NAME, "!! Synchronised draw object is null");
             }
         } else if (!mShowingLoadScreen) {
             // Make sure a frame is drawn before we return
             // otherwise we see artifacts or a black screen
             GeckoAppShell.scheduleRedraw();
             GeckoAppShell.geckoEventSync();
         }
     }
 
     public void surfaceCreated(SurfaceHolder holder) {
-        Log.i(LOG_FILE_NAME, "surface created");
-        GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED);
-        GeckoAppShell.sendEventToGecko(e);
+        // Delay sending this event if we are painting the
+        // load screen.  The native access paint path will
+        // paint directly to the screen and we will see a
+        // black screen while content is initally being
+        // drawn.
+        if (!mShowingLoadScreen) {
+            Log.i(LOG_FILE_NAME, "!! surface created");
+            GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED);
+            GeckoAppShell.sendEventToGecko(e);
+        }
     }
 
     public void saveLast(boolean sync) {
-        Log.i(LOG_FILE_NAME, "save last");
+        Log.i(LOG_FILE_NAME, "!! save last");
         GeckoEvent event = new GeckoEvent();
         event.mType = GeckoEvent.SAVE_STATE;
         event.mCharacters = getStartupBitmapFilePath();
         if (sync)
             GeckoAppShell.sendEventToGeckoSync(event);
         else
             GeckoAppShell.sendEventToGecko(event);
     }
 
     public void surfaceDestroyed(SurfaceHolder holder) {
-        Log.i(LOG_FILE_NAME, "surface destroyed");
-        saveLast(false);
-        mStartupBitmap = mLastBitmap;
-
+        Log.i(LOG_FILE_NAME, "!! surface destroyed");
         mSurfaceValid = false;
         mSoftwareBuffer = null;
         mSoftwareBufferCopy = null;
         mSoftwareBitmap = null;
-        mLastBitmap = null;
         GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED);
         if (mDrawMode == DRAW_GLES_2) {
             // Ensure GL cleanup occurs before we return.
             GeckoAppShell.sendEventToGeckoSync(e);
         } else {
             GeckoAppShell.sendEventToGecko(e);
         }
     }
@@ -357,20 +377,19 @@ class GeckoSurfaceView
     public static final int DRAW_GLES_2 = 1;
     public static final int DRAW_2D = 2;
     // Drawing is disable when the surface buffer
     // has changed size but we haven't yet processed the
     // resize event.
     public static final int DRAW_DISABLED = 3;
 
     public int beginDrawing() {
-        mStartupBitmap = null;
 
         if (mInDrawing) {
-            Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!");
+            Log.e(LOG_FILE_NAME, "!! Recursive beginDrawing call!");
             return DRAW_ERROR;
         }
 
         // Once we drawn our first frame after resize we can ignore
         // the other draw events until we handle the resize events.
         if (mAbortDraw) {
             return DRAW_DISABLED;
         }
@@ -384,45 +403,45 @@ class GeckoSurfaceView
          * We might not need to hold this lock in between
          * beginDrawing/endDrawing, and might just be able to make
          * surfaceChanged, beginDrawing, and endDrawing synchronized,
          * but this way is safer for now.
          */
         mSurfaceLock.lock();
 
         if (!mSurfaceValid) {
-            Log.e(LOG_FILE_NAME, "Surface not valid");
+            Log.e(LOG_FILE_NAME, "!! Surface not valid");
             mSurfaceLock.unlock();
             return DRAW_ERROR;
         }
 
         mInDrawing = true;
         mDrawMode = DRAW_GLES_2;
         return DRAW_GLES_2;
     }
 
     public void endDrawing() {
         if (!mInDrawing) {
-            Log.e(LOG_FILE_NAME, "endDrawing without beginDrawing!");
+            Log.e(LOG_FILE_NAME, "!! endDrawing without beginDrawing!");
             return;
         }
 
        if (mDrawSingleFrame)
             mAbortDraw = true;
 
         try {
             if (!mSurfaceValid) {
-                Log.e(LOG_FILE_NAME, "endDrawing with false mSurfaceValid");
+                Log.e(LOG_FILE_NAME, "!! endDrawing with false mSurfaceValid");
                 return;
             }
         } finally {
             mInDrawing = false;
 
             if (!mSurfaceLock.isHeldByCurrentThread())
-                Log.e(LOG_FILE_NAME, "endDrawing while mSurfaceLock not held by current thread!");
+                Log.e(LOG_FILE_NAME, "!! endDrawing while mSurfaceLock not held by current thread!");
 
             mSurfaceLock.unlock();
         }
     }
 
     /* How this works:
      * Whenever we want to draw, we want to be sure that we do not lock
      * the canvas unless we're sure we can draw. Locking the canvas clears
@@ -434,47 +453,49 @@ class GeckoSurfaceView
      *
      * Also, never try to lock the canvas while holding the surface lock
      * unless you're in SurfaceChanged, in which case the canvas was already
      * locked. Surface lock -> Canvas lock will lead to AB-BA deadlocks.
      */
     public void draw2D(Bitmap bitmap, int width, int height) {
         // mSurfaceLock ensures that we get mSyncDraw/mSoftwareBitmap/etc.
         // set correctly before determining whether we should do a sync draw
+        Log.e(LOG_FILE_NAME, "!!! draw2d1 !!!");
         mSurfaceLock.lock();
         try {
             if (mSyncDraw) {
                 if (bitmap != mSoftwareBitmap || width != mWidth || height != mHeight)
                     return;
                 mSyncDraw = false;
                 try {
                     mSyncDraws.put(bitmap);
                 } catch (InterruptedException ie) {
-                    Log.e(LOG_FILE_NAME, "Threw exception while getting sync draws queue: ", ie);
+                    Log.e(LOG_FILE_NAME, "!! Threw exception while getting sync draws queue: ", ie);
                 }
                 return;
             }
         } finally {
             mSurfaceLock.unlock();
         }
 
         draw(getHolder(), bitmap);
     }
 
     public void draw2D(ByteBuffer buffer, int stride) {
+        Log.e(LOG_FILE_NAME, "!!! draw2d2 !!!");
         mSurfaceLock.lock();
         try {
             if (mSyncDraw) {
                 if (buffer != mSoftwareBuffer || stride != (mWidth * 2))
                     return;
                 mSyncDraw = false;
                 try {
                     mSyncDraws.put(buffer);
                 } catch (InterruptedException ie) {
-                    Log.e(LOG_FILE_NAME, "Threw exception while getting sync bitmaps queue: ", ie);
+                    Log.e(LOG_FILE_NAME, "!! Threw exception while getting sync bitmaps queue: ", ie);
                 }
                 return;
             }
         } finally {
             mSurfaceLock.unlock();
         }
 
         draw(getHolder(), buffer);
@@ -613,17 +634,17 @@ class GeckoSurfaceView
     }
 
     public void onStatusChanged(String provider, int status, Bundle extras)
     {
     }
 
     // event stuff
     public boolean onTouchEvent(MotionEvent event) {
-        this.requestFocus(FOCUS_UP, null);
+        requestFocus(FOCUS_UP, null);
         GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
         return true;
     }
 
     @Override
     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
         if (event.isSystem())
             return super.onKeyPreIme(keyCode, event);
@@ -784,16 +805,15 @@ class GeckoSurfaceView
     String mIMEActionHint;
     boolean mIMELandscapeFS;
 
     // Software rendering
     Bitmap mSoftwareBitmap;
     ByteBuffer mSoftwareBuffer;
     Bitmap mSoftwareBufferCopy;
     Bitmap mStartupBitmap;
-    Bitmap mLastBitmap;
 
     Geocoder mGeocoder;
     Address  mLastGeoAddress;
 
     final SynchronousQueue<Object> mSyncDraws = new SynchronousQueue<Object>();
 }
 
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -361,27 +361,23 @@ var BrowserEventHandler = {
 
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
       case "DOMContentLoaded": {
         let browser = BrowserApp.getBrowserForDocument(aEvent.target);
         browser.focus();
 
         let tabID = BrowserApp.getTabForBrowser(browser).id;
-        let uri = browser.currentURI.spec;
-
-        dump("Setting Last uri to: " + uri);
-        Services.prefs.setCharPref("browser.last.uri", uri);
 
         sendMessageToJava({
           gecko: {
             type: "DOMContentLoaded",
             tabID: tabID,
             windowID: 0,
-            uri: uri,
+            uri: browser.currentURI.spec,
             title: browser.contentTitle
           }
         });
         break;
       }
 
       case "DOMLinkAdded": {
         let target = aEvent.originalTarget;
--- a/mobile/components/BrowserCLH.js
+++ b/mobile/components/BrowserCLH.js
@@ -1,9 +1,8 @@
-
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 
@@ -23,46 +22,38 @@ function openWindow(aParent, aURL, aTarg
   return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argString || aArgs);
 }
 
 
 function BrowserCLH() {}
 
 BrowserCLH.prototype = {
   handle: function fs_handle(aCmdLine) {
-    dump("fs_handle");
-
-    let urlParam = aCmdLine.handleFlagWithParam("remote", false);
-    if (!urlParam) {
-      urlParam = "about:support";
-      try {
-        urlParam = Services.prefs.getCharPref("browser.last.uri");
-      } catch (e) {};
-    }
+    let urlParam = "about:home";
+    try {
+        urlParam = aCmdLine.handleFlagWithParam("remote", false);
+    } catch (e) { dump("" + e); }
     dump("fs_handle: " + urlParam);
-
     try {
       let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
       let uri = urifixup.createFixupURI(urlParam, 1);
       if (!uri)
         return;
-      dump("fs_handle: " + uri);
 
       let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
       if (browserWin) {
         browserWin.browserDOMWindow.openURI(uri,
                                             null,
                                             Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW,
                                             Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
       } else {
         browserWin = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", urlParam);
       }
 
       aCmdLine.preventDefault = true;
-      dump("fs_handle: done");
     } catch (x) {
       Cc["@mozilla.org/consoleservice;1"]
           .getService(Ci.nsIConsoleService)
           .logStringMessage("fs_handle exception!:  " + x);
     }
   },
 
   // QI