Merge "Do not slip touch into window with same input channel" into udc-dev
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6b9ad44..97b57b4 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2402,6 +2402,7 @@
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 @@
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 27d7b9c..3bfc7bf 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -6140,6 +6140,28 @@
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();