diff options
author | Ryan Lin <ryanlwlin@google.com> | 2020-06-24 08:51:50 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-06-24 08:51:50 +0000 |
commit | 18905eb623ee5b30c1538a0add0ee1aec33df4be (patch) | |
tree | 483ce9fa4fbc717a5bf1a696219bcaae4b593344 /services/accessibility | |
parent | 71f139471c11200d478e4d6dafe9189851814cd8 (diff) | |
parent | 2047cd4ba1feebe88ad5eb3f15eaf5f3b3bbe17d (diff) |
Merge "Fix the multi-fingers gesture conflict with TouchExplorer" into rvc-dev
Diffstat (limited to 'services/accessibility')
2 files changed, 70 insertions, 4 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java index afe6238ca38f..b7f8e674f3ba 100644 --- a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java @@ -26,6 +26,7 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logMagnificationTripleTap; import static com.android.server.accessibility.gestures.GestureUtils.distance; +import static com.android.server.accessibility.gestures.GestureUtils.distanceClosestPointerToPoint; import static java.lang.Math.abs; import static java.util.Arrays.asList; @@ -37,6 +38,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.PointF; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -615,6 +617,7 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1; private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2; + private static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3; final int mLongTapMinDelay; final int mSwipeMinDistance; @@ -626,6 +629,7 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler private MotionEvent mPreLastDown; private MotionEvent mLastUp; private MotionEvent mPreLastUp; + private PointF mSecondPointerDownLocation = new PointF(Float.NaN, Float.NaN); private long mLastDetectingDownEventTime; @@ -656,6 +660,10 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler transitionToDelegatingStateAndClear(); } break; + case MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE: { + transitToPanningScalingStateAndClear(); + } + break; default: { throw new IllegalArgumentException("Unknown message type: " + type); } @@ -702,14 +710,20 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler } break; case ACTION_POINTER_DOWN: { - if (mMagnificationController.isMagnifying(mDisplayId)) { - transitionTo(mPanningScalingState); - clear(); + if (mMagnificationController.isMagnifying(mDisplayId) + && event.getPointerCount() == 2) { + storeSecondPointerDownLocation(event); + mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE, + ViewConfiguration.getTapTimeout()); } else { transitionToDelegatingStateAndClear(); } } break; + case ACTION_POINTER_UP: { + transitionToDelegatingStateAndClear(); + } + break; case ACTION_MOVE: { if (isFingerDown() && distance(mLastDown, /* move */ event) > mSwipeMinDistance) { @@ -719,11 +733,19 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler // For convenience, viewport dragging takes precedence // over insta-delegating on 3tap&swipe // (which is a rare combo to be used aside from magnification) - if (isMultiTapTriggered(2 /* taps */)) { + if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) { transitionToViewportDraggingStateAndClear(event); + } else if (isMagnifying() && event.getPointerCount() == 2) { + //Primary pointer is swiping, so transit to PanningScalingState + transitToPanningScalingStateAndClear(); } else { transitionToDelegatingStateAndClear(); } + } else if (isMagnifying() && secondPointerDownValid() + && distanceClosestPointerToPoint( + mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) { + //Second pointer is swiping, so transit to PanningScalingState + transitToPanningScalingStateAndClear(); } } break; @@ -755,6 +777,21 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler } } + private void storeSecondPointerDownLocation(MotionEvent event) { + final int index = event.getActionIndex(); + mSecondPointerDownLocation.set(event.getX(index), event.getY(index)); + } + + private boolean secondPointerDownValid() { + return !(Float.isNaN(mSecondPointerDownLocation.x) && Float.isNaN( + mSecondPointerDownLocation.y)); + } + + private void transitToPanningScalingStateAndClear() { + transitionTo(mPanningScalingState); + clear(); + } + public boolean isMultiTapTriggered(int numTaps) { // Shortcut acts as the 2 initial taps @@ -822,11 +859,13 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler setShortcutTriggered(false); removePendingDelayedMessages(); clearDelayedMotionEvents(); + mSecondPointerDownLocation.set(Float.NaN, Float.NaN); } private void removePendingDelayedMessages() { mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD); mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE); + mHandler.removeMessages(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE); } private void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent, @@ -890,6 +929,7 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler transitionTo(mDelegatingState); sendDelayedMotionEvents(); removePendingDelayedMessages(); + mSecondPointerDownLocation.set(Float.NaN, Float.NaN); } private void onTripleTap(MotionEvent up) { @@ -907,6 +947,10 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler } } + private boolean isMagnifying() { + return mMagnificationController.isMagnifying(mDisplayId); + } + void transitionToViewportDraggingStateAndClear(MotionEvent down) { if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()"); diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/GestureUtils.java b/services/accessibility/java/com/android/server/accessibility/gestures/GestureUtils.java index ac6748089314..ec3041848356 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/GestureUtils.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/GestureUtils.java @@ -1,5 +1,6 @@ package com.android.server.accessibility.gestures; +import android.graphics.PointF; import android.util.MathUtils; import android.view.MotionEvent; @@ -38,6 +39,27 @@ public final class GestureUtils { return MathUtils.dist(first.getX(), first.getY(), second.getX(), second.getY()); } + /** + * Returns the minimum distance between {@code pointerDown} and each pointer of + * {@link MotionEvent}. + * + * @param pointerDown The action pointer location of the {@link MotionEvent} with + * {@link MotionEvent#ACTION_DOWN} or {@link MotionEvent#ACTION_POINTER_DOWN} + * @param moveEvent The {@link MotionEvent} with {@link MotionEvent#ACTION_MOVE} + * @return the movement of the pointer. + */ + public static double distanceClosestPointerToPoint(PointF pointerDown, MotionEvent moveEvent) { + float movement = Float.MAX_VALUE; + for (int i = 0; i < moveEvent.getPointerCount(); i++) { + final float moveDelta = MathUtils.dist(pointerDown.x, pointerDown.y, moveEvent.getX(i), + moveEvent.getY(i)); + if (movement > moveDelta) { + movement = moveDelta; + } + } + return movement; + } + public static boolean isTimedOut(MotionEvent firstUp, MotionEvent secondUp, int timeout) { final long deltaTime = secondUp.getEventTime() - firstUp.getEventTime(); return (deltaTime >= timeout); |