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

Commit 907ae738 authored by Linnan Li's avatar Linnan Li Committed by Siarhei Vishniakou
Browse files

Add POLICY_FLAG_PASS_TO_USER while hovering is active



In the following hover event sequence: ENTER->MOVE->EXIT, the policy might not set POLICY_FLAG_PASS_TO_USER after the MOVE event is received. This would cause MOVE and EXIT events to be dropped. This would later cause problems with stream consistency, because the following HOVER_ENTER event would not be expected.

So add POLICY_FLAG_PASS_TO_USER to the hover event while hovering is active, even if the policy does not add
POLICY_FLAG_PASS_TO_USER.

Bug: 299055469
Test: atest inputflinger_tests

Change-Id: If99e493a6a645c66a18a97351763f00a37dc1dc0
Signed-off-by: default avatarLinnan Li <lilinnan@xiaomi.corp-partner.google.com>
parent a7333114
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -4424,7 +4424,8 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
            const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
            if (touchStateIt != mTouchStatesByDisplay.end()) {
                const TouchState& touchState = touchStateIt->second;
                if (touchState.hasTouchingPointers(args.deviceId)) {
                if (touchState.hasTouchingPointers(args.deviceId) ||
                    touchState.hasHoveringPointers(args.deviceId)) {
                    policyFlags |= POLICY_FLAG_PASS_TO_USER;
                }
            }
+63 −0
Original line number Diff line number Diff line
@@ -2166,6 +2166,69 @@ TEST_F(InputDispatcherTest, TwoPointerCancelInconsistentPolicy) {
    window->assertNoEvents();
}
/**
 * Same as the above 'TwoPointerCancelInconsistentPolicy' test, but for hovers.
 * The policy typically sets POLICY_FLAG_PASS_TO_USER to the events. But when the display is not
 * interactive, it might stop sending this flag.
 * We've already ensured the consistency of the touch event in this case, and we should also ensure
 * the consistency of the hover event in this case.
 *
 * Test procedure:
 * HOVER_ENTER -> HOVER_MOVE -> (stop sending POLICY_FLAG_PASS_TO_USER) -> HOVER_EXIT
 * HOVER_ENTER -> HOVER_MOVE -> HOVER_EXIT
 *
 * We expect to receive two full streams of hover events.
 */
TEST_F(InputDispatcherTest, HoverEventInconsistentPolicy) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
    window->setFrame(Rect(0, 0, 300, 300));
    mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(DEFAULT_POLICY_FLAGS)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(100).y(101))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(DEFAULT_POLICY_FLAGS)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(102))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_MOVE));
    // Send hover exit without the default policy flags.
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(0)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(102))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
    // Send a simple hover event stream, ensure dispatcher not crashed and window can receive
    // right event.
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(DEFAULT_POLICY_FLAGS)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(200).y(201))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(DEFAULT_POLICY_FLAGS)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(201).y(202))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_MOVE));
    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
                                      .policyFlags(DEFAULT_POLICY_FLAGS)
                                      .pointer(PointerBuilder(0, ToolType::STYLUS).x(201).y(202))
                                      .build());
    window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
}
/**
 * Two windows: a window on the left and a window on the right.
 * Mouse is hovered from the right window into the left window.