Loading services/inputflinger/dispatcher/InputDispatcher.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -2402,6 +2402,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0); sp<WindowInfoHandle> oldTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(); LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr); auto [newTouchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); // Verify targeted injection. Loading @@ -2417,13 +2418,11 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( newTouchedWindowHandle = nullptr; } if (oldTouchedWindowHandle != newTouchedWindowHandle && oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) { if (DEBUG_FOCUS) { if (!haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) { ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32, oldTouchedWindowHandle->getName().c_str(), newTouchedWindowHandle->getName().c_str(), displayId); } // Make a slippery exit from the old window. std::bitset<MAX_POINTER_ID + 1> pointerIds; const int32_t pointerId = entry.pointerProperties[0].id; Loading services/inputflinger/tests/InputDispatcher_test.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -6140,6 +6140,28 @@ TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithSc touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints); } /** * When one of the windows is slippery, the touch should not slip into the other window with the * same input channel. */ TEST_F(InputDispatcherMultiWindowSameTokenTests, TouchDoesNotSlipEvenIfSlippery) { mWindow1->setSlippery(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}}); // Touch down in window 1 mDispatcher->notifyMotion(generateMotionArgs(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {{50, 50}})); consumeMotionEvent(mWindow1, ACTION_DOWN, {{50, 50}}); // Move touch to be above window 2. Even though window 1 is slippery, touch should not slip. // That means the gesture should continue normally, without any ACTION_CANCEL or ACTION_DOWN // getting generated. mDispatcher->notifyMotion(generateMotionArgs(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {{150, 150}})); consumeMotionEvent(mWindow1, ACTION_MOVE, {{150, 150}}); } class InputDispatcherSingleWindowAnr : public InputDispatcherTest { virtual void SetUp() override { InputDispatcherTest::SetUp(); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -2402,6 +2402,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0); sp<WindowInfoHandle> oldTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(); LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr); auto [newTouchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); // Verify targeted injection. Loading @@ -2417,13 +2418,11 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( newTouchedWindowHandle = nullptr; } if (oldTouchedWindowHandle != newTouchedWindowHandle && oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) { if (DEBUG_FOCUS) { if (!haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) { ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32, oldTouchedWindowHandle->getName().c_str(), newTouchedWindowHandle->getName().c_str(), displayId); } // Make a slippery exit from the old window. std::bitset<MAX_POINTER_ID + 1> pointerIds; const int32_t pointerId = entry.pointerProperties[0].id; Loading
services/inputflinger/tests/InputDispatcher_test.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -6140,6 +6140,28 @@ TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithSc touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints); } /** * When one of the windows is slippery, the touch should not slip into the other window with the * same input channel. */ TEST_F(InputDispatcherMultiWindowSameTokenTests, TouchDoesNotSlipEvenIfSlippery) { mWindow1->setSlippery(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}}); // Touch down in window 1 mDispatcher->notifyMotion(generateMotionArgs(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {{50, 50}})); consumeMotionEvent(mWindow1, ACTION_DOWN, {{50, 50}}); // Move touch to be above window 2. Even though window 1 is slippery, touch should not slip. // That means the gesture should continue normally, without any ACTION_CANCEL or ACTION_DOWN // getting generated. mDispatcher->notifyMotion(generateMotionArgs(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {{150, 150}})); consumeMotionEvent(mWindow1, ACTION_MOVE, {{150, 150}}); } class InputDispatcherSingleWindowAnr : public InputDispatcherTest { virtual void SetUp() override { InputDispatcherTest::SetUp(); Loading