[14/n Dispatcher refactor] Move TouchState methods
In this CL we move or create following TouchState related methods to the
TouchState class:
1. clear
2. isPointerInWindow
3. hasTouchingOrHoveringPointers
4. removeAllPointersForDevice
5. dump
This CL also updates InputDispatcherUserActivityPokeTests to use current
time to inject events, to avoid them being dropped as stale.
Bug: 367661487
Bug: 245989146
Test: atest inputflinger_tests
Flag: EXEMPT refactor
Change-Id: I624700a78471a85a1e97c06b170137ee4e6ddf82
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 56be2e6..85a0b4d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1267,14 +1267,9 @@
if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
// The event is stale. However, only drop stale events if there isn't an ongoing
// gesture. That would allow us to complete the processing of the current stroke.
- const auto touchStateIt =
- mTouchStates.mTouchStatesByDisplay.find(motionEntry->displayId);
- if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
- const TouchState& touchState = touchStateIt->second;
- if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
- !touchState.hasHoveringPointers(motionEntry->deviceId)) {
- dropReason = DropReason::STALE;
- }
+ if (!mTouchStates.hasTouchingOrHoveringPointers(motionEntry->displayId,
+ motionEntry->deviceId)) {
+ dropReason = DropReason::STALE;
}
}
if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
@@ -1716,9 +1711,7 @@
synthesizeCancelationEventsForAllConnectionsLocked(options);
// Remove all active pointers from this device
- for (auto& [_, touchState] : mTouchStates.mTouchStatesByDisplay) {
- touchState.removeAllPointersForDevice(entry.deviceId);
- }
+ mTouchStates.removeAllPointersForDevice(entry.deviceId);
return true;
}
@@ -4581,13 +4574,8 @@
if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
// Set the flag anyway if we already have an ongoing gesture. That would allow us to
// complete the processing of the current stroke.
- const auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(args.displayId);
- if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
- const TouchState& touchState = touchStateIt->second;
- if (touchState.hasTouchingPointers(args.deviceId) ||
- touchState.hasHoveringPointers(args.deviceId)) {
- policyFlags |= POLICY_FLAG_PASS_TO_USER;
- }
+ if (mTouchStates.hasTouchingOrHoveringPointers(args.displayId, args.deviceId)) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
@@ -4893,13 +4881,8 @@
if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
// Set the flag anyway if we already have an ongoing motion gesture. That
// would allow us to complete the processing of the current stroke.
- const auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(displayId);
- if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
- const TouchState& touchState = touchStateIt->second;
- if (touchState.hasTouchingPointers(resolvedDeviceId) ||
- touchState.hasHoveringPointers(resolvedDeviceId)) {
- policyFlags |= POLICY_FLAG_PASS_TO_USER;
- }
+ if (mTouchStates.hasTouchingOrHoveringPointers(displayId, resolvedDeviceId)) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
@@ -5978,7 +5961,7 @@
resetNoFocusedWindowTimeoutLocked();
mAnrTracker.clear();
- mTouchStates.mTouchStatesByDisplay.clear();
+ mTouchStates.clear();
}
void InputDispatcher::logDispatchStateLocked() const {
@@ -6036,15 +6019,7 @@
dump += mFocusResolver.dump();
dump += dumpPointerCaptureStateLocked();
- if (!mTouchStates.mTouchStatesByDisplay.empty()) {
- dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
- for (const auto& [displayId, state] : mTouchStates.mTouchStatesByDisplay) {
- std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
- dump += INDENT2 + displayId.toString() + " : " + touchStateDump;
- }
- } else {
- dump += INDENT "TouchStates: <no displays touched>\n";
- }
+ dump += addLinePrefix(mTouchStates.dump(), INDENT);
if (mDragState) {
dump += StringPrintf(INDENT "DragState:\n");
@@ -7093,7 +7068,7 @@
"cancel current touch", traceContext.getTracker());
synthesizeCancelationEventsForAllConnectionsLocked(options);
- mTouchStates.mTouchStatesByDisplay.clear();
+ mTouchStates.clear();
}
// Wake up poll loop since there might be work to do.
mLooper->wake();
@@ -7228,18 +7203,7 @@
ui::LogicalDisplayId displayId, DeviceId deviceId,
int32_t pointerId) {
std::scoped_lock _l(mLock);
- auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(displayId);
- if (touchStateIt == mTouchStates.mTouchStatesByDisplay.end()) {
- return false;
- }
- for (const TouchedWindow& window : touchStateIt->second.windows) {
- if (window.windowHandle->getToken() == token &&
- (window.hasTouchingPointer(deviceId, pointerId) ||
- window.hasHoveringPointer(deviceId, pointerId))) {
- return true;
- }
- }
- return false;
+ return mTouchStates.isPointerInWindow(token, displayId, deviceId, pointerId);
}
void InputDispatcher::setInputMethodConnectionIsActive(bool isActive) {
@@ -7403,4 +7367,56 @@
return targetFlags;
}
+bool InputDispatcher::DispatcherTouchState::hasTouchingOrHoveringPointers(
+ ui::LogicalDisplayId displayId, int32_t deviceId) const {
+ const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
+ if (touchStateIt == mTouchStatesByDisplay.end()) {
+ return false;
+ }
+ return touchStateIt->second.hasTouchingPointers(deviceId) ||
+ touchStateIt->second.hasHoveringPointers(deviceId);
+}
+
+bool InputDispatcher::DispatcherTouchState::isPointerInWindow(const sp<android::IBinder>& token,
+ ui::LogicalDisplayId displayId,
+ android::DeviceId deviceId,
+ int32_t pointerId) const {
+ const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
+ if (touchStateIt == mTouchStatesByDisplay.end()) {
+ return false;
+ }
+ for (const TouchedWindow& window : touchStateIt->second.windows) {
+ if (window.windowHandle->getToken() == token &&
+ (window.hasTouchingPointer(deviceId, pointerId) ||
+ window.hasHoveringPointer(deviceId, pointerId))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string InputDispatcher::DispatcherTouchState::dump() const {
+ std::string dump;
+ if (!mTouchStatesByDisplay.empty()) {
+ dump += StringPrintf("TouchStatesByDisplay:\n");
+ for (const auto& [displayId, state] : mTouchStatesByDisplay) {
+ std::string touchStateDump = addLinePrefix(state.dump(), INDENT);
+ dump += INDENT + displayId.toString() + " : " + touchStateDump;
+ }
+ } else {
+ dump += "TouchStates: <no displays touched>\n";
+ }
+ return dump;
+}
+
+void InputDispatcher::DispatcherTouchState::removeAllPointersForDevice(android::DeviceId deviceId) {
+ for (auto& [_, touchState] : mTouchStatesByDisplay) {
+ touchState.removeAllPointersForDevice(deviceId);
+ }
+}
+
+void InputDispatcher::DispatcherTouchState::clear() {
+ mTouchStatesByDisplay.clear();
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 58c8509..86ad564 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -373,6 +373,17 @@
sp<android::gui::WindowInfoHandle> findTouchedForegroundWindow(
ui::LogicalDisplayId displayId) const;
+ bool hasTouchingOrHoveringPointers(ui::LogicalDisplayId displayId, int32_t deviceId) const;
+
+ bool isPointerInWindow(const sp<android::IBinder>& token, ui::LogicalDisplayId displayId,
+ DeviceId deviceId, int32_t pointerId) const;
+
+ std::string dump() const;
+
+ void removeAllPointersForDevice(DeviceId deviceId);
+
+ void clear();
+
std::unordered_map<ui::LogicalDisplayId, TouchState> mTouchStatesByDisplay;
private:
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 368db1b..c0e2060 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -9959,57 +9959,63 @@
InputDispatcherUserActivityPokeTests, MinPokeTimeObserved,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
+ // Use current time otherwise events may be dropped due to being stale.
+ const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
mDispatcher->setMinTimeBetweenUserActivityPokes(50ms);
// First event of type TOUCH. Should poke.
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(50));
+ currentTime + milliseconds_to_nanoseconds(50));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(50), USER_ACTIVITY_EVENT_TOUCH,
+ {{currentTime + milliseconds_to_nanoseconds(50), USER_ACTIVITY_EVENT_TOUCH,
ui::LogicalDisplayId::DEFAULT}});
// 80ns > 50ns has passed since previous TOUCH event. Should poke.
notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(130));
+ currentTime + milliseconds_to_nanoseconds(130));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(130), USER_ACTIVITY_EVENT_TOUCH,
+ {{currentTime + milliseconds_to_nanoseconds(130), USER_ACTIVITY_EVENT_TOUCH,
ui::LogicalDisplayId::DEFAULT}});
// First event of type OTHER. Should poke (despite being within 50ns of previous TOUCH event).
notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(135));
+ ui::LogicalDisplayId::DEFAULT,
+ currentTime + milliseconds_to_nanoseconds(135));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(135), USER_ACTIVITY_EVENT_OTHER,
+ {{currentTime + milliseconds_to_nanoseconds(135), USER_ACTIVITY_EVENT_OTHER,
ui::LogicalDisplayId::DEFAULT}});
// Within 50ns of previous TOUCH event. Should NOT poke.
notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(140));
+ currentTime + milliseconds_to_nanoseconds(140));
mFakePolicy->assertUserActivityNotPoked();
// Within 50ns of previous OTHER event. Should NOT poke.
notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(150));
+ ui::LogicalDisplayId::DEFAULT,
+ currentTime + milliseconds_to_nanoseconds(150));
mFakePolicy->assertUserActivityNotPoked();
// Within 50ns of previous TOUCH event (which was at time 130). Should NOT poke.
// Note that STYLUS is mapped to TOUCH user activity, since it's a pointer-type source.
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(160));
+ currentTime + milliseconds_to_nanoseconds(160));
mFakePolicy->assertUserActivityNotPoked();
// 65ns > 50ns has passed since previous OTHER event. Should poke.
notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(200));
+ ui::LogicalDisplayId::DEFAULT,
+ currentTime + milliseconds_to_nanoseconds(200));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_OTHER,
+ {{currentTime + milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_OTHER,
ui::LogicalDisplayId::DEFAULT}});
// 170ns > 50ns has passed since previous TOUCH event. Should poke.
notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(300));
+ currentTime + milliseconds_to_nanoseconds(300));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(300), USER_ACTIVITY_EVENT_TOUCH,
+ {{currentTime + milliseconds_to_nanoseconds(300), USER_ACTIVITY_EVENT_TOUCH,
ui::LogicalDisplayId::DEFAULT}});
// Assert that there's no more user activity poke event.
@@ -10020,20 +10026,22 @@
InputDispatcherUserActivityPokeTests, DefaultMinPokeTimeOf100MsUsed,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
+ // Use current time otherwise events may be dropped due to being stale.
+ const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(200));
+ currentTime + milliseconds_to_nanoseconds(200));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_TOUCH,
+ {{currentTime + milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_TOUCH,
ui::LogicalDisplayId::DEFAULT}});
notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(280));
+ currentTime + milliseconds_to_nanoseconds(280));
mFakePolicy->assertUserActivityNotPoked();
notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- milliseconds_to_nanoseconds(340));
+ currentTime + milliseconds_to_nanoseconds(340));
mFakePolicy->assertUserActivityPoked(
- {{milliseconds_to_nanoseconds(340), USER_ACTIVITY_EVENT_TOUCH,
+ {{currentTime + milliseconds_to_nanoseconds(340), USER_ACTIVITY_EVENT_TOUCH,
ui::LogicalDisplayId::DEFAULT}});
}
@@ -10041,14 +10049,16 @@
InputDispatcherUserActivityPokeTests, ZeroMinPokeTimeDisablesRateLimiting,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
+ // Use current time otherwise events may be dropped due to being stale.
+ const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
mDispatcher->setMinTimeBetweenUserActivityPokes(0ms);
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- 20);
+ currentTime + 20);
mFakePolicy->assertUserActivityPoked();
notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- 30);
+ currentTime + 30);
mFakePolicy->assertUserActivityPoked();
}