diff options
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 21 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/TouchState.cpp | 18 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/TouchState.h | 5 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/TouchedWindow.cpp | 8 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/TouchedWindow.h | 4 |
5 files changed, 42 insertions, 14 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 100b6d57f3..65c2407bec 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2218,10 +2218,7 @@ bool InputDispatcher::shouldSplitTouch(const TouchState& touchState, 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.hasTouchingPointers(entry.deviceId)) { + if (touchedWindow.hasTouchingPointers(entry.deviceId)) { return false; } } @@ -2254,8 +2251,14 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( } bool isSplit = shouldSplitTouch(tempTouchState, entry); - const bool switchedDevice = (oldState != nullptr) && - (oldState->deviceId != entry.deviceId || oldState->source != entry.source); + bool switchedDevice = false; + if (oldState != nullptr) { + std::set<int32_t> oldActiveDevices = oldState->getActiveDeviceIds(); + const bool anotherDeviceIsActive = + oldActiveDevices.count(entry.deviceId) == 0 && !oldActiveDevices.empty(); + switchedDevice |= anotherDeviceIsActive; + switchedDevice |= oldState->source != entry.source; + } const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || @@ -2274,7 +2277,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // from another device. However, if the new event is a down event, let's cancel the current // touch and let the new one take over. if (switchedDevice && wasDown && !isDown) { - LOG(INFO) << "Dropping event because a pointer for device " << oldState->deviceId + LOG(INFO) << "Dropping event because a pointer for another device " << " is already down in display " << displayId << ": " << entry.getDescription(); // TODO(b/211379801): test multiple simultaneous input streams. outInjectionResult = InputEventInjectionResult::FAILED; @@ -2284,7 +2287,6 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (newGesture) { // If a new gesture is starting, clear the touch state completely. tempTouchState.reset(); - tempTouchState.deviceId = entry.deviceId; tempTouchState.source = entry.source; isSplit = false; } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) { @@ -2692,7 +2694,6 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( } if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { - tempTouchState.deviceId = entry.deviceId; tempTouchState.source = entry.source; } } else if (maskedAction == AMOTION_EVENT_ACTION_UP) { @@ -4392,7 +4393,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId); if (touchStateIt != mTouchStatesByDisplay.end()) { const TouchState& touchState = touchStateIt->second; - if (touchState.deviceId == args.deviceId && touchState.isDown()) { + if (touchState.hasTouchingPointers(args.deviceId)) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } } diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index ef188c7844..dcbb366597 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -31,6 +31,21 @@ void TouchState::reset() { *this = TouchState(); } +std::set<int32_t> TouchState::getActiveDeviceIds() const { + std::set<int32_t> out; + for (const TouchedWindow& w : windows) { + std::set<int32_t> deviceIds = w.getActiveDeviceIds(); + out.insert(deviceIds.begin(), deviceIds.end()); + } + return out; +} + +bool TouchState::hasTouchingPointers(int32_t deviceId) const { + return std::any_of(windows.begin(), windows.end(), [&](const TouchedWindow& window) { + return window.hasTouchingPointers(deviceId); + }); +} + void TouchState::removeTouchingPointer(int32_t removedDeviceId, int32_t pointerId) { for (TouchedWindow& touchedWindow : windows) { touchedWindow.removeTouchingPointer(removedDeviceId, pointerId); @@ -262,8 +277,7 @@ void TouchState::removeAllPointersForDevice(int32_t removedDeviceId) { std::string TouchState::dump() const { std::string out; - out += StringPrintf("deviceId=%d, source=%s\n", deviceId, - inputEventSourceToString(source).c_str()); + out += StringPrintf("source=%s\n", inputEventSourceToString(source).c_str()); if (!windows.empty()) { out += " Windows:\n"; for (size_t i = 0; i < windows.size(); i++) { diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h index a2a9f75ef5..1bda0fb9e0 100644 --- a/services/inputflinger/dispatcher/TouchState.h +++ b/services/inputflinger/dispatcher/TouchState.h @@ -29,8 +29,6 @@ class WindowInfoHandle; namespace inputdispatcher { struct TouchState { - // id of the device that is currently down, others are rejected - int32_t deviceId = -1; // source of the device that is current down, others are rejected uint32_t source = 0; @@ -43,6 +41,9 @@ struct TouchState { void reset(); void clearWindowsWithoutPointers(); + std::set<int32_t> getActiveDeviceIds() const; + + bool hasTouchingPointers(int32_t device) const; void removeTouchingPointer(int32_t deviceId, int32_t pointerId); void removeTouchingPointerFromWindow(int32_t deviceId, int32_t pointerId, const sp<android::gui::WindowInfoHandle>& windowHandle); diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp index 6ab97f8ea5..ae165209bd 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.cpp +++ b/services/inputflinger/dispatcher/TouchedWindow.cpp @@ -134,6 +134,14 @@ std::set<int32_t> TouchedWindow::getTouchingDeviceIds() const { return deviceIds; } +std::set<int32_t> TouchedWindow::getActiveDeviceIds() const { + std::set<int32_t> out; + for (const auto& [deviceId, _] : mDeviceStates) { + out.emplace(deviceId); + } + return out; +} + bool TouchedWindow::hasPilferingPointers(int32_t deviceId) const { const auto stateIt = mDeviceStates.find(deviceId); if (stateIt == mDeviceStates.end()) { diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h index e50ede50b6..81393fc2fc 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.h +++ b/services/inputflinger/dispatcher/TouchedWindow.h @@ -53,6 +53,10 @@ struct TouchedWindow { * nullopt. */ std::set<int32_t> getTouchingDeviceIds() const; + /** + * The ids of devices that are currently touching or hovering. + */ + std::set<int32_t> getActiveDeviceIds() const; // Pilfering pointers bool hasPilferingPointers(int32_t deviceId) const; |