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

Commit 5cee1e36 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Add test for hover events over spy window

In this test, we check whether spy windows receive hover events.

Bug: 211379801
Test: m inputflinger_tests && adb sync data && adb shell -t /data/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: Ia4c0cbb889d1c9500b0b1696dc2f5690ef4550fe
parent 9a319744
Loading
Loading
Loading
Loading
+4 −13
Original line number Diff line number Diff line
@@ -2096,7 +2096,7 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(

    bool isSplit = shouldSplitTouch(tempTouchState, entry);
    const bool switchedDevice = (oldState != nullptr) &&
            (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source);
            (oldState->deviceId != entry.deviceId || oldState->source != entry.source);

    const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
                                maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
@@ -2104,6 +2104,7 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(
    const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
                             maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
    const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);

    if (newGesture) {
        bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
        if (switchedDevice && tempTouchState.isDown() && !down && !isHoverAction) {
@@ -2995,6 +2996,8 @@ void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                             connection->getInputChannelName().c_str(), eventEntry->id);
        ATRACE_NAME(message.c_str());
    }
    LOG_ALWAYS_FATAL_IF(!inputTarget.flags.any(InputTarget::DISPATCH_MASK),
                        "No dispatch flags are set for %s", eventEntry->getDescription().c_str());

    const bool wasEmpty = connection->outboundQueue.empty();

@@ -4981,10 +4984,6 @@ void InputDispatcher::setFocusedDisplay(int32_t displayId) {
                }
            }
        }

        if (DEBUG_FOCUS) {
            logDispatchStateLocked();
        }
    } // release lock

    // Wake up poll loop since it may need to make new input dispatching choices.
@@ -5015,10 +5014,6 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
        } else {
            changed = false;
        }

        if (DEBUG_FOCUS) {
            logDispatchStateLocked();
        }
    } // release lock

    if (changed) {
@@ -5193,10 +5188,6 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<
            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
            synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection);
        }

        if (DEBUG_FOCUS) {
            logDispatchStateLocked();
        }
    } // release lock

    // Wake up poll loop since it may need to make new input dispatching choices.
+1 −2
Original line number Diff line number Diff line
@@ -34,8 +34,7 @@ void TouchState::reset() {
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
                                   ftl::Flags<InputTarget::Flags> targetFlags, BitSet32 pointerIds,
                                   std::optional<nsecs_t> eventTime) {
    for (size_t i = 0; i < windows.size(); i++) {
        TouchedWindow& touchedWindow = windows[i];
    for (TouchedWindow& touchedWindow : windows) {
        if (touchedWindow.windowHandle == windowHandle) {
            touchedWindow.targetFlags |= targetFlags;
            if (targetFlags.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT)) {
+60 −36
Original line number Diff line number Diff line
@@ -1231,7 +1231,7 @@ public:

    void consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) {
        MotionEvent* motionEvent = consumeMotion();
        ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event";
        ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event, but expected " << matcher;
        ASSERT_THAT(*motionEvent, matcher);
    }

@@ -2128,10 +2128,8 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
                                                         .x(900)
                                                         .y(400))
                                        .build()));
    windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
                              ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
                              ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
    windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));

    // Move cursor into left window
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -2142,12 +2140,9 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
                              ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
                             ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
                             ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
    windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
    windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));

    // Inject a series of mouse events for a mouse click
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -2170,8 +2165,7 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
                             ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
@@ -2183,8 +2177,7 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
                             ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE));

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
@@ -2205,12 +2198,47 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
                                                         .x(900)
                                                         .y(400))
                                        .build()));
    windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
                             ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
                              ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
                              ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
    windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
    windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));

    // No more events
    windowLeft->assertNoEvents();
    windowRight->assertNoEvents();
}

TEST_F(InputDispatcherTest, HoverWithSpyWindows) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();

    sp<FakeWindowHandle> spyWindow =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Spy", ADISPLAY_ID_DEFAULT);
    spyWindow->setFrame(Rect(0, 0, 600, 800));
    spyWindow->setTrustedOverlay(true);
    spyWindow->setSpy(true);
    sp<FakeWindowHandle> window =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
    window->setFrame(Rect(0, 0, 600, 800));

    mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spyWindow, window}}});

    // Send mouse cursor to the window
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
                                MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
                                                   AINPUT_SOURCE_MOUSE)
                                        .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
                                                         .x(100)
                                                         .y(100))
                                        .build()));

    window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
                                     WithSource(AINPUT_SOURCE_MOUSE)));
    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
                                        WithSource(AINPUT_SOURCE_MOUSE)));

    window->assertNoEvents();
    spyWindow->assertNoEvents();
}

// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
@@ -2233,8 +2261,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
                         ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));

    // Inject a series of mouse events for a mouse click
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -2257,8 +2284,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
                         ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
@@ -2270,8 +2296,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
                         ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE));

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher,
@@ -2291,8 +2316,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
                                                         .x(300)
                                                         .y(400))
                                        .build()));
    window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
                         ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
}

/**
@@ -2362,14 +2386,13 @@ TEST_F(InputDispatcherTest, HoverEnterMoveRemoveWindowsInSecondDisplay) {
                                                         .x(300)
                                                         .y(600))
                                        .build()));
    windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
                                       ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
                                       ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowDefaultDisplay->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
    windowDefaultDisplay->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));

    // Remove all windows in secondary display and check that no event happens on window in
    // primary display.
    mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
    mDispatcher->setInputWindows(
            {{ADISPLAY_ID_DEFAULT, {windowDefaultDisplay}}, {SECOND_DISPLAY_ID, {}}});
    windowDefaultDisplay->assertNoEvents();

    // Move cursor position in window in default display and check that only hover move
@@ -2385,8 +2408,9 @@ TEST_F(InputDispatcherTest, HoverEnterMoveRemoveWindowsInSecondDisplay) {
                                                         .x(400)
                                                         .y(700))
                                        .build()));
    windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
                                       ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
    windowDefaultDisplay->consumeMotionEvent(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
                  WithSource(AINPUT_SOURCE_MOUSE)));
    windowDefaultDisplay->assertNoEvents();
}