@@ -925,6 +925,23 @@ Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInje
925925 std::forward<InputEventInjectionResult>(e));
926926}
927927
928+ InputTarget createInputTarget (const std::shared_ptr<Connection>& connection,
929+ const sp<android::gui::WindowInfoHandle>& windowHandle,
930+ InputTarget::DispatchMode dispatchMode,
931+ ftl::Flags<InputTarget::Flags> targetFlags,
932+ const ui::Transform& displayTransform,
933+ std::optional<nsecs_t > firstDownTimeInTarget) {
934+ LOG_ALWAYS_FATAL_IF (connection == nullptr );
935+ InputTarget inputTarget{connection};
936+ inputTarget.windowHandle = windowHandle;
937+ inputTarget.dispatchMode = dispatchMode;
938+ inputTarget.flags = targetFlags;
939+ inputTarget.globalScaleFactor = windowHandle->getInfo ()->globalScaleFactor ;
940+ inputTarget.displayTransform = displayTransform;
941+ inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
942+ return inputTarget;
943+ }
944+
928945} // namespace
929946
930947// --- InputDispatcher ---
@@ -1347,7 +1364,8 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt
13471364
13481365 // Alternatively, maybe there's a spy window that could handle this event.
13491366 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1350- findTouchedSpyWindowsAtLocked (displayId, x, y, isStylus, motionEntry.deviceId );
1367+ mWindowInfos .findTouchedSpyWindowsAt (displayId, x, y, isStylus,
1368+ motionEntry.deviceId , mTouchStatesByDisplay );
13511369 for (const auto & windowHandle : touchedSpies) {
13521370 const std::shared_ptr<Connection> connection =
13531371 getConnectionLocked (windowHandle->getToken ());
@@ -1500,15 +1518,16 @@ std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
15001518 return outsideTargets;
15011519}
15021520
1503- std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked (
1504- ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const {
1521+ std::vector<sp<WindowInfoHandle>> InputDispatcher::DispatcherWindowInfo::findTouchedSpyWindowsAt (
1522+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
1523+ const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) const {
15051524 // Traverse windows from front to back and gather the touched spy windows.
15061525 std::vector<sp<WindowInfoHandle>> spyWindows;
1507- const auto & windowHandles = mWindowInfos . getWindowHandlesForDisplay (displayId);
1526+ const auto & windowHandles = getWindowHandlesForDisplay (displayId);
15081527 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
15091528 const WindowInfo& info = *windowHandle->getInfo ();
15101529 if (!windowAcceptsTouchAt (info, displayId, x, y, isStylus,
1511- mWindowInfos . getDisplayTransform (displayId))) {
1530+ getDisplayTransform (displayId))) {
15121531 // Generally, we would skip any pointer that's outside of the window. However, if the
15131532 // spy prevents splitting, and already has some of the pointers from this device, then
15141533 // it should get more pointers from the same device, even if they are outside of that
@@ -1519,7 +1538,7 @@ std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked
15191538
15201539 // We know that split touch is not supported. Skip this window only if it doesn't have
15211540 // any touching pointers for this device already.
1522- if (!windowHasTouchingPointersLocked (windowHandle, deviceId)) {
1541+ if (!windowHasTouchingPointers (windowHandle, deviceId, touchStatesByDisplay )) {
15231542 continue ;
15241543 }
15251544 // If it already has pointers down for this device, then give it this pointer, too.
@@ -2520,7 +2539,8 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio
25202539 }
25212540
25222541 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
2523- findTouchedSpyWindowsAtLocked (displayId, x, y, isStylus, entry.deviceId );
2542+ mWindowInfos .findTouchedSpyWindowsAt (displayId, x, y, isStylus, entry.deviceId ,
2543+ mTouchStatesByDisplay );
25242544 if (newTouchedWindowHandle != nullptr ) {
25252545 // Process the foreground window first so that it is the first to receive the event.
25262546 newTouchedWindows.insert (newTouchedWindows.begin (), newTouchedWindowHandle);
@@ -2973,26 +2993,6 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
29732993 }
29742994}
29752995
2976- std::optional<InputTarget> InputDispatcher::createInputTargetLocked (
2977- const sp<android::gui::WindowInfoHandle>& windowHandle,
2978- InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2979- std::optional<nsecs_t > firstDownTimeInTarget) const {
2980- std::shared_ptr<Connection> connection = getConnectionLocked (windowHandle->getToken ());
2981- if (connection == nullptr ) {
2982- ALOGW (" Not creating InputTarget for %s, no input channel" , windowHandle->getName ().c_str ());
2983- return {};
2984- }
2985- InputTarget inputTarget{connection};
2986- inputTarget.windowHandle = windowHandle;
2987- inputTarget.dispatchMode = dispatchMode;
2988- inputTarget.flags = targetFlags;
2989- inputTarget.globalScaleFactor = windowHandle->getInfo ()->globalScaleFactor ;
2990- inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2991- inputTarget.displayTransform =
2992- mWindowInfos .getDisplayTransform (windowHandle->getInfo ()->displayId );
2993- return inputTarget;
2994- }
2995-
29962996void InputDispatcher::addWindowTargetLocked (const sp<WindowInfoHandle>& windowHandle,
29972997 InputTarget::DispatchMode dispatchMode,
29982998 ftl::Flags<InputTarget::Flags> targetFlags,
@@ -3007,13 +3007,17 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa
30073007 const WindowInfo* windowInfo = windowHandle->getInfo ();
30083008
30093009 if (it == inputTargets.end ()) {
3010- std::optional<InputTarget> target =
3011- createInputTargetLocked (windowHandle, dispatchMode, targetFlags,
3012- firstDownTimeInTarget);
3013- if (!target) {
3010+ std::shared_ptr<Connection> connection = getConnectionLocked (windowHandle-> getToken ());
3011+ if (connection == nullptr ) {
3012+ ALOGW ( " Not creating InputTarget for %s, no input channel " ,
3013+ windowHandle-> getName (). c_str ());
30143014 return ;
30153015 }
3016- inputTargets.push_back (*target);
3016+ inputTargets.push_back (createInputTarget (connection, windowHandle, dispatchMode,
3017+ targetFlags,
3018+ mWindowInfos .getDisplayTransform (
3019+ windowHandle->getInfo ()->displayId ),
3020+ firstDownTimeInTarget));
30173021 it = inputTargets.end () - 1 ;
30183022 }
30193023
@@ -3058,13 +3062,17 @@ void InputDispatcher::addPointerWindowTargetLocked(
30583062 const WindowInfo* windowInfo = windowHandle->getInfo ();
30593063
30603064 if (it == inputTargets.end ()) {
3061- std::optional<InputTarget> target =
3062- createInputTargetLocked (windowHandle, dispatchMode, targetFlags,
3063- firstDownTimeInTarget);
3064- if (!target) {
3065+ std::shared_ptr<Connection> connection = getConnectionLocked (windowHandle-> getToken ());
3066+ if (connection == nullptr ) {
3067+ ALOGW ( " Not creating InputTarget for %s, no input channel " ,
3068+ windowHandle-> getName (). c_str ());
30653069 return ;
30663070 }
3067- inputTargets.push_back (*target);
3071+ inputTargets.push_back (createInputTarget (connection, windowHandle, dispatchMode,
3072+ targetFlags,
3073+ mWindowInfos .getDisplayTransform (
3074+ windowHandle->getInfo ()->displayId ),
3075+ firstDownTimeInTarget));
30683076 it = inputTargets.end () - 1 ;
30693077 }
30703078
@@ -4341,7 +4349,7 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
43414349 }
43424350
43434351 const auto [_, touchedWindowState, displayId] =
4344- findTouchStateWindowAndDisplayLocked (connection->getToken ());
4352+ findTouchStateWindowAndDisplay (connection->getToken (), mTouchStatesByDisplay );
43454353 if (touchedWindowState == nullptr ) {
43464354 LOG (FATAL) << __func__ << " : Touch state is out of sync: No touched window for token" ;
43474355 }
@@ -5799,10 +5807,12 @@ void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
57995807 mMaximumObscuringOpacityForTouch = opacity;
58005808}
58015809
5802- std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
5803- InputDispatcher::findTouchStateWindowAndDisplayLocked (const sp<IBinder>& token) {
5804- for (auto & [displayId, state] : mTouchStatesByDisplay ) {
5805- for (TouchedWindow& w : state.windows ) {
5810+ std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
5811+ InputDispatcher::findTouchStateWindowAndDisplay (
5812+ const sp<IBinder>& token,
5813+ const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
5814+ for (auto & [displayId, state] : touchStatesByDisplay) {
5815+ for (const TouchedWindow& w : state.windows ) {
58065816 if (w.windowHandle ->getToken () == token) {
58075817 return std::make_tuple (&state, &w, displayId);
58085818 }
@@ -5811,15 +5821,25 @@ InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token)
58115821 return std::make_tuple (nullptr , nullptr , ui::LogicalDisplayId::DEFAULT);
58125822}
58135823
5814- std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
5815- InputDispatcher::findTouchStateWindowAndDisplayLocked (const sp<IBinder>& token) const {
5816- return const_cast <InputDispatcher*>(this )->findTouchStateWindowAndDisplayLocked (token);
5817- }
5818-
5819- bool InputDispatcher::windowHasTouchingPointersLocked (const sp<WindowInfoHandle>& windowHandle,
5820- DeviceId deviceId) const {
5824+ std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
5825+ InputDispatcher::findTouchStateWindowAndDisplay (
5826+ const sp<IBinder>& token,
5827+ std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
5828+ auto [constTouchState, constTouchedWindow, displayId] = InputDispatcher::
5829+ findTouchStateWindowAndDisplay (token,
5830+ const_cast <const std::unordered_map<ui::LogicalDisplayId,
5831+ TouchState>&>(
5832+ touchStatesByDisplay));
5833+
5834+ return std::make_tuple (const_cast <TouchState*>(constTouchState),
5835+ const_cast <TouchedWindow*>(constTouchedWindow), displayId);
5836+ }
5837+
5838+ bool InputDispatcher::windowHasTouchingPointers (
5839+ const sp<WindowInfoHandle>& windowHandle, DeviceId deviceId,
5840+ const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
58215841 const auto & [touchState, touchedWindow, _] =
5822- findTouchStateWindowAndDisplayLocked (windowHandle->getToken ());
5842+ findTouchStateWindowAndDisplay (windowHandle->getToken (), touchStatesByDisplay );
58235843 if (touchState == nullptr ) {
58245844 // No touching pointers at all
58255845 return false ;
@@ -5840,7 +5860,8 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
58405860 std::scoped_lock _l (mLock );
58415861
58425862 // Find the target touch state and touched window by fromToken.
5843- auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked (fromToken);
5863+ auto [state, touchedWindow, displayId] =
5864+ findTouchStateWindowAndDisplay (fromToken, mTouchStatesByDisplay );
58445865
58455866 if (state == nullptr || touchedWindow == nullptr ) {
58465867 ALOGD (" Touch transfer failed because from window is not being touched." );
@@ -6345,7 +6366,8 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
63456366 return BAD_VALUE;
63466367 }
63476368
6348- auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked (token);
6369+ auto [statePtr, windowPtr, displayId] =
6370+ findTouchStateWindowAndDisplay (token, mTouchStatesByDisplay );
63496371 if (statePtr == nullptr || windowPtr == nullptr ) {
63506372 LOG (WARNING)
63516373 << " Attempted to pilfer points from a channel without any on-going pointer streams."
@@ -6540,14 +6562,15 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
65406562 const auto windowHandle = mWindowInfos .findWindowHandle (connection->getToken ());
65416563 // Only dispatch fallbacks if there is a window for the connection.
65426564 if (windowHandle != nullptr ) {
6543- const auto inputTarget =
6544- createInputTargetLocked (windowHandle, InputTarget::DispatchMode::AS_IS,
6545- dispatchEntry->targetFlags ,
6546- fallbackKeyEntry->downTime );
6547- if (inputTarget.has_value ()) {
6548- enqueueDispatchEntryLocked (connection, std::move (fallbackKeyEntry),
6549- *inputTarget);
6550- }
6565+ nsecs_t downTime = fallbackKeyEntry->downTime ;
6566+ enqueueDispatchEntryLocked (connection, std::move (fallbackKeyEntry),
6567+ createInputTarget (connection, windowHandle,
6568+ InputTarget::DispatchMode::AS_IS,
6569+ dispatchEntry->targetFlags ,
6570+ mWindowInfos .getDisplayTransform (
6571+ windowHandle->getInfo ()
6572+ ->displayId ),
6573+ downTime));
65516574 }
65526575 }
65536576 releaseDispatchEntry (std::move (dispatchEntry));
0 commit comments