diff options
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 13 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 22 |
2 files changed, 28 insertions, 7 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 6b9ad446ce..97b57b4dd9 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -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. @@ -2417,13 +2418,11 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( newTouchedWindowHandle = nullptr; } - if (oldTouchedWindowHandle != newTouchedWindowHandle && - oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) { - if (DEBUG_FOCUS) { - ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32, - oldTouchedWindowHandle->getName().c_str(), - newTouchedWindowHandle->getName().c_str(), displayId); - } + 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; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 27d7b9c93f..3bfc7bf9fe 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -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(); |