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

Commit 1750d7f8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Check the DeviceId for generating DragEvent" into main

parents 54392a54 a512a53e
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) {