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

Commit 2a10ab9b authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure new InputConsumer resampling behavior does not change" into main

parents a2db5458 4ef40682
Loading
Loading
Loading
Loading
+153 −6
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ namespace {
using std::chrono::nanoseconds;
using namespace std::chrono_literals;

const std::chrono::milliseconds RESAMPLE_LATENCY{5};

struct Pointer {
    int32_t id{0};
    float x{0.0f};
@@ -440,7 +442,7 @@ TEST_F(InputConsumerResamplingTest, SampleTimeEqualsEventTime) {
            {20ms, {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + 5ms /*RESAMPLE_LATENCY*/}.count());
    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + RESAMPLE_LATENCY}.count());

    // MotionEvent should not resampled because the resample time falls exactly on the existing
    // event time.
@@ -496,14 +498,15 @@ TEST_F(InputConsumerResamplingTest, ResampledValueIsUsedForIdenticalCoordinates)
            {40ms, {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + 5ms /*RESAMPLE_LATENCY*/}.count());
    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + RESAMPLE_LATENCY}.count());
    // Original and resampled event should be both overwritten.
    assertReceivedMotionEvent(
            {InputEventEntry{40ms,
                             {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{45ms,
                             {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
                             AMOTION_EVENT_ACTION_MOVE}});

    mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
    mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
@@ -552,13 +555,14 @@ TEST_F(InputConsumerResamplingTest, OldEventReceivedAfterResampleOccurs) {

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{50ms}.count());
    // Original and resampled event should be both overwritten.
    assertReceivedMotionEvent(
            {InputEventEntry{24ms,
                             {Pointer{.id = 0, .x = 35.0f, .y = 30.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{26ms,
                             {Pointer{.id = 0, .x = 45.0f, .y = 30.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
                             AMOTION_EVENT_ACTION_MOVE}});

    mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
    mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
@@ -594,4 +598,147 @@ TEST_F(InputConsumerResamplingTest, DoNotResampleWhenFrameTimeIsNotAvailable) {
    mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
}

TEST_F(InputConsumerResamplingTest, TwoPointersAreResampledIndependently) {
    // Full action for when a pointer with index=1 appears (some other pointer must already be
    // present)
    const int32_t actionPointer1Down =
            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

    // Full action for when a pointer with index=0 disappears (some other pointer must still remain)
    const int32_t actionPointer0Up =
            AMOTION_EVENT_ACTION_POINTER_UP + (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

    mClientTestChannel->enqueueMessage(nextPointerMessage(
            {0ms, {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}}, AMOTION_EVENT_ACTION_DOWN}));

    mClientTestChannel->assertNoSentMessages();

    invokeLooperCallback();
    assertReceivedMotionEvent({InputEventEntry{0ms,
                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}},
                                               AMOTION_EVENT_ACTION_DOWN}});

    mClientTestChannel->enqueueMessage(nextPointerMessage(
            {10ms, {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}}, AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{10ms + RESAMPLE_LATENCY}.count());
    // Not resampled value because requestedFrameTime - RESAMPLE_LATENCY == eventTime
    assertReceivedMotionEvent({InputEventEntry{10ms,
                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f}},
                                               AMOTION_EVENT_ACTION_MOVE}});

    // Second pointer id=1 appears
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({15ms,
                                {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
                                 Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
                                actionPointer1Down}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + RESAMPLE_LATENCY}.count());
    // Not resampled value because requestedFrameTime - RESAMPLE_LATENCY == eventTime.
    assertReceivedMotionEvent({InputEventEntry{15ms,
                                               {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
                                                Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
                                               actionPointer1Down}});

    // Both pointers move
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({30ms,
                                {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
                                 Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
                                AMOTION_EVENT_ACTION_MOVE}));
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({40ms,
                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                                AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{45ms + RESAMPLE_LATENCY}.count());
    assertReceivedMotionEvent(
            {InputEventEntry{30ms,
                             {Pointer{.id = 0, .x = 100.0f, .y = 100.0f},
                              Pointer{.id = 1, .x = 500.0f, .y = 500.0f}},
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{40ms,
                             {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
                              Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{45ms,
                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f, .isResampled = true},
                              Pointer{.id = 1, .x = 650.0f, .y = 650.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}});

    // Both pointers move again
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({60ms,
                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                                AMOTION_EVENT_ACTION_MOVE}));
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({70ms,
                                {Pointer{.id = 0, .x = 130.0f, .y = 130.0f},
                                 Pointer{.id = 1, .x = 700.0f, .y = 700.0f}},
                                AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{75ms + RESAMPLE_LATENCY}.count());

    /*
     * The pointer id 0 at t = 60 should not be equal to 120 because the value was received twice,
     * and resampled to 130. Therefore, if we reported 130, then we should continue to report it as
     * such. Likewise, with pointer id 1.
     */

    // Not 120 because it matches a previous real event.
    assertReceivedMotionEvent(
            {InputEventEntry{60ms,
                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f, .isResampled = true},
                              Pointer{.id = 1, .x = 650.0f, .y = 650.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{70ms,
                             {Pointer{.id = 0, .x = 130.0f, .y = 130.0f},
                              Pointer{.id = 1, .x = 700.0f, .y = 700.0f}},
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{75ms,
                             {Pointer{.id = 0, .x = 135.0f, .y = 135.0f, .isResampled = true},
                              Pointer{.id = 1, .x = 750.0f, .y = 750.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}});

    // First pointer id=0 leaves the screen
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({80ms,
                                {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
                                 Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                                actionPointer0Up}));

    invokeLooperCallback();
    // Not resampled event for ACTION_POINTER_UP
    assertReceivedMotionEvent({InputEventEntry{80ms,
                                               {Pointer{.id = 0, .x = 120.0f, .y = 120.0f},
                                                Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                                               actionPointer0Up}});

    // Remaining pointer id=1 is still present, but doesn't move
    mClientTestChannel->enqueueMessage(nextPointerMessage(
            {90ms, {Pointer{.id = 1, .x = 600.0f, .y = 600.0f}}, AMOTION_EVENT_ACTION_MOVE}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{100ms}.count());

    /*
     * The latest event with ACTION_MOVE was at t = 70 with value = 700. Thus, the resampled value
     * is 700 + ((95 - 70)/(90 - 70))*(600 - 700) = 575.
     */
    assertReceivedMotionEvent(
            {InputEventEntry{90ms,
                             {Pointer{.id = 1, .x = 600.0f, .y = 600.0f}},
                             AMOTION_EVENT_ACTION_MOVE},
             InputEventEntry{95ms,
                             {Pointer{.id = 1, .x = 575.0f, .y = 575.0f, .isResampled = true}},
                             AMOTION_EVENT_ACTION_MOVE}});
}

} // namespace android
+3 −2
Original line number Diff line number Diff line
@@ -571,11 +571,12 @@ TEST_F(TouchResamplingTest, TwoPointersAreResampledIndependently) {
    std::chrono::nanoseconds frameTime;
    std::vector<InputEventEntry> entries, expectedEntries;

    // full action for when a pointer with id=1 appears (some other pointer must already be present)
    // full action for when a pointer with index=1 appears (some other pointer must already be
    // present)
    constexpr int32_t actionPointer1Down =
            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

    // full action for when a pointer with id=0 disappears (some other pointer must still remain)
    // full action for when a pointer with index=0 disappears (some other pointer must still remain)
    constexpr int32_t actionPointer0Up =
            AMOTION_EVENT_ACTION_POINTER_UP + (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);