diff options
| author | 2025-01-14 14:57:10 +0000 | |
|---|---|---|
| committer | 2025-02-03 10:58:29 +0000 | |
| commit | b9e6e59b98af873cb3b3ffa5024e29bd0e820d76 (patch) | |
| tree | 0bd0c1df2547ffc2b993dc25fb5dd20b06fe5872 | |
| parent | 403a3d7525e979cfe282796903b87b2ca8c10922 (diff) | |
[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
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 112 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 11 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 50 |
3 files changed, 105 insertions, 68 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 56be2e657f..85a0b4da69 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -1267,14 +1267,9 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) { 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 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, 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 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { 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 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev 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 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { resetNoFocusedWindowTimeoutLocked(); mAnrTracker.clear(); - mTouchStates.mTouchStatesByDisplay.clear(); + mTouchStates.clear(); } void InputDispatcher::logDispatchStateLocked() const { @@ -6036,15 +6019,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const { 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 @@ void InputDispatcher::cancelCurrentTouch() { "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 @@ bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, 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 @@ ftl::Flags<InputTarget::Flags> InputDispatcher::DispatcherTouchState::getTargetF 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 58c850929f..86ad56428f 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -373,6 +373,17 @@ private: 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 368db1b5c4..c0e2060bf8 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -9959,57 +9959,63 @@ TEST_F_WITH_FLAGS( 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 @@ TEST_F_WITH_FLAGS( 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 @@ TEST_F_WITH_FLAGS( 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(); } |