1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.browser;
17 
18 import android.os.SystemClock;
19 import android.view.MotionEvent;
20 import android.view.View;
21 import android.view.View.OnTouchListener;
22 import android.view.ViewConfiguration;
23 import android.webkit.WebView;
24 
25 import com.android.browser.BrowserWebView.OnScrollChangedListener;
26 
27 /**
28  * Helper class to manage when to show the URL bar based off of touch
29  * input, and when to begin the hide timer.
30  */
31 public class UrlBarAutoShowManager implements OnTouchListener,
32         OnScrollChangedListener {
33 
34     private static float V_TRIGGER_ANGLE = .9f;
35     private static long SCROLL_TIMEOUT_DURATION = 150;
36     private static long IGNORE_INTERVAL = 250;
37 
38     private BrowserWebView mTarget;
39     private BaseUi mUi;
40 
41     private int mSlop;
42 
43     private float mStartTouchX;
44     private float mStartTouchY;
45     private boolean mIsTracking;
46     private boolean mHasTriggered;
47     private long mLastScrollTime;
48     private long mTriggeredTime;
49     private boolean mIsScrolling;
50 
UrlBarAutoShowManager(BaseUi ui)51     public UrlBarAutoShowManager(BaseUi ui) {
52         mUi = ui;
53         ViewConfiguration config = ViewConfiguration.get(mUi.getActivity());
54         mSlop = config.getScaledTouchSlop() * 2;
55     }
56 
setTarget(BrowserWebView v)57     public void setTarget(BrowserWebView v) {
58         if (mTarget == v) return;
59 
60         if (mTarget != null) {
61             mTarget.setOnTouchListener(null);
62             mTarget.setOnScrollChangedListener(null);
63         }
64         mTarget = v;
65         if (mTarget != null) {
66             mTarget.setOnTouchListener(this);
67             mTarget.setOnScrollChangedListener(this);
68         }
69     }
70 
71     @Override
onScrollChanged(int l, int t, int oldl, int oldt)72     public void onScrollChanged(int l, int t, int oldl, int oldt) {
73         mLastScrollTime = SystemClock.uptimeMillis();
74         mIsScrolling = true;
75         if (t != 0) {
76             // If it is showing, extend it
77             if (mUi.isTitleBarShowing()) {
78                 long remaining = mLastScrollTime - mTriggeredTime;
79                 remaining = Math.max(BaseUi.HIDE_TITLEBAR_DELAY - remaining,
80                         SCROLL_TIMEOUT_DURATION);
81                 mUi.showTitleBarForDuration(remaining);
82             }
83         } else {
84             mUi.suggestHideTitleBar();
85         }
86     }
87 
stopTracking()88     void stopTracking() {
89         if (mIsTracking) {
90             mIsTracking = false;
91             mIsScrolling = false;
92             if (mUi.isTitleBarShowing()) {
93                 mUi.showTitleBarForDuration();
94             }
95         }
96     }
97 
98     @Override
onTouch(View v, MotionEvent event)99     public boolean onTouch(View v, MotionEvent event) {
100         if (event.getPointerCount() > 1) {
101             stopTracking();
102         }
103         switch (event.getAction()) {
104         case MotionEvent.ACTION_DOWN:
105             if (!mIsTracking && event.getPointerCount() == 1) {
106                 long sinceLastScroll =
107                         SystemClock.uptimeMillis() - mLastScrollTime;
108                 if (sinceLastScroll < IGNORE_INTERVAL) {
109                     break;
110                 }
111                 mStartTouchY = event.getY();
112                 mStartTouchX = event.getX();
113                 mIsTracking = true;
114                 mHasTriggered = false;
115             }
116             break;
117         case MotionEvent.ACTION_MOVE:
118             if (mIsTracking && !mHasTriggered) {
119                 WebView web = (WebView) v;
120                 float dy = event.getY() - mStartTouchY;
121                 float ady = Math.abs(dy);
122                 float adx = Math.abs(event.getX() - mStartTouchX);
123                 if (ady > mSlop) {
124                     mHasTriggered = true;
125                     float angle = (float) Math.atan2(ady, adx);
126                     if (dy > mSlop && angle > V_TRIGGER_ANGLE
127                             && !mUi.isTitleBarShowing()
128                             && (web.getVisibleTitleHeight() == 0
129                             || (!mIsScrolling && web.getScrollY() > 0))) {
130                         mTriggeredTime = SystemClock.uptimeMillis();
131                         mUi.showTitleBar();
132                     }
133                 }
134             }
135             break;
136         case MotionEvent.ACTION_CANCEL:
137         case MotionEvent.ACTION_UP:
138             stopTracking();
139             break;
140         }
141         return false;
142     }
143 
144 }
145