Skip to content

Commit 1750d7f

Browse files
Treehugger RobotGerrit Code Review
authored andcommitted
Merge "Check the DeviceId for generating DragEvent" into main
2 parents 54392a5 + a512a53 commit 1750d7f

3 files changed

Lines changed: 90 additions & 4 deletions

File tree

services/inputflinger/dispatcher/DragState.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#pragma once
1818

1919
#include <gui/WindowInfo.h>
20+
#include <input/Input.h>
2021
#include <utils/StrongPointer.h>
2122
#include <string>
2223

@@ -25,8 +26,9 @@ namespace android {
2526
namespace inputdispatcher {
2627

2728
struct DragState {
28-
DragState(const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t pointerId)
29-
: dragWindow(windowHandle), pointerId(pointerId) {}
29+
DragState(const sp<android::gui::WindowInfoHandle>& windowHandle, DeviceId deviceId,
30+
int32_t pointerId)
31+
: dragWindow(windowHandle), deviceId(deviceId), pointerId(pointerId) {}
3032
void dump(std::string& dump, const char* prefix = "");
3133

3234
// The window being dragged.
@@ -37,6 +39,8 @@ struct DragState {
3739
bool isStartDrag = false;
3840
// Indicate if the stylus button is down at the start of the drag.
3941
bool isStylusButtonDownAtStart = false;
42+
// Indicate which device started this drag and drop.
43+
const DeviceId deviceId;
4044
// Indicate which pointer id is tracked by the drag and drop.
4145
const int32_t pointerId;
4246
};

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,7 +2870,8 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x,
28702870
}
28712871

28722872
void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2873-
if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
2873+
if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId ||
2874+
mDragState->deviceId != entry.deviceId) {
28742875
return;
28752876
}
28762877

@@ -5758,7 +5759,7 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
57585759
}
57595760
// Track the pointer id for drag window and generate the drag state.
57605761
const size_t id = pointers.begin()->id;
5761-
mDragState = std::make_unique<DragState>(toWindowHandle, id);
5762+
mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id);
57625763
}
57635764

57645765
// Synthesize cancel for old window and down for new window.

services/inputflinger/tests/InputDispatcher_test.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12192,6 +12192,87 @@ TEST_F(InputDispatcherDragTests, NoDragAndDropWithHoveringPointer) {
1219212192
<< "Drag and drop should not work with a hovering pointer";
1219312193
}
1219412194

12195+
/**
12196+
* Two devices, we use the second pointer of Device A to start the drag, during the drag process, if
12197+
* we perform a click using Device B, the dispatcher should work well.
12198+
*/
12199+
TEST_F(InputDispatcherDragTests, DragAndDropWhenSplitTouchAndMultiDevice) {
12200+
const DeviceId deviceA = 1;
12201+
const DeviceId deviceB = 2;
12202+
// First down on second window with deviceA.
12203+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
12204+
.deviceId(deviceA)
12205+
.pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
12206+
.build());
12207+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA),
12208+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12209+
12210+
// Second down on first window with deviceA
12211+
mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
12212+
.deviceId(deviceA)
12213+
.pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
12214+
.pointer(PointerBuilder(1, ToolType::FINGER).x(50).y(50))
12215+
.build());
12216+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA),
12217+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12218+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12219+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12220+
12221+
// Perform drag and drop from first window.
12222+
ASSERT_TRUE(startDrag(/*sendDown=*/false));
12223+
12224+
// Click first window with device B, we should ensure dispatcher work well.
12225+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
12226+
.deviceId(deviceB)
12227+
.pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
12228+
.build());
12229+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB),
12230+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12231+
12232+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_MOUSE)
12233+
.deviceId(deviceB)
12234+
.pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
12235+
.build());
12236+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB),
12237+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12238+
12239+
// Move with device A.
12240+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
12241+
.deviceId(deviceA)
12242+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
12243+
.pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51))
12244+
.build());
12245+
12246+
mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12247+
WithDisplayId(ui::LogicalDisplayId::DEFAULT),
12248+
WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)));
12249+
mWindow->consumeDragEvent(false, 51, 51);
12250+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12251+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12252+
12253+
// Releasing the drag pointer should cause drop.
12254+
mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
12255+
.deviceId(deviceA)
12256+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
12257+
.pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51))
12258+
.build());
12259+
mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA),
12260+
WithDisplayId(ui::LogicalDisplayId::DEFAULT),
12261+
WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)));
12262+
mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindow->getToken());
12263+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12264+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12265+
12266+
// Release all pointers.
12267+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
12268+
.deviceId(deviceA)
12269+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
12270+
.build());
12271+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA),
12272+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12273+
mWindow->assertNoEvents();
12274+
}
12275+
1219512276
class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {};
1219612277

1219712278
TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) {

0 commit comments

Comments
 (0)