Clear downTime when all pointers have lifted
Due to a recent change, the TouchWindows are getting persisted inside
TouchState. As a result, we need to keep a consistent state inside them.
Before this CL, the downTime of the TouchedWindow would get set with the
first pointer, but it would never reset. We used to rely on the fact
that the TouchedWindow would go away.
Now that is no longer the case.
In this CL, the downTime is cleared when all pointers leave the window.
The downTime can be set again when a new pointer appears.
This fixes one of the crashes due to the mismatching downTimes. To
reproduce the failure, we need to:
1) Find a way to persist a window
This can be done by injecting a mouse pointer into the window, and keep
the mouse there
2) Establish a downTime
This can be done by tapping on the window
3) Send another DOWN event while splitting the pointers.
Normally, a DOWN event would not go through the "splitting" path, and
therefore the crash would be avoided. The splitting path can be
triggered if we first touch another window, and then touch the first
one. The split touch feature would cause an ACTION_DOWN to get
generated, which would then trigger the 'split' case.
Bug: 266455987
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests --gtest_filter="*HoverTapAndSplitTouch*"
Change-Id: I2340b5ab70a3659f52fc38fa4d9e2c9edfe1a768
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index 92f62b5..99c4769 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -50,6 +50,14 @@
it->second.set(pointerId);
}
+void TouchedWindow::removeTouchingPointer(int32_t pointerId) {
+ pointerIds.reset(pointerId);
+ pilferedPointerIds.reset(pointerId);
+ if (pointerIds.none()) {
+ firstDownTimeInTarget.reset();
+ }
+}
+
void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
const auto it = mHoveringPointerIdsByDevice.find(deviceId);
if (it == mHoveringPointerIdsByDevice.end()) {