Loading services/inputflinger/dispatcher/InputDispatcher.cpp +106 −51 Original line number Diff line number Diff line Loading @@ -804,6 +804,20 @@ int32_t getUserActivityEventType(const EventEntry& eventEntry) { } } std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellationMode( CancelationOptions::Mode mode) { switch (mode) { case CancelationOptions::Mode::CANCEL_ALL_EVENTS: return {true, true}; case CancelationOptions::Mode::CANCEL_POINTER_EVENTS: return {true, false}; case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS: return {false, true}; case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS: return {false, true}; } } } // namespace // --- InputDispatcher --- Loading Loading @@ -2078,7 +2092,9 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection> if (connection->status == Connection::Status::NORMAL) { CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "application not responding"); synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForConnectionLocked(connection, options, getWindowHandleLocked( connection->getToken())); } } Loading Loading @@ -3328,7 +3344,13 @@ void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked( void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection, std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) { // TODO(b/210460522): Verify all targets excluding global monitors are associated with a window. const bool isKeyOrMotion = eventEntry->type == EventEntry::Type::KEY || eventEntry->type == EventEntry::Type::MOTION; if (isKeyOrMotion && !inputTarget.windowHandle && !connection->monitor) { LOG(FATAL) << "All InputTargets for non-monitors must be associated with a window; target: " << inputTarget << " connection: " << connection->getInputChannelName() << " entry: " << eventEntry->getDescription(); } // This is a new event. // Enqueue a new dispatch entry onto the outbound queue for this connection. std::unique_ptr<DispatchEntry> dispatchEntry = Loading Loading @@ -3977,22 +3999,78 @@ int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionTok void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( const CancelationOptions& options) { for (const auto& [token, connection] : mConnectionsByToken) { synthesizeCancelationEventsForConnectionLocked(connection, options); // Cancel windows (i.e. non-monitors). // A channel must have at least one window to receive any input. If a window was removed, the // event streams directed to the window will already have been canceled during window removal. // So there is no need to generate cancellations for connections without any windows. const auto [cancelPointers, cancelNonPointers] = expandCancellationMode(options.mode); // 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) { if (options.displayId.has_value() && options.displayId != displayId) { continue; } for (const auto& touchedWindow : touchState.windows) { synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); } } } // Follow up by generating cancellations for all windows, because we don't explicitly track // the windows that have an ongoing focus event stream. if (cancelNonPointers) { for (const auto& [_, handles] : mWindowHandlesByDisplay) { for (const auto& windowHandle : handles) { synthesizeCancelationEventsForWindowLocked(windowHandle, options); } } } // Cancel monitors. synthesizeCancelationEventsForMonitorsLocked(options); } void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( const CancelationOptions& options) { for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { for (const Monitor& monitor : monitors) { synthesizeCancelationEventsForConnectionLocked(monitor.connection, options); synthesizeCancelationEventsForConnectionLocked(monitor.connection, options, /*window=*/nullptr); } } } void InputDispatcher::synthesizeCancelationEventsForWindowLocked( const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options, const std::shared_ptr<Connection>& connection) { if (windowHandle == nullptr) { LOG(FATAL) << __func__ << ": Window handle must not be null"; } if (connection) { // The connection can be optionally provided to avoid multiple lookups. if (windowHandle->getToken() != connection->getToken()) { LOG(FATAL) << __func__ << ": Wrong connection provided for window: " << windowHandle->getName(); } } std::shared_ptr<Connection> resolvedConnection = connection ? connection : getConnectionLocked(windowHandle->getToken()); if (!resolvedConnection) { LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName(); return; } synthesizeCancelationEventsForConnectionLocked(resolvedConnection, options, windowHandle); } void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options) { const std::shared_ptr<Connection>& connection, const CancelationOptions& options, const sp<WindowInfoHandle>& window) { if (!connection->monitor && window == nullptr) { LOG(FATAL) << __func__ << ": Cannot send event to non-monitor channel without a window - channel: " << connection->getInputChannelName(); } if (connection->status != Connection::Status::NORMAL) { return; } Loading Loading @@ -4029,10 +4107,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( switch (cancelationEventEntry->type) { case EventEntry::Type::KEY: { const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry); const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE ? std::make_optional(keyEntry.displayId) : std::nullopt; if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) { if (window) { addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS, /*targetFlags=*/{}, keyEntry.downTime, targets); } else { Loading @@ -4043,11 +4118,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( } case EventEntry::Type::MOTION: { const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry); const std::optional<int32_t> targetDisplay = motionEntry.displayId != ADISPLAY_ID_NONE ? std::make_optional(motionEntry.displayId) : std::nullopt; if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) { if (window) { std::bitset<MAX_POINTER_ID + 1> pointerIds; for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) { Loading Loading @@ -4175,17 +4246,6 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( } } void InputDispatcher::synthesizeCancelationEventsForWindowLocked( const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) { if (windowHandle != nullptr) { std::shared_ptr<Connection> wallpaperConnection = getConnectionLocked(windowHandle->getToken()); if (wallpaperConnection != nullptr) { synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options); } } } std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds, nsecs_t splitDownTime) { Loading Loading @@ -5216,19 +5276,16 @@ void InputDispatcher::setInputWindowsLocked( if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) { LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName() << " in display %" << displayId; std::shared_ptr<Connection> touchedConnection = getConnectionLocked(touchedWindow.windowHandle->getToken()); if (touchedConnection != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, "touched window was removed"); synthesizeCancelationEventsForConnectionLocked(touchedConnection, options); synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); // Since we are about to drop the touch, cancel the events for the wallpaper as // well. if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) && touchedWindow.windowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) { sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow(); synthesizeCancelationEventsForWindowLocked(wallpaper, options); if (const auto& ww = state.getWallpaperWindow(); ww) { synthesizeCancelationEventsForWindowLocked(ww, options); } } state.windows.erase(state.windows.begin() + i); Loading Loading @@ -5515,9 +5572,10 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< } const int32_t deviceId = *deviceIds.begin(); sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId); if (toWindowHandle == nullptr) { ALOGW("Cannot transfer touch because to window not found."); const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId); if (!toWindowHandle) { ALOGW("Cannot transfer touch because the transfer target window was not found."); return false; } Loading @@ -5530,7 +5588,6 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Erase old window. ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags; std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId); sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; state->removeWindowByToken(fromToken); // Add new window. Loading Loading @@ -5562,7 +5619,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< fromConnection->inputState.mergePointerStateTo(toConnection->inputState); CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, "transferring touch from this window to another window"); synthesizeCancelationEventsForConnectionLocked(fromConnection, options); synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection, newTargetFlags); Loading Loading @@ -6044,12 +6101,10 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { std::string canceledWindows; for (const TouchedWindow& w : state.windows) { const std::shared_ptr<Connection> connection = getConnectionLocked(w.windowHandle->getToken()); if (connection != nullptr && connection->getToken() != token) { synthesizeCancelationEventsForConnectionLocked(connection, options); if (w.windowHandle->getToken() != token) { synthesizeCancelationEventsForWindowLocked(w.windowHandle, options); canceledWindows += canceledWindows.empty() ? "[" : ", "; canceledWindows += connection->getInputChannelName(); canceledWindows += w.windowHandle->getName(); } } canceledWindows += canceledWindows.empty() ? "[]" : "]"; Loading Loading @@ -6463,7 +6518,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl "or is no longer a foreground target, " "canceling previously dispatched fallback key"); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } } connection->inputState.removeFallbackKey(originalKeyCode); Loading Loading @@ -6545,7 +6600,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, "canceling fallback, policy no longer desires it"); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } fallback = false; Loading services/inputflinger/dispatcher/InputDispatcher.h +9 −6 Original line number Diff line number Diff line Loading @@ -615,18 +615,21 @@ private: REQUIRES(mLock); void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options) REQUIRES(mLock); void synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options) void synthesizeCancelationEventsForWindowLocked(const sp<gui::WindowInfoHandle>&, const CancelationOptions&, const std::shared_ptr<Connection>& = nullptr) REQUIRES(mLock); // This is a convenience function used to generate cancellation for a connection without having // to check whether it's a monitor or a window. For non-monitors, the window handle must not be // null. Always prefer the "-ForWindow" method above when explicitly dealing with windows. void synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options, const sp<gui::WindowInfoHandle>& window) REQUIRES(mLock); void synthesizePointerDownEventsForConnectionLocked( const nsecs_t downTime, const std::shared_ptr<Connection>& connection, ftl::Flags<InputTarget::Flags> targetFlags) REQUIRES(mLock); void synthesizeCancelationEventsForWindowLocked( const sp<android::gui::WindowInfoHandle>& windowHandle, const CancelationOptions& options) REQUIRES(mLock); // Splitting motion events across windows. When splitting motion event for a target, // splitDownTime refers to the time of first 'down' event on that particular target std::unique_ptr<MotionEntry> splitMotionEvent(const MotionEntry& originalMotionEntry, Loading services/inputflinger/tests/InputDispatcher_test.cpp +38 −35 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +106 −51 Original line number Diff line number Diff line Loading @@ -804,6 +804,20 @@ int32_t getUserActivityEventType(const EventEntry& eventEntry) { } } std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellationMode( CancelationOptions::Mode mode) { switch (mode) { case CancelationOptions::Mode::CANCEL_ALL_EVENTS: return {true, true}; case CancelationOptions::Mode::CANCEL_POINTER_EVENTS: return {true, false}; case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS: return {false, true}; case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS: return {false, true}; } } } // namespace // --- InputDispatcher --- Loading Loading @@ -2078,7 +2092,9 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection> if (connection->status == Connection::Status::NORMAL) { CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "application not responding"); synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForConnectionLocked(connection, options, getWindowHandleLocked( connection->getToken())); } } Loading Loading @@ -3328,7 +3344,13 @@ void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked( void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection, std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) { // TODO(b/210460522): Verify all targets excluding global monitors are associated with a window. const bool isKeyOrMotion = eventEntry->type == EventEntry::Type::KEY || eventEntry->type == EventEntry::Type::MOTION; if (isKeyOrMotion && !inputTarget.windowHandle && !connection->monitor) { LOG(FATAL) << "All InputTargets for non-monitors must be associated with a window; target: " << inputTarget << " connection: " << connection->getInputChannelName() << " entry: " << eventEntry->getDescription(); } // This is a new event. // Enqueue a new dispatch entry onto the outbound queue for this connection. std::unique_ptr<DispatchEntry> dispatchEntry = Loading Loading @@ -3977,22 +3999,78 @@ int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionTok void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( const CancelationOptions& options) { for (const auto& [token, connection] : mConnectionsByToken) { synthesizeCancelationEventsForConnectionLocked(connection, options); // Cancel windows (i.e. non-monitors). // A channel must have at least one window to receive any input. If a window was removed, the // event streams directed to the window will already have been canceled during window removal. // So there is no need to generate cancellations for connections without any windows. const auto [cancelPointers, cancelNonPointers] = expandCancellationMode(options.mode); // 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) { if (options.displayId.has_value() && options.displayId != displayId) { continue; } for (const auto& touchedWindow : touchState.windows) { synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); } } } // Follow up by generating cancellations for all windows, because we don't explicitly track // the windows that have an ongoing focus event stream. if (cancelNonPointers) { for (const auto& [_, handles] : mWindowHandlesByDisplay) { for (const auto& windowHandle : handles) { synthesizeCancelationEventsForWindowLocked(windowHandle, options); } } } // Cancel monitors. synthesizeCancelationEventsForMonitorsLocked(options); } void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( const CancelationOptions& options) { for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { for (const Monitor& monitor : monitors) { synthesizeCancelationEventsForConnectionLocked(monitor.connection, options); synthesizeCancelationEventsForConnectionLocked(monitor.connection, options, /*window=*/nullptr); } } } void InputDispatcher::synthesizeCancelationEventsForWindowLocked( const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options, const std::shared_ptr<Connection>& connection) { if (windowHandle == nullptr) { LOG(FATAL) << __func__ << ": Window handle must not be null"; } if (connection) { // The connection can be optionally provided to avoid multiple lookups. if (windowHandle->getToken() != connection->getToken()) { LOG(FATAL) << __func__ << ": Wrong connection provided for window: " << windowHandle->getName(); } } std::shared_ptr<Connection> resolvedConnection = connection ? connection : getConnectionLocked(windowHandle->getToken()); if (!resolvedConnection) { LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName(); return; } synthesizeCancelationEventsForConnectionLocked(resolvedConnection, options, windowHandle); } void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options) { const std::shared_ptr<Connection>& connection, const CancelationOptions& options, const sp<WindowInfoHandle>& window) { if (!connection->monitor && window == nullptr) { LOG(FATAL) << __func__ << ": Cannot send event to non-monitor channel without a window - channel: " << connection->getInputChannelName(); } if (connection->status != Connection::Status::NORMAL) { return; } Loading Loading @@ -4029,10 +4107,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( switch (cancelationEventEntry->type) { case EventEntry::Type::KEY: { const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry); const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE ? std::make_optional(keyEntry.displayId) : std::nullopt; if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) { if (window) { addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS, /*targetFlags=*/{}, keyEntry.downTime, targets); } else { Loading @@ -4043,11 +4118,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( } case EventEntry::Type::MOTION: { const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry); const std::optional<int32_t> targetDisplay = motionEntry.displayId != ADISPLAY_ID_NONE ? std::make_optional(motionEntry.displayId) : std::nullopt; if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) { if (window) { std::bitset<MAX_POINTER_ID + 1> pointerIds; for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) { Loading Loading @@ -4175,17 +4246,6 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( } } void InputDispatcher::synthesizeCancelationEventsForWindowLocked( const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) { if (windowHandle != nullptr) { std::shared_ptr<Connection> wallpaperConnection = getConnectionLocked(windowHandle->getToken()); if (wallpaperConnection != nullptr) { synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options); } } } std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds, nsecs_t splitDownTime) { Loading Loading @@ -5216,19 +5276,16 @@ void InputDispatcher::setInputWindowsLocked( if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) { LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName() << " in display %" << displayId; std::shared_ptr<Connection> touchedConnection = getConnectionLocked(touchedWindow.windowHandle->getToken()); if (touchedConnection != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, "touched window was removed"); synthesizeCancelationEventsForConnectionLocked(touchedConnection, options); synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); // Since we are about to drop the touch, cancel the events for the wallpaper as // well. if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) && touchedWindow.windowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) { sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow(); synthesizeCancelationEventsForWindowLocked(wallpaper, options); if (const auto& ww = state.getWallpaperWindow(); ww) { synthesizeCancelationEventsForWindowLocked(ww, options); } } state.windows.erase(state.windows.begin() + i); Loading Loading @@ -5515,9 +5572,10 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< } const int32_t deviceId = *deviceIds.begin(); sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId); if (toWindowHandle == nullptr) { ALOGW("Cannot transfer touch because to window not found."); const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId); if (!toWindowHandle) { ALOGW("Cannot transfer touch because the transfer target window was not found."); return false; } Loading @@ -5530,7 +5588,6 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Erase old window. ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags; std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId); sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; state->removeWindowByToken(fromToken); // Add new window. Loading Loading @@ -5562,7 +5619,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< fromConnection->inputState.mergePointerStateTo(toConnection->inputState); CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, "transferring touch from this window to another window"); synthesizeCancelationEventsForConnectionLocked(fromConnection, options); synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection, newTargetFlags); Loading Loading @@ -6044,12 +6101,10 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { std::string canceledWindows; for (const TouchedWindow& w : state.windows) { const std::shared_ptr<Connection> connection = getConnectionLocked(w.windowHandle->getToken()); if (connection != nullptr && connection->getToken() != token) { synthesizeCancelationEventsForConnectionLocked(connection, options); if (w.windowHandle->getToken() != token) { synthesizeCancelationEventsForWindowLocked(w.windowHandle, options); canceledWindows += canceledWindows.empty() ? "[" : ", "; canceledWindows += connection->getInputChannelName(); canceledWindows += w.windowHandle->getName(); } } canceledWindows += canceledWindows.empty() ? "[]" : "]"; Loading Loading @@ -6463,7 +6518,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl "or is no longer a foreground target, " "canceling previously dispatched fallback key"); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } } connection->inputState.removeFallbackKey(originalKeyCode); Loading Loading @@ -6545,7 +6600,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, "canceling fallback, policy no longer desires it"); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForConnectionLocked(connection, options); synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } fallback = false; Loading
services/inputflinger/dispatcher/InputDispatcher.h +9 −6 Original line number Diff line number Diff line Loading @@ -615,18 +615,21 @@ private: REQUIRES(mLock); void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options) REQUIRES(mLock); void synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options) void synthesizeCancelationEventsForWindowLocked(const sp<gui::WindowInfoHandle>&, const CancelationOptions&, const std::shared_ptr<Connection>& = nullptr) REQUIRES(mLock); // This is a convenience function used to generate cancellation for a connection without having // to check whether it's a monitor or a window. For non-monitors, the window handle must not be // null. Always prefer the "-ForWindow" method above when explicitly dealing with windows. void synthesizeCancelationEventsForConnectionLocked( const std::shared_ptr<Connection>& connection, const CancelationOptions& options, const sp<gui::WindowInfoHandle>& window) REQUIRES(mLock); void synthesizePointerDownEventsForConnectionLocked( const nsecs_t downTime, const std::shared_ptr<Connection>& connection, ftl::Flags<InputTarget::Flags> targetFlags) REQUIRES(mLock); void synthesizeCancelationEventsForWindowLocked( const sp<android::gui::WindowInfoHandle>& windowHandle, const CancelationOptions& options) REQUIRES(mLock); // Splitting motion events across windows. When splitting motion event for a target, // splitDownTime refers to the time of first 'down' event on that particular target std::unique_ptr<MotionEntry> splitMotionEvent(const MotionEntry& originalMotionEntry, Loading
services/inputflinger/tests/InputDispatcher_test.cpp +38 −35 File changed.Preview size limit exceeded, changes collapsed. Show changes