| 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 02d851dab556a4910369bf34592b18edcca484c7..2b23fc97c7ebe7f52dd43cd849e929826285a4cb 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
|
| @@ -56,6 +56,12 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| */
|
| static final String DELTA = "Delta";
|
|
|
| + /**
|
| + * Used by UMA stat for tracking accidental double tap navigations. Specifies the amount of
|
| + * time after a double tap within which actions will be recorded to the UMA stat.
|
| + */
|
| + private static final long ACTION_AFTER_DOUBLE_TAP_WINDOW_MS = 5000;
|
| +
|
| private final Bundle mExtraParamBundleSingleTap;
|
| private final Bundle mExtraParamBundleFling;
|
| private final Bundle mExtraParamBundleScroll;
|
| @@ -176,6 +182,10 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| // Whether the click delay should always be disabled by sending clicks for double tap gestures.
|
| private final boolean mDisableClickDelay;
|
|
|
| + // Used for tracking UMA ActionAfterDoubleTap to tell user's immediate
|
| + // action after a double tap.
|
| + private long mLastDoubleTapTimeMs;
|
| +
|
| static final int GESTURE_SHOW_PRESSED_STATE = 0;
|
| static final int GESTURE_DOUBLE_TAP = 1;
|
| static final int GESTURE_SINGLE_TAP_UP = 2;
|
| @@ -342,6 +352,19 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| * Show the zoom picker UI.
|
| */
|
| public void invokeZoomPicker();
|
| +
|
| + /**
|
| + * Send action after dobule tap for UMA stat tracking.
|
| + * @param type The action that occured
|
| + * @param clickDelayEnabled Whether the tap down delay is active
|
| + */
|
| + public void sendActionAfterDoubleTapUMA(int type, boolean clickDelayEnabled);
|
| +
|
| + /**
|
| + * Send single tap UMA.
|
| + * @param type The tap type: delayed or undelayed
|
| + */
|
| + public void sendSingleTapUMA(int type);
|
| }
|
|
|
| ContentViewGestureHandler(
|
| @@ -518,6 +541,12 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| mIgnoreSingleTap = true;
|
| }
|
| setClickXAndY((int) x, (int) y);
|
| +
|
| + mMotionEventDelegate.sendSingleTapUMA(
|
| + isDoubleTapDisabled() ?
|
| + ContentViewCore.UMASingleTapType.UNDELAYED_TAP :
|
| + ContentViewCore.UMASingleTapType.DELAYED_TAP);
|
| +
|
| return true;
|
| } else if (isDoubleTapDisabled() || mDisableClickDelay) {
|
| // If double tap has been disabled, there is no need to wait
|
| @@ -541,6 +570,11 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| // These corner cases should be ignored.
|
| if (mLongPressDetector.isInLongPress() || mIgnoreSingleTap) return true;
|
|
|
| + mMotionEventDelegate.sendSingleTapUMA(
|
| + isDoubleTapDisabled() ?
|
| + ContentViewCore.UMASingleTapType.UNDELAYED_TAP :
|
| + ContentViewCore.UMASingleTapType.DELAYED_TAP);
|
| +
|
| int x = (int) e.getX();
|
| int y = (int) e.getY();
|
| mExtraParamBundleSingleTap.putBoolean(SHOW_PRESS, mShowPressIsCalled);
|
| @@ -1148,12 +1182,16 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
|
|
| private boolean sendMotionEventAsGesture(
|
| int type, MotionEvent event, Bundle extraParams) {
|
| - return mMotionEventDelegate.sendGesture(type, event.getEventTime(),
|
| + return sendGesture(type, event.getEventTime(),
|
| (int) event.getX(), (int) event.getY(), extraParams);
|
| }
|
|
|
| private boolean sendGesture(
|
| int type, long timeMs, int x, int y, Bundle extraParams) {
|
| + updateDoubleTapUmaTimer();
|
| +
|
| + if (type == GESTURE_DOUBLE_TAP) reportDoubleTap();
|
| +
|
| return mMotionEventDelegate.sendGesture(type, timeMs, x, y, extraParams);
|
| }
|
|
|
| @@ -1162,7 +1200,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| // VSync should only be signalled if the sent gesture was generated from a touch event.
|
| mSentGestureNeedsVSync = mInputEventsDeliveredAtVSync && mTouchEventHandlingStackDepth > 0;
|
| mLastVSyncGestureTimeMs = timeMs;
|
| - return mMotionEventDelegate.sendGesture(type, timeMs, x, y, extraParams);
|
| + return sendGesture(type, timeMs, x, y, extraParams);
|
| }
|
|
|
| private boolean sendTapEndingEventAsGesture(int type, MotionEvent e, Bundle extraParams) {
|
| @@ -1289,4 +1327,46 @@ class ContentViewGestureHandler implements LongPressDelegate {
|
| }
|
|
|
| }
|
| +
|
| + private void reportDoubleTap() {
|
| + // Make sure repeated double taps don't get silently dropped from
|
| + // the statistics.
|
| + if (mLastDoubleTapTimeMs > 0) {
|
| + mMotionEventDelegate.sendActionAfterDoubleTapUMA(
|
| + ContentViewCore.UMAActionAfterDoubleTap.NO_ACTION, !mDisableClickDelay);
|
| + }
|
| +
|
| + mLastDoubleTapTimeMs = SystemClock.uptimeMillis();
|
| + }
|
| +
|
| + /**
|
| + * Update the UMA stat tracking accidental double tap navigations with a user action.
|
| + * @param type The action the user performed, one of the UMAActionAfterDoubleTap values
|
| + * defined in ContentViewCore.
|
| + */
|
| + public void reportActionAfterDoubleTapUMA(int type) {
|
| + updateDoubleTapUmaTimer();
|
| +
|
| + if (mLastDoubleTapTimeMs == 0) return;
|
| +
|
| + long nowMs = SystemClock.uptimeMillis();
|
| + if ((nowMs - mLastDoubleTapTimeMs) < ACTION_AFTER_DOUBLE_TAP_WINDOW_MS) {
|
| + mMotionEventDelegate.sendActionAfterDoubleTapUMA(type, !mDisableClickDelay);
|
| + mLastDoubleTapTimeMs = 0;
|
| + }
|
| + }
|
| +
|
| + // Watch for the UMA "action after double tap" timer expiring and reset
|
| + // the timer if necessary.
|
| + private void updateDoubleTapUmaTimer() {
|
| + if (mLastDoubleTapTimeMs == 0) return;
|
| +
|
| + long nowMs = SystemClock.uptimeMillis();
|
| + if ((nowMs - mLastDoubleTapTimeMs) >= ACTION_AFTER_DOUBLE_TAP_WINDOW_MS) {
|
| + // Time expired, user took no action (that we care about).
|
| + mMotionEventDelegate.sendActionAfterDoubleTapUMA(
|
| + ContentViewCore.UMAActionAfterDoubleTap.NO_ACTION, !mDisableClickDelay);
|
| + mLastDoubleTapTimeMs = 0;
|
| + }
|
| + }
|
| }
|
|
|