Loading services/inputflinger/dispatcher/InputDispatcher.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading services/inputflinger/tests/InputDispatcher_test.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading
services/inputflinger/tests/InputDispatcher_test.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading