Allow new gestures to cancel current gestures
In a previous patch, we chose to ignore new gestures whenever there's
currently an active gesture. Generally this is fine to do, but there are
some concerns around doing that:
1) This is different from the previous behaviour, and some tests were
relying on the previous behaviour.
2) If a test injects an ACTION_DOWN event (globally) and never lifts up
the pointer, this would cause all real subsequent events to be
rejected. That means a bad test can cause device to get into a bad
state.
Rather than adding a special case to deal with 2), let's revert to the
previous behaviour.
Since we are now allowing the new device to take over, and only 1 device
can be active at a time (for now), we must reset the touching pointers
whenever we have a new gesture starting. That's because the function
synthesizeCancelationEventsForAllConnectionsLocked does not modify
TouchState.
We should also be canceling any of the currently hovering pointers by
sending an ACTION_HOVER_EXIT if a touch down occurs. This behaviour
was previously inconsistent in the mouse case.
Once per-device functionality is enabled, this behaviour will be
revisited.
Bug: 268683979
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Merged-In: I10c7ebde7c108baecb67a865f541253fa6e5f7ef
Change-Id: I10c7ebde7c108baecb67a865f541253fa6e5f7ef
(cherry picked from commit 837fab15be20e5960870e69065fda3645ef076ea)
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index 4258471..9c443f1 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -35,6 +35,7 @@
for (TouchedWindow& touchedWindow : windows) {
touchedWindow.removeTouchingPointer(pointerId);
}
+ clearWindowsWithoutPointers();
}
void TouchState::removeTouchedPointerFromWindow(
@@ -42,6 +43,7 @@
for (TouchedWindow& touchedWindow : windows) {
if (touchedWindow.windowHandle == windowHandle) {
touchedWindow.removeTouchingPointer(pointerId);
+ clearWindowsWithoutPointers();
return;
}
}
@@ -51,6 +53,7 @@
for (TouchedWindow& touchedWindow : windows) {
touchedWindow.clearHoveringPointers();
}
+ clearWindowsWithoutPointers();
}
void TouchState::clearWindowsWithoutPointers() {
@@ -135,7 +138,7 @@
w.pointerIds &= ~pointerIds;
}
});
- std::erase_if(windows, [](const TouchedWindow& w) { return w.pointerIds.none(); });
+ clearWindowsWithoutPointers();
}
/**
@@ -164,7 +167,7 @@
w.pilferedPointerIds ^ allPilferedPointerIds;
w.pointerIds &= ~pilferedByOtherWindows;
});
- std::erase_if(windows, [](const TouchedWindow& w) { return w.pointerIds.none(); });
+ clearWindowsWithoutPointers();
}
sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
@@ -216,6 +219,11 @@
[](const TouchedWindow& window) { return window.pointerIds.any(); });
}
+bool TouchState::hasHoveringPointers() const {
+ return std::any_of(windows.begin(), windows.end(),
+ [](const TouchedWindow& window) { return window.hasHoveringPointers(); });
+}
+
std::set<sp<WindowInfoHandle>> TouchState::getWindowsWithHoveringPointer(int32_t hoveringDeviceId,
int32_t pointerId) const {
std::set<sp<WindowInfoHandle>> out;
@@ -231,9 +239,7 @@
for (TouchedWindow& window : windows) {
window.removeHoveringPointer(hoveringDeviceId, hoveringPointerId);
}
- std::erase_if(windows, [](const TouchedWindow& w) {
- return w.pointerIds.none() && !w.hasHoveringPointers();
- });
+ clearWindowsWithoutPointers();
}
std::string TouchState::dump() const {