Merge "input: run bpfmt -w -s on all Android.bp files" into main
diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.cpp b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
index f92f6df..4478732 100644
--- a/libs/tracing_perfetto/tracing_perfetto_internal.cpp
+++ b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
+// Should match the definitions in: frameworks/native/cmds/atrace/atrace.cpp
 #define FRAMEWORK_CATEGORIES(C)                                  \
   C(always, "always", "Always category")                         \
-  C(graphics, "graphics", "Graphics category")                   \
+  C(graphics, "gfx", "Graphics category")                        \
   C(input, "input", "Input category")                            \
   C(view, "view", "View category")                               \
   C(webview, "webview", "WebView category")                      \
   C(windowmanager, "wm", "WindowManager category")               \
   C(activitymanager, "am", "ActivityManager category")           \
-  C(syncmanager, "syncmanager", "SyncManager category")          \
+  C(syncmanager, "sm", "SyncManager category")                   \
   C(audio, "audio", "Audio category")                            \
   C(video, "video", "Video category")                            \
   C(camera, "camera", "Camera category")                         \
@@ -33,7 +34,7 @@
   C(rs, "rs", "RS category")                                     \
   C(bionic, "bionic", "Bionic category")                         \
   C(power, "power", "Power category")                            \
-  C(packagemanager, "packagemanager", "PackageManager category") \
+  C(packagemanager, "pm", "PackageManager category")             \
   C(systemserver, "ss", "System Server category")                \
   C(database, "database", "Database category")                   \
   C(network, "network", "Network category")                      \
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 098019f..56be2e6 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1267,8 +1267,9 @@
             if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
                 // The event is stale. However, only drop stale events if there isn't an ongoing
                 // gesture. That would allow us to complete the processing of the current stroke.
-                const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId);
-                if (touchStateIt != mTouchStatesByDisplay.end()) {
+                const auto touchStateIt =
+                        mTouchStates.mTouchStatesByDisplay.find(motionEntry->displayId);
+                if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
                     const TouchState& touchState = touchStateIt->second;
                     if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
                         !touchState.hasHoveringPointers(motionEntry->deviceId)) {
@@ -1355,7 +1356,8 @@
         // Alternatively, maybe there's a spy window that could handle this event.
         const std::vector<sp<WindowInfoHandle>> touchedSpies =
                 mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus,
-                                                     motionEntry.deviceId, mTouchStatesByDisplay);
+                                                     motionEntry.deviceId,
+                                                     mTouchStates.mTouchStatesByDisplay);
         for (const auto& windowHandle : touchedSpies) {
             const std::shared_ptr<Connection> connection =
                     mConnectionManager.getConnection(windowHandle->getToken());
@@ -1480,15 +1482,16 @@
     return nullptr;
 }
 
-std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
-        ui::LogicalDisplayId displayId, const sp<WindowInfoHandle>& touchedWindow,
-        int32_t pointerId) const {
+std::vector<InputTarget> InputDispatcher::DispatcherTouchState::findOutsideTargets(
+        ui::LogicalDisplayId displayId, const sp<gui::WindowInfoHandle>& touchedWindow,
+        int32_t pointerId, const ConnectionManager& connections,
+        const DispatcherWindowInfo& windowInfos, std::function<void()> dump) {
     if (touchedWindow == nullptr) {
         return {};
     }
     // Traverse windows from front to back until we encounter the touched window.
     std::vector<InputTarget> outsideTargets;
-    const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId);
+    const auto& windowHandles = windowInfos.getWindowHandlesForDisplay(displayId);
     for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
         if (windowHandle == touchedWindow) {
             // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
@@ -1500,9 +1503,13 @@
         if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
             std::bitset<MAX_POINTER_ID + 1> pointerIds;
             pointerIds.set(pointerId);
-            addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
-                                         ftl::Flags<InputTarget::Flags>(), pointerIds,
-                                         /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
+            DispatcherTouchState::addPointerWindowTarget(windowHandle,
+                                                         InputTarget::DispatchMode::OUTSIDE,
+                                                         ftl::Flags<InputTarget::Flags>(),
+                                                         pointerIds,
+                                                         /*firstDownTimeInTarget=*/std::nullopt,
+                                                         connections, windowInfos, dump,
+                                                         outsideTargets);
         }
     }
     return outsideTargets;
@@ -1709,7 +1716,7 @@
     synthesizeCancelationEventsForAllConnectionsLocked(options);
 
     // Remove all active pointers from this device
-    for (auto& [_, touchState] : mTouchStatesByDisplay) {
+    for (auto& [_, touchState] : mTouchStates.mTouchStatesByDisplay) {
         touchState.removeAllPointersForDevice(entry.deviceId);
     }
     return true;
@@ -2073,7 +2080,16 @@
         }
 
         Result<std::vector<InputTarget>, InputEventInjectionResult> result =
-                findTouchedWindowTargetsLocked(currentTime, *entry);
+                mTouchStates
+                        .findTouchedWindowTargets(currentTime, *entry, mConnectionManager,
+                                                  mWindowInfos,
+                                                  mDragState ? mDragState->dragWindow : nullptr,
+                                                  std::bind_front(&InputDispatcher::
+                                                                          addDragEventLocked,
+                                                                  this),
+                                                  std::bind_front(&InputDispatcher::
+                                                                          logDispatchStateLocked,
+                                                                  this));
 
         if (result.ok()) {
             inputTargets = std::move(*result);
@@ -2318,7 +2334,8 @@
     }
 
     // Drop key events if requested by input feature
-    if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
+    if (focusedWindowHandle != nullptr &&
+        shouldDropInput(entry, focusedWindowHandle, mWindowInfos)) {
         return injectionError(InputEventInjectionResult::FAILED);
     }
 
@@ -2387,8 +2404,12 @@
     return focusedWindowHandle;
 }
 
-base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
-InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
+base::Result<std::vector<InputTarget>, os::InputEventInjectionResult>
+InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
+        nsecs_t currentTime, const MotionEntry& entry, const ConnectionManager& connections,
+        const DispatcherWindowInfo& windowInfos,
+        const sp<android::gui::WindowInfoHandle> dragWindow,
+        std::function<void(const MotionEntry&)> addDragEvent, std::function<void()> dump) {
     ATRACE_CALL();
 
     std::vector<InputTarget> targets;
@@ -2448,10 +2469,12 @@
         // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
         const bool isStylus = isPointerFromStylus(entry, pointerIndex);
         sp<WindowInfoHandle> newTouchedWindowHandle =
-                mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
+                windowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
 
         if (isDown) {
-            targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
+            targets += DispatcherTouchState::findOutsideTargets(displayId, newTouchedWindowHandle,
+                                                                pointer.id, connections,
+                                                                windowInfos, dump);
         }
         LOG_IF(INFO, newTouchedWindowHandle == nullptr)
                 << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
@@ -2464,8 +2487,8 @@
         }
 
         std::vector<sp<WindowInfoHandle>> newTouchedWindows =
-                mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId,
-                                                     mTouchStatesByDisplay);
+                windowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId,
+                                                    mTouchStatesByDisplay);
         if (newTouchedWindowHandle != nullptr) {
             // Process the foreground window first so that it is the first to receive the event.
             newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
@@ -2478,7 +2501,8 @@
         }
 
         for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
-            if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
+            if (!canWindowReceiveMotion(windowHandle, entry, connections, windowInfos,
+                                        mTouchStatesByDisplay)) {
                 continue;
             }
 
@@ -2489,21 +2513,9 @@
             }
 
             // Set target flags.
-            ftl::Flags<InputTarget::Flags> targetFlags;
-
-            if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
-                // There should only be one touched window that can be "foreground" for the pointer.
-                targetFlags |= InputTarget::Flags::FOREGROUND;
-            }
-
-            if (isSplit) {
-                targetFlags |= InputTarget::Flags::SPLIT;
-            }
-            if (mWindowInfos.isWindowObscuredAtPoint(windowHandle, x, y)) {
-                targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
-            } else if (mWindowInfos.isWindowObscured(windowHandle)) {
-                targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
-            }
+            ftl::Flags<InputTarget::Flags> targetFlags =
+                    DispatcherTouchState::getTargetFlags(windowHandle, {x, y}, isSplit,
+                                                         windowInfos);
 
             // Update the temporary touch state.
 
@@ -2521,7 +2533,7 @@
                 if (!addResult.ok()) {
                     LOG(ERROR) << "Error while processing " << entry << " for "
                                << windowHandle->getName();
-                    logDispatchStateLocked();
+                    dump();
                 }
                 // If this is the pointer going down and the touched window has a wallpaper
                 // then also add the touched wallpaper windows so they are locked in for the
@@ -2533,7 +2545,7 @@
                     windowHandle->getInfo()->inputConfig.test(
                             gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
                     sp<WindowInfoHandle> wallpaper =
-                            mWindowInfos.findWallpaperWindowBelow(windowHandle);
+                            windowInfos.findWallpaperWindowBelow(windowHandle);
                     if (wallpaper != nullptr) {
                         ftl::Flags<InputTarget::Flags> wallpaperFlags =
                                 InputTarget::Flags::WINDOW_IS_OBSCURED |
@@ -2592,7 +2604,7 @@
             tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
         }
 
-        addDragEventLocked(entry);
+        addDragEvent(entry);
 
         // Check whether touches should slip outside of the current foreground window.
         if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
@@ -2603,7 +2615,7 @@
                     tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
             LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
             sp<WindowInfoHandle> newTouchedWindowHandle =
-                    mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
+                    windowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
 
             // Verify targeted injection.
             if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
@@ -2613,7 +2625,8 @@
 
             // Do not slide events to the window which can not receive motion event
             if (newTouchedWindowHandle != nullptr &&
-                !canWindowReceiveMotionLocked(newTouchedWindowHandle, entry)) {
+                !canWindowReceiveMotion(newTouchedWindowHandle, entry, connections, windowInfos,
+                                        mTouchStatesByDisplay)) {
                 newTouchedWindowHandle = nullptr;
             }
 
@@ -2630,26 +2643,18 @@
 
                 const TouchedWindow& touchedWindow =
                         tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
-                addPointerWindowTargetLocked(oldTouchedWindowHandle,
-                                             InputTarget::DispatchMode::SLIPPERY_EXIT,
-                                             ftl::Flags<InputTarget::Flags>(), pointerIds,
-                                             touchedWindow.getDownTimeInTarget(entry.deviceId),
-                                             targets);
+                DispatcherTouchState::
+                        addPointerWindowTarget(oldTouchedWindowHandle,
+                                               InputTarget::DispatchMode::SLIPPERY_EXIT,
+                                               ftl::Flags<InputTarget::Flags>(), pointerIds,
+                                               touchedWindow.getDownTimeInTarget(entry.deviceId),
+                                               connections, windowInfos, dump, targets);
 
                 // Make a slippery entrance into the new window.
 
-                ftl::Flags<InputTarget::Flags> targetFlags;
-                if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
-                    targetFlags |= InputTarget::Flags::FOREGROUND;
-                }
-                if (isSplit) {
-                    targetFlags |= InputTarget::Flags::SPLIT;
-                }
-                if (mWindowInfos.isWindowObscuredAtPoint(newTouchedWindowHandle, x, y)) {
-                    targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
-                } else if (mWindowInfos.isWindowObscured(newTouchedWindowHandle)) {
-                    targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
-                }
+                ftl::Flags<InputTarget::Flags> targetFlags =
+                        DispatcherTouchState::getTargetFlags(newTouchedWindowHandle, {x, y},
+                                                             isSplit, windowInfos);
 
                 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
                                                  InputTarget::DispatchMode::SLIPPERY_ENTER,
@@ -2657,8 +2662,10 @@
                                                  entry.eventTime);
 
                 // Check if the wallpaper window should deliver the corresponding event.
-                slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
-                                   tempTouchState, entry, targets);
+                DispatcherTouchState::slipWallpaperTouch(targetFlags, oldTouchedWindowHandle,
+                                                         newTouchedWindowHandle, tempTouchState,
+                                                         entry, targets, connections, windowInfos,
+                                                         dump);
                 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
                                                                oldTouchedWindowHandle);
             }
@@ -2671,7 +2678,7 @@
             std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
             for (TouchedWindow& touchedWindow : tempTouchState.windows) {
                 // Ignore drag window for it should just track one pointer.
-                if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
+                if (dragWindow == touchedWindow.windowHandle) {
                     continue;
                 }
                 if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
@@ -2685,17 +2692,17 @@
     // Update dispatching for hover enter and exit.
     {
         std::vector<TouchedWindow> hoveringWindows =
-                getHoveringWindowsLocked(oldState, tempTouchState, entry,
-                                         std::bind_front(&InputDispatcher::logDispatchStateLocked,
-                                                         this));
+                getHoveringWindowsLocked(oldState, tempTouchState, entry, dump);
         // Hardcode to single hovering pointer for now.
         std::bitset<MAX_POINTER_ID + 1> pointerIds;
         pointerIds.set(entry.pointerProperties[0].id);
         for (const TouchedWindow& touchedWindow : hoveringWindows) {
-            addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
-                                         touchedWindow.targetFlags, pointerIds,
-                                         touchedWindow.getDownTimeInTarget(entry.deviceId),
-                                         targets);
+            DispatcherTouchState::addPointerWindowTarget(touchedWindow.windowHandle,
+                                                         touchedWindow.dispatchMode,
+                                                         touchedWindow.targetFlags, pointerIds,
+                                                         touchedWindow.getDownTimeInTarget(
+                                                                 entry.deviceId),
+                                                         connections, windowInfos, dump, targets);
         }
     }
 
@@ -2724,7 +2731,7 @@
             for (InputTarget& target : targets) {
                 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
                     sp<WindowInfoHandle> targetWindow =
-                            mWindowInfos.findWindowHandle(target.connection->getToken());
+                            windowInfos.findWindowHandle(target.connection->getToken());
                     if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
                         target.flags |= InputTarget::Flags::ZERO_COORDS;
                     }
@@ -2748,9 +2755,13 @@
         if (touchingPointers.empty()) {
             continue;
         }
-        addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
-                                     touchedWindow.targetFlags, getPointerIds(touchingPointers),
-                                     touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
+        DispatcherTouchState::addPointerWindowTarget(touchedWindow.windowHandle,
+                                                     touchedWindow.dispatchMode,
+                                                     touchedWindow.targetFlags,
+                                                     getPointerIds(touchingPointers),
+                                                     touchedWindow.getDownTimeInTarget(
+                                                             entry.deviceId),
+                                                     connections, windowInfos, dump, targets);
     }
 
     // During targeted injection, only allow owned targets to receive events
@@ -2953,11 +2964,12 @@
     }
 }
 
-void InputDispatcher::addPointerWindowTargetLocked(
+void InputDispatcher::DispatcherTouchState::addPointerWindowTarget(
         const sp<android::gui::WindowInfoHandle>& windowHandle,
         InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
         std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
-        std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
+        const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
+        std::function<void()> dump, std::vector<InputTarget>& inputTargets) {
     if (pointerIds.none()) {
         for (const auto& target : inputTargets) {
             LOG(INFO) << "Target: " << target;
@@ -2982,19 +2994,17 @@
         it = inputTargets.end();
     }
 
-    const WindowInfo* windowInfo = windowHandle->getInfo();
+    const WindowInfo& windowInfo = *windowHandle->getInfo();
 
     if (it == inputTargets.end()) {
-        std::shared_ptr<Connection> connection =
-                mConnectionManager.getConnection(windowHandle->getToken());
+        std::shared_ptr<Connection> connection = connections.getConnection(windowInfo.token);
         if (connection == nullptr) {
-            ALOGW("Not creating InputTarget for %s, no input channel",
-                  windowHandle->getName().c_str());
+            ALOGW("Not creating InputTarget for %s, no input channel", windowInfo.name.c_str());
             return;
         }
         inputTargets.push_back(
                 createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
-                                  mWindowInfos.getRawTransform(*windowHandle->getInfo()),
+                                  windowInfos.getRawTransform(*windowHandle->getInfo()),
                                   firstDownTimeInTarget));
         it = inputTargets.end() - 1;
     }
@@ -3007,14 +3017,14 @@
         LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
                    << ", it=" << *it;
     }
-    if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
+    if (it->globalScaleFactor != windowInfo.globalScaleFactor) {
         LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
-                   << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
+                   << ", windowInfo->globalScaleFactor=" << windowInfo.globalScaleFactor;
     }
 
-    Result<void> result = it->addPointers(pointerIds, windowInfo->transform);
+    Result<void> result = it->addPointers(pointerIds, windowInfo.transform);
     if (!result.ok()) {
-        logDispatchStateLocked();
+        dump();
         LOG(FATAL) << result.error().message();
     }
 }
@@ -4069,7 +4079,7 @@
     // Generate cancellations for touched windows first. This is to avoid generating cancellations
     // through a non-touched window if there are more than one window for an input channel.
     if (cancelPointers) {
-        for (const auto& [displayId, touchState] : mTouchStatesByDisplay) {
+        for (const auto& [displayId, touchState] : mTouchStates.mTouchStatesByDisplay) {
             if (options.displayId.has_value() && options.displayId != displayId) {
                 continue;
             }
@@ -4204,9 +4214,15 @@
                         sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
                         mDragState.reset();
                     }
-                    addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
-                                                 ftl::Flags<InputTarget::Flags>(), pointerIds,
-                                                 motionEntry.downTime, targets);
+                    DispatcherTouchState::
+                            addPointerWindowTarget(window, InputTarget::DispatchMode::AS_IS,
+                                                   ftl::Flags<InputTarget::Flags>(), pointerIds,
+                                                   motionEntry.downTime, mConnectionManager,
+                                                   mWindowInfos,
+                                                   std::bind_front(&InputDispatcher::
+                                                                           logDispatchStateLocked,
+                                                                   this),
+                                                   targets);
                 } else {
                     targets.emplace_back(fallbackTarget);
                     // Since we don't have a window, use the display transform as the raw transform.
@@ -4268,7 +4284,8 @@
     }
 
     const auto [_, touchedWindowState, displayId] =
-            findTouchStateWindowAndDisplay(connection->getToken(), mTouchStatesByDisplay);
+            findTouchStateWindowAndDisplay(connection->getToken(),
+                                           mTouchStates.mTouchStatesByDisplay);
     if (touchedWindowState == nullptr) {
         LOG(FATAL) << __func__ << ": Touch state is out of sync: No touched window for token";
     }
@@ -4290,9 +4307,14 @@
                          pointerIndex++) {
                         pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
                     }
-                    addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
-                                                 targetFlags, pointerIds, motionEntry.downTime,
-                                                 targets);
+                    DispatcherTouchState::
+                            addPointerWindowTarget(windowHandle, InputTarget::DispatchMode::AS_IS,
+                                                   targetFlags, pointerIds, motionEntry.downTime,
+                                                   mConnectionManager, mWindowInfos,
+                                                   std::bind_front(&InputDispatcher::
+                                                                           logDispatchStateLocked,
+                                                                   this),
+                                                   targets);
                 } else {
                     targets.emplace_back(connection, targetFlags);
                     // Since we don't have a window, use the display transform as the raw transform.
@@ -4559,8 +4581,8 @@
         if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
             // Set the flag anyway if we already have an ongoing gesture. That would allow us to
             // complete the processing of the current stroke.
-            const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
-            if (touchStateIt != mTouchStatesByDisplay.end()) {
+            const auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(args.displayId);
+            if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
                 const TouchState& touchState = touchStateIt->second;
                 if (touchState.hasTouchingPointers(args.deviceId) ||
                     touchState.hasHoveringPointers(args.deviceId)) {
@@ -4871,8 +4893,8 @@
             if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
                 // Set the flag anyway if we already have an ongoing motion gesture. That
                 // would allow us to complete the processing of the current stroke.
-                const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
-                if (touchStateIt != mTouchStatesByDisplay.end()) {
+                const auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(displayId);
+                if (touchStateIt != mTouchStates.mTouchStatesByDisplay.end()) {
                     const TouchState& touchState = touchStateIt->second;
                     if (touchState.hasTouchingPointers(resolvedDeviceId) ||
                         touchState.hasHoveringPointers(resolvedDeviceId)) {
@@ -5266,9 +5288,11 @@
     return dump;
 }
 
-bool InputDispatcher::canWindowReceiveMotionLocked(
+bool InputDispatcher::canWindowReceiveMotion(
         const sp<android::gui::WindowInfoHandle>& window,
-        const android::inputdispatcher::MotionEntry& motionEntry) const {
+        const android::inputdispatcher::MotionEntry& motionEntry,
+        const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
+        const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStates) {
     const WindowInfo& info = *window->getInfo();
 
     // Skip spy window targets that are not valid for targeted injection.
@@ -5287,7 +5311,7 @@
         return false;
     }
 
-    std::shared_ptr<Connection> connection = mConnectionManager.getConnection(window->getToken());
+    std::shared_ptr<Connection> connection = connections.getConnection(window->getToken());
     if (connection == nullptr) {
         ALOGW("Not sending touch to %s because there's no corresponding connection",
               window->getName().c_str());
@@ -5302,8 +5326,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)) {
+            windowInfos.computeTouchOcclusionInfo(window, x, y);
+    if (!windowInfos.isTouchTrusted(occlusionInfo)) {
         if (DEBUG_TOUCH_OCCLUSION) {
             ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
             for (const auto& log : occlusionInfo.debugInfo) {
@@ -5316,13 +5340,13 @@
     }
 
     // Drop touch events if requested by input feature
-    if (shouldDropInput(motionEntry, window)) {
+    if (shouldDropInput(motionEntry, window, windowInfos)) {
         return false;
     }
 
     // Ignore touches if stylus is down anywhere on screen
     if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
-        isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) {
+        isStylusActiveInDisplay(info.displayId, touchStates)) {
         LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
         return false;
     }
@@ -5446,7 +5470,8 @@
         onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle);
     }
 
-    if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
+    if (const auto& it = mTouchStates.mTouchStatesByDisplay.find(displayId);
+        it != mTouchStates.mTouchStatesByDisplay.end()) {
         TouchState& state = it->second;
         for (size_t i = 0; i < state.windows.size();) {
             TouchedWindow& touchedWindow = state.windows[i];
@@ -5487,7 +5512,8 @@
 
     // Check if the hovering should stop because the window is no longer eligible to receive it
     // (for example, if the touchable region changed)
-    if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
+    if (const auto& it = mTouchStates.mTouchStatesByDisplay.find(displayId);
+        it != mTouchStates.mTouchStatesByDisplay.end()) {
         TouchState& state = it->second;
         for (TouchedWindow& touchedWindow : state.windows) {
             std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
@@ -5793,7 +5819,7 @@
 
         // Find the target touch state and touched window by fromToken.
         auto [state, touchedWindow, displayId] =
-                findTouchStateWindowAndDisplay(fromToken, mTouchStatesByDisplay);
+                findTouchStateWindowAndDisplay(fromToken, mTouchStates.mTouchStatesByDisplay);
 
         if (state == nullptr || touchedWindow == nullptr) {
             ALOGD("Touch transfer failed because from window is not being touched.");
@@ -5885,11 +5911,10 @@
  * Return null if there are no windows touched on that display, or if more than one foreground
  * window is being touched.
  */
-sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindow(
-        const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay,
-        ui::LogicalDisplayId displayId) {
-    const auto stateIt = touchStatesByDisplay.find(displayId);
-    if (stateIt == touchStatesByDisplay.end()) {
+sp<WindowInfoHandle> InputDispatcher::DispatcherTouchState::findTouchedForegroundWindow(
+        ui::LogicalDisplayId displayId) const {
+    const auto stateIt = mTouchStatesByDisplay.find(displayId);
+    if (stateIt == mTouchStatesByDisplay.end()) {
         ALOGI("No touch state on display %s", displayId.toString().c_str());
         return nullptr;
     }
@@ -5925,7 +5950,7 @@
             return false;
         }
 
-        sp<WindowInfoHandle> from = findTouchedForegroundWindow(mTouchStatesByDisplay, displayId);
+        sp<WindowInfoHandle> from = mTouchStates.findTouchedForegroundWindow(displayId);
         if (from == nullptr) {
             ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
             return false;
@@ -5953,7 +5978,7 @@
     resetNoFocusedWindowTimeoutLocked();
 
     mAnrTracker.clear();
-    mTouchStatesByDisplay.clear();
+    mTouchStates.mTouchStatesByDisplay.clear();
 }
 
 void InputDispatcher::logDispatchStateLocked() const {
@@ -6011,9 +6036,9 @@
     dump += mFocusResolver.dump();
     dump += dumpPointerCaptureStateLocked();
 
-    if (!mTouchStatesByDisplay.empty()) {
+    if (!mTouchStates.mTouchStatesByDisplay.empty()) {
         dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
-        for (const auto& [displayId, state] : mTouchStatesByDisplay) {
+        for (const auto& [displayId, state] : mTouchStates.mTouchStatesByDisplay) {
             std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
             dump += INDENT2 + displayId.toString() + " : " + touchStateDump;
         }
@@ -6222,7 +6247,7 @@
     }
 
     auto [statePtr, windowPtr, displayId] =
-            findTouchStateWindowAndDisplay(token, mTouchStatesByDisplay);
+            findTouchStateWindowAndDisplay(token, mTouchStates.mTouchStatesByDisplay);
     if (statePtr == nullptr || windowPtr == nullptr) {
         LOG(WARNING)
                 << "Attempted to pilfer points from a channel without any on-going pointer streams."
@@ -7037,12 +7062,13 @@
     mLooper->wake();
 }
 
-bool InputDispatcher::shouldDropInput(
-        const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
+bool InputDispatcher::shouldDropInput(const EventEntry& entry,
+                                      const sp<WindowInfoHandle>& windowHandle,
+                                      const DispatcherWindowInfo& windowInfos) {
     if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
         (windowHandle->getInfo()->inputConfig.test(
                  WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
-         mWindowInfos.isWindowObscured(windowHandle))) {
+         windowInfos.isWindowObscured(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(),
@@ -7067,7 +7093,7 @@
                                    "cancel current touch", traceContext.getTracker());
         synthesizeCancelationEventsForAllConnectionsLocked(options);
 
-        mTouchStatesByDisplay.clear();
+        mTouchStates.mTouchStatesByDisplay.clear();
     }
     // Wake up poll loop since there might be work to do.
     mLooper->wake();
@@ -7078,11 +7104,11 @@
     mMonitorDispatchingTimeout = timeout;
 }
 
-void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
-                                         const sp<WindowInfoHandle>& oldWindowHandle,
-                                         const sp<WindowInfoHandle>& newWindowHandle,
-                                         TouchState& state, const MotionEntry& entry,
-                                         std::vector<InputTarget>& targets) const {
+void InputDispatcher::DispatcherTouchState::slipWallpaperTouch(
+        ftl::Flags<InputTarget::Flags> targetFlags, const sp<WindowInfoHandle>& oldWindowHandle,
+        const sp<WindowInfoHandle>& newWindowHandle, TouchState& state, const MotionEntry& entry,
+        std::vector<InputTarget>& targets, const ConnectionManager& connections,
+        const DispatcherWindowInfo& windowInfos, std::function<void()> dump) {
     LOG_IF(FATAL, entry.getPointerCount() != 1) << "Entry not eligible for slip: " << entry;
     const DeviceId deviceId = entry.deviceId;
     const PointerProperties& pointerProperties = entry.pointerProperties[0];
@@ -7095,16 +7121,19 @@
     const sp<WindowInfoHandle> oldWallpaper =
             oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
     const sp<WindowInfoHandle> newWallpaper =
-            newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr;
+            newHasWallpaper ? windowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr;
     if (oldWallpaper == newWallpaper) {
         return;
     }
 
     if (oldWallpaper != nullptr) {
         const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
-        addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
-                                     oldTouchedWindow.targetFlags, getPointerIds(pointers),
-                                     oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
+        DispatcherTouchState::addPointerWindowTarget(oldWallpaper,
+                                                     InputTarget::DispatchMode::SLIPPERY_EXIT,
+                                                     oldTouchedWindow.targetFlags,
+                                                     getPointerIds(pointers),
+                                                     oldTouchedWindow.getDownTimeInTarget(deviceId),
+                                                     connections, windowInfos, dump, targets);
         state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
     }
 
@@ -7199,8 +7228,8 @@
                                         ui::LogicalDisplayId displayId, DeviceId deviceId,
                                         int32_t pointerId) {
     std::scoped_lock _l(mLock);
-    auto touchStateIt = mTouchStatesByDisplay.find(displayId);
-    if (touchStateIt == mTouchStatesByDisplay.end()) {
+    auto touchStateIt = mTouchStates.mTouchStatesByDisplay.find(displayId);
+    if (touchStateIt == mTouchStates.mTouchStatesByDisplay.end()) {
         return false;
     }
     for (const TouchedWindow& window : touchStateIt->second.windows) {
@@ -7355,4 +7384,23 @@
     mMaximumObscuringOpacityForTouch = opacity;
 }
 
+ftl::Flags<InputTarget::Flags> InputDispatcher::DispatcherTouchState::getTargetFlags(
+        const sp<WindowInfoHandle>& targetWindow, vec2 targetPosition, bool isSplit,
+        const DispatcherWindowInfo& windowInfos) {
+    ftl::Flags<InputTarget::Flags> targetFlags;
+    if (canReceiveForegroundTouches(*targetWindow->getInfo())) {
+        // There should only be one touched window that can be "foreground" for the pointer.
+        targetFlags |= InputTarget::Flags::FOREGROUND;
+    }
+    if (isSplit) {
+        targetFlags |= InputTarget::Flags::SPLIT;
+    }
+    if (windowInfos.isWindowObscuredAtPoint(targetWindow, targetPosition.x, targetPosition.y)) {
+        targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
+    } else if (windowInfos.isWindowObscured(targetWindow)) {
+        targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
+    }
+    return targetFlags;
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 415f4c8..58c8509 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -350,6 +350,67 @@
 
     DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
 
+    class DispatcherTouchState {
+    public:
+        static void addPointerWindowTarget(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                                           InputTarget::DispatchMode dispatchMode,
+                                           ftl::Flags<InputTarget::Flags> targetFlags,
+                                           std::bitset<MAX_POINTER_ID + 1> pointerIds,
+                                           std::optional<nsecs_t> firstDownTimeInTarget,
+                                           const ConnectionManager& connections,
+                                           const DispatcherWindowInfo& windowInfos,
+                                           std::function<void()> dump,
+                                           std::vector<InputTarget>& inputTargets);
+
+        base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
+        findTouchedWindowTargets(nsecs_t currentTime, const MotionEntry& entry,
+                                 const ConnectionManager& connections,
+                                 const DispatcherWindowInfo& windowInfos,
+                                 const sp<android::gui::WindowInfoHandle> dragWindow,
+                                 std::function<void(const MotionEntry&)> addDragEvent,
+                                 std::function<void()> dump);
+
+        sp<android::gui::WindowInfoHandle> findTouchedForegroundWindow(
+                ui::LogicalDisplayId displayId) const;
+
+        std::unordered_map<ui::LogicalDisplayId, TouchState> mTouchStatesByDisplay;
+
+    private:
+        static std::vector<InputTarget> findOutsideTargets(
+                ui::LogicalDisplayId displayId,
+                const sp<android::gui::WindowInfoHandle>& touchedWindow, int32_t pointerId,
+                const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
+                std::function<void()> dump);
+
+        /**
+         * Slip the wallpaper touch if necessary.
+         *
+         * @param targetFlags the target flags
+         * @param oldWindowHandle the old window that the touch slipped out of
+         * @param newWindowHandle the new window that the touch is slipping into
+         * @param state the current touch state. This will be updated if necessary to reflect the
+         * new windows that are receiving touch.
+         * @param deviceId the device id of the current motion being processed
+         * @param pointerProperties the pointer properties of the current motion being processed
+         * @param targets the current targets to add the walpaper ones to
+         * @param eventTime the new downTime for the wallpaper target
+         */
+        static void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
+                                       const sp<android::gui::WindowInfoHandle>& oldWindowHandle,
+                                       const sp<android::gui::WindowInfoHandle>& newWindowHandle,
+                                       TouchState& state, const MotionEntry& entry,
+                                       std::vector<InputTarget>& targets,
+                                       const ConnectionManager& connections,
+                                       const DispatcherWindowInfo& windowInfos,
+                                       std::function<void()> dump);
+
+        static ftl::Flags<InputTarget::Flags> getTargetFlags(
+                const sp<android::gui::WindowInfoHandle>& targetWindow, vec2 targetPosition,
+                bool isSplit, const DispatcherWindowInfo& windowInfos);
+    };
+
+    DispatcherTouchState mTouchStates 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.
@@ -378,14 +439,6 @@
     // to transfer focus to a new application.
     std::shared_ptr<const EventEntry> mNextUnblockedEvent GUARDED_BY(mLock);
 
-    std::vector<InputTarget> findOutsideTargetsLocked(
-            ui::LogicalDisplayId displayId, const sp<android::gui::WindowInfoHandle>& touchedWindow,
-            int32_t pointerId) const REQUIRES(mLock);
-
-    static sp<android::gui::WindowInfoHandle> findTouchedForegroundWindow(
-            const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay,
-            ui::LogicalDisplayId displayId);
-
     status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock);
 
     const HmacKeyManager mHmacKeyManager;
@@ -470,8 +523,11 @@
 
     sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked(
             ui::LogicalDisplayId displayId) const REQUIRES(mLock);
-    bool canWindowReceiveMotionLocked(const sp<android::gui::WindowInfoHandle>& window,
-                                      const MotionEntry& motionEntry) const REQUIRES(mLock);
+
+    static bool canWindowReceiveMotion(
+            const sp<android::gui::WindowInfoHandle>& window, const MotionEntry& motionEntry,
+            const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
+            const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStates);
 
     // Returns all the input targets (with their respective input channels) from the window handles
     // passed as argument.
@@ -486,8 +542,6 @@
             const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
             ui::LogicalDisplayId displayId) REQUIRES(mLock);
 
-    std::unordered_map<ui::LogicalDisplayId /*displayId*/, TouchState> mTouchStatesByDisplay
-            GUARDED_BY(mLock);
     std::unique_ptr<DragState> mDragState GUARDED_BY(mLock);
 
     void setFocusedApplicationLocked(
@@ -627,20 +681,12 @@
     base::Result<sp<android::gui::WindowInfoHandle>, android::os::InputEventInjectionResult>
     findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
                                   nsecs_t& nextWakeupTime) REQUIRES(mLock);
-    base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
-    findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock);
 
     void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                InputTarget::DispatchMode dispatchMode,
                                ftl::Flags<InputTarget::Flags> targetFlags,
                                std::optional<nsecs_t> firstDownTimeInTarget,
                                std::vector<InputTarget>& inputTargets) const REQUIRES(mLock);
-    void addPointerWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
-                                      InputTarget::DispatchMode dispatchMode,
-                                      ftl::Flags<InputTarget::Flags> targetFlags,
-                                      std::bitset<MAX_POINTER_ID + 1> pointerIds,
-                                      std::optional<nsecs_t> firstDownTimeInTarget,
-                                      std::vector<InputTarget>& inputTargets) const REQUIRES(mLock);
     void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
                                           ui::LogicalDisplayId displayId) REQUIRES(mLock);
     void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
@@ -652,9 +698,9 @@
     std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
                                           const sp<android::gui::WindowInfoHandle>& windowHandle);
 
-    bool shouldDropInput(const EventEntry& entry,
-                         const sp<android::gui::WindowInfoHandle>& windowHandle) const
-            REQUIRES(mLock);
+    static bool shouldDropInput(const EventEntry& entry,
+                                const sp<android::gui::WindowInfoHandle>& windowHandle,
+                                const DispatcherWindowInfo& windowInfo);
 
     // Manage the dispatch cycle for a single connection.
     // These methods are deliberately not Interruptible because doing all of the work
@@ -774,24 +820,6 @@
 
     sp<InputReporterInterface> mReporter;
 
-    /**
-     * Slip the wallpaper touch if necessary.
-     *
-     * @param targetFlags the target flags
-     * @param oldWindowHandle the old window that the touch slipped out of
-     * @param newWindowHandle the new window that the touch is slipping into
-     * @param state the current touch state. This will be updated if necessary to reflect the new
-     *        windows that are receiving touch.
-     * @param deviceId the device id of the current motion being processed
-     * @param pointerProperties the pointer properties of the current motion being processed
-     * @param targets the current targets to add the walpaper ones to
-     * @param eventTime the new downTime for the wallpaper target
-     */
-    void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
-                            const sp<android::gui::WindowInfoHandle>& oldWindowHandle,
-                            const sp<android::gui::WindowInfoHandle>& newWindowHandle,
-                            TouchState& state, const MotionEntry& entry,
-                            std::vector<InputTarget>& targets) const REQUIRES(mLock);
     void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
                                 ftl::Flags<InputTarget::Flags> newTargetFlags,
                                 const sp<android::gui::WindowInfoHandle> fromWindowHandle,