Store pointers per-device
Previously, input dispatcher assumed that a single input device is
active. However, we are trying to add multi-device support.
In this CL, store the pointers inside touched windows on a per-device
basis. This CL should not cause any behaviour changes. We expect there
to be a single device active at a time still.
Bug: 211379801
Bug: 281806933
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: I73fc4adcf306bb49e153f3daeed68753e0632c86
Signed-off-by: Siarhei Vishniakou <svv@google.com>
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index d55d657..6ab97f8 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -16,6 +16,7 @@
#include "TouchedWindow.h"
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <input/PrintTools.h>
@@ -26,67 +27,228 @@
namespace inputdispatcher {
bool TouchedWindow::hasHoveringPointers() const {
- return !mHoveringPointerIdsByDevice.empty();
+ for (const auto& [_, state] : mDeviceStates) {
+ if (state.hoveringPointerIds.any()) {
+ return true;
+ }
+ }
+ return false;
}
bool TouchedWindow::hasHoveringPointers(int32_t deviceId) const {
- return mHoveringPointerIdsByDevice.find(deviceId) != mHoveringPointerIdsByDevice.end();
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return false;
+ }
+ const DeviceState& state = stateIt->second;
+
+ return state.hoveringPointerIds.any();
}
void TouchedWindow::clearHoveringPointers() {
- mHoveringPointerIdsByDevice.clear();
+ for (auto& [_, state] : mDeviceStates) {
+ state.hoveringPointerIds.reset();
+ }
+
+ std::erase_if(mDeviceStates, [](const auto& pair) { return !pair.second.hasPointers(); });
}
bool TouchedWindow::hasHoveringPointer(int32_t deviceId, int32_t pointerId) const {
- auto it = mHoveringPointerIdsByDevice.find(deviceId);
- if (it == mHoveringPointerIdsByDevice.end()) {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
return false;
}
- return it->second.test(pointerId);
+ const DeviceState& state = stateIt->second;
+
+ return state.hoveringPointerIds.test(pointerId);
}
void TouchedWindow::addHoveringPointer(int32_t deviceId, int32_t pointerId) {
- const auto [it, _] = mHoveringPointerIdsByDevice.insert({deviceId, {}});
- it->second.set(pointerId);
+ mDeviceStates[deviceId].hoveringPointerIds.set(pointerId);
}
-void TouchedWindow::removeTouchingPointer(int32_t pointerId) {
- pointerIds.reset(pointerId);
- pilferedPointerIds.reset(pointerId);
- if (pointerIds.none()) {
- firstDownTimeInTarget.reset();
+void TouchedWindow::addTouchingPointer(int32_t deviceId, int32_t pointerId) {
+ mDeviceStates[deviceId].touchingPointerIds.set(pointerId);
+}
+
+void TouchedWindow::addTouchingPointers(int32_t deviceId,
+ std::bitset<MAX_POINTER_ID + 1> pointers) {
+ mDeviceStates[deviceId].touchingPointerIds |= pointers;
+}
+
+bool TouchedWindow::hasTouchingPointers() const {
+ for (const auto& [_, state] : mDeviceStates) {
+ if (state.touchingPointerIds.any()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TouchedWindow::hasTouchingPointers(int32_t deviceId) const {
+ return getTouchingPointers(deviceId).any();
+}
+
+bool TouchedWindow::hasTouchingPointer(int32_t deviceId, int32_t pointerId) const {
+ return getTouchingPointers(deviceId).test(pointerId);
+}
+
+std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getTouchingPointers(int32_t deviceId) const {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return {};
+ }
+ const DeviceState& state = stateIt->second;
+
+ return state.touchingPointerIds;
+}
+
+void TouchedWindow::removeTouchingPointer(int32_t deviceId, int32_t pointerId) {
+ std::bitset<MAX_POINTER_ID + 1> pointerIds;
+ pointerIds.set(pointerId, true);
+
+ removeTouchingPointers(deviceId, pointerIds);
+}
+
+void TouchedWindow::removeTouchingPointers(int32_t deviceId,
+ std::bitset<MAX_POINTER_ID + 1> pointers) {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return;
+ }
+ DeviceState& state = stateIt->second;
+
+ state.touchingPointerIds &= ~pointers;
+ state.pilferingPointerIds &= ~pointers;
+
+ if (!state.hasPointers()) {
+ mDeviceStates.erase(stateIt);
}
}
-void TouchedWindow::removeAllTouchingPointers() {
- pointerIds.reset();
+std::set<int32_t> TouchedWindow::getTouchingDeviceIds() const {
+ std::set<int32_t> deviceIds;
+ for (const auto& [deviceId, _] : mDeviceStates) {
+ deviceIds.insert(deviceId);
+ }
+ return deviceIds;
+}
+
+bool TouchedWindow::hasPilferingPointers(int32_t deviceId) const {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return false;
+ }
+ const DeviceState& state = stateIt->second;
+
+ return state.pilferingPointerIds.any();
+}
+
+void TouchedWindow::addPilferingPointers(int32_t deviceId,
+ std::bitset<MAX_POINTER_ID + 1> pointerIds) {
+ mDeviceStates[deviceId].pilferingPointerIds |= pointerIds;
+}
+
+void TouchedWindow::addPilferingPointer(int32_t deviceId, int32_t pointerId) {
+ mDeviceStates[deviceId].pilferingPointerIds.set(pointerId);
+}
+
+std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getPilferingPointers(int32_t deviceId) const {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return {};
+ }
+ const DeviceState& state = stateIt->second;
+
+ return state.pilferingPointerIds;
+}
+
+std::map<int32_t, std::bitset<MAX_POINTER_ID + 1>> TouchedWindow::getPilferingPointers() const {
+ std::map<int32_t, std::bitset<MAX_POINTER_ID + 1>> out;
+ for (const auto& [deviceId, state] : mDeviceStates) {
+ out.emplace(deviceId, state.pilferingPointerIds);
+ }
+ return out;
+}
+
+std::optional<nsecs_t> TouchedWindow::getDownTimeInTarget(int32_t deviceId) const {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return {};
+ }
+ const DeviceState& state = stateIt->second;
+ return state.downTimeInTarget;
+}
+
+void TouchedWindow::trySetDownTimeInTarget(int32_t deviceId, nsecs_t downTime) {
+ auto [stateIt, _] = mDeviceStates.try_emplace(deviceId);
+ DeviceState& state = stateIt->second;
+
+ if (!state.downTimeInTarget) {
+ state.downTimeInTarget = downTime;
+ }
+}
+
+void TouchedWindow::removeAllTouchingPointersForDevice(int32_t deviceId) {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return;
+ }
+ DeviceState& state = stateIt->second;
+
+ state.touchingPointerIds.reset();
+ state.pilferingPointerIds.reset();
+ state.downTimeInTarget.reset();
+
+ if (!state.hasPointers()) {
+ mDeviceStates.erase(stateIt);
+ }
}
void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
- const auto it = mHoveringPointerIdsByDevice.find(deviceId);
- if (it == mHoveringPointerIdsByDevice.end()) {
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
return;
}
- it->second.set(pointerId, false);
+ DeviceState& state = stateIt->second;
- if (it->second.none()) {
- mHoveringPointerIdsByDevice.erase(deviceId);
+ state.hoveringPointerIds.set(pointerId, false);
+
+ if (!state.hasPointers()) {
+ mDeviceStates.erase(stateIt);
}
}
void TouchedWindow::removeAllHoveringPointersForDevice(int32_t deviceId) {
- mHoveringPointerIdsByDevice.erase(deviceId);
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return;
+ }
+ DeviceState& state = stateIt->second;
+
+ state.hoveringPointerIds.reset();
+
+ if (!state.hasPointers()) {
+ mDeviceStates.erase(stateIt);
+ }
+}
+
+std::string TouchedWindow::deviceStateToString(const TouchedWindow::DeviceState& state) {
+ return StringPrintf("[touchingPointerIds=%s, "
+ "downTimeInTarget=%s, hoveringPointerIds=%s, pilferingPointerIds=%s]",
+ bitsetToString(state.touchingPointerIds).c_str(),
+ toString(state.downTimeInTarget).c_str(),
+ bitsetToString(state.hoveringPointerIds).c_str(),
+ bitsetToString(state.pilferingPointerIds).c_str());
}
std::string TouchedWindow::dump() const {
std::string out;
- std::string hoveringPointers =
- dumpMap(mHoveringPointerIdsByDevice, constToString, bitsetToString);
- out += StringPrintf("name='%s', pointerIds=%s, targetFlags=%s, firstDownTimeInTarget=%s, "
- "mHoveringPointerIdsByDevice=%s, pilferedPointerIds=%s\n",
- windowHandle->getName().c_str(), bitsetToString(pointerIds).c_str(),
- targetFlags.string().c_str(), toString(firstDownTimeInTarget).c_str(),
- hoveringPointers.c_str(), bitsetToString(pilferedPointerIds).c_str());
+ std::string deviceStates =
+ dumpMap(mDeviceStates, constToString, TouchedWindow::deviceStateToString);
+ out += StringPrintf("name='%s', targetFlags=%s, mDeviceStates=%s\n",
+ windowHandle->getName().c_str(), targetFlags.string().c_str(),
+ deviceStates.c_str());
return out;
}