Skip to content

Commit a39f7d7

Browse files
Treehugger Robotandroid-build-merge-worker-robot
authored andcommitted
Merge "Check the DeviceId for generating DragEvent" into main am: 1750d7f am: 2d82af6
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3298276 Change-Id: Icc925765de8007f567d0ea85e5716e2f3c1fdaa2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 parents d7fbe20 + 2d82af6 commit a39f7d7

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
@@ -2895,7 +2895,8 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x,
28952895
}
28962896

28972897
void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2898-
if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
2898+
if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId ||
2899+
mDragState->deviceId != entry.deviceId) {
28992900
return;
29002901
}
29012902

@@ -5820,7 +5821,7 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s
58205821
}
58215822
// Track the pointer id for drag window and generate the drag state.
58225823
const size_t id = pointers.begin()->id;
5823-
mDragState = std::make_unique<DragState>(toWindowHandle, id);
5824+
mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id);
58245825
}
58255826

58265827
// 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
@@ -12927,6 +12927,87 @@ TEST_F(InputDispatcherDragTests, NoDragAndDropWithHoveringPointer) {
1292712927
<< "Drag and drop should not work with a hovering pointer";
1292812928
}
1292912929

12930+
/**
12931+
* Two devices, we use the second pointer of Device A to start the drag, during the drag process, if
12932+
* we perform a click using Device B, the dispatcher should work well.
12933+
*/
12934+
TEST_F(InputDispatcherDragTests, DragAndDropWhenSplitTouchAndMultiDevice) {
12935+
const DeviceId deviceA = 1;
12936+
const DeviceId deviceB = 2;
12937+
// First down on second window with deviceA.
12938+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
12939+
.deviceId(deviceA)
12940+
.pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
12941+
.build());
12942+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA),
12943+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12944+
12945+
// Second down on first window with deviceA
12946+
mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
12947+
.deviceId(deviceA)
12948+
.pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
12949+
.pointer(PointerBuilder(1, ToolType::FINGER).x(50).y(50))
12950+
.build());
12951+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA),
12952+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12953+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12954+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12955+
12956+
// Perform drag and drop from first window.
12957+
ASSERT_TRUE(startDrag(/*sendDown=*/false));
12958+
12959+
// Click first window with device B, we should ensure dispatcher work well.
12960+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
12961+
.deviceId(deviceB)
12962+
.pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
12963+
.build());
12964+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB),
12965+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12966+
12967+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_MOUSE)
12968+
.deviceId(deviceB)
12969+
.pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
12970+
.build());
12971+
mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB),
12972+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12973+
12974+
// Move with device A.
12975+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
12976+
.deviceId(deviceA)
12977+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
12978+
.pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51))
12979+
.build());
12980+
12981+
mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12982+
WithDisplayId(ui::LogicalDisplayId::DEFAULT),
12983+
WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)));
12984+
mWindow->consumeDragEvent(false, 51, 51);
12985+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12986+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
12987+
12988+
// Releasing the drag pointer should cause drop.
12989+
mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
12990+
.deviceId(deviceA)
12991+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
12992+
.pointer(PointerBuilder(1, ToolType::FINGER).x(51).y(51))
12993+
.build());
12994+
mDragWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA),
12995+
WithDisplayId(ui::LogicalDisplayId::DEFAULT),
12996+
WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)));
12997+
mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindow->getToken());
12998+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(deviceA),
12999+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
13000+
13001+
// Release all pointers.
13002+
mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
13003+
.deviceId(deviceA)
13004+
.pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(51))
13005+
.build());
13006+
mSecondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA),
13007+
WithDisplayId(ui::LogicalDisplayId::DEFAULT)));
13008+
mWindow->assertNoEvents();
13009+
}
13010+
1293013011
class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {};
1293113012

1293213013
TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) {

0 commit comments

Comments
 (0)