@@ -2510,6 +2510,24 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
25102510 return injectionError (InputEventInjectionResult::TARGET_MISMATCH);
25112511 }
25122512
2513+ if (newTouchedWindowHandle != nullptr &&
2514+ maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2515+ // Check if this should be redirected to another window, in case this window previously
2516+ // called 'transferTouch' for this gesture.
2517+ const auto it =
2518+ std::find_if (tempTouchState.windows .begin (), tempTouchState.windows .end (),
2519+ [&](const TouchedWindow& touchedWindow) {
2520+ return touchedWindow.forwardingWindowToken ==
2521+ newTouchedWindowHandle->getToken () &&
2522+ touchedWindow.hasTouchingPointers (entry.deviceId );
2523+ });
2524+ if (it != tempTouchState.windows .end ()) {
2525+ LOG (INFO) << " Forwarding pointer from " << newTouchedWindowHandle->getName ()
2526+ << " to " << it->windowHandle ->getName ();
2527+ newTouchedWindowHandle = it->windowHandle ;
2528+ }
2529+ }
2530+
25132531 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
25142532 findTouchedSpyWindowsAt (displayId, x, y, isStylus, entry.deviceId , mWindowInfos );
25152533 if (newTouchedWindowHandle != nullptr ) {
@@ -2550,7 +2568,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
25502568 isDownOrPointerDown
25512569 ? std::make_optional (
25522570 entry.eventTime )
2553- : std::nullopt );
2571+ : std::nullopt ,
2572+ /* forwardingWindowToken=*/ nullptr );
25542573 if (!addResult.ok ()) {
25552574 LOG (ERROR) << " Error while processing " << entry << " for "
25562575 << windowHandle->getName ();
@@ -2577,7 +2596,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
25772596 tempTouchState.addOrUpdateWindow (wallpaper,
25782597 InputTarget::DispatchMode::AS_IS,
25792598 wallpaperFlags, entry.deviceId , {pointer},
2580- entry.eventTime );
2599+ entry.eventTime ,
2600+ /* forwardingWindowToken=*/ nullptr );
25812601 }
25822602 }
25832603 }
@@ -2676,7 +2696,8 @@ InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
26762696 tempTouchState.addOrUpdateWindow (newTouchedWindowHandle,
26772697 InputTarget::DispatchMode::SLIPPERY_ENTER,
26782698 targetFlags, entry.deviceId , {pointer},
2679- entry.eventTime );
2699+ entry.eventTime ,
2700+ /* forwardingWindowToken=*/ nullptr );
26802701
26812702 // Check if the wallpaper window should deliver the corresponding event.
26822703 slipWallpaperTouch (targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
@@ -5833,7 +5854,7 @@ void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
58335854}
58345855
58355856bool InputDispatcher::transferTouchGesture (const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5836- bool isDragDrop) {
5857+ bool isDragDrop, bool transferEntireGesture ) {
58375858 if (fromToken == toToken) {
58385859 LOG_IF (INFO, DEBUG_FOCUS) << " Trivial transfer to same window." ;
58395860 return true ;
@@ -5847,7 +5868,7 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
58475868 " transferring touch from this window to another window" ,
58485869 traceContext.getTracker ());
58495870
5850- auto result = mTouchStates .transferTouchGesture (fromToken, toToken);
5871+ auto result = mTouchStates .transferTouchGesture (fromToken, toToken, transferEntireGesture );
58515872 if (!result.has_value ()) {
58525873 return false ;
58535874 }
@@ -5891,7 +5912,8 @@ std::optional<std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<Pointe
58915912 std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
58925913 std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>>
58935914InputDispatcher::DispatcherTouchState::transferTouchGesture (const sp<android::IBinder>& fromToken,
5894- const sp<android::IBinder>& toToken) {
5915+ const sp<android::IBinder>& toToken,
5916+ bool transferEntireGesture) {
58955917 // Find the target touch state and touched window by fromToken.
58965918 auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay (fromToken);
58975919 if (!touchStateWindowAndDisplay.has_value ()) {
@@ -5934,8 +5956,12 @@ InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IB
59345956 }
59355957 // Transferring touch focus using this API should not effect the focused window.
59365958 newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
5959+ sp<IBinder> forwardingWindowToken;
5960+ if (transferEntireGesture && com::android::input::flags::allow_transfer_of_entire_gesture ()) {
5961+ forwardingWindowToken = fromToken;
5962+ }
59375963 state.addOrUpdateWindow (toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
5938- deviceId, pointers, downTimeInTarget);
5964+ deviceId, pointers, downTimeInTarget, forwardingWindowToken );
59395965
59405966 // Synthesize cancel for old window and down for new window.
59415967 std::shared_ptr<Connection> fromConnection = mConnectionManager .getConnection (fromToken);
@@ -6017,7 +6043,8 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken
60176043 fromToken = from->getToken ();
60186044 } // release lock
60196045
6020- return transferTouchGesture (fromToken, destChannelToken);
6046+ return transferTouchGesture (fromToken, destChannelToken, /* isDragDrop=*/ false ,
6047+ /* transferEntireGesture=*/ false );
60216048}
60226049
60236050void InputDispatcher::resetAndDropEverythingLocked (const char * reason) {
@@ -7195,7 +7222,8 @@ void InputDispatcher::DispatcherTouchState::slipWallpaperTouch(
71957222 state.addOrUpdateWindow (newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
71967223 InputTarget::Flags::WINDOW_IS_OBSCURED |
71977224 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
7198- deviceId, pointers, entry.eventTime );
7225+ deviceId, pointers, entry.eventTime ,
7226+ /* forwardingWindowToken=*/ nullptr );
71997227 }
72007228}
72017229
@@ -7236,7 +7264,8 @@ InputDispatcher::DispatcherTouchState::transferWallpaperTouch(
72367264 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
72377265 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
72387266 state.addOrUpdateWindow (newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
7239- deviceId, pointers, downTimeInTarget);
7267+ deviceId, pointers, downTimeInTarget,
7268+ /* forwardingWindowToken=*/ nullptr );
72407269 std::shared_ptr<Connection> wallpaperConnection =
72417270 mConnectionManager .getConnection (newWallpaper->getToken ());
72427271 if (wallpaperConnection != nullptr ) {
0 commit comments