summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Siarhei Vishniakou <svv@google.com> 2023-05-08 22:35:50 -0700
committer Siarhei Vishniakou <svv@google.com> 2023-05-08 22:49:00 -0700
commitafa08cc62d993eabafd8676a296f55e4c86e05bb (patch)
tree650dcb7f4157daf059f7a4fcbe0b6f6eacd6b76c
parent85b26eb444a954155a631763b77d4e1ad108f006 (diff)
Slip touch when the new window is valid
Previously, the condition for slipping touch was based on the difference in window tokens. However, that check missed the possibility of the new window handle being null. In this CL, that check is returned. To reproduce this crash, touch needs to try to slip from a slippery window into a window that requests to drop input. Bug: 281601168 Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests Change-Id: I0add7ee65a6492695e9b2368c83fe553677a32f6
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp3
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp40
2 files changed, 42 insertions, 1 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 326ca87c41..f3ada8e298 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2476,7 +2476,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
newTouchedWindowHandle = nullptr;
}
- if (!haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
+ if (newTouchedWindowHandle != nullptr &&
+ !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);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index a6cdee5fb1..f6f02d8241 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -5535,6 +5535,46 @@ TEST_F(InputDispatcherTest, SlipperyWindow_SetsFlagPartiallyObscured) {
AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
}
+/**
+ * Two windows, one on the left and another on the right. The left window is slippery. The right
+ * window isn't eligible to receive touch because it specifies InputConfig::DROP_INPUT. When the
+ * touch moves from the left window into the right window, the gesture should continue to go to the
+ * left window. Touch shouldn't slip because the right window can't receive touches. This test
+ * reproduces a crash.
+ */
+TEST_F(InputDispatcherTest, TouchSlippingIntoWindowThatDropsTouches) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+ sp<FakeWindowHandle> leftSlipperyWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
+ leftSlipperyWindow->setSlippery(true);
+ leftSlipperyWindow->setFrame(Rect(0, 0, 100, 100));
+
+ sp<FakeWindowHandle> rightDropTouchesWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
+ rightDropTouchesWindow->setFrame(Rect(100, 0, 200, 100));
+ rightDropTouchesWindow->setDropInput(true);
+
+ mDispatcher->setInputWindows(
+ {{ADISPLAY_ID_DEFAULT, {leftSlipperyWindow, rightDropTouchesWindow}}});
+
+ // Start touch in the left window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .build());
+ leftSlipperyWindow->consumeMotionDown();
+
+ // And move it into the right window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+ .build());
+
+ // Since the right window isn't eligible to receive input, touch does not slip.
+ // The left window continues to receive the gesture.
+ leftSlipperyWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
+ rightDropTouchesWindow->assertNoEvents();
+}
+
class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
protected:
static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms