diff options
author | 2022-09-15 13:49:23 +0000 | |
---|---|---|
committer | 2022-09-23 13:38:02 +0000 | |
commit | 2800fb0c6b56711c6daf70491270dbea89fbf660 (patch) | |
tree | 4005bd4ceb50ddc62585e94e87df907ff56f48e1 | |
parent | 9425077b65c67bea06e87ea06d6f16d7eb8ff845 (diff) |
Use TWO_FINGER_SWIPE classification for touchpad scroll events
This allows apps to distinguish the fake finger created for touchpad
scrolling from an actual finger.
Bug: 246758376
Test: add classification to InputDispatcher's outbound event logs and
check the new value is used when scrolling
Change-Id: Ia90f9984e75ad6fde2d0e42628ab42eab371b7a5
-rw-r--r-- | include/android/input.h | 6 | ||||
-rw-r--r-- | include/input/Input.h | 4 | ||||
-rw-r--r-- | libs/input/Input.cpp | 2 | ||||
-rw-r--r-- | services/inputflinger/InputProcessor.cpp | 9 | ||||
-rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 59 | ||||
-rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.h | 3 | ||||
-rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 8 |
7 files changed, 69 insertions, 22 deletions
diff --git a/include/android/input.h b/include/android/input.h index 8cd9e9551a..7080386df7 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -840,6 +840,12 @@ enum AMotionClassification : uint32_t { * This classification type should be used to accelerate the long press behaviour. */ AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS = 2, + /** + * Classification constant: touchpad two-finger swipe. + * + * The current event stream represents the user swiping with two fingers on a touchpad. + */ + AMOTION_EVENT_CLASSIFICATION_TWO_FINGER_SWIPE = 3, }; /** diff --git a/include/input/Input.h b/include/input/Input.h index 2dd651e9d7..172e5b46d8 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -289,6 +289,10 @@ enum class MotionClassification : uint8_t { * The current gesture likely represents a user intentionally exerting force on the touchscreen. */ DEEP_PRESS = AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS, + /** + * The current gesture represents the user swiping with two fingers on a touchpad. + */ + TWO_FINGER_SWIPE = AMOTION_EVENT_CLASSIFICATION_TWO_FINGER_SWIPE, }; /** diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 2b7483d27d..579b28e588 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -87,6 +87,8 @@ const char* motionClassificationToString(MotionClassification classification) { return "AMBIGUOUS_GESTURE"; case MotionClassification::DEEP_PRESS: return "DEEP_PRESS"; + case MotionClassification::TWO_FINGER_SWIPE: + return "TWO_FINGER_SWIPE"; } } diff --git a/services/inputflinger/InputProcessor.cpp b/services/inputflinger/InputProcessor.cpp index 0749441694..126cb33b8d 100644 --- a/services/inputflinger/InputProcessor.cpp +++ b/services/inputflinger/InputProcessor.cpp @@ -22,6 +22,7 @@ #include <android-base/stringprintf.h> #include <android/binder_manager.h> #include <android/binder_process.h> +#include <input/Input.h> #include <inttypes.h> #include <log/log.h> #include <algorithm> @@ -436,7 +437,13 @@ void InputProcessor::notifyMotion(const NotifyMotionArgs* args) { mQueuedListener.notifyMotion(args); } else { NotifyMotionArgs newArgs(*args); - newArgs.classification = mMotionClassifier->classify(newArgs); + const MotionClassification newClassification = mMotionClassifier->classify(newArgs); + LOG_ALWAYS_FATAL_IF(args->classification != MotionClassification::NONE && + newClassification != MotionClassification::NONE, + "Conflicting classifications %s (new) and %s (old)!", + motionClassificationToString(newClassification), + motionClassificationToString(args->classification)); + newArgs.classification = newClassification; mQueuedListener.notifyMotion(&newArgs); } } // release lock diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index 8c241f2f09..4cd2cce9f9 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -1950,7 +1950,8 @@ void TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readTime, uint32_t pol mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); mCurrentMotionAborted = true; } } @@ -1970,7 +1971,8 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } } else { // There may be pointers going up and pointers going down and pointers moving @@ -2005,7 +2007,8 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t mLastCookedState.cookedPointerData.pointerProperties, mLastCookedState.cookedPointerData.pointerCoords, mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); dispatchedIdBits.clearBit(upId); mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId); } @@ -2020,7 +2023,8 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } // Dispatch pointer down events using the new pointer locations. @@ -2038,7 +2042,8 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, - downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime); + downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } } } @@ -2054,7 +2059,7 @@ void TouchInputMapper::dispatchHoverExit(nsecs_t when, nsecs_t readTime, uint32_ mLastCookedState.cookedPointerData.pointerCoords, mLastCookedState.cookedPointerData.idToIndex, mLastCookedState.cookedPointerData.hoveringIdBits, -1, mOrientedXPrecision, - mOrientedYPrecision, mDownTime); + mOrientedYPrecision, mDownTime, MotionClassification::NONE); mSentHoverEnter = false; } } @@ -2071,7 +2076,8 @@ void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, mCurrentCookedState.cookedPointerData.hoveringIdBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); mSentHoverEnter = true; } @@ -2081,7 +2087,8 @@ void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, mCurrentCookedState.cookedPointerData.hoveringIdBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } } @@ -2098,7 +2105,8 @@ void TouchInputMapper::dispatchButtonRelease(nsecs_t when, nsecs_t readTime, uin mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } } @@ -2115,7 +2123,8 @@ void TouchInputMapper::dispatchButtonPress(nsecs_t when, nsecs_t readTime, uint3 mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1, - mOrientedXPrecision, mOrientedYPrecision, mDownTime); + mOrientedXPrecision, mOrientedYPrecision, mDownTime, + MotionClassification::NONE); } } @@ -2502,6 +2511,10 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u // Send events! int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mCurrentCookedState.buttonState; + const MotionClassification classification = + mPointerGesture.currentGestureMode == PointerGesture::Mode::SWIPE + ? MotionClassification::TWO_FINGER_SWIPE + : MotionClassification::NONE; uint32_t flags = 0; @@ -2542,7 +2555,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, dispatchedGestureIdBits, -1, 0, 0, - mPointerGesture.downTime); + mPointerGesture.downTime, classification); dispatchedGestureIdBits.clear(); } else { @@ -2561,7 +2574,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, dispatchedGestureIdBits, id, 0, - 0, mPointerGesture.downTime); + 0, mPointerGesture.downTime, classification); dispatchedGestureIdBits.clearBit(id); } @@ -2575,7 +2588,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, -1, 0, 0, - mPointerGesture.downTime); + mPointerGesture.downTime, classification); } // Send motion events for all pointers that went down. @@ -2595,7 +2608,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, id, 0, - 0, mPointerGesture.downTime); + 0, mPointerGesture.downTime, classification); } } @@ -2606,7 +2619,8 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, - mPointerGesture.currentGestureIdBits, -1, 0, 0, mPointerGesture.downTime); + mPointerGesture.currentGestureIdBits, -1, 0, 0, mPointerGesture.downTime, + MotionClassification::NONE); } else if (dispatchedGestureIdBits.isEmpty() && !mPointerGesture.lastGestureIdBits.isEmpty()) { // Synthesize a hover move event after all pointers go up to indicate that // the pointer is hovering again even if the user is not currently touching @@ -2653,6 +2667,10 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u } void TouchInputMapper::abortPointerGestures(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) { + const MotionClassification classification = + mPointerGesture.lastGestureMode == PointerGesture::Mode::SWIPE + ? MotionClassification::TWO_FINGER_SWIPE + : MotionClassification::NONE; // Cancel previously dispatches pointers. if (!mPointerGesture.lastGestureIdBits.isEmpty()) { int32_t metaState = getContext()->getGlobalMetaState(); @@ -2661,7 +2679,7 @@ void TouchInputMapper::abortPointerGestures(nsecs_t when, nsecs_t readTime, uint metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, mPointerGesture.lastGestureIdBits, -1, - 0, 0, mPointerGesture.downTime); + 0, 0, mPointerGesture.downTime, classification); } // Reset the current pointer gesture. @@ -3611,7 +3629,8 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t p int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords, const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, - float yPrecision, nsecs_t downTime) { + float yPrecision, nsecs_t downTime, + MotionClassification classification) { PointerCoords pointerCoords[MAX_POINTERS]; PointerProperties pointerProperties[MAX_POINTERS]; uint32_t pointerCount = 0; @@ -3659,9 +3678,9 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t p [this](TouchVideoFrame& frame) { frame.rotate(this->mInputDeviceOrientation); }); NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId, policyFlags, action, actionButton, flags, metaState, buttonState, - MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties, - pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition, - downTime, std::move(frames)); + classification, edgeFlags, pointerCount, pointerProperties, pointerCoords, + xPrecision, yPrecision, xCursorPosition, yCursorPosition, downTime, + std::move(frames)); getListener().notifyMotion(&args); } diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index bd4cff6d9a..31806e12e3 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -779,7 +779,8 @@ private: int32_t action, int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords, const uint32_t* idToIndex, BitSet32 idBits, - int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime); + int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime, + MotionClassification classification); // Updates pointer coords and properties for pointers with specified ids that have moved. // Returns true if any of them changed. diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index ee6993ced0..097659b631 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -9751,6 +9751,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) { ASSERT_EQ(1U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); ASSERT_NO_FATAL_FAILURE( assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)); @@ -9772,6 +9773,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) { ASSERT_EQ(1U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0, movingDistance * mPointerMovementScale, 1, 0, 0, 0, 0, 0, 0, 0)); @@ -9809,6 +9811,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) ASSERT_EQ(1U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); ASSERT_NO_FATAL_FAILURE( assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)); @@ -9830,6 +9833,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) ASSERT_EQ(1U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification); // New coordinate is the scaled relative coordinate from the initial coordinate. ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0, movingDistance * mPointerMovementScale, 1, 0, 0, 0, @@ -9863,6 +9867,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { ASSERT_EQ(1U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates. ASSERT_NO_FATAL_FAILURE( assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)); @@ -9892,9 +9897,11 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); ASSERT_EQ(2U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); // Two pointers' scaled relative coordinates from their initial centroid. // Initial y coordinates are 0 as y1 and y2 have the same value. float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale; @@ -9924,6 +9931,7 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { ASSERT_EQ(2U, motionArgs.pointerCount); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1, movingDistance * 2 * mPointerMovementScale, 1, 0, 0, 0, 0, 0, 0, 0)); |