diff options
author | 2022-11-02 14:16:03 +0000 | |
---|---|---|
committer | 2022-11-02 14:16:03 +0000 | |
commit | 4c9142ee597fe7445d5363e7e57d43c0bcc6dc9c (patch) | |
tree | fa95496924014f46b7f366c2df32d5479a594dca | |
parent | d3819acc71e4f3042eb2719af134a5b6d6800cb7 (diff) | |
parent | 64a985343395e051a5f5520a9646bb6175e200fa (diff) |
Merge "Remove TouchState::split variable"
4 files changed, 38 insertions, 25 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index ead093c6bd..63a241887b 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2034,6 +2034,36 @@ std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked( return responsiveMonitors; } +/** + * In general, touch should be always split between windows. Some exceptions: + * 1. Don't split touch is if we have an active pointer down, and a new pointer is going down that's + * from the same device, *and* the window that's receiving the current pointer does not support + * split touch. + * 2. Don't split mouse events + */ +bool InputDispatcher::shouldSplitTouch(const TouchState& touchState, + const MotionEntry& entry) const { + if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) { + // We should never split mouse events + return false; + } + for (const TouchedWindow& touchedWindow : touchState.windows) { + if (touchedWindow.windowHandle->getInfo()->isSpy()) { + // Spy windows should not affect whether or not touch is split. + continue; + } + if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) { + continue; + } + // Eventually, touchedWindow will contain the deviceId of each pointer that's currently + // being sent there. For now, use deviceId from touch state. + if (entry.deviceId == touchState.deviceId && !touchedWindow.pointerIds.isEmpty()) { + return false; + } + } + return true; +} + std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked( nsecs_t currentTime, const MotionEntry& entry, bool* outConflictingPointerActions, InputEventInjectionResult& outInjectionResult) { @@ -2061,7 +2091,7 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState = *oldState; } - bool isSplit = tempTouchState.split; + bool isSplit = shouldSplitTouch(tempTouchState, entry); bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 && (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source || tempTouchState.displayId != displayId); @@ -2141,7 +2171,7 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked( // No window is touched, so set split to true. This will allow the next pointer down to // be delivered to a new window which supports split touch. Pointers from a mouse device // should never be split. - tempTouchState.split = isSplit = !isFromMouse; + isSplit = !isFromMouse; } // Update hover state. @@ -5301,9 +5331,9 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += StringPrintf(INDENT "TouchStatesByDisplay:\n"); for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) { const TouchState& state = pair.second; - dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n", - state.displayId, toString(state.down), toString(state.split), - state.deviceId, state.source); + dump += StringPrintf(INDENT2 "%d: down=%s, deviceId=%d, source=0x%08x\n", + state.displayId, toString(state.down), state.deviceId, + state.source); if (!state.windows.empty()) { dump += INDENT3 "Windows:\n"; for (size_t i = 0; i < state.windows.size(); i++) { @@ -5676,10 +5706,7 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { "input channel stole pointer stream"); options.deviceId = state.deviceId; options.displayId = state.displayId; - if (state.split) { - // If split pointers then selectively cancel pointers otherwise cancel all pointers - options.pointerIds = window.pointerIds; - } + options.pointerIds = window.pointerIds; std::string canceledWindows; for (const TouchedWindow& w : state.windows) { const std::shared_ptr<InputChannel> channel = @@ -5698,11 +5725,7 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { // This only blocks relevant pointers to be sent to other windows window.isPilferingPointers = true; - if (state.split) { - state.cancelPointersForWindowsExcept(window.pointerIds, token); - } else { - state.filterWindowsExcept(token); - } + state.cancelPointersForWindowsExcept(window.pointerIds, token); return OK; } diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index c2fe19614f..3b44a8e85d 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -541,6 +541,7 @@ private: // shade is pulled down while we are counting down the timeout). void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock); + bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) const; int32_t getTargetDisplayId(const EventEntry& entry); sp<android::gui::WindowInfoHandle> findFocusedWindowTargetLocked( nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime, diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index cf0c38af33..eb31046d9c 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -31,10 +31,6 @@ void TouchState::reset() { void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, BitSet32 pointerIds, std::optional<nsecs_t> eventTime) { - if (targetFlags & InputTarget::FLAG_SPLIT) { - split = true; - } - for (size_t i = 0; i < windows.size(); i++) { TouchedWindow& touchedWindow = windows[i]; if (touchedWindow.windowHandle == windowHandle) { @@ -105,11 +101,6 @@ void TouchState::cancelPointersForNonPilferingWindows(const BitSet32 pointerIds) std::erase_if(windows, [](const TouchedWindow& w) { return w.pointerIds.isEmpty(); }); } -void TouchState::filterWindowsExcept(const sp<IBinder>& token) { - std::erase_if(windows, - [&token](const TouchedWindow& w) { return w.windowHandle->getToken() != token; }); -} - sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const { for (size_t i = 0; i < windows.size(); i++) { const TouchedWindow& window = windows[i]; diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h index cf5f1e58c6..d32461184b 100644 --- a/services/inputflinger/dispatcher/TouchState.h +++ b/services/inputflinger/dispatcher/TouchState.h @@ -29,7 +29,6 @@ namespace inputdispatcher { struct TouchState { bool down = false; - bool split = false; // id of the device that is currently down, others are rejected int32_t deviceId = -1; @@ -50,7 +49,6 @@ struct TouchState { std::optional<nsecs_t> eventTime = std::nullopt); void removeWindowByToken(const sp<IBinder>& token); void filterNonAsIsTouchWindows(); - void filterWindowsExcept(const sp<IBinder>& token); // Cancel pointers for current set of windows except the window with particular binder token. void cancelPointersForWindowsExcept(const BitSet32 pointerIds, const sp<IBinder>& token); |