| Index: content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
|
| index 82624c1758bdbb897b7fed33e77bb338a65640bc..1516863e2c499a4f1163aef609b3b7d4ff1a5e20 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
|
| @@ -14,6 +14,7 @@ import android.view.MotionEvent;
|
| import android.view.ViewConfiguration;
|
|
|
| import org.chromium.content.browser.third_party.GestureDetector;
|
| +import org.chromium.content.browser.third_party.GestureDetector.OnDoubleTapListener;
|
| import org.chromium.content.browser.third_party.GestureDetector.OnGestureListener;
|
| import org.chromium.content.browser.LongPressDetector.LongPressDelegate;
|
| import org.chromium.content.browser.SnapScrollController;
|
| @@ -63,6 +64,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| private final ZoomManager mZoomManager;
|
| private LongPressDetector mLongPressDetector;
|
| private OnGestureListener mListener;
|
| + private OnDoubleTapListener mDoubleTapListener;
|
| private MotionEvent mCurrentDownEvent;
|
| private final MotionEventDelegate mMotionEventDelegate;
|
|
|
| @@ -113,8 +115,8 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| private int mSingleTapX;
|
| private int mSingleTapY;
|
|
|
| - // Indicate current double tap drag mode state.
|
| - private int mDoubleTapDragMode = DOUBLE_TAP_DRAG_MODE_NONE;
|
| + // Indicate current double tap mode state.
|
| + private int mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
|
|
|
| // x, y coordinates for an Anchor on double tap drag zoom.
|
| private float mDoubleTapDragZoomAnchorX;
|
| @@ -152,6 +154,9 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| private boolean mSentGestureNeedsVSync;
|
| private long mLastVSyncGestureTimeMs;
|
|
|
| + // If the page scale is fixed, double tap gesture detection can be disabled.
|
| + private boolean mHasFixedPageScale;
|
| +
|
| // Incremented and decremented when the methods onTouchEvent() and confirmTouchEvent() start
|
| // and finish execution, respectively. This provides accounting for synchronous calls to
|
| // confirmTouchEvent(), from either itself or onTouchEvent().
|
| @@ -191,10 +196,10 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
|
|
| private final float mPxToDp;
|
|
|
| - static final int DOUBLE_TAP_DRAG_MODE_NONE = 0;
|
| - static final int DOUBLE_TAP_DRAG_MODE_DETECTION_IN_PROGRESS = 1;
|
| - static final int DOUBLE_TAP_DRAG_MODE_ZOOM = 2;
|
| - static final int DOUBLE_TAP_DRAG_MODE_DISABLED = 3;
|
| + static final int DOUBLE_TAP_MODE_NONE = 0;
|
| + static final int DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS = 1;
|
| + static final int DOUBLE_TAP_MODE_DRAG_ZOOM = 2;
|
| + static final int DOUBLE_TAP_MODE_DISABLED = 3;
|
|
|
| private class TouchEventTimeoutHandler implements Runnable {
|
| private static final int TOUCH_EVENT_TIMEOUT = 200;
|
| @@ -326,11 +331,6 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| * Show the zoom picker UI.
|
| */
|
| public void invokeZoomPicker();
|
| -
|
| - /**
|
| - * @return Whether changing the page scale is not possible on the current page.
|
| - */
|
| - public boolean hasFixedPageScale();
|
| }
|
|
|
| ContentViewGestureHandler(
|
| @@ -497,20 +497,10 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| }
|
| setClickXAndY((int) x, (int) y);
|
| return true;
|
| - } else if (mMotionEventDelegate.hasFixedPageScale()) {
|
| - // If page is not user scalable, we don't need to wait
|
| - // for double tap timeout.
|
| - float x = e.getX();
|
| - float y = e.getY();
|
| - mExtraParamBundleSingleTap.putBoolean(SHOW_PRESS,
|
| - mShowPressIsCalled);
|
| - assert mExtraParamBundleSingleTap.size() == 1;
|
| -
|
| - if (sendMotionEventAsGesture(GESTURE_SINGLE_TAP_CONFIRMED, e,
|
| - mExtraParamBundleSingleTap)) {
|
| - mIgnoreSingleTap = true;
|
| - }
|
| - setClickXAndY((int) x, (int) y);
|
| + } else if (isDoubleTapDisabled()) {
|
| + // If double tap has been disabled, there is no need to wait
|
| + // for the double tap timeout.
|
| + return onSingleTapConfirmed(e);
|
| } else {
|
| // Notify Blink about this tapUp event anyway,
|
| // when none of the above conditions applied.
|
| @@ -532,9 +522,11 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| int x = (int) e.getX();
|
| int y = (int) e.getY();
|
| mExtraParamBundleSingleTap.putBoolean(SHOW_PRESS, mShowPressIsCalled);
|
| - sendMotionEventAsGesture(GESTURE_SINGLE_TAP_CONFIRMED, e,
|
| - mExtraParamBundleSingleTap);
|
| assert mExtraParamBundleSingleTap.size() == 1;
|
| + if (sendMotionEventAsGesture(GESTURE_SINGLE_TAP_CONFIRMED, e,
|
| + mExtraParamBundleSingleTap)) {
|
| + mIgnoreSingleTap = true;
|
| + }
|
|
|
| setClickXAndY(x, y);
|
| return true;
|
| @@ -542,17 +534,17 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
|
|
| @Override
|
| public boolean onDoubleTapEvent(MotionEvent e) {
|
| - if (isDoubleTapDragDisabled()) return false;
|
| + if (isDoubleTapDisabled()) return false;
|
| switch (e.getActionMasked()) {
|
| case MotionEvent.ACTION_DOWN:
|
| sendShowPressCancelIfNecessary(e);
|
| mDoubleTapDragZoomAnchorX = e.getX();
|
| mDoubleTapDragZoomAnchorY = e.getY();
|
| - mDoubleTapDragMode = DOUBLE_TAP_DRAG_MODE_DETECTION_IN_PROGRESS;
|
| + mDoubleTapMode = DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS;
|
| break;
|
| case MotionEvent.ACTION_MOVE:
|
| - if (mDoubleTapDragMode
|
| - == DOUBLE_TAP_DRAG_MODE_DETECTION_IN_PROGRESS) {
|
| + if (mDoubleTapMode
|
| + == DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS) {
|
| float distanceX = mDoubleTapDragZoomAnchorX - e.getX();
|
| float distanceY = mDoubleTapDragZoomAnchorY - e.getY();
|
|
|
| @@ -565,9 +557,9 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| pinchBegin(e.getEventTime(),
|
| Math.round(mDoubleTapDragZoomAnchorX),
|
| Math.round(mDoubleTapDragZoomAnchorY));
|
| - mDoubleTapDragMode = DOUBLE_TAP_DRAG_MODE_ZOOM;
|
| + mDoubleTapMode = DOUBLE_TAP_MODE_DRAG_ZOOM;
|
| }
|
| - } else if (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_ZOOM) {
|
| + } else if (mDoubleTapMode == DOUBLE_TAP_MODE_DRAG_ZOOM) {
|
| assert mExtraParamBundleDoubleTapDragZoom.isEmpty();
|
| sendGesture(GESTURE_SCROLL_BY, e.getEventTime(),
|
| (int) e.getX(), (int) e.getY(),
|
| @@ -584,14 +576,14 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| }
|
| break;
|
| case MotionEvent.ACTION_UP:
|
| - if (mDoubleTapDragMode != DOUBLE_TAP_DRAG_MODE_ZOOM) {
|
| + if (mDoubleTapMode != DOUBLE_TAP_MODE_DRAG_ZOOM) {
|
| // Normal double tap gesture.
|
| sendMotionEventAsGesture(GESTURE_DOUBLE_TAP, e, null);
|
| }
|
| - endDoubleTapDragMode(e);
|
| + endDoubleTapDragIfNecessary(e);
|
| break;
|
| case MotionEvent.ACTION_CANCEL:
|
| - endDoubleTapDragMode(e);
|
| + endDoubleTapDragIfNecessary(e);
|
| break;
|
| default:
|
| break;
|
| @@ -603,8 +595,8 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| @Override
|
| public void onLongPress(MotionEvent e) {
|
| if (!mZoomManager.isScaleGestureDetectionInProgress() &&
|
| - (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE ||
|
| - isDoubleTapDragDisabled())) {
|
| + (mDoubleTapMode == DOUBLE_TAP_MODE_NONE ||
|
| + isDoubleTapDisabled())) {
|
| mLastLongPressEvent = e;
|
| sendMotionEventAsGesture(GESTURE_LONG_PRESS, e, null);
|
| }
|
| @@ -630,6 +622,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| }
|
| };
|
| mListener = listener;
|
| + mDoubleTapListener = listener;
|
| mGestureDetector = new GestureDetector(context, listener);
|
| mGestureDetector.setIsLongpressEnabled(false);
|
| } finally {
|
| @@ -700,19 +693,19 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| }
|
|
|
| /**
|
| - * End DOUBLE_TAP_DRAG_MODE_ZOOM by sending GESTURE_SCROLL_END and GESTURE_PINCH_END events.
|
| + * End DOUBLE_TAP_MODE_DRAG_ZOOM by sending GESTURE_SCROLL_END and GESTURE_PINCH_END events.
|
| * @param event A hint event that its x, y, and eventTime will be used for the ending events
|
| * to send. This argument is an optional and can be null.
|
| */
|
| - void endDoubleTapDragMode(MotionEvent event) {
|
| - if (isDoubleTapDragDisabled()) return;
|
| - if (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_ZOOM) {
|
| + void endDoubleTapDragIfNecessary(MotionEvent event) {
|
| + if (mDoubleTapMode == DOUBLE_TAP_MODE_DISABLED) return;
|
| + if (mDoubleTapMode == DOUBLE_TAP_MODE_DRAG_ZOOM) {
|
| if (event == null) event = obtainActionCancelMotionEvent();
|
| pinchEnd(event.getEventTime());
|
| sendGesture(GESTURE_SCROLL_END, event.getEventTime(),
|
| (int) event.getX(), (int) event.getY(), null);
|
| }
|
| - mDoubleTapDragMode = DOUBLE_TAP_DRAG_MODE_NONE;
|
| + mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
|
| }
|
|
|
| /**
|
| @@ -844,7 +837,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| mJavaScriptIsConsumingGesture = false;
|
| endFlingIfNecessary(event.getEventTime());
|
| } else if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
|
| - endDoubleTapDragMode(null);
|
| + endDoubleTapDragIfNecessary(null);
|
| }
|
|
|
| if (offerTouchEventToJavaScript(event)) {
|
| @@ -1211,14 +1204,47 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| return mTouchEventTimeoutHandler.hasScheduledTimeoutEventForTesting();
|
| }
|
|
|
| - public void updateDoubleTapDragSupport(boolean supportDoubleTapDrag) {
|
| - assert (mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_DISABLED ||
|
| - mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE);
|
| - mDoubleTapDragMode = supportDoubleTapDrag ?
|
| - DOUBLE_TAP_DRAG_MODE_NONE : DOUBLE_TAP_DRAG_MODE_DISABLED;
|
| + /**
|
| + * Update whether double-tap gestures are supported. This allows
|
| + * double-tap gesture suppression independent of whether or not the page
|
| + * scale is fixed.
|
| + * Note: This should never be called while a double-tap gesture is in progress.
|
| + * @param supportDoubleTap Whether double-tap gestures are supported.
|
| + */
|
| + public void updateDoubleTapSupport(boolean supportDoubleTap) {
|
| + assert (mDoubleTapMode == DOUBLE_TAP_MODE_DISABLED ||
|
| + mDoubleTapMode == DOUBLE_TAP_MODE_NONE);
|
| + int doubleTapMode = supportDoubleTap ?
|
| + DOUBLE_TAP_MODE_NONE : DOUBLE_TAP_MODE_DISABLED;
|
| + if (mDoubleTapMode == doubleTapMode) return;
|
| + mDoubleTapMode = doubleTapMode;
|
| + updateDoubleTapListener();
|
| + }
|
| +
|
| + /**
|
| + * Update whether the current page has a fixed page scale.
|
| + * A fixed page scale will suppress double-tap gesture detection, allowing
|
| + * for rapid and responsive single-tap gestures.
|
| + * @param hasFixedPageScale Whether the page scale is fixed.
|
| + */
|
| + public void updateHasFixedPageScale(boolean hasFixedPageScale) {
|
| + if (mHasFixedPageScale == hasFixedPageScale) return;
|
| + mHasFixedPageScale = hasFixedPageScale;
|
| + updateDoubleTapListener();
|
| }
|
|
|
| - private boolean isDoubleTapDragDisabled() {
|
| - return mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_DISABLED;
|
| + private boolean isDoubleTapDisabled() {
|
| + return mDoubleTapMode == DOUBLE_TAP_MODE_DISABLED ||
|
| + mHasFixedPageScale;
|
| + }
|
| +
|
| + private void updateDoubleTapListener() {
|
| + if (isDoubleTapDisabled()) {
|
| + endDoubleTapDragIfNecessary(null);
|
| + mGestureDetector.setOnDoubleTapListener(null);
|
| + } else {
|
| + mGestureDetector.setOnDoubleTapListener(mDoubleTapListener);
|
| + }
|
| +
|
| }
|
| }
|
|
|