Loading services/inputflinger/dispatcher/InputDispatcher.cpp +50 −20 Original line number Diff line number Diff line Loading @@ -1872,6 +1872,17 @@ bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime, return false; } static std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) { if (eventEntry.type == EventEntry::Type::KEY) { const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry); return keyEntry.downTime; } else if (eventEntry.type == EventEntry::Type::MOTION) { const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry); return motionEntry.downTime; } return std::nullopt; } InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { Loading Loading @@ -1961,7 +1972,7 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( // Success! Output targets. addWindowTargetLocked(focusedWindowHandle, InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0), inputTargets); BitSet32(0), getDownTime(entry), inputTargets); // Done. return InputEventInjectionResult::SUCCEEDED; Loading Loading @@ -2200,7 +2211,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( pointerIds.markBit(pointerId); } tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds); tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds, entry.eventTime); } // If any existing window is pilfering pointers from newly added window, remove it Loading Loading @@ -2287,7 +2299,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( if (isSplit) { pointerIds.markBit(entry.pointerProperties[0].id); } tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds, entry.eventTime); } } } Loading Loading @@ -2404,7 +2417,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( InputTarget:: FLAG_WINDOW_IS_PARTIALLY_OBSCURED | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0)); BitSet32(0), entry.eventTime); } } } Loading @@ -2415,7 +2428,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( for (const TouchedWindow& touchedWindow : tempTouchState.windows) { addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.pointerIds, inputTargets); touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget, inputTargets); } // Drop the outside or hover touch windows since we will not care about them Loading Loading @@ -2600,6 +2614,7 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) { std::vector<InputTarget>::iterator it = std::find_if(inputTargets.begin(), inputTargets.end(), Loading @@ -2621,6 +2636,7 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa inputTarget.inputChannel = inputChannel; inputTarget.flags = targetFlags; inputTarget.globalScaleFactor = windowInfo->globalScaleFactor; inputTarget.firstDownTimeInTarget = firstDownTimeInTarget; const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId); if (displayInfoIt != mDisplayInfos.end()) { inputTarget.displayTransform = displayInfoIt->second.transform; Loading @@ -2646,6 +2662,8 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& InputTarget target; target.inputChannel = monitor.inputChannel; target.flags = InputTarget::FLAG_DISPATCH_AS_IS; // target.firstDownTimeInTarget is not set for global monitors. It is only required in split // touch and global monitoring works as intended even without setting firstDownTimeInTarget if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { target.displayTransform = it->second.transform; } Loading Loading @@ -2930,8 +2948,12 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry); if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) { LOG_ALWAYS_FATAL_IF(!inputTarget.firstDownTimeInTarget.has_value(), "Splitting motion events requires a down time to be set for the " "target"); std::unique_ptr<MotionEntry> splitMotionEntry = splitMotionEvent(originalMotionEntry, inputTarget.pointerIds); splitMotionEvent(originalMotionEntry, inputTarget.pointerIds, inputTarget.firstDownTimeInTarget.value()); if (!splitMotionEntry) { return; // split event was dropped } Loading Loading @@ -3687,15 +3709,13 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( } void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( const sp<Connection>& connection) { const nsecs_t downTime, const sp<Connection>& connection) { if (connection->status == Connection::Status::BROKEN) { return; } nsecs_t currentTime = now(); std::vector<std::unique_ptr<EventEntry>> downEvents = connection->inputState.synthesizePointerDownEvents(currentTime); connection->inputState.synthesizePointerDownEvents(downTime); if (downEvents.empty()) { return; Loading Loading @@ -3743,11 +3763,11 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( InputTarget::FLAG_DISPATCH_AS_IS); } startDispatchCycleLocked(currentTime, connection); startDispatchCycleLocked(downTime, connection); } std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( const MotionEntry& originalMotionEntry, BitSet32 pointerIds) { const MotionEntry& originalMotionEntry, BitSet32 pointerIds, nsecs_t splitDownTime) { ALOG_ASSERT(pointerIds.value != 0); uint32_t splitPointerIndexMap[MAX_POINTERS]; Loading Loading @@ -3815,6 +3835,13 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( } } if (action == AMOTION_EVENT_ACTION_DOWN) { LOG_ALWAYS_FATAL_IF(splitDownTime != originalMotionEntry.eventTime, "Split motion event has mismatching downTime and eventTime for " "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64 "ms", originalMotionEntry.getDescription().c_str(), ns2ms(splitDownTime)); } int32_t newId = mIdGenerator.nextId(); if (ATRACE_ENABLED()) { std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32 Loading @@ -3835,9 +3862,9 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( originalMotionEntry.xPrecision, originalMotionEntry.yPrecision, originalMotionEntry.xCursorPosition, originalMotionEntry.yCursorPosition, originalMotionEntry.downTime, splitPointerCount, splitPointerProperties, splitPointerCoords); originalMotionEntry.yCursorPosition, splitDownTime, splitPointerCount, splitPointerProperties, splitPointerCoords); if (originalMotionEntry.injectionState) { splitMotionEntry->injectionState = originalMotionEntry.injectionState; Loading Loading @@ -5074,12 +5101,13 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< state->removeWindowByToken(fromToken); // Add new window. nsecs_t downTimeInTarget = now(); int32_t newTargetFlags = oldTargetFlags & (InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) { newTargetFlags |= InputTarget::FLAG_FOREGROUND; } state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds, downTimeInTarget); // Store the dragging window. if (isDragDrop) { Loading @@ -5103,7 +5131,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< options(CancelationOptions::CANCEL_POINTER_EVENTS, "transferring touch focus from this window to another window"); synthesizeCancelationEventsForConnectionLocked(fromConnection, options); synthesizePointerDownEventsForConnectionLocked(toConnection); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection); } if (DEBUG_FOCUS) { Loading Loading @@ -5253,10 +5281,12 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += INDENT3 "Windows:\n"; for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, " "targetFlags=0x%x, firstDownTimeInTarget=%" PRId64 "ms\n", i, touchedWindow.windowHandle->getName().c_str(), touchedWindow.pointerIds.value, touchedWindow.targetFlags); touchedWindow.pointerIds.value, touchedWindow.targetFlags, ns2ms(touchedWindow.firstDownTimeInTarget.value_or(0))); } } else { dump += INDENT3 "Windows: <none>\n"; Loading services/inputflinger/dispatcher/InputDispatcher.h +6 −3 Original line number Diff line number Diff line Loading @@ -550,6 +550,7 @@ private: void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId) REQUIRES(mLock); Loading Loading @@ -621,12 +622,14 @@ private: const CancelationOptions& options) REQUIRES(mLock); void synthesizePointerDownEventsForConnectionLocked(const sp<Connection>& connection) void synthesizePointerDownEventsForConnectionLocked(const nsecs_t downTime, const sp<Connection>& connection) REQUIRES(mLock); // Splitting motion events across windows. // 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, BitSet32 pointerIds); BitSet32 pointerIds, nsecs_t splitDownTime); // Reset and drop everything the dispatcher is doing. void resetAndDropEverythingLocked(const char* reason) REQUIRES(mLock); Loading services/inputflinger/dispatcher/InputTarget.h +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ struct InputTarget { // The subset of pointer ids to include in motion events dispatched to this input target // if FLAG_SPLIT is set. BitSet32 pointerIds; // Event time for the first motion event (ACTION_DOWN) dispatched to this input target if // FLAG_SPLIT is set. std::optional<nsecs_t> firstDownTimeInTarget; // The data is stored by the pointerId. Use the bit position of pointerIds to look up // Transform per pointerId. ui::Transform pointerTransforms[MAX_POINTERS]; Loading services/inputflinger/dispatcher/TouchState.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ void TouchState::reset() { } void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds) { BitSet32 pointerIds, std::optional<nsecs_t> eventTime) { if (targetFlags & InputTarget::FLAG_SPLIT) { split = true; } Loading @@ -42,7 +42,13 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS; } // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have // downTime set initially. Need to update existing window when an pointer is down for // the window. touchedWindow.pointerIds.value |= pointerIds.value; if (!touchedWindow.firstDownTimeInTarget.has_value()) { touchedWindow.firstDownTimeInTarget = eventTime; } return; } } Loading @@ -51,6 +57,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int touchedWindow.windowHandle = windowHandle; touchedWindow.targetFlags = targetFlags; touchedWindow.pointerIds = pointerIds; touchedWindow.firstDownTimeInTarget = eventTime; windows.push_back(touchedWindow); } Loading services/inputflinger/dispatcher/TouchState.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ struct TouchState { void reset(); void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds); int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> eventTime = std::nullopt); void removeWindowByToken(const sp<IBinder>& token); void filterNonAsIsTouchWindows(); void filterWindowsExcept(const sp<IBinder>& token); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +50 −20 Original line number Diff line number Diff line Loading @@ -1872,6 +1872,17 @@ bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime, return false; } static std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) { if (eventEntry.type == EventEntry::Type::KEY) { const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry); return keyEntry.downTime; } else if (eventEntry.type == EventEntry::Type::MOTION) { const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry); return motionEntry.downTime; } return std::nullopt; } InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { Loading Loading @@ -1961,7 +1972,7 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( // Success! Output targets. addWindowTargetLocked(focusedWindowHandle, InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0), inputTargets); BitSet32(0), getDownTime(entry), inputTargets); // Done. return InputEventInjectionResult::SUCCEEDED; Loading Loading @@ -2200,7 +2211,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( pointerIds.markBit(pointerId); } tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds); tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds, entry.eventTime); } // If any existing window is pilfering pointers from newly added window, remove it Loading Loading @@ -2287,7 +2299,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( if (isSplit) { pointerIds.markBit(entry.pointerProperties[0].id); } tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds, entry.eventTime); } } } Loading Loading @@ -2404,7 +2417,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( InputTarget:: FLAG_WINDOW_IS_PARTIALLY_OBSCURED | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0)); BitSet32(0), entry.eventTime); } } } Loading @@ -2415,7 +2428,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( for (const TouchedWindow& touchedWindow : tempTouchState.windows) { addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.pointerIds, inputTargets); touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget, inputTargets); } // Drop the outside or hover touch windows since we will not care about them Loading Loading @@ -2600,6 +2614,7 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) { std::vector<InputTarget>::iterator it = std::find_if(inputTargets.begin(), inputTargets.end(), Loading @@ -2621,6 +2636,7 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa inputTarget.inputChannel = inputChannel; inputTarget.flags = targetFlags; inputTarget.globalScaleFactor = windowInfo->globalScaleFactor; inputTarget.firstDownTimeInTarget = firstDownTimeInTarget; const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId); if (displayInfoIt != mDisplayInfos.end()) { inputTarget.displayTransform = displayInfoIt->second.transform; Loading @@ -2646,6 +2662,8 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& InputTarget target; target.inputChannel = monitor.inputChannel; target.flags = InputTarget::FLAG_DISPATCH_AS_IS; // target.firstDownTimeInTarget is not set for global monitors. It is only required in split // touch and global monitoring works as intended even without setting firstDownTimeInTarget if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { target.displayTransform = it->second.transform; } Loading Loading @@ -2930,8 +2948,12 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry); if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) { LOG_ALWAYS_FATAL_IF(!inputTarget.firstDownTimeInTarget.has_value(), "Splitting motion events requires a down time to be set for the " "target"); std::unique_ptr<MotionEntry> splitMotionEntry = splitMotionEvent(originalMotionEntry, inputTarget.pointerIds); splitMotionEvent(originalMotionEntry, inputTarget.pointerIds, inputTarget.firstDownTimeInTarget.value()); if (!splitMotionEntry) { return; // split event was dropped } Loading Loading @@ -3687,15 +3709,13 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( } void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( const sp<Connection>& connection) { const nsecs_t downTime, const sp<Connection>& connection) { if (connection->status == Connection::Status::BROKEN) { return; } nsecs_t currentTime = now(); std::vector<std::unique_ptr<EventEntry>> downEvents = connection->inputState.synthesizePointerDownEvents(currentTime); connection->inputState.synthesizePointerDownEvents(downTime); if (downEvents.empty()) { return; Loading Loading @@ -3743,11 +3763,11 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( InputTarget::FLAG_DISPATCH_AS_IS); } startDispatchCycleLocked(currentTime, connection); startDispatchCycleLocked(downTime, connection); } std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( const MotionEntry& originalMotionEntry, BitSet32 pointerIds) { const MotionEntry& originalMotionEntry, BitSet32 pointerIds, nsecs_t splitDownTime) { ALOG_ASSERT(pointerIds.value != 0); uint32_t splitPointerIndexMap[MAX_POINTERS]; Loading Loading @@ -3815,6 +3835,13 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( } } if (action == AMOTION_EVENT_ACTION_DOWN) { LOG_ALWAYS_FATAL_IF(splitDownTime != originalMotionEntry.eventTime, "Split motion event has mismatching downTime and eventTime for " "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64 "ms", originalMotionEntry.getDescription().c_str(), ns2ms(splitDownTime)); } int32_t newId = mIdGenerator.nextId(); if (ATRACE_ENABLED()) { std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32 Loading @@ -3835,9 +3862,9 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( originalMotionEntry.xPrecision, originalMotionEntry.yPrecision, originalMotionEntry.xCursorPosition, originalMotionEntry.yCursorPosition, originalMotionEntry.downTime, splitPointerCount, splitPointerProperties, splitPointerCoords); originalMotionEntry.yCursorPosition, splitDownTime, splitPointerCount, splitPointerProperties, splitPointerCoords); if (originalMotionEntry.injectionState) { splitMotionEntry->injectionState = originalMotionEntry.injectionState; Loading Loading @@ -5074,12 +5101,13 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< state->removeWindowByToken(fromToken); // Add new window. nsecs_t downTimeInTarget = now(); int32_t newTargetFlags = oldTargetFlags & (InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) { newTargetFlags |= InputTarget::FLAG_FOREGROUND; } state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds, downTimeInTarget); // Store the dragging window. if (isDragDrop) { Loading @@ -5103,7 +5131,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< options(CancelationOptions::CANCEL_POINTER_EVENTS, "transferring touch focus from this window to another window"); synthesizeCancelationEventsForConnectionLocked(fromConnection, options); synthesizePointerDownEventsForConnectionLocked(toConnection); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection); } if (DEBUG_FOCUS) { Loading Loading @@ -5253,10 +5281,12 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += INDENT3 "Windows:\n"; for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, " "targetFlags=0x%x, firstDownTimeInTarget=%" PRId64 "ms\n", i, touchedWindow.windowHandle->getName().c_str(), touchedWindow.pointerIds.value, touchedWindow.targetFlags); touchedWindow.pointerIds.value, touchedWindow.targetFlags, ns2ms(touchedWindow.firstDownTimeInTarget.value_or(0))); } } else { dump += INDENT3 "Windows: <none>\n"; Loading
services/inputflinger/dispatcher/InputDispatcher.h +6 −3 Original line number Diff line number Diff line Loading @@ -550,6 +550,7 @@ private: void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId) REQUIRES(mLock); Loading Loading @@ -621,12 +622,14 @@ private: const CancelationOptions& options) REQUIRES(mLock); void synthesizePointerDownEventsForConnectionLocked(const sp<Connection>& connection) void synthesizePointerDownEventsForConnectionLocked(const nsecs_t downTime, const sp<Connection>& connection) REQUIRES(mLock); // Splitting motion events across windows. // 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, BitSet32 pointerIds); BitSet32 pointerIds, nsecs_t splitDownTime); // Reset and drop everything the dispatcher is doing. void resetAndDropEverythingLocked(const char* reason) REQUIRES(mLock); Loading
services/inputflinger/dispatcher/InputTarget.h +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ struct InputTarget { // The subset of pointer ids to include in motion events dispatched to this input target // if FLAG_SPLIT is set. BitSet32 pointerIds; // Event time for the first motion event (ACTION_DOWN) dispatched to this input target if // FLAG_SPLIT is set. std::optional<nsecs_t> firstDownTimeInTarget; // The data is stored by the pointerId. Use the bit position of pointerIds to look up // Transform per pointerId. ui::Transform pointerTransforms[MAX_POINTERS]; Loading
services/inputflinger/dispatcher/TouchState.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ void TouchState::reset() { } void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds) { BitSet32 pointerIds, std::optional<nsecs_t> eventTime) { if (targetFlags & InputTarget::FLAG_SPLIT) { split = true; } Loading @@ -42,7 +42,13 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS; } // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have // downTime set initially. Need to update existing window when an pointer is down for // the window. touchedWindow.pointerIds.value |= pointerIds.value; if (!touchedWindow.firstDownTimeInTarget.has_value()) { touchedWindow.firstDownTimeInTarget = eventTime; } return; } } Loading @@ -51,6 +57,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int touchedWindow.windowHandle = windowHandle; touchedWindow.targetFlags = targetFlags; touchedWindow.pointerIds = pointerIds; touchedWindow.firstDownTimeInTarget = eventTime; windows.push_back(touchedWindow); } Loading
services/inputflinger/dispatcher/TouchState.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ struct TouchState { void reset(); void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds); int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> eventTime = std::nullopt); void removeWindowByToken(const sp<IBinder>& token); void filterNonAsIsTouchWindows(); void filterWindowsExcept(const sp<IBinder>& token); Loading