Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d82af65 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Check the DeviceId for generating DragEvent" into main am: 1750d7f8

parents c659eed8 1750d7f8
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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;
};
+3 −2
Original line number Diff line number Diff line
@@ -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.
+81 −0
Original line number Diff line number Diff line
@@ -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) {