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

Commit 74c248d8 authored by Arthur Hung's avatar Arthur Hung
Browse files

Fix wallpaper window can't receive up event

If the wallpaper window is touchable and the above touched window has
`DUPLICATE_TOUCH_TO_WALLPAPER` flag, it would also deliver the same
touch event to the wallpaper window, and it have to set the
corresponding pointer ids to prevent it being erased in next pointer up.

Bug: 240308355
Test: atest inputflinger_tests
Change-Id: Ibf82b494e45e35babe9ba9f3dd1236fee8bcea6d
parent 327b9350
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2429,12 +2429,14 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(
                if (info->displayId == displayId &&
                    windowHandle->getInfo()->inputConfig.test(
                            WindowInfo::InputConfig::IS_WALLPAPER)) {
                    BitSet32 pointerIds;
                    pointerIds.markBit(entry.pointerProperties[0].id);
                    tempTouchState.addOrUpdateWindow(windowHandle,
                                                     InputTarget::Flags::WINDOW_IS_OBSCURED |
                                                             InputTarget::Flags::
                                                                     WINDOW_IS_PARTIALLY_OBSCURED |
                                                             InputTarget::Flags::DISPATCH_AS_IS,
                                                     BitSet32(0), entry.eventTime);
                                                     pointerIds, entry.eventTime);
                }
            }
        }
+58 −0
Original line number Diff line number Diff line
@@ -1922,6 +1922,64 @@ TEST_F(InputDispatcherTest, TwoWindows_SplitWallpaperTouch) {
    wallpaperWindow->assertNoEvents();
}

TEST_F(InputDispatcherTest, WallpaperWindowReceivesMultiTouch) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
    window->setDupTouchToWallpaper(true);

    sp<FakeWindowHandle> wallpaperWindow =
            sp<FakeWindowHandle>::make(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT);
    wallpaperWindow->setIsWallpaper(true);
    constexpr int expectedWallpaperFlags =
            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
    wallpaperWindow->setPreventSplitting(true);

    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, wallpaperWindow}}});

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                               {50, 50}))
            << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
    window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
    wallpaperWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT, expectedWallpaperFlags);

    const MotionEvent secondFingerDownEvent =
            MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
                    .displayId(ADISPLAY_ID_DEFAULT)
                    .eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
                    .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
                    .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
                    .build();
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
                                InputEventInjectionSync::WAIT_FOR_RESULT))
            << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";

    window->consumeMotionPointerDown(1);
    wallpaperWindow->consumeMotionPointerDown(1, ADISPLAY_ID_DEFAULT, expectedWallpaperFlags);

    const MotionEvent secondFingerUpEvent =
            MotionEventBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
                    .displayId(ADISPLAY_ID_DEFAULT)
                    .eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
                    .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
                    .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
                    .build();
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT,
                                InputEventInjectionSync::WAIT_FOR_RESULT))
            << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
    window->consumeMotionPointerUp(1);
    wallpaperWindow->consumeMotionPointerUp(1, ADISPLAY_ID_DEFAULT, expectedWallpaperFlags);

    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {50, 50}))
            << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
    window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
    wallpaperWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT, expectedWallpaperFlags);
}

/**
 * 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.