diff options
author | 2024-10-09 21:26:47 +0000 | |
---|---|---|
committer | 2024-10-09 21:26:47 +0000 | |
commit | 1750d7f8b9e15b6e3617234ea41b3940bb0f550c (patch) | |
tree | 148c33acc55905e46ab8c1be1e80a2501d6db6d6 | |
parent | 54392a54fb6845bf1b2fbbe7c2a1c981253f610b (diff) | |
parent | a512a53e89c79ed5c5a18fab0fb1a0ae2949ad74 (diff) |
Merge "Check the DeviceId for generating DragEvent" into main
-rw-r--r-- | services/inputflinger/dispatcher/DragState.h | 8 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 5 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 81 |
3 files changed, 90 insertions, 4 deletions
diff --git a/services/inputflinger/dispatcher/DragState.h b/services/inputflinger/dispatcher/DragState.h index 9809148853..1ed6c29851 100644 --- a/services/inputflinger/dispatcher/DragState.h +++ b/services/inputflinger/dispatcher/DragState.h @@ -17,6 +17,7 @@ #pragma once #include <gui/WindowInfo.h> +#include <input/Input.h> #include <utils/StrongPointer.h> #include <string> @@ -25,8 +26,9 @@ namespace android { namespace inputdispatcher { struct DragState { - DragState(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t pointerId) - : dragWindow(windowHandle), pointerId(pointerId) {} + DragState(const sp<android::gui::WindowInfoHandle>& windowHandle, DeviceId deviceId, + int32_t pointerId) + : dragWindow(windowHandle), deviceId(deviceId), pointerId(pointerId) {} void dump(std::string& dump, const char* prefix = ""); // The window being dragged. @@ -37,6 +39,8 @@ struct DragState { bool isStartDrag = false; // Indicate if the stylus button is down at the start of the drag. bool isStylusButtonDownAtStart = false; + // Indicate which device started this drag and drop. + const DeviceId deviceId; // Indicate which pointer id is tracked by the drag and drop. const int32_t pointerId; }; diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index f9fbfef3ec..2161e0985b 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2870,7 +2870,8 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x, } void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { - if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) { + if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId || + mDragState->deviceId != entry.deviceId) { return; } @@ -5758,7 +5759,7 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s } // Track the pointer id for drag window and generate the drag state. const size_t id = pointers.begin()->id; - mDragState = std::make_unique<DragState>(toWindowHandle, id); + mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id); } // Synthesize cancel for old window and down for new window. diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 2056372f2d..73ab0dae41 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -12192,6 +12192,87 @@ TEST_F(InputDispatcherDragTests, NoDragAndDropWithHoveringPointer) { << "Drag and drop should not work with a hovering pointer"; } +/** + * Two devices, we use the second pointer of Device A to start the drag, during the drag process, if + * we perform a click using Device B, the dispatcher should work well. + */ +TEST_F(InputDispatcherDragTests, DragAndDropWhenSplitTouchAndMultiDevice) { + const DeviceId deviceA = 1; + const DeviceId deviceB = 2; + // First down on second window with deviceA. + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(deviceA) + .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50)) + .build()); + mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + // Second down on first window with deviceA + mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(deviceA) + .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50)) + .pointer(PointerBuilder(1, ToolType::FINGER).x(50).y(50)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + // Perform drag and drop from first window. + ASSERT_TRUE(startDrag(/*sendDown=*/false)); + + // Click first window with device B, we should ensure dispatcher work well. + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE) + .deviceId(deviceB) + .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_MOUSE) + .deviceId(deviceB) + .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + // Move with device A. + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(deviceA) + .pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51)) + .pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51)) + .build()); + + mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT), + WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))); + mWindow->consumeDragEvent(false, 51, 51); + mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + // Releasing the drag pointer should cause drop. + mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(deviceA) + .pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51)) + .pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51)) + .build()); + mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT), + WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))); + mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindow->getToken()); + mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + + // Release all pointers. + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(deviceA) + .pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51)) + .build()); + mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA), + WithDisplayId(ui::LogicalDisplayId::DEFAULT))); + mWindow->assertNoEvents(); +} + class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {}; TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) { |