From 6dc501b986dabc049ea2bf414b47910079dff46c Mon Sep 17 00:00:00 2001 From: Ameer Armaly Date: Tue, 4 Feb 2020 14:04:18 -0800 Subject: [PATCH] Fix crash when a motion event doesn't include locations for all pointers. When performing a multi-finger gesture, if one finger goes up before the rest of the fingers have finished moving, we need to account for that finger not being present in subsequent motion events. Bug: 148880038 Bug:136131815 Test: Enable talkback. Enable debugging in TouchExplorer. Perform multi-finger gestures in such a way that one finger goes up just before the other fingers finish moving. Inspect logs. Test: atest GestureManifoldTest AccessibilityGestureDetectorTest TouchExplorerTest Change-Id: Ic3158301be657f39232db9f5b3006f87d8d83c4f --- .../gestures/MultiFingerSwipe.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java index 8249239e3602e..96ef2b54fab9f 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java @@ -250,11 +250,29 @@ class MultiFingerSwipe extends GestureMatcher { @Override protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) { - for (int pointerIndex = 0; pointerIndex < rawEvent.getPointerCount(); ++pointerIndex) { + for (int pointerIndex = 0; pointerIndex < mTargetFingerCount; ++pointerIndex) { + if (mPointerIds[pointerIndex] == INVALID_POINTER_ID) { + // Fingers have started to move before the required number of fingers are down. + // However, they can still move less than the touch slop and still be considered + // touching, not moving. + // So we just ignore fingers that haven't been assigned a pointer id and process + // those who have. + continue; + } if (DEBUG) { Slog.d(getGestureName(), "Processing move on finger " + pointerIndex); } int index = rawEvent.findPointerIndex(mPointerIds[pointerIndex]); + if (index < 0) { + // This finger is not present in this event. It could have gone up just before this + // movement. + if (DEBUG) { + Slog.d( + getGestureName(), + "Finger " + pointerIndex + " not found in this event. skipping."); + } + continue; + } final float x = rawEvent.getX(index); final float y = rawEvent.getY(index); if (x < 0f || y < 0f) {