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

Commit 21c02580 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "Call pilfer pointers when second pointer goes down during D&D"

parents dbee1759 6abcf8ff
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1657,6 +1657,13 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<
    InputEventInjectionResult injectionResult;
    if (isPointerEvent) {
        // Pointer event.  (eg. touchscreen)

        if (mDragState &&
            (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
            // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
            pilferPointersLocked(mDragState->dragWindow->getToken());
        }

        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
@@ -5575,7 +5582,10 @@ void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionTo

status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
    std::scoped_lock _l(mLock);
    return pilferPointersLocked(token);
}

status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
    const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
    if (!requestingChannel) {
        ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
+2 −0
Original line number Diff line number Diff line
@@ -255,6 +255,8 @@ private:

    void removeConnectionLocked(const sp<Connection>& connection) REQUIRES(mLock);

    status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock);

    template <typename T>
    struct StrongPointerHash {
        std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
+35 −2
Original line number Diff line number Diff line
@@ -6094,6 +6094,7 @@ protected:
    sp<FakeWindowHandle> mWindow;
    sp<FakeWindowHandle> mSecondWindow;
    sp<FakeWindowHandle> mDragWindow;
    sp<FakeWindowHandle> mSpyWindow;

    void SetUp() override {
        InputDispatcherTest::SetUp();
@@ -6104,8 +6105,13 @@ protected:
        mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
        mSecondWindow->setFrame(Rect(100, 0, 200, 100));

        mSpyWindow = new FakeWindowHandle(mApp, mDispatcher, "SpyWindow", ADISPLAY_ID_DEFAULT);
        mSpyWindow->setSpy(true);
        mSpyWindow->setTrustedOverlay(true);
        mSpyWindow->setFrame(Rect(0, 0, 200, 100));

        mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mSpyWindow, mWindow, mSecondWindow}}});
    }

    void injectDown() {
@@ -6116,6 +6122,8 @@ protected:

        // Window should receive motion event.
        mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
        // Spy window should also receive motion event
        mSpyWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
    }

    // Start performing drag, we will create a drag window and transfer touch to it.
@@ -6128,8 +6136,9 @@ protected:

        // The drag window covers the entire display
        mDragWindow = new FakeWindowHandle(mApp, mDispatcher, "DragWindow", ADISPLAY_ID_DEFAULT);
        mDragWindow->setTouchableRegion(Region{{0, 0, 0, 0}});
        mDispatcher->setInputWindows(
                {{ADISPLAY_ID_DEFAULT, {mDragWindow, mWindow, mSecondWindow}}});
                {{ADISPLAY_ID_DEFAULT, {mDragWindow, mSpyWindow, mWindow, mSecondWindow}}});

        // Transfer touch focus to the drag window
        bool transferred =
@@ -6207,6 +6216,30 @@ TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
    mSecondWindow->assertNoEvents();
}

TEST_F(InputDispatcherDragTests, DragEnterAndPointerDownPilfersPointers) {
    performDrag();

    // No cancel event after drag start
    mSpyWindow->assertNoEvents();

    const MotionEvent secondFingerDownEvent =
            MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
                    .eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
                    .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
                    .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(60).y(60))
                    .build();
    ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
              injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
                                InputEventInjectionSync::WAIT_FOR_RESULT))
            << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";

    // Receives cancel for first pointer after next pointer down
    mSpyWindow->consumeMotionCancel();
    mSpyWindow->consumeMotionDown();

    mSpyWindow->assertNoEvents();
}

TEST_F(InputDispatcherDragTests, DragAndDrop) {
    performDrag();