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

Commit d5876bad authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Create new input targets for hover events

Hover events don't need to reuse the existing input targets in order to
lump events with some pointers into others.

It's possible that we need to send the same pointer as both
DISPATCH_AS_HOVER_EXIT and as DISPATCH_AS_HOVER_ENTER from the
dispatcher for the same input channel.

This is the case when we are hovering over two windows with the same
input token. Since the windows may have different transforms, we should
re-start the hovering gesture.

Bug: 263319225
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: I2bd90c9893183c0526128b124b983654e0e6a37c
parent 5796a176
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -2561,9 +2561,17 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
        std::vector<TouchedWindow> hoveringWindows =
                getHoveringWindowsLocked(oldState, tempTouchState, entry);
        for (const TouchedWindow& touchedWindow : hoveringWindows) {
            addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
                                  touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget,
                                  targets);
            std::optional<InputTarget> target =
                    createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
                                            touchedWindow.firstDownTimeInTarget);
            if (!target) {
                continue;
            }
            // Hardcode to single hovering pointer for now.
            std::bitset<MAX_POINTER_ID + 1> pointerIds;
            pointerIds.set(entry.pointerProperties[0].id);
            target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
            targets.push_back(*target);
        }
    }

+23 −0
Original line number Diff line number Diff line
@@ -6592,6 +6592,29 @@ TEST_F(InputDispatcherMultiWindowSameTokenTests, TouchDoesNotSlipEvenIfSlippery)
    consumeMotionEvent(mWindow1, ACTION_MOVE, {{150, 150}});
}

/**
 * When hover starts in one window and continues into the other, there should be a HOVER_EXIT and
 * a HOVER_ENTER generated, even if the windows have the same token. This is because the new window
 * that the pointer is hovering over may have a different transform.
 */
TEST_F(InputDispatcherMultiWindowSameTokenTests, HoverIntoClone) {
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});

    // Start hover in window 1
    mDispatcher->notifyMotion(generateMotionArgs(ACTION_HOVER_ENTER, AINPUT_SOURCE_TOUCHSCREEN,
                                                 ADISPLAY_ID_DEFAULT, {{50, 50}}));
    consumeMotionEvent(mWindow1, ACTION_HOVER_ENTER,
                       {getPointInWindow(mWindow1->getInfo(), PointF{50, 50})});

    // Move hover to window 2.
    mDispatcher->notifyMotion(generateMotionArgs(ACTION_HOVER_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
                                                 ADISPLAY_ID_DEFAULT, {{150, 150}}));

    consumeMotionEvent(mWindow1, ACTION_HOVER_EXIT, {{50, 50}});
    consumeMotionEvent(mWindow1, ACTION_HOVER_ENTER,
                       {getPointInWindow(mWindow2->getInfo(), PointF{150, 150})});
}

class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
    virtual void SetUp() override {
        InputDispatcherTest::SetUp();