URL Bar auto show tweaks

 Bug: 5144824
 Bug: 5142398

Change-Id: I235828d52bc8d8c35e2b625d767caeffb2d9b654
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 368021a..a52bc56 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -36,11 +36,8 @@
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
@@ -60,7 +57,7 @@
 /**
  * UI interface definitions
  */
-public abstract class BaseUi implements UI, OnTouchListener {
+public abstract class BaseUi implements UI {
 
     private static final String LOGTAG = "BaseUi";
 
@@ -97,10 +94,9 @@
 
     private LinearLayout mErrorConsoleContainer = null;
 
-    private Toast mStopToast;
+    private UrlBarAutoShowManager mUrlBarAutoShowManager;
 
-    private float mInitialY;
-    private int mTitlebarScrollTriggerSlop;
+    private Toast mStopToast;
 
     // the default <video> poster
     private Bitmap mDefaultVideoPoster;
@@ -135,16 +131,11 @@
         setFullscreen(BrowserSettings.getInstance().useFullscreen());
         mGenericFavicon = res.getDrawable(
                 R.drawable.app_web_browser_sm);
-        ViewConfiguration config = ViewConfiguration.get(browser);
-        mTitlebarScrollTriggerSlop = Math.max(
-                config.getScaledOverflingDistance(),
-                config.getScaledOverscrollDistance());
-        mTitlebarScrollTriggerSlop = Math.max(mTitlebarScrollTriggerSlop,
-                config.getScaledTouchSlop());
         mTitleBar = new TitleBar(mActivity, mUiController, this,
                 mContentView);
         mTitleBar.setProgress(100);
         mNavigationBar = mTitleBar.getNavigationBar();
+        mUrlBarAutoShowManager = new UrlBarAutoShowManager(this);
     }
 
     private void cancelStopToast() {
@@ -244,9 +235,7 @@
         }
         mActiveTab = tab;
         WebView web = mActiveTab.getWebView();
-        if (web != null && !mUseQuickControls) {
-            web.setOnTouchListener(this);
-        }
+        updateUrlBarAutoShowManagerTarget();
         attachTabToContentView(tab);
         setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
         onTabDataChanged(tab);
@@ -261,6 +250,15 @@
         }
     }
 
+    protected void updateUrlBarAutoShowManagerTarget() {
+        WebView web = mActiveTab != null ? mActiveTab.getWebView() : null;
+        if (!mUseQuickControls && web instanceof BrowserWebView) {
+            mUrlBarAutoShowManager.setTarget((BrowserWebView) web);
+        } else {
+            mUrlBarAutoShowManager.setTarget(null);
+        }
+    }
+
     Tab getActiveTab() {
         return mActiveTab;
     }
@@ -805,34 +803,6 @@
         mHandler.sendMessageDelayed(msg, HIDE_TITLEBAR_DELAY);
     }
 
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        switch (event.getAction()) {
-        case MotionEvent.ACTION_DOWN:
-            mInitialY = event.getY();
-            break;
-        case MotionEvent.ACTION_MOVE:
-            WebView web = (WebView) v;
-            if (event.getPointerCount() == 1
-                    && !isTitleBarShowing()
-                    && web.getVisibleTitleHeight() == 0
-                    && event.getY() > (mInitialY + mTitlebarScrollTriggerSlop)) {
-                showTitleBar();
-            } else if (event.getY() < mInitialY) {
-                mInitialY = event.getY();
-            }
-            break;
-        case MotionEvent.ACTION_CANCEL:
-        case MotionEvent.ACTION_UP:
-            if (isTitleBarShowing()) {
-                Message msg = Message.obtain(mHandler, MSG_HIDE_TITLEBAR);
-                mHandler.sendMessageDelayed(msg, HIDE_TITLEBAR_DELAY);
-            }
-            break;
-        }
-        return false;
-    }
-
     private Handler mHandler = new Handler() {
 
         @Override
diff --git a/src/com/android/browser/BrowserWebView.java b/src/com/android/browser/BrowserWebView.java
index dd93c1f..2042ccf 100644
--- a/src/com/android/browser/BrowserWebView.java
+++ b/src/com/android/browser/BrowserWebView.java
@@ -29,8 +29,13 @@
  */
 public class BrowserWebView extends WebView {
 
+    public interface OnScrollChangedListener {
+        void onScrollChanged(int l, int t, int oldl, int oldt);
+    }
+
     private boolean mBackgroundRemoved = false;
     private TitleBar mTitleBar;
+    private OnScrollChangedListener mOnScrollChangedListener;
 
     /**
      * @param context
@@ -88,7 +93,7 @@
     }
 
     @Override
-    protected void onDraw(android.graphics.Canvas c) {
+    protected void onDraw(Canvas c) {
         super.onDraw(c);
         if (!mBackgroundRemoved && getRootView().getBackground() != null) {
             mBackgroundRemoved = true;
@@ -104,4 +109,16 @@
         onDraw(c);
     }
 
+    @Override
+    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+        super.onScrollChanged(l, t, oldl, oldt);
+        if (mOnScrollChangedListener != null) {
+            mOnScrollChangedListener.onScrollChanged(l, t, oldl, oldt);
+        }
+    }
+
+    public void setOnScrollChangedListener(OnScrollChangedListener listener) {
+        mOnScrollChangedListener = listener;
+    }
+
 }
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index e453296..863a628 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -17,7 +17,6 @@
 package com.android.browser;
 
 import android.app.Activity;
-import android.os.Bundle;
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.Gravity;
@@ -228,8 +227,6 @@
             WebView web = getWebView();
             if (web != null) {
                 web.setEmbeddedTitleBar(null);
-                // don't show url bar on scrolling
-                web.setOnTouchListener(null);
             }
         } else {
             if (mPieControl != null) {
@@ -238,11 +235,10 @@
             WebView web = getWebView();
             if (web != null) {
                 web.setEmbeddedTitleBar(mTitleBar);
-                // show url bar on scrolling
-                web.setOnTouchListener(this);
             }
             setTitleGravity(Gravity.NO_GRAVITY);
         }
+        updateUrlBarAutoShowManagerTarget();
     }
 
     void showNavScreen() {
diff --git a/src/com/android/browser/UrlBarAutoShowManager.java b/src/com/android/browser/UrlBarAutoShowManager.java
new file mode 100644
index 0000000..25192ca
--- /dev/null
+++ b/src/com/android/browser/UrlBarAutoShowManager.java
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewConfiguration;
+import android.webkit.WebView;
+
+import com.android.browser.BrowserWebView.OnScrollChangedListener;
+
+/**
+ * Helper class to manage when to show the URL bar based off of touch
+ * input, and when to begin the hide timer.
+ */
+public class UrlBarAutoShowManager implements OnTouchListener,
+        OnScrollChangedListener {
+
+    private static float V_TRIGGER_ANGLE = .9f;
+
+    private BrowserWebView mTarget;
+    private BaseUi mUi;
+
+    private int mSlop;
+
+    private float mStartTouchX;
+    private float mStartTouchY;
+    private float mLastTouchX;
+    private float mLastTouchY;
+    private boolean mIsTracking;
+    private boolean mHasTriggered;
+
+    public UrlBarAutoShowManager(BaseUi ui) {
+        mUi = ui;
+        ViewConfiguration config = ViewConfiguration.get(mUi.getActivity());
+        mSlop = config.getScaledTouchSlop() * 2;
+    }
+
+    public void setTarget(BrowserWebView v) {
+        if (mTarget == v) return;
+
+        if (mTarget != null) {
+            mTarget.setOnTouchListener(null);
+            mTarget.setOnScrollChangedListener(null);
+        }
+        mTarget = v;
+        if (mTarget != null) {
+            mTarget.setOnTouchListener(this);
+            mTarget.setOnScrollChangedListener(this);
+        }
+    }
+
+    @Override
+    public void onScrollChanged(int l, int t, int oldl, int oldt) {
+        if (t != oldt) {
+            if (t != 0) {
+                // If it is showing, extend it
+                if (mUi.isTitleBarShowing()) {
+                    mUi.showTitleBarForDuration();
+                }
+            } else {
+                mUi.suggestHideTitleBar();
+            }
+        }
+    }
+
+    void stopTracking() {
+        if (mIsTracking) {
+            mIsTracking = false;
+            if (mUi.isTitleBarShowing()) {
+                mUi.showTitleBarForDuration();
+            }
+        }
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if (event.getPointerCount() > 1) {
+            stopTracking();
+        }
+        switch (event.getAction()) {
+        case MotionEvent.ACTION_DOWN:
+            if (!mIsTracking && event.getPointerCount() == 1) {
+                mStartTouchY = event.getY();
+                mStartTouchX = event.getX();
+                mIsTracking = true;
+                mHasTriggered = false;
+            }
+            break;
+        case MotionEvent.ACTION_MOVE:
+            if (mIsTracking && !mHasTriggered) {
+                WebView web = (WebView) v;
+                float dy = event.getY() - mStartTouchY;
+                float ady = Math.abs(dy);
+                float adx = Math.abs(event.getX() - mStartTouchX);
+                if (ady > mSlop) {
+                    mHasTriggered = true;
+                    float angle = (float) Math.atan2(ady, adx);
+                    if (dy > mSlop && angle > V_TRIGGER_ANGLE
+                            && !mUi.isTitleBarShowing()
+                            && web.getVisibleTitleHeight() == 0) {
+                        mUi.showTitleBar();
+                    }
+                }
+            }
+            break;
+        case MotionEvent.ACTION_CANCEL:
+        case MotionEvent.ACTION_UP:
+            stopTracking();
+            break;
+        }
+        return false;
+    }
+
+}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 724708b..ea6fddd 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -92,8 +92,6 @@
             WebView web = getWebView();
             if (web != null) {
                 web.setEmbeddedTitleBar(null);
-                // don't show url bar on scrolling
-                web.setOnTouchListener(null);
 
             }
         } else {
@@ -108,8 +106,6 @@
                     p.removeView(mTitleBar);
                 }
                 web.setEmbeddedTitleBar(mTitleBar);
-                // show url bar on scrolling
-                web.setOnTouchListener(this);
             }
             setTitleGravity(Gravity.NO_GRAVITY);
         }
@@ -118,6 +114,7 @@
         for (Tab t : mTabControl.getTabs()) {
             t.updateShouldCaptureThumbnails();
         }
+        updateUrlBarAutoShowManagerTarget();
     }
 
     private void checkTabCount() {