From a70778f1c9c3ae946f890b0ac7116a5df844c39b Mon Sep 17 00:00:00 2001 From: Zachary Kuznia Date: Mon, 11 Jan 2016 14:22:46 -0800 Subject: [PATCH] Renable split tapping while in Touch Explore mode. b/26496116 Change-Id: I9c819e8d3fb2332120b143cf074c0d7cc3921eae --- .../AccessibilityGestureDetector.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java index 28121b41c84fb..e31080150280f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java @@ -64,6 +64,14 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // Indicates that motion events are being collected to match a gesture. private boolean mRecognizingGesture; + // Indicates that motion events from the second pointer are being checked + // for a double tap. + private boolean mSecondFingerDoubleTap; + + // Tracks the most recent time where ACTION_POINTER_DOWN was sent for the + // second pointer. + private long mSecondPointerDownTime; + // Policy flags of the previous event. private int mPolicyFlags; @@ -102,6 +110,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mDoubleTapDetected = false; + mSecondFingerDoubleTap = false; mRecognizingGesture = true; mPreviousX = x; mPreviousY = y; @@ -133,6 +142,43 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen } } break; + + case MotionEvent.ACTION_POINTER_DOWN: + // Once a second finger is used, we're definitely not + // recognizing a gesture. + cancelGesture(); + + if (event.getPointerCount() == 2) { + // If this was the second finger, attempt to recognize double + // taps on it. + mSecondFingerDoubleTap = true; + mSecondPointerDownTime = event.getEventTime(); + } else { + // If there are more than two fingers down, stop watching + // for a double tap. + mSecondFingerDoubleTap = false; + } + break; + + case MotionEvent.ACTION_POINTER_UP: + // If we're detecting taps on the second finger, see if we + // should finish the double tap. + if (mSecondFingerDoubleTap && maybeFinishDoubleTap(event, policyFlags)) { + return true; + } + break; + } + + // If we're detecting taps on the second finger, map events from the + // finger to the first finger. + if (mSecondFingerDoubleTap) { + MotionEvent newEvent = mapSecondPointerToFirstPointer(event); + if (newEvent == null) { + return false; + } + boolean handled = mGestureDetector.onTouchEvent(newEvent); + newEvent.recycle(); + return handled; } if (!mRecognizingGesture) { @@ -146,6 +192,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen public void clear() { mFirstTapDetected = false; mDoubleTapDetected = false; + mSecondFingerDoubleTap = false; cancelGesture(); mStrokeBuffer.clear(); } @@ -229,4 +276,28 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen return false; } + + private MotionEvent mapSecondPointerToFirstPointer(MotionEvent event) { + // Only map basic events when two fingers are down. + if (event.getPointerCount() != 2 || + (event.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN && + event.getActionMasked() != MotionEvent.ACTION_POINTER_UP && + event.getActionMasked() != MotionEvent.ACTION_MOVE)) { + return null; + } + + int action = event.getActionMasked(); + + if (action == MotionEvent.ACTION_POINTER_DOWN) { + action = MotionEvent.ACTION_DOWN; + } else if (action == MotionEvent.ACTION_POINTER_UP) { + action = MotionEvent.ACTION_UP; + } + + // Map the information from the second pointer to the first. + return MotionEvent.obtain(mSecondPointerDownTime, event.getEventTime(), action, + event.getX(1), event.getY(1), event.getPressure(1), event.getSize(1), + event.getMetaState(), event.getXPrecision(), event.getYPrecision(), + event.getDeviceId(), event.getEdgeFlags()); + } }