Commit d01f368a authored by kkimlabs@chromium.org's avatar kkimlabs@chromium.org

[Android] Remove hardware menu button dragging support.

This code path was broken sometime within a year, and we don't think
it's worth to support this more.

BUG=366154

Review URL: https://codereview.chromium.org/317083005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275395 0039d316-1c4b-4281-b951-d872f2087c98
parent 85317221
...@@ -8,24 +8,15 @@ import android.animation.TimeAnimator; ...@@ -8,24 +8,15 @@ import android.animation.TimeAnimator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewParent;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ListPopupWindow; import android.widget.ListPopupWindow;
import android.widget.ListView; import android.widget.ListView;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.UmaBridge;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -37,8 +28,6 @@ import java.util.ArrayList; ...@@ -37,8 +28,6 @@ import java.util.ArrayList;
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
class AppMenuDragHelper { class AppMenuDragHelper {
private static final String TAG = "AppMenuDragHelper";
private final Activity mActivity; private final Activity mActivity;
private final AppMenu mAppMenu; private final AppMenu mAppMenu;
...@@ -48,28 +37,15 @@ class AppMenuDragHelper { ...@@ -48,28 +37,15 @@ class AppMenuDragHelper {
private static final int ITEM_ACTION_CLEAR_HIGHLIGHT_ALL = 2; private static final int ITEM_ACTION_CLEAR_HIGHLIGHT_ALL = 2;
private static final float AUTO_SCROLL_AREA_MAX_RATIO = 0.25f; private static final float AUTO_SCROLL_AREA_MAX_RATIO = 0.25f;
private static final int EDGE_SWIPE_IN_ADDITIONAL_SLOP_TIME_MS = 500;
// Dragging related variables, i.e., menu showing initiated by touch down and drag to navigate. // Dragging related variables, i.e., menu showing initiated by touch down and drag to navigate.
private final float mAutoScrollFullVelocity; private final float mAutoScrollFullVelocity;
private final int mEdgeSwipeInSlop;
private final int mEdgeSwipeInAdditionalSlop;
private final int mEdgeSwipeOutSlop;
private int mScaledTouchSlop;
private long mHardwareMenuButtonUpTime;
private boolean mDragPending;
private final TimeAnimator mDragScrolling = new TimeAnimator(); private final TimeAnimator mDragScrolling = new TimeAnimator();
private float mDragScrollOffset; private float mDragScrollOffset;
private int mDragScrollOffsetRounded; private int mDragScrollOffsetRounded;
private volatile float mDragScrollingVelocity; private volatile float mDragScrollingVelocity;
private volatile float mLastTouchX; private volatile float mLastTouchX;
private volatile float mLastTouchY; private volatile float mLastTouchY;
private float mTopTouchMovedBound;
private float mBottomTouchMovedBound;
private boolean mIsDownScrollable;
private boolean mIsUpScrollable;
private boolean mIsByHardwareButton;
private int mCurrentScreenRotation = -1;
private final int mItemRowHeight; private final int mItemRowHeight;
// These are used in a function locally, but defined here to avoid heap allocation on every // These are used in a function locally, but defined here to avoid heap allocation on every
...@@ -77,28 +53,12 @@ class AppMenuDragHelper { ...@@ -77,28 +53,12 @@ class AppMenuDragHelper {
private final Rect mScreenVisibleRect = new Rect(); private final Rect mScreenVisibleRect = new Rect();
private final int[] mScreenVisiblePoint = new int[2]; private final int[] mScreenVisiblePoint = new int[2];
// Sub-UI-controls, backward, forward, bookmark and listView, are getting a touch event first
// if the app menu is initiated by hardware menu button. For those cases, we need to
// conditionally forward the touch event to our drag scrolling method.
private final OnTouchListener mDragScrollTouchEventForwarder = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
return handleDragging(event);
}
};
AppMenuDragHelper(Activity activity, AppMenu appMenu, int itemRowHeight) { AppMenuDragHelper(Activity activity, AppMenu appMenu, int itemRowHeight) {
mActivity = activity; mActivity = activity;
mAppMenu = appMenu; mAppMenu = appMenu;
mItemRowHeight = itemRowHeight; mItemRowHeight = itemRowHeight;
mScaledTouchSlop = ViewConfiguration.get(
mActivity.getApplicationContext()).getScaledTouchSlop();
Resources res = mActivity.getResources(); Resources res = mActivity.getResources();
mAutoScrollFullVelocity = res.getDimensionPixelSize(R.dimen.auto_scroll_full_velocity); mAutoScrollFullVelocity = res.getDimensionPixelSize(R.dimen.auto_scroll_full_velocity);
mEdgeSwipeInSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_in_slop);
mEdgeSwipeInAdditionalSlop = res.getDimensionPixelSize(
R.dimen.edge_swipe_in_additional_slop);
mEdgeSwipeOutSlop = res.getDimensionPixelSize(R.dimen.edge_swipe_out_slop);
// If user is dragging and the popup ListView is too big to display at once, // If user is dragging and the popup ListView is too big to display at once,
// mDragScrolling animator scrolls mPopup.getListView() automatically depending on // mDragScrolling animator scrolls mPopup.getListView() automatically depending on
// the user's touch position. // the user's touch position.
...@@ -118,10 +78,8 @@ class AppMenuDragHelper { ...@@ -118,10 +78,8 @@ class AppMenuDragHelper {
// Force touch move event to highlight items correctly for the scrolled position. // Force touch move event to highlight items correctly for the scrolled position.
if (!Float.isNaN(mLastTouchX) && !Float.isNaN(mLastTouchY)) { if (!Float.isNaN(mLastTouchX) && !Float.isNaN(mLastTouchY)) {
int actionToPerform = isInSwipeOutRegion(mLastTouchX, mLastTouchY) ?
ITEM_ACTION_CLEAR_HIGHLIGHT_ALL : ITEM_ACTION_HIGHLIGHT;
menuItemAction(Math.round(mLastTouchX), Math.round(mLastTouchY), menuItemAction(Math.round(mLastTouchX), Math.round(mLastTouchY),
actionToPerform); ITEM_ACTION_HIGHLIGHT);
} }
} }
}); });
...@@ -129,63 +87,25 @@ class AppMenuDragHelper { ...@@ -129,63 +87,25 @@ class AppMenuDragHelper {
/** /**
* Sets up all the internal state to prepare for menu dragging. * Sets up all the internal state to prepare for menu dragging.
*
* @param isByHardwareButton Whether or not hardware button triggered it. (oppose to software
* button)
* @param startDragging Whether dragging is started. For example, if the app menu * @param startDragging Whether dragging is started. For example, if the app menu
* is showed by tapping on a button, this should be false. If it is * is showed by tapping on a button, this should be false. If it is
* showed by start dragging down on the menu button, this should be * showed by start dragging down on the menu button, this should be
* true. Note that if isByHardwareButton is true, this is ignored. * true.
*/ */
void onShow(boolean isByHardwareButton, boolean startDragging) { void onShow(boolean startDragging) {
mCurrentScreenRotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
mLastTouchX = Float.NaN; mLastTouchX = Float.NaN;
mLastTouchY = Float.NaN; mLastTouchY = Float.NaN;
mDragScrollOffset = 0.0f; mDragScrollOffset = 0.0f;
mDragScrollOffsetRounded = 0; mDragScrollOffsetRounded = 0;
mDragScrollingVelocity = 0.0f; mDragScrollingVelocity = 0.0f;
mIsByHardwareButton = isByHardwareButton; if (startDragging) mDragScrolling.start();
mDragPending = isByHardwareButton;
mIsDownScrollable = !isByHardwareButton;
mIsUpScrollable = !isByHardwareButton;
mTopTouchMovedBound = Float.POSITIVE_INFINITY;
mBottomTouchMovedBound = Float.NEGATIVE_INFINITY;
mHardwareMenuButtonUpTime = -1;
ListPopupWindow popup = mAppMenu.getPopup();
popup.getListView().setOnTouchListener(mDragScrollTouchEventForwarder);
// We assume that the parent of popup ListView is an instance of View. Otherwise, dragging
// from a hardware menu button won't work.
ViewParent listViewParent = popup.getListView().getParent();
if (listViewParent instanceof View) {
((View) listViewParent).setOnTouchListener(mDragScrollTouchEventForwarder);
} else {
assert false;
}
if (!isByHardwareButton && startDragging) mDragScrolling.start();
} }
void onDismiss() { void onDismiss() {
mDragScrolling.cancel(); mDragScrolling.cancel();
} }
/**
* This is a hint for adjusting edgeSwipeInSlop. For example. If the touch event started
* immediately after hardware menu button up, then we use larger edgeSwipeInSlop because it
* implies user is swiping in fast.
*/
public void hardwareMenuButtonUp() {
// There should be only one time hardware menu button up.
assert mHardwareMenuButtonUpTime == -1;
mHardwareMenuButtonUpTime = SystemClock.uptimeMillis();
}
/** /**
* Gets all the touch events and updates dragging related logic. Note that if this app menu * Gets all the touch events and updates dragging related logic. Note that if this app menu
* is initiated by software UI control, then the control should set onTouchListener and forward * is initiated by software UI control, then the control should set onTouchListener and forward
...@@ -196,7 +116,7 @@ class AppMenuDragHelper { ...@@ -196,7 +116,7 @@ class AppMenuDragHelper {
* @return Whether the event is handled. * @return Whether the event is handled.
*/ */
boolean handleDragging(MotionEvent event) { boolean handleDragging(MotionEvent event) {
if (!mAppMenu.isShowing() || (!mDragPending && !mDragScrolling.isRunning())) return false; if (!mAppMenu.isShowing() || !mDragScrolling.isRunning()) return false;
// We will only use the screen space coordinate (rawX, rawY) to reduce confusion. // We will only use the screen space coordinate (rawX, rawY) to reduce confusion.
// This code works across many different controls, so using local coordinates will be // This code works across many different controls, so using local coordinates will be
...@@ -212,60 +132,26 @@ class AppMenuDragHelper { ...@@ -212,60 +132,26 @@ class AppMenuDragHelper {
mLastTouchX = rawX; mLastTouchX = rawX;
mLastTouchY = rawY; mLastTouchY = rawY;
// Because (hardware) menu button can be right or left side of the screen, if we just
// trigger auto scrolling based on Y inside the listView, it might be scrolled
// unintentionally. Therefore, we will require touch position to move up or down a certain
// amount of distance to trigger auto scrolling up or down.
mTopTouchMovedBound = Math.min(mTopTouchMovedBound, rawY);
mBottomTouchMovedBound = Math.max(mBottomTouchMovedBound, rawY);
if (rawY <= mBottomTouchMovedBound - mScaledTouchSlop) {
mIsUpScrollable = true;
}
if (rawY >= mTopTouchMovedBound + mScaledTouchSlop) {
mIsDownScrollable = true;
}
if (eventActionMasked == MotionEvent.ACTION_CANCEL) { if (eventActionMasked == MotionEvent.ACTION_CANCEL) {
mAppMenu.dismiss(); mAppMenu.dismiss();
return true; return true;
} }
if (eventActionMasked == MotionEvent.ACTION_DOWN) {
assert mIsByHardwareButton != mDragScrolling.isStarted();
if (mIsByHardwareButton) {
if (mDragPending && getDistanceFromHardwareMenuButtonSideEdge(rawX, rawY) <
getEdgeSwipeInSlop(event)) {
mDragScrolling.start();
mDragPending = false;
UmaBridge.usingMenu(true, true);
} else {
if (!getScreenVisibleRect(listView).contains(roundedRawX, roundedRawY)) {
mAppMenu.dismiss();
}
mDragPending = false;
UmaBridge.usingMenu(true, false);
return false;
}
}
}
// After this line, drag scrolling is happening. // After this line, drag scrolling is happening.
if (!mDragScrolling.isRunning()) return false; if (!mDragScrolling.isRunning()) return false;
boolean didPerformClick = false; boolean didPerformClick = false;
int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL; int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL;
if (!isInSwipeOutRegion(rawX, rawY)) { switch (eventActionMasked) {
switch (eventActionMasked) { case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_MOVE: itemAction = ITEM_ACTION_HIGHLIGHT;
itemAction = ITEM_ACTION_HIGHLIGHT; break;
break; case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_UP: itemAction = ITEM_ACTION_PERFORM;
itemAction = ITEM_ACTION_PERFORM; break;
break; default:
default: break;
break;
}
} }
didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction); didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction);
...@@ -278,11 +164,11 @@ class AppMenuDragHelper { ...@@ -278,11 +164,11 @@ class AppMenuDragHelper {
mItemRowHeight * 1.2f / listView.getHeight()); mItemRowHeight * 1.2f / listView.getHeight());
float normalizedY = float normalizedY =
(rawY - getScreenVisibleRect(listView).top) / listView.getHeight(); (rawY - getScreenVisibleRect(listView).top) / listView.getHeight();
if (mIsUpScrollable && normalizedY < autoScrollAreaRatio) { if (normalizedY < autoScrollAreaRatio) {
// Top // Top
mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f) mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f)
* mAutoScrollFullVelocity; * mAutoScrollFullVelocity;
} else if (mIsDownScrollable && normalizedY > 1.0f - autoScrollAreaRatio) { } else if (normalizedY > 1.0f - autoScrollAreaRatio) {
// Bottom // Bottom
mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f) mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f)
* mAutoScrollFullVelocity; * mAutoScrollFullVelocity;
...@@ -296,33 +182,6 @@ class AppMenuDragHelper { ...@@ -296,33 +182,6 @@ class AppMenuDragHelper {
return true; return true;
} }
/**
* @return Whether or not the position should be considered swiping-out, if ACTION_UP happens
* at the position.
*/
private boolean isInSwipeOutRegion(float rawX, float rawY) {
return getShortestDistanceFromEdge(rawX, rawY) < mEdgeSwipeOutSlop;
}
/**
* @return The shortest distance from the screen edges for the given position rawX, rawY
* in screen coordinates.
*/
private float getShortestDistanceFromEdge(float rawX, float rawY) {
Display display = mActivity.getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
float distance = Math.min(
Math.min(rawY, displaySize.y - rawY - 1),
Math.min(rawX, displaySize.x - rawX - 1));
if (distance < 0.0f) {
Log.d(TAG, "Received touch event out of the screen edge boundary. distance = " +
distance);
}
return Math.abs(distance);
}
/** /**
* Performs the specified action on the menu item specified by the screen coordinate position. * Performs the specified action on the menu item specified by the screen coordinate position.
* @param screenX X in screen space coordinate. * @param screenX X in screen space coordinate.
...@@ -374,43 +233,6 @@ class AppMenuDragHelper { ...@@ -374,43 +233,6 @@ class AppMenuDragHelper {
return didPerformClick; return didPerformClick;
} }
/**
* @return The distance from the screen edge that is likely where the hardware menu button is
* located at. We assume the hardware menu button is at the bottom in the default,
* ROTATION_0, rotation. Note that there is a bug filed for Android API to request
* hardware menu button position b/10007237.
*/
private float getDistanceFromHardwareMenuButtonSideEdge(float rawX, float rawY) {
Display display = mActivity.getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
float distance;
switch (mCurrentScreenRotation) {
case Surface.ROTATION_0:
distance = displaySize.y - rawY - 1;
break;
case Surface.ROTATION_180:
distance = rawY;
break;
case Surface.ROTATION_90:
distance = displaySize.x - rawX - 1;
break;
case Surface.ROTATION_270:
distance = rawX;
break;
default:
distance = 0.0f;
assert false;
break;
}
if (distance < 0.0f) {
Log.d(TAG, "Received touch event out of hardware menu button side edge boundary." +
" distance = " + distance);
}
return Math.abs(distance);
}
/** /**
* @return Visible rect in screen coordinates for the given View. * @return Visible rect in screen coordinates for the given View.
*/ */
...@@ -420,32 +242,4 @@ class AppMenuDragHelper { ...@@ -420,32 +242,4 @@ class AppMenuDragHelper {
mScreenVisibleRect.offset(mScreenVisiblePoint[0], mScreenVisiblePoint[1]); mScreenVisibleRect.offset(mScreenVisiblePoint[0], mScreenVisiblePoint[1]);
return mScreenVisibleRect; return mScreenVisibleRect;
} }
/**
* Computes Edge-swipe-in-slop and returns it.
*
* When user swipes in from a hardware menu button, because the swiping-in touch event doesn't
* necessarily start form the exact edge, we should also consider slightly more inside touch
* event as swiping-in. This value, Edge-swipe-in-slop, is the threshold distance from the
* edge that separates swiping-in and normal touch.
*
* @param event Touch event that eventually made this call.
* @return Edge-swipe-in-slop.
*/
private float getEdgeSwipeInSlop(MotionEvent event) {
float edgeSwipeInSlope = mEdgeSwipeInSlop;
if (mHardwareMenuButtonUpTime == -1) {
// Hardware menu hasn't even had UP event yet. That means, user is swiping in really
// really fast. So use large edgeSwipeInSlope.
edgeSwipeInSlope += mEdgeSwipeInAdditionalSlop;
} else {
// If it's right after we had hardware menu button UP event, use large edgeSwipeInSlop,
// Otherwise, use small edgeSwipeInSlop.
float additionalEdgeSwipeInSlop = ((mHardwareMenuButtonUpTime - event.getEventTime()
+ EDGE_SWIPE_IN_ADDITIONAL_SLOP_TIME_MS) * 0.001f)
* mEdgeSwipeInAdditionalSlop;
edgeSwipeInSlope += Math.max(0.0f, additionalEdgeSwipeInSlop);
}
return edgeSwipeInSlope;
}
} }
...@@ -57,12 +57,14 @@ public class AppMenuHandler { ...@@ -57,12 +57,14 @@ public class AppMenuHandler {
* @param startDragging Whether dragging is started. For example, if the app menu is * @param startDragging Whether dragging is started. For example, if the app menu is
* showed by tapping on a button, this should be false. If it is * showed by tapping on a button, this should be false. If it is
* showed by start dragging down on the menu button, this should * showed by start dragging down on the menu button, this should
* be true. Note that if isByHardwareButton is true, this is * be true. Note that if isByHardwareButton is true, this must
* ignored. * be false since we no longer support hardware menu button
* dragging.
* @return True, if the menu is shown, false, if menu is not shown, example reasons: * @return True, if the menu is shown, false, if menu is not shown, example reasons:
* the menu is not yet available to be shown, or the menu is already showing. * the menu is not yet available to be shown, or the menu is already showing.
*/ */
public boolean showAppMenu(View anchorView, boolean isByHardwareButton, boolean startDragging) { public boolean showAppMenu(View anchorView, boolean isByHardwareButton, boolean startDragging) {
assert !(isByHardwareButton && startDragging);
if (!mDelegate.shouldShowAppMenu() || isAppMenuShowing()) return false; if (!mDelegate.shouldShowAppMenu() || isAppMenuShowing()) return false;
if (mMenu == null) { if (mMenu == null) {
...@@ -93,7 +95,7 @@ public class AppMenuHandler { ...@@ -93,7 +95,7 @@ public class AppMenuHandler {
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(appRect); mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(appRect);
int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
mAppMenu.show(wrapper, anchorView, isByHardwareButton, rotation, appRect); mAppMenu.show(wrapper, anchorView, isByHardwareButton, rotation, appRect);
mAppMenuDragHelper.onShow(isByHardwareButton, startDragging); mAppMenuDragHelper.onShow(startDragging);
UmaBridge.menuShow(); UmaBridge.menuShow();
return true; return true;
} }
...@@ -157,11 +159,4 @@ public class AppMenuHandler { ...@@ -157,11 +159,4 @@ public class AppMenuHandler {
mObservers.get(i).onMenuVisibilityChanged(isVisible); mObservers.get(i).onMenuVisibilityChanged(isVisible);
} }
} }
/**
* TODO(kkimlabs) remove this call.
*/
public void hardwareMenuButtonUp() {
if (mAppMenuDragHelper != null) mAppMenuDragHelper.hardwareMenuButtonUp();
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment