Track hovering pointers explicitly -- try 2
Update:
Compared to the first version of this CL that got reverted, this version
also adds Flags::FOREGROUND to the windows whenever appropriate.
Before this CL, hovering window was tracked separately inside
InputDispatcher. This window was getting updated in various places.
Inconsistent motion streams, like HOVER_ENTER->DOWN->UP->HOVER_EXIT were
possible.
In this CL, we track hovering pointers inside TouchedWindow. At all
times, the currently tracked pointer must always be in the touch state.
The hovering pointer is removed when HOVER_EXIT is received.
This CL also establishes the foundation for multi-device, multi-pointer
streams, by storing hovering pointers inside TouchedWindow per-device.
Eventually, we can look into separately creating touched targets from
updating the touch state. This approach is partially used in this CL.
TouchState is used to keep track of where the hovering pointer is
currently. The 'addHoveringWindowsLocked' function returns the
equivalent of InputTargets. Eventually, we can change this to return
InputTargets.
39d37cfb471c69f924e90f8e35afcff4ad4e6042
Bug: 211379801
Test: atest android.accessibilityservice.cts.AccessibilityEndToEndTest
Test: atest VirtualMouseTest
Test: m inputflinger_tests && adb sync data && adb shell -t /data/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: I0aa77bc9f680786b154312c4c936da2cf6efffa1
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index af74598..3704edd 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -25,11 +25,49 @@
namespace inputdispatcher {
+bool TouchedWindow::hasHoveringPointers() const {
+ return !mHoveringPointerIdsByDevice.empty();
+}
+
+void TouchedWindow::clearHoveringPointers() {
+ mHoveringPointerIdsByDevice.clear();
+}
+
+bool TouchedWindow::hasHoveringPointer(int32_t deviceId, int32_t pointerId) const {
+ auto it = mHoveringPointerIdsByDevice.find(deviceId);
+ if (it == mHoveringPointerIdsByDevice.end()) {
+ return false;
+ }
+ return it->second.test(pointerId);
+}
+
+void TouchedWindow::addHoveringPointer(int32_t deviceId, int32_t pointerId) {
+ const auto [it, _] = mHoveringPointerIdsByDevice.insert({deviceId, {}});
+ it->second.set(pointerId);
+}
+
+void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
+ const auto it = mHoveringPointerIdsByDevice.find(deviceId);
+ if (it == mHoveringPointerIdsByDevice.end()) {
+ return;
+ }
+ it->second.set(pointerId, false);
+
+ if (it->second.none()) {
+ mHoveringPointerIdsByDevice.erase(deviceId);
+ }
+}
+
std::string TouchedWindow::dump() const {
- return StringPrintf("name='%s', pointerIds=0x%0x, "
- "targetFlags=%s, firstDownTimeInTarget=%s\n",
+ std::string out;
+ std::string hoveringPointers =
+ dumpMap(mHoveringPointerIdsByDevice, constToString, bitsetToString);
+ out += StringPrintf("name='%s', pointerIds=0x%0x, targetFlags=%s, firstDownTimeInTarget=%s, "
+ "mHoveringPointerIdsByDevice=%s\n",
windowHandle->getName().c_str(), pointerIds.value,
- targetFlags.string().c_str(), toString(firstDownTimeInTarget).c_str());
+ targetFlags.string().c_str(), toString(firstDownTimeInTarget).c_str(),
+ hoveringPointers.c_str());
+ return out;
}
} // namespace inputdispatcher