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

Commit 45b321e0 authored by Linnan Li's avatar Linnan Li Committed by Siarhei Vishniakou
Browse files

Fix stylus hover spot not disappearing



When we turn off the stylus hover icon feature and turn on
“show touches”, we will use the touch spot display to show the stylus
hover icon. But currently, we don't remove the hover spot after
HOVER_EXIT, so the stylus hover spot will never disappear. We should
add corresponding logic to handle it.

This patch also refines a previous test to ensure that stylus events
can be handled correctly by PointerChoreographer.

Test: atest inputflinger_tests
Flag: EXEMPT bugfix
Bug: 353451540

Signed-off-by: default avatarLinnan Li <lilinnan@xiaomi.corp-partner.google.com>
(cherry picked from https://partner-android-review.googlesource.com/q/commit:a7cf0f24aa5f979243ea67c99502ed87534ff7c4)
Merged-In: I4b04992605ba19bdf3fc5db74580b919ef8356c0
Change-Id: I4b04992605ba19bdf3fc5db74580b919ef8356c0
parent db32303a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -368,7 +368,8 @@ void PointerChoreographer::processTouchscreenAndStylusEventLocked(const NotifyMo
    const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
    std::array<uint32_t, MAX_POINTER_ID + 1> idToIndex;
    BitSet32 idBits;
    if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL) {
    if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL &&
        maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
        for (size_t i = 0; i < args.getPointerCount(); i++) {
            if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP && actionIndex == i) {
                continue;
+73 −2
Original line number Diff line number Diff line
@@ -830,15 +830,20 @@ TEST_F(PointerChoreographerTest, TouchSetsSpots) {
    pc->assertSpotCount(DISPLAY_ID, 0);
}

/**
 * In this test, we simulate the complete event of the stylus approaching and clicking on the
 * screen, and then leaving the screen. We should ensure that spots are displayed correctly.
 */
TEST_F(PointerChoreographerTest, TouchSetsSpotsForStylusEvent) {
    mChoreographer.setShowTouchesEnabled(true);
    mChoreographer.setStylusPointerIconEnabled(false);
    mChoreographer.notifyInputDevicesChanged(
            {/*id=*/0,
             {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
                                     DISPLAY_ID)}});

    // Emit down event with stylus properties.
    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
    // First, the stylus begin to approach the screen.
    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
@@ -846,6 +851,72 @@ TEST_F(PointerChoreographerTest, TouchSetsSpotsForStylusEvent) {
                                        .build());
    auto pc = assertPointerControllerCreated(ControllerType::TOUCH);
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 0);

    // Now, use stylus touch the screen.
    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_UP,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 0);

    // Then, the stylus start leave from the screen.
    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 1);

    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                        .pointer(STYLUS_POINTER)
                                        .deviceId(DEVICE_ID)
                                        .displayId(DISPLAY_ID)
                                        .build());
    pc->assertSpotCount(DISPLAY_ID, 0);
}

TEST_F(PointerChoreographerTest, TouchSetsSpotsForTwoDisplays) {