Loading services/inputflinger/dispatcher/InputDispatcher.cpp +34 −13 Original line number Diff line number Diff line Loading @@ -1106,7 +1106,8 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt const auto [x, y] = resolveTouchedPosition(motionEntry); const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0); auto [touchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); sp<WindowInfoHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mAwaitedFocusedApplication->getApplicationToken()) { Loading Loading @@ -1230,11 +1231,10 @@ void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) { } } std::pair<sp<WindowInfoHandle>, std::vector<InputTarget>> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus, sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus, bool ignoreDragWindow) const { // Traverse windows from front to back to find touched window. std::vector<InputTarget> outsideTargets; const auto& windowHandles = getWindowHandlesLocked(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) { Loading @@ -1244,16 +1244,35 @@ InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, const WindowInfo& info = *windowHandle->getInfo(); if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) { return {windowHandle, outsideTargets}; return windowHandle; } } return nullptr; } std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked( int32_t displayId, const sp<WindowInfoHandle>& touchedWindow) const { if (touchedWindow == nullptr) { return {}; } // Traverse windows from front to back until we encounter the touched window. std::vector<InputTarget> outsideTargets; const auto& windowHandles = getWindowHandlesLocked(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { if (windowHandle == touchedWindow) { // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window // below the touched window will not get ACTION_OUTSIDE event. return outsideTargets; } const WindowInfo& info = *windowHandle->getInfo(); if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) { addWindowTargetLocked(windowHandle, InputTarget::Flags::DISPATCH_AS_OUTSIDE, /*pointerIds=*/{}, /*firstDownTimeInTarget=*/std::nullopt, outsideTargets); } } return {nullptr, {}}; return outsideTargets; } std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked( Loading Loading @@ -2309,11 +2328,11 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Outside targets should be added upon first dispatched DOWN event. That means, this should // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down. const bool isStylus = isPointerFromStylus(entry, pointerIndex); auto [newTouchedWindowHandle, outsideTargets] = sp<WindowInfoHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); if (isDown) { targets += outsideTargets; targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle); } // Handle the case where we did not find a window. if (newTouchedWindowHandle == nullptr) { Loading Loading @@ -2489,7 +2508,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( sp<WindowInfoHandle> oldTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(); LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr); auto [newTouchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); sp<WindowInfoHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { Loading Loading @@ -2735,7 +2755,7 @@ void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) { // have an explicit reason to support it. constexpr bool isStylus = false; auto [dropWindow, _] = sp<WindowInfoHandle> dropWindow = findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true); if (dropWindow) { vec2 local = dropWindow->getInfo()->transform.transform(x, y); Loading Loading @@ -2789,7 +2809,8 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { // until we have an explicit reason to support it. constexpr bool isStylus = false; auto [hoverWindowHandle, _] = findTouchedWindowAtLocked(entry.displayId, x, y, isStylus, sp<WindowInfoHandle> hoverWindowHandle = findTouchedWindowAtLocked(entry.displayId, x, y, isStylus, /*ignoreDragWindow=*/true); // enqueue drag exit if needed. if (hoverWindowHandle != mDragState->dragHoverWindowHandle && Loading services/inputflinger/dispatcher/InputDispatcher.h +6 −3 Original line number Diff line number Diff line Loading @@ -238,9 +238,12 @@ private: // to transfer focus to a new application. std::shared_ptr<EventEntry> mNextUnblockedEvent GUARDED_BY(mLock); std::pair<sp<android::gui::WindowInfoHandle>, std::vector<InputTarget>> findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus = false, sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked( int32_t displayId, float x, float y, bool isStylus = false, bool ignoreDragWindow = false) const REQUIRES(mLock); std::vector<InputTarget> findOutsideTargetsLocked( int32_t displayId, const sp<android::gui::WindowInfoHandle>& touchedWindow) const REQUIRES(mLock); std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked( int32_t displayId, float x, float y, bool isStylus) const REQUIRES(mLock); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +34 −13 Original line number Diff line number Diff line Loading @@ -1106,7 +1106,8 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt const auto [x, y] = resolveTouchedPosition(motionEntry); const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0); auto [touchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); sp<WindowInfoHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mAwaitedFocusedApplication->getApplicationToken()) { Loading Loading @@ -1230,11 +1231,10 @@ void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) { } } std::pair<sp<WindowInfoHandle>, std::vector<InputTarget>> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus, sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus, bool ignoreDragWindow) const { // Traverse windows from front to back to find touched window. std::vector<InputTarget> outsideTargets; const auto& windowHandles = getWindowHandlesLocked(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) { Loading @@ -1244,16 +1244,35 @@ InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y, const WindowInfo& info = *windowHandle->getInfo(); if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) { return {windowHandle, outsideTargets}; return windowHandle; } } return nullptr; } std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked( int32_t displayId, const sp<WindowInfoHandle>& touchedWindow) const { if (touchedWindow == nullptr) { return {}; } // Traverse windows from front to back until we encounter the touched window. std::vector<InputTarget> outsideTargets; const auto& windowHandles = getWindowHandlesLocked(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { if (windowHandle == touchedWindow) { // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window // below the touched window will not get ACTION_OUTSIDE event. return outsideTargets; } const WindowInfo& info = *windowHandle->getInfo(); if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) { addWindowTargetLocked(windowHandle, InputTarget::Flags::DISPATCH_AS_OUTSIDE, /*pointerIds=*/{}, /*firstDownTimeInTarget=*/std::nullopt, outsideTargets); } } return {nullptr, {}}; return outsideTargets; } std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked( Loading Loading @@ -2309,11 +2328,11 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Outside targets should be added upon first dispatched DOWN event. That means, this should // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down. const bool isStylus = isPointerFromStylus(entry, pointerIndex); auto [newTouchedWindowHandle, outsideTargets] = sp<WindowInfoHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); if (isDown) { targets += outsideTargets; targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle); } // Handle the case where we did not find a window. if (newTouchedWindowHandle == nullptr) { Loading Loading @@ -2489,7 +2508,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( sp<WindowInfoHandle> oldTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(); LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr); auto [newTouchedWindowHandle, _] = findTouchedWindowAtLocked(displayId, x, y, isStylus); sp<WindowInfoHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, isStylus); // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { Loading Loading @@ -2735,7 +2755,7 @@ void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) { // have an explicit reason to support it. constexpr bool isStylus = false; auto [dropWindow, _] = sp<WindowInfoHandle> dropWindow = findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true); if (dropWindow) { vec2 local = dropWindow->getInfo()->transform.transform(x, y); Loading Loading @@ -2789,7 +2809,8 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { // until we have an explicit reason to support it. constexpr bool isStylus = false; auto [hoverWindowHandle, _] = findTouchedWindowAtLocked(entry.displayId, x, y, isStylus, sp<WindowInfoHandle> hoverWindowHandle = findTouchedWindowAtLocked(entry.displayId, x, y, isStylus, /*ignoreDragWindow=*/true); // enqueue drag exit if needed. if (hoverWindowHandle != mDragState->dragHoverWindowHandle && Loading
services/inputflinger/dispatcher/InputDispatcher.h +6 −3 Original line number Diff line number Diff line Loading @@ -238,9 +238,12 @@ private: // to transfer focus to a new application. std::shared_ptr<EventEntry> mNextUnblockedEvent GUARDED_BY(mLock); std::pair<sp<android::gui::WindowInfoHandle>, std::vector<InputTarget>> findTouchedWindowAtLocked(int32_t displayId, float x, float y, bool isStylus = false, sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked( int32_t displayId, float x, float y, bool isStylus = false, bool ignoreDragWindow = false) const REQUIRES(mLock); std::vector<InputTarget> findOutsideTargetsLocked( int32_t displayId, const sp<android::gui::WindowInfoHandle>& touchedWindow) const REQUIRES(mLock); std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked( int32_t displayId, float x, float y, bool isStylus) const REQUIRES(mLock); Loading