Prevent tab switcher from showing obsolete thumbnails

The browser will capture the tab bitmap only after first
visual pixel has been drawn.

Change-Id: Ic9ae344c8ff5b39e5e2a76eaf08ba06bd825aef9
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index d7f389a..9e32f49 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -35,12 +35,11 @@
 import android.widget.RelativeLayout;
 
 import com.android.browser.NavTabScroller.OnRemoveListener;
-import com.android.browser.TabControl.OnThumbnailUpdatedListener;
 
 import java.util.HashMap;
 
 public class NavScreen extends RelativeLayout
-        implements OnClickListener, OnMenuItemClickListener, OnThumbnailUpdatedListener {
+        implements OnClickListener, OnMenuItemClickListener {
 
 
     private final UiController mUiController;
@@ -257,13 +256,4 @@
         }
 
     }
-
-    @Override
-    public void onThumbnailUpdated(Tab t) {
-        View v = mTabViews.get(t);
-        if (v != null) {
-            v.invalidate();
-        }
-    }
-
 }
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index a1cb7b3..d606b79 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -23,10 +23,7 @@
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
 import android.os.Message;
 import android.util.Log;
 import android.view.ActionMode;
@@ -37,12 +34,12 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.DecelerateInterpolator;
-import android.webkit.ValueCallback;
-import org.codeaurora.swe.WebView;
 import android.widget.ImageView;
 
 import com.android.browser.UrlInputView.StateListener;
 
+import org.codeaurora.swe.WebView;
+
 /**
  * Ui for regular phone screen sizes
  */
@@ -250,44 +247,43 @@
     }
 
     void showNavScreen() {
-        WebView webView = getWebView();
-        if (webView != null) {
-            blockEvents();
-            mNavScreenRequested = true;
+        blockEvents();
+        mNavScreenRequested = true;
+        mTabControl.setOnThumbnailUpdatedListener(
+                new TabControl.OnThumbnailUpdatedListener() {
+                    @Override
+                    public void onThumbnailUpdated(Tab t) {
+                        mTabControl.setOnThumbnailUpdatedListener(null);
 
-            //To conserve memory, get a scaled down version of the screen and
-            //scale back up to full size
-            //0.25 uses 16 times less memory than the full size
-            final float downscaleRatio = 0.25f;
-            final float upscaleRatio = 1/downscaleRatio;
-            webView.getContentBitmapAsync(
-                    downscaleRatio,
-                    new Rect(),
-                    new ValueCallback<Bitmap>() {
-                        @Override
-                        public void onReceiveValue(Bitmap bm) {
-                            // Discard the callback if the req is interrupted
-                            if (!mNavScreenRequested) {
-                                unblockEvents();
-                                return;
-                            }
-
-                            Bitmap sbm = bm;
-                            if (bm != null) {
-                                //Upscale the low-res bitmap to the needed size
-                                sbm = Bitmap.createBitmap((int) upscaleRatio * bm.getWidth(),
-                                        (int) upscaleRatio * bm.getHeight(), Bitmap.Config.RGB_565);
-                                Canvas canvas = new Canvas(sbm);
-                                Matrix m = new Matrix();
-                                m.setScale(upscaleRatio, upscaleRatio, 0.0f, 0.0f);
-                                canvas.drawBitmap(bm, m, new Paint(Paint.FILTER_BITMAP_FLAG));
-                            }
-
-                            onShowNavScreenContinue(sbm);
+                        // Discard the callback if the req is interrupted
+                        if (!mNavScreenRequested) {
+                            unblockEvents();
+                            return;
                         }
+
+                        Bitmap bm = t.getScreenshot();
+                        Bitmap sbm;
+                        WebView webView = getWebView();
+                        if (webView != null) {
+                            int view_width = webView.getWidth();
+                            int capture_width = mActivity.getResources().getDimensionPixelSize(
+                                    R.dimen.tab_thumbnail_width);
+
+                            float scale =  (float) view_width / capture_width;
+
+                            //Upscale the low-res bitmap to the needed size
+                            Matrix m = new Matrix();
+                            m.postScale(scale, scale);
+                            sbm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
+                                    bm.getHeight(), m, false);
+                        } else {
+                            sbm = bm;
+                        }
+
+                        onShowNavScreenContinue(sbm);
                     }
-            );
-        }
+                });
+        mActiveTab.capture();
     }
 
     void onShowNavScreenContinue(Bitmap viewportBitmap) {
@@ -302,7 +298,6 @@
             mNavScreen.setAlpha(1f);
             mNavScreen.refreshAdapter();
         }
-        mActiveTab.capture();
         if (mAnimScreen == null) {
             mAnimScreen = new AnimScreen(mActivity);
         } else {
@@ -369,7 +364,6 @@
         if (showingNavScreen()) {
             // notify accessibility manager about the screen change
             mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-            mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
         }
     }
 
@@ -517,7 +511,6 @@
     }
 
     private void finishAnimateOut() {
-        mTabControl.setOnThumbnailUpdatedListener(null);
         mNavScreen.setVisibility(View.GONE);
         mCustomViewContainer.setAlpha(1f);
         mCustomViewContainer.setVisibility(View.GONE);
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index fa6e372..107ab07 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -166,6 +166,7 @@
     private boolean mInPageLoad;
     private boolean mPageFinished;
     private boolean mDisableOverrideUrlLoading;
+    private boolean mFirstVisualPixelPainted = false;
     // The last reported progress of the current page
     private int mPageLoadProgress;
     // The time the load started, used to find load page time
@@ -374,6 +375,7 @@
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             mInPageLoad = true;
             mPageFinished = false;
+            mFirstVisualPixelPainted = false;
             mReceivedError = false;
             mUpdateThumbnail = true;
             mPageLoadProgress = INITIAL_PROGRESS;
@@ -412,6 +414,11 @@
             mWebViewController.onPageFinished(Tab.this);
         }
 
+        @Override
+        public void onFirstVisualPixel(WebView view) {
+            mFirstVisualPixelPainted = true;
+        }
+
         // return true if want to hijack the url to let another app to handle it
         @Override
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
@@ -2068,6 +2075,26 @@
             return;
         }
 
+        if (!mFirstVisualPixelPainted) {
+            mCapture = Bitmap.createBitmap(
+                    mCaptureWidth,
+                    mCaptureHeight,
+                    Bitmap.Config.RGB_565);
+            mCapture.eraseColor(Color.WHITE);
+
+            mHandler.removeMessages(MSG_CAPTURE);
+
+            TabControl tc = mWebViewController.getTabControl();
+            if (tc != null) {
+                OnThumbnailUpdatedListener updateListener
+                        = tc.getOnThumbnailUpdatedListener();
+                if (updateListener != null) {
+                    updateListener.onThumbnailUpdated(this);
+                }
+            }
+            return;
+        }
+
         mMainView
             .getContentBitmapAsync(
                  (float) mCaptureWidth / mMainView.getWidth(),