Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afb31288 authored by Philip Quinn's avatar Philip Quinn
Browse files

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
parent 015ae27a
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -368,7 +368,7 @@ constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<floa
 * Pointer coordinate data.
 * Pointer coordinate data.
 */
 */
struct PointerCoords {
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.
    // Bitfield of axes that are present in this structure.
    uint64_t bits __attribute__((aligned(8)));
    uint64_t bits __attribute__((aligned(8)));
@@ -377,8 +377,15 @@ struct PointerCoords {
    // for each axis that is present in the structure according to 'bits'.
    // for each axis that is present in the structure according to 'bits'.
    std::array<float, MAX_AXES> values;
    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() {
    inline void clear() {
        BitSet64::clear(bits);
        BitSet64::clear(bits);
        isResampled = false;
    }
    }


    bool isEmpty() const {
    bool isEmpty() const {
@@ -769,6 +776,10 @@ public:
                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
                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;
    ssize_t findPointerIndex(int32_t pointerId) const;


    void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
    void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
+7 −0
Original line number Original line Diff line number Diff line
@@ -411,6 +411,8 @@ status_t PointerCoords::readFromParcel(Parcel* parcel) {
    for (uint32_t i = 0; i < count; i++) {
    for (uint32_t i = 0; i < count; i++) {
        values[i] = parcel->readFloat();
        values[i] = parcel->readFloat();
    }
    }

    isResampled = parcel->readBool();
    return OK;
    return OK;
}
}


@@ -421,6 +423,8 @@ status_t PointerCoords::writeToParcel(Parcel* parcel) const {
    for (uint32_t i = 0; i < count; i++) {
    for (uint32_t i = 0; i < count; i++) {
        parcel->writeFloat(values[i]);
        parcel->writeFloat(values[i]);
    }
    }

    parcel->writeBool(isResampled);
    return OK;
    return OK;
}
}
#endif
#endif
@@ -440,6 +444,9 @@ bool PointerCoords::operator==(const PointerCoords& other) const {
            return false;
            return false;
        }
        }
    }
    }
    if (isResampled != other.isResampled) {
        return false;
    }
    return true;
    return true;
}
}


+6 −0
Original line number Original line Diff line number Diff line
@@ -267,6 +267,8 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
                memcpy(&msg->body.motion.pointers[i].coords.values[0],
                memcpy(&msg->body.motion.pointers[i].coords.values[0],
                        &body.motion.pointers[i].coords.values[0],
                        &body.motion.pointers[i].coords.values[0],
                        count * (sizeof(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;
            break;
        }
        }
@@ -1079,6 +1081,7 @@ void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) {
#endif
#endif
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
                msgCoords.isResampled = true;
            } else {
            } else {
                state.lastResample.idBits.clearBit(id);
                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
            // We maintain the previously resampled value for this pointer (stored in
            // oldLastResample) when the coordinates for this pointer haven't changed since then.
            // 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.
            // 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
            // 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
            // 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));
                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
            resampledCoords.isResampled = true;
#if DEBUG_RESAMPLING
#if DEBUG_RESAMPLING
            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
                    "other (%0.3f, %0.3f), alpha %0.3f",
                    "other (%0.3f, %0.3f), alpha %0.3f",
+18 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
    coords.clear();
    coords.clear();


    ASSERT_EQ(0ULL, coords.bits);
    ASSERT_EQ(0ULL, coords.bits);
    ASSERT_FALSE(coords.isResampled);
}
}


TEST_F(PointerCoordsTest, AxisValues) {
TEST_F(PointerCoordsTest, AxisValues) {
@@ -158,11 +159,13 @@ TEST_F(PointerCoordsTest, Parcel) {
    outCoords.readFromParcel(&parcel);
    outCoords.readFromParcel(&parcel);


    ASSERT_EQ(0ULL, outCoords.bits);
    ASSERT_EQ(0ULL, outCoords.bits);
    ASSERT_FALSE(outCoords.isResampled);


    // Round trip with some values.
    // Round trip with some values.
    parcel.freeData();
    parcel.freeData();
    inCoords.setAxisValue(2, 5);
    inCoords.setAxisValue(2, 5);
    inCoords.setAxisValue(5, 8);
    inCoords.setAxisValue(5, 8);
    inCoords.isResampled = true;


    inCoords.writeToParcel(&parcel);
    inCoords.writeToParcel(&parcel);
    parcel.setDataPosition(0);
    parcel.setDataPosition(0);
@@ -171,6 +174,7 @@ TEST_F(PointerCoordsTest, Parcel) {
    ASSERT_EQ(outCoords.bits, inCoords.bits);
    ASSERT_EQ(outCoords.bits, inCoords.bits);
    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
    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_MAJOR, 16);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
    pointerCoords[0].isResampled = true;
    pointerCoords[1].clear();
    pointerCoords[1].clear();
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
    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,
                      mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2,
                      pointerProperties, pointerCoords);
                      pointerProperties, pointerCoords);


    pointerCoords[0].clear();
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
    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_MAJOR, 116);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
    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_X, 120);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
    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_MAJOR, 126);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
    pointerCoords[1].isResampled = true;
    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);


    pointerCoords[0].clear();
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
    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_MAJOR, 216);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
    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_X, 220);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
    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(128), event->getHistoricalOrientation(1, 1));
    ASSERT_EQ(toScaledOrientation(218), event->getOrientation(0));
    ASSERT_EQ(toScaledOrientation(218), event->getOrientation(0));
    ASSERT_EQ(toScaledOrientation(228), event->getOrientation(1));
    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) {
TEST_F(MotionEventTest, Properties) {
+7 −7
Original line number Original line Diff line number Diff line
@@ -117,7 +117,7 @@ void TestHeaderSize() {


void TestBodySize() {
void TestBodySize() {
    static_assert(sizeof(InputMessage::Body::Key) == 96);
    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) ==
    static_assert(sizeof(InputMessage::Body::Motion) ==
                  offsetof(InputMessage::Body::Motion, pointers) +
                  offsetof(InputMessage::Body::Motion, pointers) +
                          sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
                          sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
@@ -137,8 +137,8 @@ void TestBodySize() {
    static_assert(sizeof(InputMessage::Body) ==
    static_assert(sizeof(InputMessage::Body) ==
                  offsetof(InputMessage::Body::Motion, pointers) +
                  offsetof(InputMessage::Body::Motion, pointers) +
                          sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
                          sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
    static_assert(sizeof(InputMessage::Body) == 160 + 136 * 16);
    static_assert(sizeof(InputMessage::Body) == 160 + 144 * 16);
    static_assert(sizeof(InputMessage::Body) == 2336);
    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.
 * still helpful to compute to get an idea of the sizes that are involved.
 */
 */
void TestWorstCaseInputMessageSize() {
void TestWorstCaseInputMessageSize() {
    static_assert(sizeof(InputMessage) == /*header*/ 8 + /*body*/ 2336);
    static_assert(sizeof(InputMessage) == /*header*/ 8 + /*body*/ 2464);
    static_assert(sizeof(InputMessage) == 2344);
    static_assert(sizeof(InputMessage) == 2472);
}
}


/**
/**
@@ -159,8 +159,8 @@ void CalculateSinglePointerInputMessageSize() {
    constexpr size_t pointerCount = 1;
    constexpr size_t pointerCount = 1;
    constexpr size_t bodySize = offsetof(InputMessage::Body::Motion, pointers) +
    constexpr size_t bodySize = offsetof(InputMessage::Body::Motion, pointers) +
            sizeof(InputMessage::Body::Motion::Pointer) * pointerCount;
            sizeof(InputMessage::Body::Motion::Pointer) * pointerCount;
    static_assert(bodySize == 160 + 136);
    static_assert(bodySize == 160 + 144);
    static_assert(bodySize == 296); // For the total message size, add the small header
    static_assert(bodySize == 304); // For the total message size, add the small header
}
}


// --- VerifiedInputEvent ---
// --- VerifiedInputEvent ---
Loading