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

Commit b290a139 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou Committed by Android (Google) Code Review
Browse files

Merge "Clear downTime when all pointers have lifted"

parents 32ce29d9 6464e46b
Loading
Loading
Loading
Loading
+2 −4
Original line number Original line Diff line number Diff line
@@ -33,8 +33,7 @@ void TouchState::reset() {


void TouchState::removeTouchedPointer(int32_t pointerId) {
void TouchState::removeTouchedPointer(int32_t pointerId) {
    for (TouchedWindow& touchedWindow : windows) {
    for (TouchedWindow& touchedWindow : windows) {
        touchedWindow.pointerIds.reset(pointerId);
        touchedWindow.removeTouchingPointer(pointerId);
        touchedWindow.pilferedPointerIds.reset(pointerId);
    }
    }
}
}


@@ -42,8 +41,7 @@ void TouchState::removeTouchedPointerFromWindow(
        int32_t pointerId, const sp<android::gui::WindowInfoHandle>& windowHandle) {
        int32_t pointerId, const sp<android::gui::WindowInfoHandle>& windowHandle) {
    for (TouchedWindow& touchedWindow : windows) {
    for (TouchedWindow& touchedWindow : windows) {
        if (touchedWindow.windowHandle == windowHandle) {
        if (touchedWindow.windowHandle == windowHandle) {
            touchedWindow.pointerIds.reset(pointerId);
            touchedWindow.removeTouchingPointer(pointerId);
            touchedWindow.pilferedPointerIds.reset(pointerId);
            return;
            return;
        }
        }
    }
    }
+8 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,14 @@ void TouchedWindow::addHoveringPointer(int32_t deviceId, int32_t pointerId) {
    it->second.set(pointerId);
    it->second.set(pointerId);
}
}


void TouchedWindow::removeTouchingPointer(int32_t pointerId) {
    pointerIds.reset(pointerId);
    pilferedPointerIds.reset(pointerId);
    if (pointerIds.none()) {
        firstDownTimeInTarget.reset();
    }
}

void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
    const auto it = mHoveringPointerIdsByDevice.find(deviceId);
    const auto it = mHoveringPointerIdsByDevice.find(deviceId);
    if (it == mHoveringPointerIdsByDevice.end()) {
    if (it == mHoveringPointerIdsByDevice.end()) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@ struct TouchedWindow {
    bool hasHoveringPointer(int32_t deviceId, int32_t pointerId) const;
    bool hasHoveringPointer(int32_t deviceId, int32_t pointerId) const;
    void addHoveringPointer(int32_t deviceId, int32_t pointerId);
    void addHoveringPointer(int32_t deviceId, int32_t pointerId);
    void removeHoveringPointer(int32_t deviceId, int32_t pointerId);
    void removeHoveringPointer(int32_t deviceId, int32_t pointerId);
    void removeTouchingPointer(int32_t pointerId);
    void clearHoveringPointers();
    void clearHoveringPointers();
    std::string dump() const;
    std::string dump() const;


+96 −0
Original line number Original line Diff line number Diff line
@@ -2171,6 +2171,102 @@ TEST_F(InputDispatcherTest, HoverFromLeftToRightAndTap) {
    rightWindow->assertNoEvents();
    rightWindow->assertNoEvents();
}
}


/**
 * This test is similar to the test above, but the sequence of injected events is different.
 *
 * Two windows: a window on the left and a window on the right.
 * Mouse is hovered over the left window.
 * Next, we tap on the left window, where the cursor was last seen.
 *
 * After that, we inject one finger down onto the right window, and then a second finger down onto
 * the left window.
 * The touch is split, so this last gesture should cause 2 ACTION_DOWN events, one in the right
 * window (first), and then another on the left window (second).
 * This test reproduces a crash where there is a mismatch between the downTime and eventTime.
 * In the buggy implementation, second finger down on the left window would cause a crash.
 */
TEST_F(InputDispatcherTest, HoverTapAndSplitTouch) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> leftWindow =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
    leftWindow->setFrame(Rect(0, 0, 200, 200));

    sp<FakeWindowHandle> rightWindow =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
    rightWindow->setFrame(Rect(200, 0, 400, 200));

    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {leftWindow, rightWindow}}});

    const int32_t mouseDeviceId = 6;
    const int32_t touchDeviceId = 4;
    // Hover over the left window. Keep the cursor there.
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
                                                   AINPUT_SOURCE_MOUSE)
                                        .deviceId(mouseDeviceId)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
                                                         .x(50)
                                                         .y(50))
                                        .build()));
    leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));

    // Tap on left window
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
                                                   AINPUT_SOURCE_TOUCHSCREEN)
                                        .deviceId(touchDeviceId)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
                                                         .x(100)
                                                         .y(100))
                                        .build()));

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(AMOTION_EVENT_ACTION_UP,
                                                   AINPUT_SOURCE_TOUCHSCREEN)
                                        .deviceId(touchDeviceId)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
                                                         .x(100)
                                                         .y(100))
                                        .build()));
    leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
    leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
    leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_UP));

    // First finger down on right window
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
                                                   AINPUT_SOURCE_TOUCHSCREEN)
                                        .deviceId(touchDeviceId)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
                                                         .x(300)
                                                         .y(100))
                                        .build()));
    rightWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));

    // Second finger down on the left window
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
                                        .deviceId(touchDeviceId)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
                                                         .x(300)
                                                         .y(100))
                                        .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER)
                                                         .x(100)
                                                         .y(100))
                                        .build()));
    leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
    rightWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_MOVE));

    // No more events
    leftWindow->assertNoEvents();
    rightWindow->assertNoEvents();
}

/**
/**
 * On the display, have a single window, and also an area where there's no window.
 * On the display, have a single window, and also an area where there's no window.
 * First pointer touches the "no window" area of the screen. Second pointer touches the window.
 * First pointer touches the "no window" area of the screen. Second pointer touches the window.