Merge "Add API to allow plugins to lock their orientation in full-screen"
diff --git a/res/layout/nav_tab_view.xml b/res/layout/nav_tab_view.xml
index 7d9263d..5a71c71 100644
--- a/res/layout/nav_tab_view.xml
+++ b/res/layout/nav_tab_view.xml
@@ -79,7 +79,7 @@
             android:src="@drawable/ic_stop_holo_dark"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="right|bottom"
+            android:layout_gravity="bottom|right"
             android:background="@drawable/navtab_close_background" />
     </FrameLayout>
 </LinearLayout>
diff --git a/res/values-land/dimensions.xml b/res/values-land/dimensions.xml
index e69bd82..df4bc84 100644
--- a/res/values-land/dimensions.xml
+++ b/res/values-land/dimensions.xml
@@ -17,5 +17,4 @@
     <dimen name="preference_widget_width">72dp</dimen>
     <dimen name="nav_tab_width">280dip</dimen>
     <dimen name="nav_tab_height">240dip</dimen>
-    <dimen name="nav_scroller_padding">101dip</dimen>
 </resources>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index e1ae0eb..dbb0c60 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -71,5 +71,6 @@
     <dimen name="tab_capture_size">160dp</dimen>
     <dimen name="nav_tab_width">280dip</dimen>
     <dimen name="nav_tab_height">280dip</dimen>
-    <dimen name="nav_scroller_padding">68dip</dimen>
+    <dimen name="nav_tab_text_normal">18sp</dimen>
+    <dimen name="nav_tab_text_small">14sp</dimen>
 </resources>
diff --git a/src/com/android/browser/BrowserWebView.java b/src/com/android/browser/BrowserWebView.java
index 6cdc063..5a40b3c 100644
--- a/src/com/android/browser/BrowserWebView.java
+++ b/src/com/android/browser/BrowserWebView.java
@@ -22,9 +22,10 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.webkit.WebView;
 
+import com.android.browser.NavTabView.WebProxyView;
+
 import java.util.Map;
 
 /**
@@ -39,10 +40,7 @@
     private TitleBarBase mTitleBar;
     private int mCaptureSize;
     private Bitmap mCapture;
-    private boolean mNavMode;
-    private boolean mTracking;
-    private int mSlop;
-    float mDownX, mDownY;
+    private WebProxyView mProxyView;
 
     /**
      * @param context
@@ -84,15 +82,21 @@
     }
 
     private void init() {
-        mNavMode = false;
-        mSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
         mCaptureSize = mContext.getResources().getDimensionPixelSize(R.dimen.tab_capture_size);
         mCapture = Bitmap.createBitmap(mCaptureSize, mCaptureSize,
                 Bitmap.Config.RGB_565);
     }
 
-    protected void setNavMode(boolean enabled) {
-        mNavMode = enabled;
+    protected void setProxyView(WebProxyView p) {
+        mProxyView = p;
+    }
+
+    @Override
+    public void invalidate() {
+        super.invalidate();
+        if (mProxyView != null) {
+            mProxyView.invalidate();
+        }
     }
 
     @Override
@@ -127,36 +131,13 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent evt) {
-        if (mNavMode) {
-            if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
-                mDownX = evt.getX();
-                mDownY = evt.getY();
-                mTracking = true;
-                return true;
-            } else if (mTracking && MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
-                if (mSlop < Math.abs(evt.getX() - mDownX)
-                        || mSlop < Math.abs(evt.getY() - mDownY)) {
-                    mTracking = false;
-                }
-                return mTracking;
-            } else if (mTracking && MotionEvent.ACTION_UP == evt.getActionMasked()) {
-                performClick();
-                mTracking = false;
-                return true;
-            } else if (mTracking && MotionEvent.ACTION_CANCEL == evt.getActionMasked()) {
-                mTracking = false;
-                return true;
-            }
-            return super.onTouchEvent(evt);
-        } else {
-            if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
-                mUserInitiated = true;
-            } else if (MotionEvent.ACTION_UP == evt.getActionMasked()
-                    || (MotionEvent.ACTION_CANCEL == evt.getActionMasked())) {
-                mUserInitiated = false;
-            }
-            return super.onTouchEvent(evt);
+        if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
+            mUserInitiated = true;
+        } else if (MotionEvent.ACTION_UP == evt.getActionMasked()
+                || (MotionEvent.ACTION_CANCEL == evt.getActionMasked())) {
+            mUserInitiated = false;
         }
+        return super.onTouchEvent(evt);
     }
 
     @Override
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
index cbb2cfd..bd26df7 100644
--- a/src/com/android/browser/NavTabScroller.java
+++ b/src/com/android/browser/NavTabScroller.java
@@ -66,6 +66,25 @@
         addView(sview);
     }
 
+    @Override
+    protected void onMeasure(int wspec, int hspec) {
+        super.onMeasure(wspec, hspec);
+        calcPadding();
+    }
+
+    private void calcPadding() {
+        if (mAdapter.getCount() > 0) {
+            View v = mContentView.getChildAt(0);
+            if (mOrientation == Configuration.ORIENTATION_PORTRAIT) {
+                int pad = (getMeasuredHeight() - v.getMeasuredHeight()) / 2;
+                mContentView.setPadding(0, pad, 0, pad);
+            } else {
+                int pad = (getMeasuredWidth() - v.getMeasuredWidth()) / 2;
+                mContentView.setPadding(pad, 0, pad, 0);
+            }
+        }
+    }
+
     protected void setAdapter(BaseAdapter adapter) {
         mAdapter = adapter;
         mAdapter.registerDataSetObserver(new DataSetObserver() {
@@ -151,8 +170,6 @@
             mContentView.setOrientation(LinearLayout.VERTICAL);
             setVerticalScrollBarEnabled(false);
             setSmoothScrollingEnabled(true);
-            int pad = ctx.getResources().getDimensionPixelSize(R.dimen.nav_scroller_padding);
-            mContentView.setPadding(0, pad, 0, pad);
             mContentView.setLayoutParams(
                     new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
             addView(mContentView);
@@ -175,20 +192,28 @@
             int midy = getScrollY() + getHeight() / 2;
             int sel = -1;
             for (int i = 0; i < mContentView.getChildCount(); i++) {
-                View child = mContentView.getChildAt(i);
-                if (child.getTop() <= midy && child.getBottom() >= midy) {
+                NavTabView child = (NavTabView) mContentView.getChildAt(i);
+                int top = child.getTop();
+                int bottom = child.getBottom();
+                if (top <= midy && bottom >= midy) {
                     sel = i;
-                    break;
+                } else {
+                    // check if on screen
+                    if (top > getScrollY() + getHeight() || bottom < getScrollY()) {
+                        if (!child.isPaused()) {
+                            child.pause();
+                        }
+                    } else {
+                        if (child.isPaused()) {
+                            child.resume();
+                        }
+                    }
                 }
             }
             if (sel != -1) {
                 if (sel != mSelected) {
                     setSelection(sel);
                 }
-                if (!isCentered(mSelected)) {
-                    NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(false);
-                }
             }
         }
 
@@ -201,6 +226,11 @@
                 if (mScroller.isFinished() && dragged) {
                     snapToSelected();
                 }
+            } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
+                NavTabView ntv = (NavTabView) getSelectedView();
+                if (mIsBeingDragged && ntv.isHighlighted()) {
+                    ntv.setHighlighted(false);
+                }
             }
             return result;
         }
@@ -215,17 +245,11 @@
                     // reset snap scrolling flag
                     mSnapScroll = false;
                     NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(isCentered(mSelected));
+                    ntv.setHighlighted(true);
                 }
             }
         }
 
-        private boolean isCentered(int ix) {
-            int midy = getScrollY() + (getTop() + getBottom()) / 2;
-            View v = mContentView.getChildAt(ix);
-            return (v.getTop() + v.getBottom()) / 2 == midy;
-        }
-
         private void snapToSelected() {
             View v = mContentView.getChildAt(mSelected);
             int top = (v.getTop() + v.getBottom()) / 2;
@@ -234,6 +258,9 @@
                 // snap to selected
                 mSnapScroll = true;
                 smoothScrollTo(0, top);
+            } else {
+                NavTabView ntv = (NavTabView) getSelectedView();
+                ntv.setHighlighted(true);
             }
         }
 
@@ -270,12 +297,9 @@
             mContentView.setOrientation(LinearLayout.HORIZONTAL);
             setVerticalScrollBarEnabled(false);
             setSmoothScrollingEnabled(true);
-            int pad = ctx.getResources().getDimensionPixelSize(R.dimen.nav_scroller_padding);
-            mContentView.setPadding(pad, 0, pad, 0);
             mContentView.setLayoutParams(
                     new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
             addView(mContentView);
-
         }
 
         public LinearLayout getContentView() {
@@ -304,10 +328,6 @@
                 if (sel != mSelected) {
                     setSelection(sel);
                 }
-                if (!isCentered(mSelected)) {
-                    NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(false);
-                }
             }
         }
 
@@ -320,6 +340,11 @@
                 if (mScroller.isFinished() && dragged) {
                     snapToSelected();
                 }
+            } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
+                NavTabView ntv = (NavTabView) getSelectedView();
+                if (mIsBeingDragged && ntv.isHighlighted()) {
+                    ntv.setHighlighted(false);
+                }
             }
             return result;
         }
@@ -334,17 +359,11 @@
                     // reset snap scrolling flag
                     mSnapScroll = false;
                     NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(isCentered(mSelected));
+                    ntv.setHighlighted(true);
                 }
             }
         }
 
-        private boolean isCentered(int ix) {
-            int midx = getScrollX() + getWidth() / 2;
-            View v = mContentView.getChildAt(ix);
-            return (v.getLeft() + v.getRight()) / 2 == midx;
-        }
-
         private void snapToSelected() {
             View v = mContentView.getChildAt(mSelected);
             int left = (v.getLeft() + v.getRight()) / 2;
@@ -353,6 +372,9 @@
                 // snap to selected
                 mSnapScroll = true;
                 smoothScrollTo(left, 0);
+            } else {
+                NavTabView ntv = (NavTabView) getSelectedView();
+                ntv.setHighlighted(true);
             }
         }
 
diff --git a/src/com/android/browser/NavTabView.java b/src/com/android/browser/NavTabView.java
index 14453dc..061e024 100644
--- a/src/com/android/browser/NavTabView.java
+++ b/src/com/android/browser/NavTabView.java
@@ -17,8 +17,11 @@
 package com.android.browser;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -30,18 +33,23 @@
 
 public class NavTabView extends LinearLayout {
 
-    Tab mTab;
-    BrowserWebView mWebView;
-    ImageButton mForward;
-    ImageButton mRefresh;
-    ImageView mFavicon;
-    ImageButton mClose;
-    FrameLayout mContainer;
-    TextView mTitle;
-    View mTitleBar;
-    OnClickListener mClickListener;
-    boolean mHighlighted;
-    Drawable mTitleBg;
+    private Tab mTab;
+    private BrowserWebView mWebView;
+    private WebProxyView mProxy;
+    private ImageButton mForward;
+    private ImageButton mRefresh;
+    private ImageView mFavicon;
+    private ImageButton mClose;
+    private FrameLayout mContainer;
+    private TextView mTitle;
+    private View mTitleBar;
+    private OnClickListener mClickListener;
+    private boolean mHighlighted;
+    private Drawable mTitleBg;
+    private Drawable mUrlBg;
+    private float mMediumTextSize;
+    private float mSmallTextSize;
+    private boolean mPaused;
 
     public NavTabView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -59,6 +67,9 @@
     }
 
     private void init() {
+        final Resources res = mContext.getResources();
+        mMediumTextSize = res.getDimension(R.dimen.nav_tab_text_normal);
+        mSmallTextSize = res.getDimension(R.dimen.nav_tab_text_small);
         LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view,
                     this);
         mContainer = (FrameLayout) findViewById(R.id.tab_view);
@@ -68,9 +79,24 @@
         mTitle = (TextView) findViewById(R.id.title);
         mFavicon = (ImageView) findViewById(R.id.favicon);
         mTitleBar = findViewById(R.id.titlebar);
-        mTitleBg = mContext.getResources().getDrawable(R.drawable.bg_urlbar);
+        mTitleBg = res.getDrawable(R.drawable.bg_urlbar);
+        mUrlBg = res.getDrawable(
+                com.android.internal.R.drawable.edit_text_holo_dark);
         setState(false);
-        // refresh titlebar
+    }
+
+    protected void pause() {
+        mPaused = true;
+        mWebView.onPause();
+    }
+
+    protected void resume() {
+        mPaused = false;
+        mWebView.onResume();
+    }
+
+    protected boolean isPaused() {
+        return mPaused;
     }
 
     protected boolean isRefresh(View v) {
@@ -90,7 +116,7 @@
     }
 
     protected boolean isWebView(View v) {
-        return v == mWebView;
+        return v == mProxy;
     }
 
     protected void setHighlighted(boolean highlighted) {
@@ -108,6 +134,8 @@
                     ? View.VISIBLE : View.GONE);
             mTitleBar.setBackgroundDrawable(mTitleBg);
             mClose.setVisibility(View.VISIBLE);
+            mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMediumTextSize);
+            mTitle.setBackgroundDrawable(mUrlBg);
         } else {
             setAlpha(0.8f);
             mForward.setVisibility(View.GONE);
@@ -115,6 +143,8 @@
             mFavicon.setVisibility(View.INVISIBLE);
             mClose.setVisibility(View.GONE);
             mTitleBar.setBackgroundDrawable(null);
+            mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mSmallTextSize);
+            mTitle.setBackgroundDrawable(null);
         }
         setTitle();
     }
@@ -140,8 +170,8 @@
         if (web == null) return;
         mWebView = web;
         removeFromParent(mWebView);
-        mWebView.setNavMode(true);
-        mContainer.addView(mWebView, 0);
+        mProxy = new WebProxyView(mContext, mWebView);
+        mContainer.addView(mProxy, 0);
         if (mWebView != null) {
             mForward.setVisibility(mWebView.canGoForward()
                     ? View.VISIBLE : View.GONE);
@@ -161,15 +191,39 @@
         mRefresh.setOnClickListener(mClickListener);
         mForward.setOnClickListener(mClickListener);
         mClose.setOnClickListener(mClickListener);
-        if (mWebView != null) {
-            mWebView.setOnClickListener(mClickListener);
+        if (mProxy != null) {
+            mProxy.setOnClickListener(mClickListener);
         }
     }
 
+    @Override
+    public void onDetachedFromWindow() {
+        mWebView.setProxyView(null);
+    }
+
     private static void removeFromParent(View v) {
         if (v.getParent() != null) {
             ((ViewGroup) v.getParent()).removeView(v);
         }
     }
 
+    static class WebProxyView extends View {
+
+        private BrowserWebView mWeb;
+
+        public WebProxyView(Context context, BrowserWebView web) {
+            super(context);
+            setWillNotDraw(false);
+            mWeb = web;
+            mWeb.setProxyView(this);
+
+        }
+
+        public void onDraw(Canvas c) {
+            c.translate(-mWeb.getScrollX(), -mWeb.getScrollY());
+            mWeb.onDraw(c);
+        }
+
+    }
+
 }
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index ce993fd..f94a8ab 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -167,7 +167,6 @@
             Log.e(LOGTAG, "active tab with no webview detected");
             return;
         }
-        view.setNavMode(false);
         // Request focus on the top window.
         if (mUseQuickControls) {
             mPieControl.forceToTop(mContentView);