summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arpit Singh <arpitks@google.com> 2024-12-20 15:35:08 +0000
committer Arpit Singh <arpitks@google.com> 2024-12-31 13:04:12 +0000
commit5614714ae22e9ceac6ff2561f7d2a10f80bc0f9c (patch)
treed587c945d0e6b9ca927f2cfdd386d8ab73c0a494
parent94bfc4b17173eef7a233c6229438503b295c8c48 (diff)
[2/n InputDispatcher refactor] Consolidate Window and DisplayInfo
Consolidating window and display infos in a subclass. This will enable us abstract out related states in dispatcher by passing references. Bug: 367661487 Bug: 245989146 Test: atest inputflinger_tests Flag: EXEMPT refactor Change-Id: I09d234687cd797ee9ff2f6b44b6b890e50d4636f
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp271
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h56
2 files changed, 197 insertions, 130 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 15df89b990..b5287a2254 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1128,7 +1128,7 @@ std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
if (connection->monitor) {
return mMonitorDispatchingTimeout;
}
- const sp<WindowInfoHandle> window = getWindowHandleLocked(connection->getToken());
+ const sp<WindowInfoHandle> window = mWindowInfos.findWindowHandle(connection->getToken());
if (window != nullptr) {
return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
}
@@ -1456,7 +1456,7 @@ sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(ui::LogicalDispl
float x, float y, bool isStylus,
bool ignoreDragWindow) const {
// Traverse windows from front to back to find touched window.
- const auto& windowHandles = getWindowHandlesLocked(displayId);
+ const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
continue;
@@ -1464,7 +1464,8 @@ sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(ui::LogicalDispl
const WindowInfo& info = *windowHandle->getInfo();
if (!info.isSpy() &&
- windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
+ windowAcceptsTouchAt(info, displayId, x, y, isStylus,
+ mWindowInfos.getDisplayTransform(displayId))) {
return windowHandle;
}
}
@@ -1479,7 +1480,7 @@ std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
}
// Traverse windows from front to back until we encounter the touched window.
std::vector<InputTarget> outsideTargets;
- const auto& windowHandles = getWindowHandlesLocked(displayId);
+ const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
if (windowHandle == touchedWindow) {
// Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
@@ -1503,10 +1504,11 @@ std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked
ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const {
// Traverse windows from front to back and gather the touched spy windows.
std::vector<sp<WindowInfoHandle>> spyWindows;
- const auto& windowHandles = getWindowHandlesLocked(displayId);
+ const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
const WindowInfo& info = *windowHandle->getInfo();
- if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
+ if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus,
+ mWindowInfos.getDisplayTransform(displayId))) {
// Generally, we would skip any pointer that's outside of the window. However, if the
// spy prevents splitting, and already has some of the pointers from this device, then
// it should get more pointers from the same device, even if they are outside of that
@@ -1828,7 +1830,7 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
void InputDispatcher::dispatchTouchModeChangeLocked(
nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
const std::vector<sp<WindowInfoHandle>>& windowHandles =
- getWindowHandlesLocked(entry->displayId);
+ mWindowInfos.getWindowHandlesForDisplay(entry->displayId);
if (windowHandles.empty()) {
return;
}
@@ -2216,7 +2218,7 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>
sp<WindowInfoHandle> windowHandle;
if (!connection->monitor) {
- windowHandle = getWindowHandleLocked(connection->getToken());
+ windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
if (windowHandle == nullptr) {
// The window that is receiving this ANR was removed, so there is no need to generate
// cancellations, because the cancellations would have already been generated when
@@ -2779,7 +2781,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
for (InputTarget& target : targets) {
if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
sp<WindowInfoHandle> targetWindow =
- getWindowHandleLocked(target.connection->getToken());
+ mWindowInfos.findWindowHandle(target.connection->getToken());
if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
target.flags |= InputTarget::Flags::ZERO_COORDS;
}
@@ -2985,13 +2987,8 @@ std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
inputTarget.flags = targetFlags;
inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
- const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
- if (displayInfoIt != mDisplayInfos.end()) {
- inputTarget.displayTransform = displayInfoIt->second.transform;
- } else {
- // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
- // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
- }
+ inputTarget.displayTransform =
+ mWindowInfos.getDisplayTransform(windowHandle->getInfo()->displayId);
return inputTarget;
}
@@ -3099,9 +3096,7 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>&
InputTarget target{monitor.connection};
// target.firstDownTimeInTarget is not set for global monitors. It is only required in split
// touch and global monitoring works as intended even without setting firstDownTimeInTarget
- if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
- target.displayTransform = it->second.transform;
- }
+ target.displayTransform = mWindowInfos.getDisplayTransform(displayId);
target.setDefaultPointerTransform(target.displayTransform);
inputTargets.push_back(target);
}
@@ -3164,7 +3159,8 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo
const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
const WindowInfo* windowInfo = windowHandle->getInfo();
ui::LogicalDisplayId displayId = windowInfo->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
TouchOcclusionInfo info;
info.hasBlockingOcclusion = false;
info.obscuringOpacity = 0;
@@ -3176,7 +3172,8 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo
}
const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
- windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId)) &&
+ windowOccludesTouchAt(*otherInfo, displayId, x, y,
+ mWindowInfos.getDisplayTransform(displayId)) &&
!haveSameApplicationToken(windowInfo, otherInfo)) {
if (DEBUG_TOUCH_OCCLUSION) {
info.debugInfo.push_back(
@@ -3248,14 +3245,16 @@ bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionIn
bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
float x, float y) const {
ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
break; // All future windows are below us. Exit early.
}
const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
- windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId))) {
+ windowOccludesTouchAt(*otherInfo, displayId, x, y,
+ mWindowInfos.getDisplayTransform(displayId))) {
return true;
}
}
@@ -3264,7 +3263,8 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>&
bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
const WindowInfo* windowInfo = windowHandle->getInfo();
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
@@ -4118,7 +4118,8 @@ int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionTok
} else {
// Monitor channels are never explicitly unregistered.
// We do it automatically when the remote endpoint is closed so don't warn about them.
- const bool stillHaveWindowHandle = getWindowHandleLocked(connection->getToken()) != nullptr;
+ const bool stillHaveWindowHandle =
+ mWindowInfos.findWindowHandle(connection->getToken()) != nullptr;
notify = !connection->monitor && stillHaveWindowHandle;
if (notify) {
ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
@@ -4153,11 +4154,11 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
// Follow up by generating cancellations for all windows, because we don't explicitly track
// the windows that have an ongoing focus event stream.
if (cancelNonPointers) {
- for (const auto& [_, handles] : mWindowHandlesByDisplay) {
- for (const auto& windowHandle : handles) {
- synthesizeCancelationEventsForWindowLocked(windowHandle, options);
- }
- }
+ mWindowInfos.forEachWindowHandle(
+ [&](const sp<android::gui::WindowInfoHandle>& windowHandle) {
+ base::ScopedLockAssertion assumeLocked(mLock);
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options);
+ });
}
// Cancel monitors.
@@ -4281,11 +4282,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
motionEntry.downTime, targets);
} else {
targets.emplace_back(fallbackTarget);
- const auto it = mDisplayInfos.find(motionEntry.displayId);
- if (it != mDisplayInfos.end()) {
- targets.back().displayTransform = it->second.transform;
- targets.back().setDefaultPointerTransform(it->second.transform);
- }
+ const ui::Transform displayTransform =
+ mWindowInfos.getDisplayTransform(motionEntry.displayId);
+ targets.back().displayTransform = displayTransform;
+ targets.back().setDefaultPointerTransform(displayTransform);
}
logOutboundMotionDetails("cancel - ", motionEntry);
break;
@@ -4367,11 +4367,10 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
targets);
} else {
targets.emplace_back(connection, targetFlags);
- const auto it = mDisplayInfos.find(motionEntry.displayId);
- if (it != mDisplayInfos.end()) {
- targets.back().displayTransform = it->second.transform;
- targets.back().setDefaultPointerTransform(it->second.transform);
- }
+ const ui::Transform displayTransform =
+ mWindowInfos.getDisplayTransform(motionEntry.displayId);
+ targets.back().displayTransform = displayTransform;
+ targets.back().setDefaultPointerTransform(displayTransform);
}
logOutboundMotionDetails("down - ", motionEntry);
break;
@@ -4642,10 +4641,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
}
if (shouldSendMotionToInputFilterLocked(args)) {
- ui::Transform displayTransform;
- if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
- displayTransform = it->second.transform;
- }
+ ui::Transform displayTransform = mWindowInfos.getDisplayTransform(args.displayId);
mLock.unlock();
@@ -5149,9 +5145,8 @@ void InputDispatcher::transformMotionEntryForInjectionLocked(
MotionEntry& entry, const ui::Transform& injectedTransform) const {
// Input injection works in the logical display coordinate space, but the input pipeline works
// display space, so we need to transform the injected events accordingly.
- const auto it = mDisplayInfos.find(entry.displayId);
- if (it == mDisplayInfos.end()) return;
- const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
+ const ui::Transform displayTransform = mWindowInfos.getDisplayTransform(entry.displayId);
+ const auto& transformToDisplay = displayTransform.inverse() * injectedTransform;
if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
@@ -5184,14 +5179,7 @@ void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& ent
}
}
-const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
- ui::LogicalDisplayId displayId) const {
- static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
- auto it = mWindowHandlesByDisplay.find(displayId);
- return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
-}
-
-sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
+sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandle(
const sp<IBinder>& windowHandleToken, std::optional<ui::LogicalDisplayId> displayId) const {
if (windowHandleToken == nullptr) {
return nullptr;
@@ -5210,7 +5198,7 @@ sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
}
// Only look through the requested display.
- for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
+ for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesForDisplay(*displayId)) {
if (windowHandle->getToken() == windowHandleToken) {
return windowHandle;
}
@@ -5218,7 +5206,8 @@ sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
return nullptr;
}
-bool InputDispatcher::isWindowPresentLocked(const sp<WindowInfoHandle>& windowHandle) const {
+bool InputDispatcher::DispatcherWindowInfo::isWindowPresent(
+ const sp<WindowInfoHandle>& windowHandle) const {
for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
for (const sp<WindowInfoHandle>& handle : windowHandles) {
if (handle->getId() == windowHandle->getId() &&
@@ -5239,15 +5228,88 @@ bool InputDispatcher::isWindowPresentLocked(const sp<WindowInfoHandle>& windowHa
sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(
ui::LogicalDisplayId displayId) const {
sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
- return getWindowHandleLocked(focusedToken, displayId);
+ return mWindowInfos.findWindowHandle(focusedToken, displayId);
+}
+
+void InputDispatcher::DispatcherWindowInfo::setWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId, std::vector<sp<WindowInfoHandle>>&& windowHandles) {
+ // Insert or replace
+ mWindowHandlesByDisplay[displayId] = std::move(windowHandles);
}
-ui::Transform InputDispatcher::getTransformLocked(ui::LogicalDisplayId displayId) const {
+void InputDispatcher::DispatcherWindowInfo::setDisplayInfos(
+ const std::vector<android::gui::DisplayInfo>& displayInfos) {
+ mDisplayInfos.clear();
+ for (const auto& displayInfo : displayInfos) {
+ mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
+ }
+}
+
+void InputDispatcher::DispatcherWindowInfo::removeDisplay(ui::LogicalDisplayId displayId) {
+ mWindowHandlesByDisplay.erase(displayId);
+}
+
+const std::vector<sp<android::gui::WindowInfoHandle>>&
+InputDispatcher::DispatcherWindowInfo::getWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId) const {
+ static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
+ const auto it = mWindowHandlesByDisplay.find(displayId);
+ return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
+}
+
+void InputDispatcher::DispatcherWindowInfo::forEachWindowHandle(
+ std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const {
+ for (const auto& [_, windowHandles] : mWindowHandlesByDisplay) {
+ for (const auto& windowHandle : windowHandles) {
+ f(windowHandle);
+ }
+ }
+}
+
+void InputDispatcher::DispatcherWindowInfo::forEachDisplayId(
+ std::function<void(ui::LogicalDisplayId)> f) const {
+ for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
+ f(displayId);
+ }
+}
+
+ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform(
+ ui::LogicalDisplayId displayId) const {
auto displayInfoIt = mDisplayInfos.find(displayId);
return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
: kIdentityTransform;
}
+std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
+ std::string dump;
+ if (!mWindowHandlesByDisplay.empty()) {
+ for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
+ dump += StringPrintf("Display: %s\n", displayId.toString().c_str());
+ if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
+ const auto& displayInfo = it->second;
+ dump += StringPrintf(INDENT "logicalSize=%dx%d\n", displayInfo.logicalWidth,
+ displayInfo.logicalHeight);
+ displayInfo.transform.dump(dump, "transform", INDENT3);
+ } else {
+ dump += INDENT "No DisplayInfo found!\n";
+ }
+
+ if (!windowHandles.empty()) {
+ dump += INDENT "Windows:\n";
+ for (size_t i = 0; i < windowHandles.size(); i++) {
+ dump += StringPrintf(INDENT2 "%zu: %s", i,
+ streamableToString(*windowHandles[i]).c_str());
+ }
+ } else {
+ dump += INDENT "Windows: <none>\n";
+ }
+ }
+ } else {
+ dump += "Displays: <none>\n";
+ }
+ return dump;
+}
+
bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
const MotionEntry& motionEntry) const {
const WindowInfo& info = *window->getInfo();
@@ -5315,13 +5377,14 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked(
ui::LogicalDisplayId displayId) {
if (windowInfoHandles.empty()) {
// Remove all handles on a display if there are no windows left.
- mWindowHandlesByDisplay.erase(displayId);
+ mWindowInfos.removeDisplay(displayId);
return;
}
// Since we compare the pointer of input window handles across window updates, we need
// to make sure the handle object for the same window stays unchanged across updates.
- const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& oldHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
for (const sp<WindowInfoHandle>& handle : oldHandles) {
oldHandlesById[handle->getId()] = handle;
@@ -5360,8 +5423,7 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked(
}
}
- // Insert or replace
- mWindowHandlesByDisplay[displayId] = newHandles;
+ mWindowInfos.setWindowHandlesForDisplay(displayId, std::move(newHandles));
}
/**
@@ -5411,12 +5473,14 @@ void InputDispatcher::setInputWindowsLocked(
}
// Copy old handles for release if they are no longer present.
- const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>> oldWindowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
const sp<WindowInfoHandle> removedFocusedWindowHandle = getFocusedWindowHandleLocked(displayId);
updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
std::optional<FocusResolver::FocusChanges> changes =
mFocusResolver.setInputWindows(displayId, windowHandles);
@@ -5428,7 +5492,7 @@ void InputDispatcher::setInputWindowsLocked(
TouchState& state = it->second;
for (size_t i = 0; i < state.windows.size();) {
TouchedWindow& touchedWindow = state.windows[i];
- if (isWindowPresentLocked(touchedWindow.windowHandle)) {
+ if (mWindowInfos.isWindowPresent(touchedWindow.windowHandle)) {
i++;
continue;
}
@@ -5472,7 +5536,8 @@ void InputDispatcher::setInputWindowsLocked(
[this, displayId, &touchedWindow](const PointerProperties& properties, float x,
float y) REQUIRES(mLock) {
const bool isStylus = properties.toolType == ToolType::STYLUS;
- const ui::Transform displayTransform = getTransformLocked(displayId);
+ const ui::Transform displayTransform =
+ mWindowInfos.getDisplayTransform(displayId);
const bool stillAcceptsTouch =
windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(),
displayId, x, y, isStylus, displayTransform);
@@ -5494,7 +5559,7 @@ void InputDispatcher::setInputWindowsLocked(
// Otherwise, they might stick around until the window handle is destroyed
// which might not happen until the next GC.
for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
- if (!isWindowPresentLocked(oldWindowHandle)) {
+ if (!mWindowInfos.isWindowPresent(oldWindowHandle)) {
if (DEBUG_FOCUS) {
ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
}
@@ -5571,7 +5636,7 @@ void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) {
mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
if (oldFocusedWindowToken != nullptr) {
const auto windowHandle =
- getWindowHandleLocked(oldFocusedWindowToken, mFocusedDisplayId);
+ mWindowInfos.findWindowHandle(oldFocusedWindowToken, mFocusedDisplayId);
if (windowHandle == nullptr) {
LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
}
@@ -5710,7 +5775,7 @@ bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
if (focusedToken == nullptr) {
return false;
}
- sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
+ sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(focusedToken);
return isWindowOwnedBy(windowHandle, pid, uid);
}
@@ -5718,7 +5783,7 @@ bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid)
return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
[&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
const sp<WindowInfoHandle> windowHandle =
- getWindowHandleLocked(connectionToken);
+ mWindowInfos.findWindowHandle(connectionToken);
return isWindowOwnedBy(windowHandle, pid, uid);
}) != mInteractionConnectionTokens.end();
}
@@ -5789,7 +5854,8 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
const DeviceId deviceId = *deviceIds.begin();
const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
- const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
+ const sp<WindowInfoHandle> toWindowHandle =
+ mWindowInfos.findWindowHandle(toToken, displayId);
if (!toWindowHandle) {
ALOGW("Cannot transfer touch because the transfer target window was not found.");
return false;
@@ -5896,7 +5962,8 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken
sp<IBinder> fromToken;
{ // acquire lock
std::scoped_lock _l(mLock);
- sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
+ sp<WindowInfoHandle> toWindowHandle =
+ mWindowInfos.findWindowHandle(destChannelToken, displayId);
if (toWindowHandle == nullptr) {
ALOGW("Could not find window associated with token=%p on display %s",
destChannelToken.get(), displayId.toString().c_str());
@@ -5955,7 +6022,7 @@ std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
std::string windowName = "None";
if (mWindowTokenWithPointerCapture) {
const sp<WindowInfoHandle> captureWindowHandle =
- getWindowHandleLocked(mWindowTokenWithPointerCapture);
+ mWindowInfos.findWindowHandle(mWindowTokenWithPointerCapture);
windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
: "token has capture without window";
}
@@ -6004,31 +6071,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
mDragState->dump(dump, INDENT2);
}
- if (!mWindowHandlesByDisplay.empty()) {
- for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
- dump += StringPrintf(INDENT "Display: %s\n", displayId.toString().c_str());
- if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
- const auto& displayInfo = it->second;
- dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
- displayInfo.logicalHeight);
- displayInfo.transform.dump(dump, "transform", INDENT4);
- } else {
- dump += INDENT2 "No DisplayInfo found!\n";
- }
-
- if (!windowHandles.empty()) {
- dump += INDENT2 "Windows:\n";
- for (size_t i = 0; i < windowHandles.size(); i++) {
- dump += StringPrintf(INDENT3 "%zu: %s", i,
- streamableToString(*windowHandles[i]).c_str());
- }
- } else {
- dump += INDENT2 "Windows: <none>\n";
- }
- }
- } else {
- dump += INDENT "Displays: <none>\n";
- }
+ dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT);
if (!mGlobalMonitorsByDisplay.empty()) {
for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
@@ -6352,7 +6395,7 @@ void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool
{ // acquire lock
std::scoped_lock _l(mLock);
if (DEBUG_FOCUS) {
- const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
+ const sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(windowToken);
ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
windowHandle != nullptr ? windowHandle->getName().c_str()
: "token without window");
@@ -6492,7 +6535,7 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
}
traceWaitQueueLength(*connection);
if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
- const auto windowHandle = getWindowHandleLocked(connection->getToken());
+ const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
// Only dispatch fallbacks if there is a window for the connection.
if (windowHandle != nullptr) {
const auto inputTarget =
@@ -6556,7 +6599,7 @@ void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection)
ns2ms(currentWait),
oldestEntry.eventEntry->getDescription().c_str());
sp<IBinder> connectionToken = connection->getToken();
- updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
+ updateLastAnrStateLocked(mWindowInfos.findWindowHandle(connectionToken), reason);
processConnectionUnresponsiveLocked(*connection, std::move(reason));
@@ -6664,7 +6707,7 @@ void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& conn
// The connection is a window
ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(),
reason.c_str());
- const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
+ const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
if (handle != nullptr) {
pid = handle->getInfo()->ownerPid;
}
@@ -6682,7 +6725,7 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec
pid = findMonitorPidByTokenLocked(connectionToken);
} else {
// The connection is a window
- const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
+ const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
if (handle != nullptr) {
pid = handle->getInfo()->ownerPid;
}
@@ -6747,7 +6790,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl
// Cancel the fallback key, but only if we still have a window for the channel.
// It could have been removed during the policy call.
if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
- const auto windowHandle = getWindowHandleLocked(connection->getToken());
+ const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
if (windowHandle != nullptr) {
CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
"application handled the original non-fallback key "
@@ -6833,7 +6876,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl
}
}
- const auto windowHandle = getWindowHandleLocked(connection->getToken());
+ const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
if (windowHandle != nullptr) {
CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
"canceling fallback, policy no longer desires it",
@@ -6975,7 +7018,7 @@ void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
std::scoped_lock _l(mLock);
std::optional<FocusResolver::FocusChanges> changes =
mFocusResolver.setFocusedWindow(request,
- getWindowHandlesLocked(
+ mWindowInfos.getWindowHandlesForDisplay(
ui::LogicalDisplayId{request.displayId}));
ScopedSyntheticEventTracer traceContext(mTracer);
if (changes) {
@@ -6993,7 +7036,7 @@ void InputDispatcher::onFocusChangedLocked(
if (changes.oldFocus) {
const auto resolvedWindow = removedFocusedWindowHandle != nullptr
? removedFocusedWindowHandle
- : getWindowHandleLocked(changes.oldFocus, changes.displayId);
+ : mWindowInfos.findWindowHandle(changes.oldFocus, changes.displayId);
if (resolvedWindow == nullptr) {
LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
}
@@ -7111,14 +7154,10 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update)
// Ensure that we have an entry created for all existing displays so that if a displayId has
// no windows, we can tell that the windows were removed from the display.
- for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
- handlesPerDisplay[displayId];
- }
+ mWindowInfos.forEachDisplayId(
+ [&](ui::LogicalDisplayId displayId) { handlesPerDisplay[displayId]; });
- mDisplayInfos.clear();
- for (const auto& displayInfo : update.displayInfos) {
- mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
- }
+ mWindowInfos.setDisplayInfos(update.displayInfos);
for (const auto& [displayId, handles] : handlesPerDisplay) {
setInputWindowsLocked(handles, displayId);
@@ -7265,7 +7304,7 @@ void InputDispatcher::transferWallpaperTouch(
sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
const sp<WindowInfoHandle>& windowHandle) const {
const std::vector<sp<WindowInfoHandle>>& windowHandles =
- getWindowHandlesLocked(windowHandle->getInfo()->displayId);
+ mWindowInfos.getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
bool foundWindow = false;
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (!foundWindow && otherHandle != windowHandle) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index c6342c5876..e245acc147 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -368,24 +368,52 @@ private:
};
sp<gui::WindowInfosListener> mWindowInfoListener;
- std::unordered_map<ui::LogicalDisplayId /*displayId*/,
- std::vector<sp<android::gui::WindowInfoHandle>>>
- mWindowHandlesByDisplay GUARDED_BY(mLock);
- std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo> mDisplayInfos
- GUARDED_BY(mLock);
+ class DispatcherWindowInfo {
+ public:
+ void setWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId,
+ std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles);
+
+ void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos);
+
+ void removeDisplay(ui::LogicalDisplayId displayId);
+
+ // Get a reference to window handles by display, return an empty vector if not found.
+ const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId) const;
+
+ void forEachWindowHandle(
+ std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const;
+
+ void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const;
+
+ // Get the transform for display, returns Identity-transform if display is missing.
+ ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;
+
+ // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
+ // display-id is not provided lookup is done for all displays.
+ sp<android::gui::WindowInfoHandle> findWindowHandle(
+ const sp<IBinder>& windowHandleToken,
+ std::optional<ui::LogicalDisplayId> displayId = {}) const;
+
+ bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const;
+
+ std::string dumpDisplayAndWindowInfo() const;
+
+ private:
+ std::unordered_map<ui::LogicalDisplayId /*displayId*/,
+ std::vector<sp<android::gui::WindowInfoHandle>>>
+ mWindowHandlesByDisplay;
+ std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
+ mDisplayInfos;
+ };
+
+ DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
+
void setInputWindowsLocked(
const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
ui::LogicalDisplayId displayId) REQUIRES(mLock);
- // Get a reference to window handles by display, return an empty vector if not found.
- const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesLocked(
- ui::LogicalDisplayId displayId) const REQUIRES(mLock);
- ui::Transform getTransformLocked(ui::LogicalDisplayId displayId) const REQUIRES(mLock);
- sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
- const sp<IBinder>& windowHandleToken,
- std::optional<ui::LogicalDisplayId> displayId = {}) const REQUIRES(mLock);
- bool isWindowPresentLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
- REQUIRES(mLock);
sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked(
ui::LogicalDisplayId displayId) const REQUIRES(mLock);
bool canWindowReceiveMotionLocked(const sp<android::gui::WindowInfoHandle>& window,