diff options
author | 2022-10-05 15:55:48 +0000 | |
---|---|---|
committer | 2022-10-13 10:39:16 +0000 | |
commit | 39b7ca2933ffde9094aed908a507158d20be3d7a (patch) | |
tree | a0e3ebef1f565839d919186480e0b4a833990a64 | |
parent | f1f601e01d6af47d658b7ba30fbe8f4b8f84b283 (diff) |
Report motion offsets for touchpad swipes
Adds two new axes, AXIS_GESTURE_X_OFFSET and AXIS_GESTURE_Y_OFFSET,
which report the movement of swipe gestures on the touchpad as a
fraction of the touchpad's size.
Bug: 246758376
Test: check axis values come through in a test app
Change-Id: I313410053a8db13273bd05a33d3a6a1f75081dae
-rw-r--r-- | include/android/input.h | 17 | ||||
-rw-r--r-- | libs/input/InputEventLabels.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/InputCommonConverter.cpp | 5 | ||||
-rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 30 | ||||
-rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 46 |
5 files changed, 89 insertions, 13 deletions
diff --git a/include/android/input.h b/include/android/input.h index d906af6e0c..5d19c5cb13 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -771,6 +771,21 @@ enum { * The interpretation of a generic axis is device-specific. */ AMOTION_EVENT_AXIS_GENERIC_16 = 47, + /** + * Axis constant: X gesture offset axis of a motion event. + * + * - For a touch pad, reports the distance that a swipe gesture has moved in the X axis, as a + * proportion of the touch pad's size. For example, if a touch pad is 1000 units wide, and a + * swipe gesture starts at X = 500 then moves to X = 400, this axis would have a value of + * -0.1. + */ + AMOTION_EVENT_AXIS_GESTURE_X_OFFSET = 48, + /** + * Axis constant: Y gesture offset axis of a motion event. + * + * The same as {@link AMOTION_EVENT_AXIS_GESTURE_X_OFFSET}, but for the Y axis. + */ + AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET = 49, /** * Note: This is not an "Axis constant". It does not represent any axis, nor should it be used @@ -778,7 +793,7 @@ enum { * to make some computations (like iterating through all possible axes) cleaner. * Please update the value accordingly if you add a new axis. */ - AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE = AMOTION_EVENT_AXIS_GENERIC_16, + AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE = AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, // NOTE: If you add a new axis here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp index 163a2fe924..b78fae3027 100644 --- a/libs/input/InputEventLabels.cpp +++ b/libs/input/InputEventLabels.cpp @@ -391,7 +391,9 @@ namespace android { DEFINE_AXIS(GENERIC_13), \ DEFINE_AXIS(GENERIC_14), \ DEFINE_AXIS(GENERIC_15), \ - DEFINE_AXIS(GENERIC_16) + DEFINE_AXIS(GENERIC_16), \ + DEFINE_AXIS(GESTURE_X_OFFSET), \ + DEFINE_AXIS(GESTURE_Y_OFFSET) // NOTE: If you add new LEDs here, you must also add them to Input.h #define LEDS_SEQUENCE \ diff --git a/services/inputflinger/InputCommonConverter.cpp b/services/inputflinger/InputCommonConverter.cpp index 23b6f57b23..6db89d4759 100644 --- a/services/inputflinger/InputCommonConverter.cpp +++ b/services/inputflinger/InputCommonConverter.cpp @@ -263,8 +263,11 @@ static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_13) == common static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_14) == common::Axis::GENERIC_14); static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_15) == common::Axis::GENERIC_15); static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_16) == common::Axis::GENERIC_16); +// TODO(hcutts): add GESTURE_X_OFFSET and GESTURE_Y_OFFSET. +// If you added a new axis, consider whether this should also be exposed as a HAL axis. Update the +// static_assert below and add the new axis here, or leave a comment summarizing your decision. static_assert(static_cast<common::Axis>(AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE) == - static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_16)); + static_cast<common::Axis>(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET)); static common::VideoFrame getHalVideoFrame(const TouchVideoFrame& frame) { common::VideoFrame out; diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index da58efde31..7f6785eaa6 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -3175,7 +3175,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi mPointerGesture.referenceIdBits = mCurrentCookedState.fingerIdBits; // Add delta for all fingers and calculate a common movement delta. - float commonDeltaX = 0, commonDeltaY = 0; + int32_t commonDeltaRawX = 0, commonDeltaRawY = 0; BitSet32 commonIdBits(mLastCookedState.fingerIdBits.value & mCurrentCookedState.fingerIdBits.value); for (BitSet32 idBits(commonIdBits); !idBits.isEmpty();) { @@ -3188,11 +3188,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi delta.dy += cpd.y - lpd.y; if (first) { - commonDeltaX = delta.dx; - commonDeltaY = delta.dy; + commonDeltaRawX = delta.dx; + commonDeltaRawY = delta.dy; } else { - commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); - commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); + commonDeltaRawX = calculateCommonVector(commonDeltaRawX, delta.dx); + commonDeltaRawY = calculateCommonVector(commonDeltaRawY, delta.dy); } } @@ -3298,7 +3298,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi // Move the reference points based on the overall group motion of the fingers // except in PRESS mode while waiting for a transition to occur. if (mPointerGesture.currentGestureMode != PointerGesture::Mode::PRESS && - (commonDeltaX || commonDeltaY)) { + (commonDeltaRawX || commonDeltaRawY)) { for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty();) { uint32_t id = idBits.clearFirstMarkedBit(); PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; @@ -3306,11 +3306,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi delta.dy = 0; } - mPointerGesture.referenceTouchX += commonDeltaX; - mPointerGesture.referenceTouchY += commonDeltaY; + mPointerGesture.referenceTouchX += commonDeltaRawX; + mPointerGesture.referenceTouchY += commonDeltaRawY; - commonDeltaX *= mPointerXMovementScale; - commonDeltaY *= mPointerYMovementScale; + float commonDeltaX = commonDeltaRawX * mPointerXMovementScale; + float commonDeltaY = commonDeltaRawY * mPointerYMovementScale; rotateDelta(mInputDeviceOrientation, &commonDeltaX, &commonDeltaY); mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY); @@ -3341,6 +3341,16 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); + if (mPointerGesture.currentGestureMode == PointerGesture::Mode::SWIPE) { + float xOffset = static_cast<float>(commonDeltaRawX) / + (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue); + float yOffset = static_cast<float>(commonDeltaRawY) / + (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue); + mPointerGesture.currentGestureCoords[0] + .setAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, xOffset); + mPointerGesture.currentGestureCoords[0] + .setAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, yOffset); + } } else if (mPointerGesture.currentGestureMode == PointerGesture::Mode::FREEFORM) { // FREEFORM mode. ALOGD_IF(DEBUG_GESTURES, diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index dded6a13e0..1e26265b46 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -10085,6 +10085,52 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { 0, 0, 0, 0, 0)); } +TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) { + preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); + NotifyMotionArgs motionArgs; + + // Place two fingers down. + int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125; + + processId(mapper, FIRST_TRACKING_ID); + processPosition(mapper, x1, y1); + processMTSync(mapper); + processId(mapper, SECOND_TRACKING_ID); + processPosition(mapper, x2, y2); + processMTSync(mapper); + processSync(mapper); + + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); + ASSERT_EQ(1U, motionArgs.pointerCount); + ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); + ASSERT_EQ(MotionClassification::NONE, motionArgs.classification); + ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET)); + ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET)); + + // Move the two fingers down and to the left. + int32_t movingDistance = 200; + x1 -= movingDistance; + y1 += movingDistance; + x2 -= movingDistance; + y2 += movingDistance; + + processId(mapper, FIRST_TRACKING_ID); + processPosition(mapper, x1, y1); + processMTSync(mapper); + processId(mapper, SECOND_TRACKING_ID); + processPosition(mapper, x2, y2); + processMTSync(mapper); + processSync(mapper); + + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); + ASSERT_EQ(1U, motionArgs.pointerCount); + ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); + ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification); + ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0); + ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0); +} + // --- JoystickInputMapperTest --- class JoystickInputMapperTest : public InputMapperTest { |