Loading services/inputflinger/dispatcher/InputDispatcher.cpp +11 −10 Original line number Diff line number Diff line Loading @@ -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; } } Loading Loading @@ -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 || Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading services/inputflinger/dispatcher/TouchState.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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++) { Loading services/inputflinger/dispatcher/TouchState.h +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading services/inputflinger/dispatcher/TouchedWindow.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading services/inputflinger/dispatcher/TouchedWindow.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +11 −10 Original line number Diff line number Diff line Loading @@ -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; } } Loading Loading @@ -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 || Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading
services/inputflinger/dispatcher/TouchState.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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++) { Loading
services/inputflinger/dispatcher/TouchState.h +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading
services/inputflinger/dispatcher/TouchedWindow.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading
services/inputflinger/dispatcher/TouchedWindow.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading