Merge "Fix delay when multi-tap out of distance slop."

This commit is contained in:
Rhed Jao
2019-01-23 05:58:13 +00:00
committed by Android (Google) Code Review
2 changed files with 64 additions and 4 deletions

View File

@@ -676,6 +676,10 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
// 3tap and hold
afterLongTapTimeoutTransitionToDraggingState(event);
} else if (isTapOutOfDistanceSlop()) {
transitionToDelegatingStateAndClear();
} else if (mDetectTripleTap
// If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
// to ensure reachability of
@@ -921,6 +925,31 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
// TODO: multi-display support for magnification gesture handler
mMagnificationController.setForceShowMagnifiableBounds(Display.DEFAULT_DISPLAY, state);
}
/**
* Detects if last action down is out of distance slop between with previous
* one, when triple tap is enabled.
*
* @return true if tap is out of distance slop
*/
boolean isTapOutOfDistanceSlop() {
if (!mDetectTripleTap) return false;
if (mPreLastDown == null || mLastDown == null) {
return false;
}
final boolean outOfDistanceSlop =
GestureUtils.distance(mPreLastDown, mLastDown) > mMultiTapMaxDistance;
if (tapCount() > 0) {
return outOfDistanceSlop;
}
// There's no tap in the queue here. We still need to check if this is the case that
// user tap screen quickly and out of distance slop.
if (outOfDistanceSlop
&& !GestureUtils.isTimedOut(mPreLastDown, mLastDown, mMultiTapMaxDelay)) {
return true;
}
return false;
}
}
private void zoomOn(float centerX, float centerY) {

View File

@@ -308,6 +308,24 @@ public class MagnificationGestureHandlerTest {
assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED);
}
@Test
public void testMultiTap_outOfDistanceSlop_shouldInIdle() {
// All delay motion events should be sent, if multi-tap with out of distance slop.
// STATE_IDLE will check if tapCount() < 2.
allowEventDelegation();
assertStaysIn(STATE_IDLE, () -> {
tap();
tap(DEFAULT_X * 2, DEFAULT_Y * 2);
});
assertStaysIn(STATE_IDLE, () -> {
tap();
tap(DEFAULT_X * 2, DEFAULT_Y * 2);
tap();
tap(DEFAULT_X * 2, DEFAULT_Y * 2);
tap();
});
}
private void assertZoomsImmediatelyOnSwipeFrom(int state) {
goFromStateIdleTo(state);
swipeAndHold();
@@ -531,6 +549,11 @@ public class MagnificationGestureHandlerTest {
send(upEvent());
}
private void tap(float x, float y) {
send(downEvent(x, y));
send(upEvent(x, y));
}
private void swipe() {
swipeAndHold();
send(upEvent());
@@ -572,18 +595,26 @@ public class MagnificationGestureHandlerTest {
}
private MotionEvent downEvent() {
return downEvent(DEFAULT_X, DEFAULT_Y);
}
private MotionEvent downEvent(float x, float y) {
mLastDownTime = mClock.now();
return fromTouchscreen(MotionEvent.obtain(mLastDownTime, mLastDownTime,
ACTION_DOWN, DEFAULT_X, DEFAULT_Y, 0));
ACTION_DOWN, x, y, 0));
}
private MotionEvent upEvent() {
return upEvent(mLastDownTime);
return upEvent(DEFAULT_X, DEFAULT_Y, mLastDownTime);
}
private MotionEvent upEvent(long downTime) {
private MotionEvent upEvent(float x, float y) {
return upEvent(x, y, mLastDownTime);
}
private MotionEvent upEvent(float x, float y, long downTime) {
return fromTouchscreen(MotionEvent.obtain(downTime, mClock.now(),
MotionEvent.ACTION_UP, DEFAULT_X, DEFAULT_Y, 0));
MotionEvent.ACTION_UP, x, y, 0));
}
private MotionEvent pointerEvent(int action, float x, float y) {