Merge changes from topic "revert-31063667-ZXNTVOTPQF" into main

* changes:
  Revert "[8/n InputDispatcher refactor] move input connections to a subclass"
  Revert "[9/n Dispatcher refactor] Move computeTouchOcclusionInfo..."
  Revert "[10/n Dispatcher refactor] Move obscuring related method..."
  Revert "[11/n Dispatcher refactor] Move isTouchTrusted to WindowInfo"
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 266e691..fcd784d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -918,21 +918,6 @@
     return inputTarget;
 }
 
-std::string dumpWindowForTouchOcclusion(const WindowInfo& info, bool isTouchedWindow) {
-    return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
-                                "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
-                                "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
-                                "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
-                        isTouchedWindow ? "[TOUCHED] " : "", info.packageName.c_str(),
-                        info.ownerUid.toString().c_str(), info.id,
-                        toString(info.touchOcclusionMode).c_str(), info.alpha, info.frame.left,
-                        info.frame.top, info.frame.right, info.frame.bottom,
-                        dumpRegion(info.touchableRegion).c_str(), info.name.c_str(),
-                        info.inputConfig.string().c_str(), toString(info.token != nullptr),
-                        info.applicationInfo.name.c_str(),
-                        binderToString(info.applicationInfo.token).c_str());
-}
-
 } // namespace
 
 // --- InputDispatcher ---
@@ -943,17 +928,16 @@
 InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
                                  std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)
       : mPolicy(policy),
-        mLooper(sp<Looper>::make(false)),
         mPendingEvent(nullptr),
         mLastDropReason(DropReason::NOT_DROPPED),
         mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
         mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
-        mConnectionManager(mLooper),
         mNextUnblockedEvent(nullptr),
         mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
         mDispatchEnabled(false),
         mDispatchFrozen(false),
         mInputFilterEnabled(false),
+        mMaximumObscuringOpacityForTouch(1.0f),
         mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT),
         mWindowTokenWithPointerCapture(nullptr),
         mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID),
@@ -964,6 +948,7 @@
                         : std::move(std::unique_ptr<InputEventTimelineProcessor>(
                                   new LatencyAggregator()))),
         mLatencyTracker(*mInputEventTimelineProcessor) {
+    mLooper = sp<Looper>::make(false);
     mReporter = createInputReporter();
 
     mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
@@ -986,6 +971,11 @@
     releasePendingEventLocked();
     drainInboundQueueLocked();
     mCommandQueue.clear();
+
+    while (!mConnectionsByToken.empty()) {
+        std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
+        removeInputChannelLocked(connection, /*notify=*/false);
+    }
 }
 
 status_t InputDispatcher::start() {
@@ -1102,8 +1092,7 @@
     }
 
     // If we reached here, we have an unresponsive connection.
-    std::shared_ptr<Connection> connection =
-            mConnectionManager.getConnection(mAnrTracker.firstToken());
+    std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
     if (connection == nullptr) {
         ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
         return nextAnrCheck;
@@ -1355,7 +1344,7 @@
                                                      motionEntry.deviceId, mTouchStatesByDisplay);
         for (const auto& windowHandle : touchedSpies) {
             const std::shared_ptr<Connection> connection =
-                    mConnectionManager.getConnection(windowHandle->getToken());
+                    getConnectionLocked(windowHandle->getToken());
             if (connection != nullptr && connection->responsive) {
                 // This spy window could take more input. Drop all events preceding this
                 // event, so that the spy window can get a chance to receive the stream.
@@ -1738,8 +1727,7 @@
 
 void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
                                           std::shared_ptr<const FocusEntry> entry) {
-    std::shared_ptr<Connection> connection =
-            mConnectionManager.getConnection(entry->connectionToken);
+    std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
     if (connection == nullptr) {
         return; // Connection has gone away
     }
@@ -1807,7 +1795,7 @@
         }
     }
 
-    auto connection = mConnectionManager.getConnection(token);
+    auto connection = getConnectionLocked(token);
     if (connection == nullptr) {
         // Window has gone away, clean up Pointer Capture state.
         mWindowTokenWithPointerCapture = nullptr;
@@ -1846,7 +1834,7 @@
         if (token == nullptr) {
             continue;
         }
-        std::shared_ptr<Connection> connection = mConnectionManager.getConnection(token);
+        std::shared_ptr<Connection> connection = getConnectionLocked(token);
         if (connection == nullptr) {
             continue; // Connection has gone away
         }
@@ -1970,8 +1958,7 @@
                           InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
 
     // Add monitor channels from event's or focused display.
-    ui::LogicalDisplayId displayId = getTargetDisplayId(*entry);
-    addGlobalMonitoringTargetsLocked(inputTargets, displayId);
+    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
 
     if (mTracer) {
         ensureEventTraced(*entry);
@@ -2113,8 +2100,7 @@
     }
 
     // Add monitor channels from event's or focused display.
-    ui::LogicalDisplayId displayId = getTargetDisplayId(*entry);
-    addGlobalMonitoringTargetsLocked(inputTargets, displayId);
+    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
 
     if (mTracer) {
         ensureEventTraced(*entry);
@@ -2141,8 +2127,7 @@
 
 void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
                                          std::shared_ptr<const DragEntry> entry) {
-    std::shared_ptr<Connection> connection =
-            mConnectionManager.getConnection(entry->connectionToken);
+    std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
     if (connection == nullptr) {
         return; // Connection has gone away
     }
@@ -2386,6 +2371,26 @@
     return focusedWindowHandle;
 }
 
+/**
+ * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
+ * that are currently unresponsive.
+ */
+std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
+        const std::vector<Monitor>& monitors) const {
+    std::vector<Monitor> responsiveMonitors;
+    std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
+                 [](const Monitor& monitor) REQUIRES(mLock) {
+                     std::shared_ptr<Connection> connection = monitor.connection;
+                     if (!connection->responsive) {
+                         ALOGW("Unresponsive monitor %s will not get the new gesture",
+                               connection->getInputChannelName().c_str());
+                         return false;
+                     }
+                     return true;
+                 });
+    return responsiveMonitors;
+}
+
 base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
 InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
     ATRACE_CALL();
@@ -2505,9 +2510,9 @@
             if (isSplit) {
                 targetFlags |= InputTarget::Flags::SPLIT;
             }
-            if (mWindowInfos.isWindowObscuredAtPoint(windowHandle, x, y)) {
+            if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
                 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
-            } else if (mWindowInfos.isWindowObscured(windowHandle)) {
+            } else if (isWindowObscuredLocked(windowHandle)) {
                 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
             }
 
@@ -2538,8 +2543,7 @@
                 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
                     windowHandle->getInfo()->inputConfig.test(
                             gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
-                    sp<WindowInfoHandle> wallpaper =
-                            mWindowInfos.findWallpaperWindowBelow(windowHandle);
+                    sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
                     if (wallpaper != nullptr) {
                         ftl::Flags<InputTarget::Flags> wallpaperFlags =
                                 InputTarget::Flags::WINDOW_IS_OBSCURED |
@@ -2652,9 +2656,9 @@
                 if (isSplit) {
                     targetFlags |= InputTarget::Flags::SPLIT;
                 }
-                if (mWindowInfos.isWindowObscuredAtPoint(newTouchedWindowHandle, x, y)) {
+                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
                     targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
-                } else if (mWindowInfos.isWindowObscured(newTouchedWindowHandle)) {
+                } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
                     targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
                 }
 
@@ -2937,8 +2941,7 @@
     const WindowInfo* windowInfo = windowHandle->getInfo();
 
     if (it == inputTargets.end()) {
-        std::shared_ptr<Connection> connection =
-                mConnectionManager.getConnection(windowHandle->getToken());
+        std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken());
         if (connection == nullptr) {
             ALOGW("Not creating InputTarget for %s, no input channel",
                   windowHandle->getName().c_str());
@@ -2992,8 +2995,7 @@
     const WindowInfo* windowInfo = windowHandle->getInfo();
 
     if (it == inputTargets.end()) {
-        std::shared_ptr<Connection> connection =
-                mConnectionManager.getConnection(windowHandle->getToken());
+        std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken());
         if (connection == nullptr) {
             ALOGW("Not creating InputTarget for %s, no input channel",
                   windowHandle->getName().c_str());
@@ -3028,31 +3030,18 @@
 
 void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
                                                        ui::LogicalDisplayId displayId) {
-    ui::Transform displayTransform = mWindowInfos.getDisplayTransform(displayId);
-    mConnectionManager
-            .forEachGlobalMonitorConnection(displayId,
-                                            [&](const std::shared_ptr<Connection>& connection) {
-                                                if (!connection->responsive) {
-                                                    ALOGW("Ignoring unrsponsive monitor: %s",
-                                                          connection->getInputChannelName()
-                                                                  .c_str());
-                                                    return;
-                                                }
+    auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
+    if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
 
-                                                InputTarget target{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. Since
-                                                // global monitors don't have windows, use the
-                                                // display transform as the raw transform.
-                                                base::ScopedLockAssertion assumeLocked(mLock);
-                                                target.rawTransform =
-                                                        mWindowInfos.getDisplayTransform(displayId);
-                                                target.setDefaultPointerTransform(
-                                                        target.rawTransform);
-                                                inputTargets.push_back(target);
-                                            });
+    for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
+        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.
+        // Since global monitors don't have windows, use the display transform as the raw transform.
+        target.rawTransform = mWindowInfos.getDisplayTransform(displayId);
+        target.setDefaultPointerTransform(target.rawTransform);
+        inputTargets.push_back(target);
+    }
 }
 
 /**
@@ -3108,12 +3097,12 @@
  *
  * If neither of those is true, then it means the touch can be allowed.
  */
-InputDispatcher::DispatcherWindowInfo::TouchOcclusionInfo
-InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
+InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
         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 = getWindowHandlesForDisplay(displayId);
+    const std::vector<sp<WindowInfoHandle>>& windowHandles =
+            mWindowInfos.getWindowHandlesForDisplay(displayId);
     TouchOcclusionInfo info;
     info.hasBlockingOcclusion = false;
     info.obscuringOpacity = 0;
@@ -3125,11 +3114,12 @@
         }
         const WindowInfo* otherInfo = otherHandle->getInfo();
         if (canBeObscuredBy(windowHandle, otherHandle) &&
-            windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId)) &&
+            windowOccludesTouchAt(*otherInfo, displayId, x, y,
+                                  mWindowInfos.getDisplayTransform(displayId)) &&
             !haveSameApplicationToken(windowInfo, otherInfo)) {
             if (DEBUG_TOUCH_OCCLUSION) {
                 info.debugInfo.push_back(
-                        dumpWindowForTouchOcclusion(*otherInfo, /*isTouchedWindow=*/false));
+                        dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
             }
             // canBeObscuredBy() has returned true above, which means this window is untrusted, so
             // we perform the checks below to see if the touch can be propagated or not based on the
@@ -3157,14 +3147,28 @@
         }
     }
     if (DEBUG_TOUCH_OCCLUSION) {
-        info.debugInfo.push_back(
-                dumpWindowForTouchOcclusion(*windowInfo, /*isTouchedWindow=*/true));
+        info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
     }
     return info;
 }
 
-bool InputDispatcher::DispatcherWindowInfo::isTouchTrusted(
-        const TouchOcclusionInfo& occlusionInfo) const {
+std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
+                                                         bool isTouchedWindow) const {
+    return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
+                                "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
+                                "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
+                                "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
+                        isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
+                        info->ownerUid.toString().c_str(), info->id,
+                        toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
+                        info->frame.top, info->frame.right, info->frame.bottom,
+                        dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
+                        info->inputConfig.string().c_str(), toString(info->token != nullptr),
+                        info->applicationInfo.name.c_str(),
+                        binderToString(info->applicationInfo.token).c_str());
+}
+
+bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
     if (occlusionInfo.hasBlockingOcclusion) {
         ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
               occlusionInfo.obscuringUid.toString().c_str());
@@ -3180,27 +3184,29 @@
     return true;
 }
 
-bool InputDispatcher::DispatcherWindowInfo::isWindowObscuredAtPoint(
-        const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
+bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
+                                                    float x, float y) const {
     ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
-    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(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, getDisplayTransform(displayId))) {
+            windowOccludesTouchAt(*otherInfo, displayId, x, y,
+                                  mWindowInfos.getDisplayTransform(displayId))) {
             return true;
         }
     }
     return false;
 }
 
-bool InputDispatcher::DispatcherWindowInfo::isWindowObscured(
-        const sp<WindowInfoHandle>& windowHandle) const {
+bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
     ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
-    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
+    const std::vector<sp<WindowInfoHandle>>& windowHandles =
+            mWindowInfos.getWindowHandlesForDisplay(displayId);
     const WindowInfo* windowInfo = windowHandle->getInfo();
     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
         if (windowHandle == otherHandle) {
@@ -3994,7 +4000,7 @@
 
 int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
     std::scoped_lock _l(mLock);
-    std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
+    std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
     if (connection == nullptr) {
         ALOGW("Received looper callback for unknown input channel token %p.  events=0x%x",
               connectionToken.get(), events);
@@ -4102,12 +4108,12 @@
 
 void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
         const CancelationOptions& options) {
-    mConnectionManager.forEachGlobalMonitorConnection(
-            [&](const std::shared_ptr<Connection>& connection) {
-                base::ScopedLockAssertion assumeLocked(mLock);
-                synthesizeCancelationEventsForConnectionLocked(connection, options,
-                                                               /*window=*/nullptr);
-            });
+    for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
+        for (const Monitor& monitor : monitors) {
+            synthesizeCancelationEventsForConnectionLocked(monitor.connection, options,
+                                                           /*window=*/nullptr);
+        }
+    }
 }
 
 void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
@@ -4125,7 +4131,7 @@
     }
 
     std::shared_ptr<Connection> resolvedConnection =
-            connection ? connection : mConnectionManager.getConnection(windowHandle->getToken());
+            connection ? connection : getConnectionLocked(windowHandle->getToken());
     if (!resolvedConnection) {
         LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName();
         return;
@@ -5270,9 +5276,8 @@
     return dump;
 }
 
-bool InputDispatcher::canWindowReceiveMotionLocked(
-        const sp<android::gui::WindowInfoHandle>& window,
-        const android::inputdispatcher::MotionEntry& motionEntry) const {
+bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
+                                                   const MotionEntry& motionEntry) const {
     const WindowInfo& info = *window->getInfo();
 
     // Skip spy window targets that are not valid for targeted injection.
@@ -5291,7 +5296,7 @@
         return false;
     }
 
-    std::shared_ptr<Connection> connection = mConnectionManager.getConnection(window->getToken());
+    std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
     if (connection == nullptr) {
         ALOGW("Not sending touch to %s because there's no corresponding connection",
               window->getName().c_str());
@@ -5305,9 +5310,8 @@
 
     // Drop events that can't be trusted due to occlusion
     const auto [x, y] = resolveTouchedPosition(motionEntry);
-    DispatcherWindowInfo::TouchOcclusionInfo occlusionInfo =
-            mWindowInfos.computeTouchOcclusionInfo(window, x, y);
-    if (!mWindowInfos.isTouchTrusted(occlusionInfo)) {
+    TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
+    if (!isTouchTrustedLocked(occlusionInfo)) {
         if (DEBUG_TOUCH_OCCLUSION) {
             ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
             for (const auto& log : occlusionInfo.debugInfo) {
@@ -5355,7 +5359,7 @@
     std::vector<sp<WindowInfoHandle>> newHandles;
     for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
         const WindowInfo* info = handle->getInfo();
-        if (mConnectionManager.getConnection(handle->getToken()) == nullptr) {
+        if (getConnectionLocked(handle->getToken()) == nullptr) {
             const bool noInputChannel =
                     info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
             const bool canReceiveInput =
@@ -5751,8 +5755,13 @@
 }
 
 void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
+    if (opacity < 0 || opacity > 1) {
+        LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
+        return;
+    }
+
     std::scoped_lock lock(mLock);
-    mWindowInfos.setMaximumObscuringOpacityForTouch(opacity);
+    mMaximumObscuringOpacityForTouch = opacity;
 }
 
 std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
@@ -5856,8 +5865,8 @@
 
         // Synthesize cancel for old window and down for new window.
         ScopedSyntheticEventTracer traceContext(mTracer);
-        std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken);
-        std::shared_ptr<Connection> toConnection = mConnectionManager.getConnection(toToken);
+        std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
+        std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
         if (fromConnection != nullptr && toConnection != nullptr) {
             fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
             CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
@@ -6032,9 +6041,17 @@
 
     dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT);
 
-    const nsecs_t currentTime = now();
+    if (!mGlobalMonitorsByDisplay.empty()) {
+        for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
+            dump += StringPrintf(INDENT "Global monitors on display %s:\n",
+                                 displayId.toString().c_str());
+            dumpMonitors(dump, monitors);
+        }
+    } else {
+        dump += INDENT "Global Monitors: <none>\n";
+    }
 
-    dump += addLinePrefix(mConnectionManager.dump(currentTime), INDENT);
+    const nsecs_t currentTime = now();
 
     // Dump recently dispatched or dropped events from oldest to newest.
     if (!mRecentQueue.empty()) {
@@ -6077,6 +6094,37 @@
         dump += INDENT "CommandQueue: <empty>\n";
     }
 
+    if (!mConnectionsByToken.empty()) {
+        dump += INDENT "Connections:\n";
+        for (const auto& [token, connection] : mConnectionsByToken) {
+            dump += StringPrintf(INDENT2 "%i: channelName='%s', "
+                                         "status=%s, monitor=%s, responsive=%s\n",
+                                 connection->inputPublisher.getChannel().getFd(),
+                                 connection->getInputChannelName().c_str(),
+                                 ftl::enum_string(connection->status).c_str(),
+                                 toString(connection->monitor), toString(connection->responsive));
+
+            if (!connection->outboundQueue.empty()) {
+                dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
+                                     connection->outboundQueue.size());
+                dump += dumpQueue(connection->outboundQueue, currentTime);
+            }
+
+            if (!connection->waitQueue.empty()) {
+                dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
+                                     connection->waitQueue.size());
+                dump += dumpQueue(connection->waitQueue, currentTime);
+            }
+            std::string inputStateDump = streamableToString(connection->inputState);
+            if (!inputStateDump.empty()) {
+                dump += INDENT3 "InputState: ";
+                dump += inputStateDump + "\n";
+            }
+        }
+    } else {
+        dump += INDENT "Connections: <none>\n";
+    }
+
     if (!mTouchModePerDisplay.empty()) {
         dump += INDENT "TouchModePerDisplay:\n";
         for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
@@ -6097,6 +6145,16 @@
     dump += mTracer == nullptr ? "Disabled" : "Enabled";
 }
 
+void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
+    const size_t numMonitors = monitors.size();
+    for (size_t i = 0; i < numMonitors; i++) {
+        const Monitor& monitor = monitors[i];
+        const std::shared_ptr<Connection>& connection = monitor.connection;
+        dump += StringPrintf(INDENT2 "%zu: '%s', ", i, connection->getInputChannelName().c_str());
+        dump += "\n";
+    }
+}
+
 class LooperEventCallback : public LooperCallback {
 public:
     LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
@@ -6123,8 +6181,14 @@
         std::scoped_lock _l(mLock);
         const sp<IBinder>& token = serverChannel->getConnectionToken();
         const int fd = serverChannel->getFd();
+        std::shared_ptr<Connection> connection =
+                std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
+                                             mIdGenerator);
 
-        mConnectionManager.createConnection(std::move(serverChannel), mIdGenerator);
+        auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
+        if (!inserted) {
+            ALOGE("Created a new connection, but the token %p is already known", token.get());
+        }
 
         std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
                                                             this, std::placeholders::_1, token);
@@ -6157,11 +6221,19 @@
 
         const sp<IBinder>& token = serverChannel->getConnectionToken();
         const int fd = serverChannel->getFd();
+        std::shared_ptr<Connection> connection =
+                std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/true,
+                                             mIdGenerator);
+
+        auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
+        if (!inserted) {
+            ALOGE("Created a new connection, but the token %p is already known", token.get());
+        }
+
         std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
                                                             this, std::placeholders::_1, token);
 
-        mConnectionManager.createGlobalInputMonitor(displayId, std::move(serverChannel),
-                                                    mIdGenerator, pid);
+        mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
 
         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
                        nullptr);
@@ -6175,14 +6247,14 @@
 status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
     { // acquire lock
         std::scoped_lock _l(mLock);
-        std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
+        std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
         if (connection == nullptr) {
             // Connection can be removed via socket hang up or an explicit call to
             // 'removeInputChannel'
             return BAD_VALUE;
         }
 
-        status_t status = mConnectionManager.removeInputChannel(connection);
+        status_t status = removeInputChannelLocked(connection, /*notify=*/false);
         if (status) {
             return status;
         }
@@ -6198,14 +6270,19 @@
                                                    bool notify) {
     LOG_ALWAYS_FATAL_IF(connection == nullptr);
     abortBrokenDispatchCycleLocked(connection, notify);
+    removeConnectionLocked(connection);
 
-    mAnrTracker.eraseToken(connection->getToken());
-    mConnectionManager.removeInputChannel(connection);
+    if (connection->monitor) {
+        removeMonitorChannelLocked(connection->getToken());
+    }
 
+    mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
+
+    connection->status = Connection::Status::ZOMBIE;
     return OK;
 }
 
-void InputDispatcher::ConnectionManager::removeMonitorChannel(const sp<IBinder>& connectionToken) {
+void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
     for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
         auto& [displayId, monitors] = *it;
         std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
@@ -6226,8 +6303,7 @@
 }
 
 status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
-    const std::shared_ptr<Connection> requestingConnection =
-            mConnectionManager.getConnection(token);
+    const std::shared_ptr<Connection> requestingConnection = getConnectionLocked(token);
     if (!requestingConnection) {
         LOG(WARNING)
                 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
@@ -6334,8 +6410,7 @@
     } // release lock
 }
 
-std::optional<gui::Pid> InputDispatcher::ConnectionManager::findMonitorPidByToken(
-        const sp<IBinder>& token) const {
+std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
     for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
         for (const Monitor& monitor : monitors) {
             if (monitor.connection->getToken() == token) {
@@ -6346,7 +6421,7 @@
     return std::nullopt;
 }
 
-std::shared_ptr<Connection> InputDispatcher::ConnectionManager::getConnection(
+std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
         const sp<IBinder>& inputConnectionToken) const {
     if (inputConnectionToken == nullptr) {
         return nullptr;
@@ -6361,8 +6436,16 @@
     return nullptr;
 }
 
-void InputDispatcher::ConnectionManager::removeConnection(
-        const std::shared_ptr<Connection>& connection) {
+std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
+    std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
+    if (connection == nullptr) {
+        return "<nullptr>";
+    }
+    return connection->getInputChannelName();
+}
+
+void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
+    mAnrTracker.eraseToken(connection->getToken());
     mConnectionsByToken.erase(connection->getToken());
 }
 
@@ -6590,7 +6673,7 @@
     if (connection.monitor) {
         ALOGW("Monitor %s is unresponsive: %s", connection.getInputChannelName().c_str(),
               reason.c_str());
-        pid = mConnectionManager.findMonitorPidByToken(connectionToken);
+        pid = findMonitorPidByTokenLocked(connectionToken);
     } else {
         // The connection is a window
         ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(),
@@ -6610,7 +6693,7 @@
     const sp<IBinder>& connectionToken = connection.getToken();
     std::optional<gui::Pid> pid;
     if (connection.monitor) {
-        pid = mConnectionManager.findMonitorPidByToken(connectionToken);
+        pid = findMonitorPidByTokenLocked(connectionToken);
     } else {
         // The connection is a window
         const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
@@ -7060,7 +7143,7 @@
     if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
         (windowHandle->getInfo()->inputConfig.test(
                  WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
-         mWindowInfos.isWindowObscured(windowHandle))) {
+         isWindowObscuredLocked(windowHandle))) {
         ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
               "display %s.",
               ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
@@ -7113,7 +7196,7 @@
     const sp<WindowInfoHandle> oldWallpaper =
             oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
     const sp<WindowInfoHandle> newWallpaper =
-            newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr;
+            newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
     if (oldWallpaper == newWallpaper) {
         return;
     }
@@ -7150,7 +7233,7 @@
     const sp<WindowInfoHandle> oldWallpaper =
             oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
     const sp<WindowInfoHandle> newWallpaper =
-            newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr;
+            newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
     if (oldWallpaper == newWallpaper) {
         return;
     }
@@ -7171,10 +7254,10 @@
         state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
                                 deviceId, pointers, downTimeInTarget);
         std::shared_ptr<Connection> wallpaperConnection =
-                mConnectionManager.getConnection(newWallpaper->getToken());
+                getConnectionLocked(newWallpaper->getToken());
         if (wallpaperConnection != nullptr) {
             std::shared_ptr<Connection> toConnection =
-                    mConnectionManager.getConnection(toWindowHandle->getToken());
+                    getConnectionLocked(toWindowHandle->getToken());
             toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
             synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
                                                            wallpaperFlags, traceTracker);
@@ -7182,10 +7265,10 @@
     }
 }
 
-sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWallpaperWindowBelow(
+sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
         const sp<WindowInfoHandle>& windowHandle) const {
     const std::vector<sp<WindowInfoHandle>>& windowHandles =
-            getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
+            mWindowInfos.getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
     bool foundWindow = false;
     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
         if (!foundWindow && otherHandle != windowHandle) {
@@ -7238,130 +7321,4 @@
     }
 }
 
-InputDispatcher::ConnectionManager::ConnectionManager(sp<android::Looper> looper)
-      : mLooper(looper) {}
-
-InputDispatcher::ConnectionManager::~ConnectionManager() {
-    while (!mConnectionsByToken.empty()) {
-        std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
-        removeInputChannel(connection);
-    }
-}
-
-void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
-        std::function<void(const std::shared_ptr<Connection>&)> f) const {
-    for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
-        for (const Monitor& monitor : monitors) {
-            f(monitor.connection);
-        }
-    }
-}
-
-void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
-        ui::LogicalDisplayId displayId,
-        std::function<void(const std::shared_ptr<Connection>&)> f) const {
-    auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
-    if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
-
-    for (const Monitor& monitor : monitorsIt->second) {
-        f(monitor.connection);
-    }
-}
-
-void InputDispatcher::ConnectionManager::createGlobalInputMonitor(
-        ui::LogicalDisplayId displayId, std::unique_ptr<InputChannel>&& inputChannel,
-        const android::IdGenerator& idGenerator, gui::Pid pid) {
-    std::shared_ptr<Connection> connection =
-            std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/true, idGenerator);
-    sp<IBinder> token = connection->getToken();
-    auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
-    if (!inserted) {
-        ALOGE("Created a new connection, but the token %p is already known", token.get());
-    }
-    mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
-}
-
-void InputDispatcher::ConnectionManager::createConnection(
-        std::unique_ptr<InputChannel>&& inputChannel, const android::IdGenerator& idGenerator) {
-    std::shared_ptr<Connection> connection =
-            std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/false, idGenerator);
-    sp<IBinder> token = connection->getToken();
-    auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
-    if (!inserted) {
-        ALOGE("Created a new connection, but the token %p is already known", token.get());
-    }
-}
-
-status_t InputDispatcher::ConnectionManager::removeInputChannel(
-        const std::shared_ptr<Connection>& connection) {
-    removeConnection(connection);
-
-    if (connection->monitor) {
-        removeMonitorChannel(connection->getToken());
-    }
-
-    mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
-
-    connection->status = Connection::Status::ZOMBIE;
-    return OK;
-}
-
-std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const {
-    std::string dump;
-    if (!mGlobalMonitorsByDisplay.empty()) {
-        for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
-            dump += StringPrintf("Global monitors on display %s:\n", displayId.toString().c_str());
-            const size_t numMonitors = monitors.size();
-            for (size_t i = 0; i < numMonitors; i++) {
-                const Monitor& monitor = monitors[i];
-                const std::shared_ptr<Connection>& connection = monitor.connection;
-                dump += StringPrintf(INDENT "%zu: '%s', ", i,
-                                     connection->getInputChannelName().c_str());
-                dump += "\n";
-            }
-        }
-    } else {
-        dump += "Global Monitors: <none>\n";
-    }
-
-    if (!mConnectionsByToken.empty()) {
-        dump += "Connections:\n";
-        for (const auto& [token, connection] : mConnectionsByToken) {
-            dump += StringPrintf(INDENT "%i: channelName='%s', "
-                                        "status=%s, monitor=%s, responsive=%s\n",
-                                 connection->inputPublisher.getChannel().getFd(),
-                                 connection->getInputChannelName().c_str(),
-                                 ftl::enum_string(connection->status).c_str(),
-                                 toString(connection->monitor), toString(connection->responsive));
-
-            if (!connection->outboundQueue.empty()) {
-                dump += StringPrintf(INDENT2 "OutboundQueue: length=%zu\n",
-                                     connection->outboundQueue.size());
-                dump += dumpQueue(connection->outboundQueue, currentTime);
-            }
-
-            if (!connection->waitQueue.empty()) {
-                dump += StringPrintf(INDENT2 "WaitQueue: length=%zu\n",
-                                     connection->waitQueue.size());
-                dump += dumpQueue(connection->waitQueue, currentTime);
-            }
-            std::string inputStateDump = streamableToString(connection->inputState);
-            if (!inputStateDump.empty()) {
-                dump += INDENT2 "InputState: ";
-                dump += inputStateDump + "\n";
-            }
-        }
-    } else {
-        dump += "Connections: <none>\n";
-    }
-    return dump;
-}
-
-void InputDispatcher::DispatcherWindowInfo::setMaximumObscuringOpacityForTouch(float opacity) {
-    if (opacity < 0 || opacity > 1) {
-        LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
-    }
-    mMaximumObscuringOpacityForTouch = opacity;
-}
-
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 13fec2a..bca1c67 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -224,133 +224,6 @@
     /** Stores the latest user-activity poke event times per user activity types. */
     std::array<nsecs_t, USER_ACTIVITY_EVENT_LAST + 1> mLastUserActivityTimes GUARDED_BY(mLock);
 
-    template <typename T>
-    struct StrongPointerHash {
-        std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
-    };
-
-    class ConnectionManager {
-    public:
-        ConnectionManager(sp<Looper> lopper);
-        ~ConnectionManager();
-
-        std::shared_ptr<Connection> getConnection(const sp<IBinder>& inputConnectionToken) const;
-        std::string getConnectionName(const sp<IBinder>& connectionToken) const;
-
-        // Find a monitor pid by the provided token.
-        std::optional<gui::Pid> findMonitorPidByToken(const sp<IBinder>& token) const;
-        void forEachGlobalMonitorConnection(
-                std::function<void(const std::shared_ptr<Connection>&)> f) const;
-        void forEachGlobalMonitorConnection(
-                ui::LogicalDisplayId displayId,
-                std::function<void(const std::shared_ptr<Connection>&)> f) const;
-
-        void createGlobalInputMonitor(ui::LogicalDisplayId displayId,
-                                      std::unique_ptr<InputChannel>&& inputChannel,
-                                      const IdGenerator& idGenerator, gui::Pid pid);
-
-        status_t removeInputChannel(const std::shared_ptr<Connection>& connection);
-        void removeConnection(const std::shared_ptr<Connection>& connection);
-
-        void createConnection(std::unique_ptr<InputChannel>&& inputChannel,
-                              const IdGenerator& idGenerator);
-
-        std::string dump(nsecs_t currentTime) const;
-
-    private:
-        sp<Looper> mLooper;
-
-        // All registered connections mapped by input channel token.
-        std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
-                mConnectionsByToken;
-
-        // Input channels that will receive a copy of all input events sent to the provided display.
-        std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay;
-
-        void removeMonitorChannel(const sp<IBinder>& connectionToken);
-    };
-
-    ConnectionManager mConnectionManager GUARDED_BY(mLock);
-
-    class DispatcherWindowInfo {
-    public:
-        struct TouchOcclusionInfo {
-            bool hasBlockingOcclusion;
-            float obscuringOpacity;
-            std::string obscuringPackage;
-            gui::Uid obscuringUid = gui::Uid::INVALID;
-            std::vector<std::string> debugInfo;
-        };
-
-        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);
-
-        void setMaximumObscuringOpacityForTouch(float opacity);
-
-        // 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;
-
-        // Get the raw transform to use for motion events going to the given window.
-        ui::Transform getRawTransform(const android::gui::WindowInfo&) 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;
-
-        // Returns the touched window at the given location, excluding the ignoreWindow if provided.
-        sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
-                ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
-                const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;
-
-        std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
-                ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
-                const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
-                const;
-
-        TouchOcclusionInfo computeTouchOcclusionInfo(
-                const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const;
-
-        bool isWindowObscured(const sp<android::gui::WindowInfoHandle>& windowHandle) const;
-
-        bool isWindowObscuredAtPoint(const sp<android::gui::WindowInfoHandle>& windowHandle,
-                                     float x, float y) const;
-
-        sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
-                const sp<android::gui::WindowInfoHandle>& windowHandle) const;
-
-        bool isTouchTrusted(const TouchOcclusionInfo& occlusionInfo) 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;
-        float mMaximumObscuringOpacityForTouch{1.0f};
-    };
-
-    DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
-
     // With each iteration, InputDispatcher nominally processes one queued event,
     // a timeout, or a response from an input consumer.
     // This method should only be called on the input dispatcher's own thread.
@@ -387,8 +260,31 @@
             const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay,
             ui::LogicalDisplayId displayId);
 
+    std::shared_ptr<Connection> getConnectionLocked(const sp<IBinder>& inputConnectionToken) const
+            REQUIRES(mLock);
+
+    std::string getConnectionNameLocked(const sp<IBinder>& connectionToken) const REQUIRES(mLock);
+
+    void removeConnectionLocked(const std::shared_ptr<Connection>& connection) REQUIRES(mLock);
+
     status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock);
 
+    template <typename T>
+    struct StrongPointerHash {
+        std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
+    };
+
+    // All registered connections mapped by input channel token.
+    std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
+            mConnectionsByToken GUARDED_BY(mLock);
+
+    // Find a monitor pid by the provided token.
+    std::optional<gui::Pid> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock);
+
+    // Input channels that will receive a copy of all input events sent to the provided display.
+    std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay
+            GUARDED_BY(mLock);
+
     const HmacKeyManager mHmacKeyManager;
     const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry,
                                                const DispatchEntry& dispatchEntry) const;
@@ -448,6 +344,7 @@
     bool mDispatchEnabled GUARDED_BY(mLock);
     bool mDispatchFrozen GUARDED_BY(mLock);
     bool mInputFilterEnabled GUARDED_BY(mLock);
+    float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock);
 
     // This map is not really needed, but it helps a lot with debugging (dumpsys input).
     // In the java layer, touch mode states are spread across multiple DisplayContent objects,
@@ -465,6 +362,61 @@
     };
     sp<gui::WindowInfosListener> mWindowInfoListener;
 
+    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;
+
+        // Get the raw transform to use for motion events going to the given window.
+        ui::Transform getRawTransform(const android::gui::WindowInfo&) 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;
+
+        // Returns the touched window at the given location, excluding the ignoreWindow if provided.
+        sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
+                ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
+                const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;
+
+        std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
+                ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
+                const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
+                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);
@@ -630,6 +582,8 @@
                                   nsecs_t& nextWakeupTime) REQUIRES(mLock);
     base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
     findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock);
+    std::vector<Monitor> selectResponsiveMonitorsLocked(
+            const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock);
 
     void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                InputTarget::DispatchMode dispatchMode,
@@ -650,6 +604,24 @@
     void addDragEventLocked(const MotionEntry& entry) REQUIRES(mLock);
     void finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) REQUIRES(mLock);
 
+    struct TouchOcclusionInfo {
+        bool hasBlockingOcclusion;
+        float obscuringOpacity;
+        std::string obscuringPackage;
+        gui::Uid obscuringUid = gui::Uid::INVALID;
+        std::vector<std::string> debugInfo;
+    };
+
+    TouchOcclusionInfo computeTouchOcclusionInfoLocked(
+            const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const
+            REQUIRES(mLock);
+    bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
+    bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                                       float x, float y) const REQUIRES(mLock);
+    bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
+            REQUIRES(mLock);
+    std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
+                                            bool isTouchWindow) const;
     std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
                                           const sp<android::gui::WindowInfoHandle>& windowHandle);
 
@@ -717,9 +689,12 @@
 
     // Dump state.
     void dumpDispatchStateLocked(std::string& dump) const REQUIRES(mLock);
+    void dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const;
     void logDispatchStateLocked() const REQUIRES(mLock);
     std::string dumpPointerCaptureStateLocked() const REQUIRES(mLock);
 
+    // Registration.
+    void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock);
     status_t removeInputChannelLocked(const std::shared_ptr<Connection>& connection, bool notify)
             REQUIRES(mLock);
 
@@ -802,6 +777,9 @@
                                 const std::unique_ptr<trace::EventTrackerInterface>& traceTracker)
             REQUIRES(mLock);
 
+    sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
+            const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
+
     /** Stores the value of the input flag for per device input latency metrics. */
     const bool mPerDeviceInputLatencyMetricsFlag =
             com::android::input::flags::enable_per_device_input_latency_metrics();