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 Original line Diff line number Diff line
@@ -1657,6 +1657,13 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<
    InputEventInjectionResult injectionResult;
    InputEventInjectionResult injectionResult;
    if (isPointerEvent) {
    if (isPointerEvent) {
        // Pointer event.  (eg. touchscreen)
        // 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 =
        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
                                               &conflictingPointerActions);
@@ -5575,7 +5582,10 @@ void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionTo


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


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


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


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

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


    void SetUp() override {
    void SetUp() override {
        InputDispatcherTest::SetUp();
        InputDispatcherTest::SetUp();
@@ -6104,8 +6105,13 @@ protected:
        mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
        mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
        mSecondWindow->setFrame(Rect(100, 0, 200, 100));
        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->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mSpyWindow, mWindow, mSecondWindow}}});
    }
    }


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


        // Window should receive motion event.
        // Window should receive motion event.
        mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
        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.
    // 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
        // The drag window covers the entire display
        mDragWindow = new FakeWindowHandle(mApp, mDispatcher, "DragWindow", ADISPLAY_ID_DEFAULT);
        mDragWindow = new FakeWindowHandle(mApp, mDispatcher, "DragWindow", ADISPLAY_ID_DEFAULT);
        mDragWindow->setTouchableRegion(Region{{0, 0, 0, 0}});
        mDispatcher->setInputWindows(
        mDispatcher->setInputWindows(
                {{ADISPLAY_ID_DEFAULT, {mDragWindow, mWindow, mSecondWindow}}});
                {{ADISPLAY_ID_DEFAULT, {mDragWindow, mSpyWindow, mWindow, mSecondWindow}}});


        // Transfer touch focus to the drag window
        // Transfer touch focus to the drag window
        bool transferred =
        bool transferred =
@@ -6207,6 +6216,30 @@ TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
    mSecondWindow->assertNoEvents();
    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) {
TEST_F(InputDispatcherDragTests, DragAndDrop) {
    performDrag();
    performDrag();