diff options
author | 2022-12-20 18:17:55 -0800 | |
---|---|---|
committer | 2023-01-05 18:08:33 -0800 | |
commit | afb312889849d435e59f8e1014e1385ac419c4ea (patch) | |
tree | 920730b1ad0334324ab1e1459bbe9cc45c0578f5 | |
parent | 015ae27a731030bd87b8274fe64ac45eceb7d7f7 (diff) |
Add isResampled field to PointerCoords.
This field is set if a pointer's coordinate data were generated by
input resampling and did not originate from the input device.
Bug: 167946721
Test: atest libinput_tests
Change-Id: I30d9aee85d462e6536fa33be5242365b52a11a6c
-rw-r--r-- | include/input/Input.h | 13 | ||||
-rw-r--r-- | libs/input/Input.cpp | 7 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 6 | ||||
-rw-r--r-- | libs/input/tests/InputEvent_test.cpp | 18 | ||||
-rw-r--r-- | libs/input/tests/StructLayout_test.cpp | 14 | ||||
-rw-r--r-- | libs/input/tests/TouchResampling_test.cpp | 41 |
6 files changed, 78 insertions, 21 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 1a35196036..08d9019911 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -368,7 +368,7 @@ constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<floa * Pointer coordinate data. */ struct PointerCoords { - enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128 + enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 136 // Bitfield of axes that are present in this structure. uint64_t bits __attribute__((aligned(8))); @@ -377,8 +377,15 @@ struct PointerCoords { // for each axis that is present in the structure according to 'bits'. std::array<float, MAX_AXES> values; + // Whether these coordinate data were generated by resampling. + bool isResampled; + + static_assert(sizeof(bool) == 1); // Ensure padding is correctly sized. + uint8_t empty[7]; + inline void clear() { BitSet64::clear(bits); + isResampled = false; } bool isEmpty() const { @@ -769,6 +776,10 @@ public: AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex); } + inline bool isResampled(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->isResampled; + } + ssize_t findPointerIndex(int32_t pointerId) const; void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index d893cb99ba..cdc779dfd9 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -411,6 +411,8 @@ status_t PointerCoords::readFromParcel(Parcel* parcel) { for (uint32_t i = 0; i < count; i++) { values[i] = parcel->readFloat(); } + + isResampled = parcel->readBool(); return OK; } @@ -421,6 +423,8 @@ status_t PointerCoords::writeToParcel(Parcel* parcel) const { for (uint32_t i = 0; i < count; i++) { parcel->writeFloat(values[i]); } + + parcel->writeBool(isResampled); return OK; } #endif @@ -440,6 +444,9 @@ bool PointerCoords::operator==(const PointerCoords& other) const { return false; } } + if (isResampled != other.isResampled) { + return false; + } return true; } diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 8d8433b973..9f0a314041 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -267,6 +267,8 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { memcpy(&msg->body.motion.pointers[i].coords.values[0], &body.motion.pointers[i].coords.values[0], count * (sizeof(body.motion.pointers[i].coords.values[0]))); + msg->body.motion.pointers[i].coords.isResampled = + body.motion.pointers[i].coords.isResampled; } break; } @@ -1079,6 +1081,7 @@ void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) { #endif msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX()); msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY()); + msgCoords.isResampled = true; } else { state.lastResample.idBits.clearBit(id); } @@ -1191,6 +1194,8 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, // We maintain the previously resampled value for this pointer (stored in // oldLastResample) when the coordinates for this pointer haven't changed since then. // This way we don't introduce artificial jitter when pointers haven't actually moved. + // The isResampled flag isn't cleared as the values don't reflect what the device is + // actually reporting. // We know here that the coordinates for the pointer haven't changed because we // would've cleared the resampled bit in rewriteMessage if they had. We can't modify @@ -1209,6 +1214,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, lerp(currentCoords.getX(), otherCoords.getX(), alpha)); resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, lerp(currentCoords.getY(), otherCoords.getY(), alpha)); + resampledCoords.isResampled = true; #if DEBUG_RESAMPLING ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), " "other (%0.3f, %0.3f), alpha %0.3f", diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index 4b3124636b..8a6e983bb5 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -46,6 +46,7 @@ TEST_F(PointerCoordsTest, ClearSetsBitsToZero) { coords.clear(); ASSERT_EQ(0ULL, coords.bits); + ASSERT_FALSE(coords.isResampled); } TEST_F(PointerCoordsTest, AxisValues) { @@ -158,11 +159,13 @@ TEST_F(PointerCoordsTest, Parcel) { outCoords.readFromParcel(&parcel); ASSERT_EQ(0ULL, outCoords.bits); + ASSERT_FALSE(outCoords.isResampled); // Round trip with some values. parcel.freeData(); inCoords.setAxisValue(2, 5); inCoords.setAxisValue(5, 8); + inCoords.isResampled = true; inCoords.writeToParcel(&parcel); parcel.setDataPosition(0); @@ -171,6 +174,7 @@ TEST_F(PointerCoordsTest, Parcel) { ASSERT_EQ(outCoords.bits, inCoords.bits); ASSERT_EQ(outCoords.values[0], inCoords.values[0]); ASSERT_EQ(outCoords.values[1], inCoords.values[1]); + ASSERT_TRUE(outCoords.isResampled); } @@ -263,6 +267,7 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18); + pointerCoords[0].isResampled = true; pointerCoords[1].clear(); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21); @@ -281,6 +286,7 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties, pointerCoords); + pointerCoords[0].clear(); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112); @@ -290,6 +296,8 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118); + pointerCoords[0].isResampled = true; + pointerCoords[1].clear(); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122); @@ -299,8 +307,10 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128); + pointerCoords[1].isResampled = true; event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords); + pointerCoords[0].clear(); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212); @@ -310,6 +320,7 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217); pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218); + pointerCoords[1].clear(); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221); pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222); @@ -457,6 +468,13 @@ void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) { ASSERT_EQ(toScaledOrientation(128), event->getHistoricalOrientation(1, 1)); ASSERT_EQ(toScaledOrientation(218), event->getOrientation(0)); ASSERT_EQ(toScaledOrientation(228), event->getOrientation(1)); + + ASSERT_TRUE(event->isResampled(0, 0)); + ASSERT_FALSE(event->isResampled(1, 0)); + ASSERT_TRUE(event->isResampled(0, 1)); + ASSERT_TRUE(event->isResampled(1, 1)); + ASSERT_FALSE(event->isResampled(0, 2)); + ASSERT_FALSE(event->isResampled(1, 2)); } TEST_F(MotionEventTest, Properties) { diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp index 1c8658b69a..024b6d3d43 100644 --- a/libs/input/tests/StructLayout_test.cpp +++ b/libs/input/tests/StructLayout_test.cpp @@ -117,7 +117,7 @@ void TestHeaderSize() { void TestBodySize() { static_assert(sizeof(InputMessage::Body::Key) == 96); - static_assert(sizeof(InputMessage::Body::Motion::Pointer) == 136); + static_assert(sizeof(InputMessage::Body::Motion::Pointer) == 144); static_assert(sizeof(InputMessage::Body::Motion) == offsetof(InputMessage::Body::Motion, pointers) + sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS); @@ -137,8 +137,8 @@ void TestBodySize() { static_assert(sizeof(InputMessage::Body) == offsetof(InputMessage::Body::Motion, pointers) + sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS); - static_assert(sizeof(InputMessage::Body) == 160 + 136 * 16); - static_assert(sizeof(InputMessage::Body) == 2336); + static_assert(sizeof(InputMessage::Body) == 160 + 144 * 16); + static_assert(sizeof(InputMessage::Body) == 2464); } /** @@ -148,8 +148,8 @@ void TestBodySize() { * still helpful to compute to get an idea of the sizes that are involved. */ void TestWorstCaseInputMessageSize() { - static_assert(sizeof(InputMessage) == /*header*/ 8 + /*body*/ 2336); - static_assert(sizeof(InputMessage) == 2344); + static_assert(sizeof(InputMessage) == /*header*/ 8 + /*body*/ 2464); + static_assert(sizeof(InputMessage) == 2472); } /** @@ -159,8 +159,8 @@ void CalculateSinglePointerInputMessageSize() { constexpr size_t pointerCount = 1; constexpr size_t bodySize = offsetof(InputMessage::Body::Motion, pointers) + sizeof(InputMessage::Body::Motion::Pointer) * pointerCount; - static_assert(bodySize == 160 + 136); - static_assert(bodySize == 296); // For the total message size, add the small header + static_assert(bodySize == 160 + 144); + static_assert(bodySize == 304); // For the total message size, add the small header } // --- VerifiedInputEvent --- diff --git a/libs/input/tests/TouchResampling_test.cpp b/libs/input/tests/TouchResampling_test.cpp index c09a8e9358..d01258c783 100644 --- a/libs/input/tests/TouchResampling_test.cpp +++ b/libs/input/tests/TouchResampling_test.cpp @@ -31,6 +31,7 @@ struct Pointer { int32_t id; float x; float y; + bool isResampled = false; }; struct InputEventEntry { @@ -190,6 +191,8 @@ void TouchResamplingTest::consumeInputEventEntries(const std::vector<InputEventE ASSERT_EQ(entry.pointers[p].y, motionEvent->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, motionEventPointerIndex, i)); + ASSERT_EQ(entry.pointers[p].isResampled, + motionEvent->isResampled(motionEventPointerIndex, i)); } } @@ -244,7 +247,7 @@ TEST_F(TouchResamplingTest, EventIsResampled) { // id x y {10ms, {{0, 20, 30}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30}}, AMOTION_EVENT_ACTION_MOVE}, - {25ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {25ms, {{0, 35, 30, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } @@ -283,7 +286,7 @@ TEST_F(TouchResamplingTest, EventIsResampledWithDifferentId) { // id x y {10ms, {{1, 20, 30}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{1, 30, 30}}, AMOTION_EVENT_ACTION_MOVE}, - {25ms, {{1, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {25ms, {{1, 35, 30, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } @@ -361,7 +364,7 @@ TEST_F(TouchResamplingTest, ResampledValueIsUsedForIdenticalCoordinates) { // id x y {10ms, {{0, 20, 30}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30}}, AMOTION_EVENT_ACTION_MOVE}, - {25ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {25ms, {{0, 35, 30, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); @@ -375,8 +378,12 @@ TEST_F(TouchResamplingTest, ResampledValueIsUsedForIdenticalCoordinates) { frameTime = 45ms + 5ms /*RESAMPLE_LATENCY*/; expectedEntries = { // id x y - {40ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten - {45ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled event, rewritten + {40ms, + {{0, 35, 30, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten + {45ms, + {{0, 35, 30, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, // resampled event, rewritten }; consumeInputEventEntries(expectedEntries, frameTime); } @@ -411,7 +418,7 @@ TEST_F(TouchResamplingTest, OldEventReceivedAfterResampleOccurs) { // id x y {10ms, {{0, 20, 30}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30}}, AMOTION_EVENT_ACTION_MOVE}, - {25ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {25ms, {{0, 35, 30, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); // Above, the resampled event is at 25ms rather than at 30 ms = 35ms - RESAMPLE_LATENCY @@ -428,8 +435,12 @@ TEST_F(TouchResamplingTest, OldEventReceivedAfterResampleOccurs) { frameTime = 50ms; expectedEntries = { // id x y - {24ms, {{0, 35, 30}}, AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten - {26ms, {{0, 45, 30}}, AMOTION_EVENT_ACTION_MOVE}, // resampled event, rewritten + {24ms, + {{0, 35, 30, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten + {26ms, + {{0, 45, 30, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, // resampled event, rewritten }; consumeInputEventEntries(expectedEntries, frameTime); } @@ -499,7 +510,9 @@ TEST_F(TouchResamplingTest, TwoPointersAreResampledIndependently) { // id x y {30ms, {{0, 100, 100}, {1, 500, 500}}, AMOTION_EVENT_ACTION_MOVE}, {40ms, {{0, 120, 120}, {1, 600, 600}}, AMOTION_EVENT_ACTION_MOVE}, - {45ms, {{0, 130, 130}, {1, 650, 650}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {45ms, + {{0, 130, 130, .isResampled = true}, {1, 650, 650, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); @@ -518,11 +531,13 @@ TEST_F(TouchResamplingTest, TwoPointersAreResampledIndependently) { */ expectedEntries = { {60ms, - {{0, 130, 130}, // not 120! because it matches previous real event - {1, 650, 650}}, + {{0, 130, 130, .isResampled = true}, // not 120! because it matches previous real event + {1, 650, 650, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, {70ms, {{0, 130, 130}, {1, 700, 700}}, AMOTION_EVENT_ACTION_MOVE}, - {75ms, {{0, 135, 135}, {1, 750, 750}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {75ms, + {{0, 135, 135, .isResampled = true}, {1, 750, 750, .isResampled = true}}, + AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); @@ -554,7 +569,7 @@ TEST_F(TouchResamplingTest, TwoPointersAreResampledIndependently) { * The latest event with ACTION_MOVE was at t = 70, coord = 700. * Use that value for resampling here: (600 - 700) / (90 - 70) * 5 + 600 */ - {95ms, {{1, 575, 575}}, AMOTION_EVENT_ACTION_MOVE}, // resampled value + {95ms, {{1, 575, 575, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } |