diff options
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 39 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 6 |
2 files changed, 38 insertions, 7 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 35558a7a07..ba8c814bd5 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -4072,13 +4072,17 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( // Generate cancellations for touched windows first. This is to avoid generating cancellations // through a non-touched window if there are more than one window for an input channel. if (cancelPointers) { - for (const auto& [displayId, touchState] : mTouchStates.mTouchStatesByDisplay) { - if (options.displayId.has_value() && options.displayId != displayId) { - continue; - } - for (const auto& touchedWindow : touchState.windows) { - synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); - } + if (options.displayId.has_value()) { + mTouchStates.forAllTouchedWindowsOnDisplay( + options.displayId.value(), [&](const sp<gui::WindowInfoHandle>& windowHandle) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForWindowLocked(windowHandle, options); + }); + } else { + mTouchStates.forAllTouchedWindows([&](const sp<gui::WindowInfoHandle>& windowHandle) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForWindowLocked(windowHandle, options); + }); } } // Follow up by generating cancellations for all windows, because we don't explicitly track @@ -7475,6 +7479,27 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowHandleAndDisplay( return std::nullopt; } +void InputDispatcher::DispatcherTouchState::forAllTouchedWindows( + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const { + for (const auto& [_, state] : mTouchStatesByDisplay) { + for (const TouchedWindow& window : state.windows) { + f(window.windowHandle); + } + } +} + +void InputDispatcher::DispatcherTouchState::forAllTouchedWindowsOnDisplay( + ui::LogicalDisplayId displayId, + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const { + const auto touchStateIt = mTouchStatesByDisplay.find(displayId); + if (touchStateIt == mTouchStatesByDisplay.end()) { + return; + } + for (const TouchedWindow& window : touchStateIt->second.windows) { + f(window.windowHandle); + } +} + std::string InputDispatcher::DispatcherTouchState::dump() const { std::string dump; if (!mTouchStatesByDisplay.empty()) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 9b11c14819..f468be8a3d 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -396,6 +396,12 @@ private: std::optional<std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>> findTouchedWindowHandleAndDisplay(const sp<IBinder>& token) const; + void forAllTouchedWindows(std::function<void(const sp<gui::WindowInfoHandle>&)> f) const; + + void forAllTouchedWindowsOnDisplay( + ui::LogicalDisplayId displayId, + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const; + std::string dump() const; // Updates the touchState for display from WindowInfo, |