smooth navscreen animation

Change-Id: I87bfba8a18a1aaeffa95d15e4ddb4313dd2752d9
diff --git a/src/com/android/browser/BrowserWebView.java b/src/com/android/browser/BrowserWebView.java
index 6111aa6..9be9ad9 100644
--- a/src/com/android/browser/BrowserWebView.java
+++ b/src/com/android/browser/BrowserWebView.java
@@ -17,6 +17,8 @@
 package com.android.browser;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -34,6 +36,7 @@
     private boolean mBackgroundRemoved = false;
     private boolean mUserInitiated = false;
     private TitleBarBase mTitleBar;
+    private Bitmap mCapture;
 
     /**
      * @param context
@@ -72,6 +75,12 @@
     }
 
     @Override
+    protected void onSizeChanged(int w, int h, int ow, int oh) {
+        super.onSizeChanged(w, h, ow, oh);
+        mCapture = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+    }
+
+    @Override
     protected int getTitleHeight() {
         return (mTitleBar != null) ? mTitleBar.getEmbeddedHeight() : 0;
     }
@@ -138,6 +147,14 @@
         public void onScroll(int visibleTitleHeight, boolean userInitiated);
     }
 
+    protected Bitmap capture() {
+        if (mCapture == null) return null;
+        Canvas c = new Canvas(mCapture);
+        c.translate(-getScrollX(), -(getScrollY() + getVisibleTitleHeight()));
+        onDraw(c);
+        return mCapture;
+    }
+
     @Override
     protected void onDraw(android.graphics.Canvas c) {
         super.onDraw(c);
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index a1fa639..8cc2271 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -34,13 +34,13 @@
 import android.widget.Gallery;
 import android.widget.ImageButton;
 import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
 import android.widget.LinearLayout;
 import android.widget.ListPopupWindow;
 import android.widget.TextView;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Semaphore;
 
 public class NavScreen extends LinearLayout implements OnClickListener {
 
@@ -65,8 +65,7 @@
     int mTabHeight;
     TabAdapter mAdapter;
     ListPopupWindow mPopup;
-
-    boolean mReady;
+    Semaphore mLock;
 
     public NavScreen(Activity activity, UiController ctl, PhoneUi ui) {
         super(activity);
@@ -86,6 +85,30 @@
         requestLayout();
     }
 
+    protected synchronized void startTask(Runnable r) {
+        Thread task = new Thread(r);
+        mLock = new Semaphore(1);
+        try {
+            mLock.acquire();
+        } catch (InterruptedException e) {
+        }
+        task.start();
+    }
+
+    protected synchronized void finishTask() {
+        mLock.release();
+    }
+
+    protected synchronized void waitForTask() {
+        if (mLock != null) {
+            try {
+                mLock.acquire();
+            } catch (InterruptedException e) {
+            }
+        }
+        mLock = null;
+    }
+
     protected void showMenu() {
         Menu menu = mUi.getMenu();
         menu.setGroupVisible(R.id.NAV_MENU, false);
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index f2ace49..b2435a3 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -46,6 +46,7 @@
 
     boolean mExtendedMenuOpen;
     boolean mOptionsMenuOpen;
+    boolean mAnimating;
 
     /**
      * @param browser
@@ -304,8 +305,18 @@
     }
 
     void showNavScreen() {
-        captureTab(mActiveTab);
+        if (mAnimating) return;
+        mAnimating = true;
         mNavScreen = new NavScreen(mActivity, mUiController, this);
+        mNavScreen.startTask(new Runnable() {
+            public void run() {
+                BrowserWebView web = (BrowserWebView) getWebView();
+                if (web != null) {
+                    mActiveTab.setScreenshot(web.capture());
+                }
+                mNavScreen.finishTask();
+            }
+        });
         WebView web = getWebView();
         if (web != null) {
             int w = web.getWidth();
@@ -315,6 +326,7 @@
         }
         // Add the custom view to its container.
         mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_GRAVITY_CENTER);
+        mContentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         ObjectAnimator animx = ObjectAnimator.ofFloat(mContentView,
                 "scaleX", 1.0f, 0.85f);
         ObjectAnimator animy = ObjectAnimator.ofFloat(mContentView,
@@ -325,7 +337,6 @@
 
             @Override
             public void onAnimationCancel(Animator animation) {
-                finishShowNavScreen();
             }
 
             @Override
@@ -347,16 +358,21 @@
 
     private void finishShowNavScreen() {
         // Hide the content view.
+        mContentView.setLayerType(View.LAYER_TYPE_NONE, null);
         mContentView.setVisibility(View.GONE);
         mContentView.setScaleX(1.0f);
         mContentView.setScaleY(1.0f);
+        mNavScreen.waitForTask();
         // Finally show the custom view container.
         mCustomViewContainer.setVisibility(View.VISIBLE);
         mCustomViewContainer.bringToFront();
+        mAnimating = false;
     }
 
     void hideNavScreen(boolean animateToPage) {
-        if (mNavScreen == null) return;
+        if (mAnimating || mNavScreen == null) return;
+        mAnimating = true;
+        mNavScreen.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         if (animateToPage) {
             ObjectAnimator animx = ObjectAnimator.ofFloat(mNavScreen, "scaleX",
                     1.0f, 1.2f);
@@ -368,7 +384,6 @@
 
                 @Override
                 public void onAnimationCancel(Animator animation) {
-                    finishHideNavScreen();
                 }
 
                 @Override
@@ -395,12 +410,14 @@
     private void finishHideNavScreen() {
         // Hide the custom view.
         mNavScreen.setVisibility(View.GONE);
+        mNavScreen.setLayerType(View.LAYER_TYPE_NONE, null);
         // Remove the custom view from its container.
         mCustomViewContainer.removeView(mNavScreen);
         mNavScreen = null;
         mCustomViewContainer.setVisibility(View.GONE);
         // Show the content view.
         mContentView.setVisibility(View.VISIBLE);
+        mAnimating = false;
     }
 
 }
diff --git a/src/com/android/browser/view/TabHolderView.java b/src/com/android/browser/view/TabHolderView.java
new file mode 100644
index 0000000..c5a2b32
--- /dev/null
+++ b/src/com/android/browser/view/TabHolderView.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public class TabHolderView extends LinearLayout {
+
+    /**
+     * @param context
+     * @param attrs
+     * @param defStyle
+     */
+    public TabHolderView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * @param context
+     * @param attrs
+     */
+    public TabHolderView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * @param context
+     */
+    public TabHolderView(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void setPressed(boolean p) {}
+
+}