diff options
| author | 2021-04-12 10:08:20 +0000 | |
|---|---|---|
| committer | 2021-04-12 10:08:20 +0000 | |
| commit | 286c7f2ae69ce07ce5d4d49ddb612ef26d2a04b1 (patch) | |
| tree | 9b451df804c28061c2ffcffa959d1e493d008607 | |
| parent | 494199e2d72b068ecb0c3986a21d07e1a166589c (diff) | |
| parent | 6d0571e4e8523d14d471d5a0e093d6a2edbc49f1 (diff) | |
Merge "Fix the drag window still alive after drop failed" into sc-dev
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 3 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 40 |
2 files changed, 43 insertions, 0 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 073455a7ff..4e058478a7 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2326,6 +2326,8 @@ void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) { if (dropWindow) { vec2 local = dropWindow->getInfo()->transform.transform(x, y); notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y); + } else { + notifyDropWindowLocked(nullptr, 0, 0); } mDragState.reset(); } @@ -2372,6 +2374,7 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { } else if (maskedAction == AMOTION_EVENT_ACTION_UP) { finishDragAndDrop(entry.displayId, x, y); } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) { + notifyDropWindowLocked(nullptr, 0, 0); mDragState.reset(); } } diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index b62fce4a1c..31d6900ef2 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -268,7 +268,9 @@ public: void assertDropTargetEquals(const sp<IBinder>& targetToken) { std::scoped_lock lock(mLock); + ASSERT_TRUE(mNotifyDropWindowWasCalled); ASSERT_EQ(targetToken, mDropTargetWindowToken); + mNotifyDropWindowWasCalled = false; } private: @@ -290,6 +292,7 @@ private: std::condition_variable mNotifyAnr; sp<IBinder> mDropTargetWindowToken GUARDED_BY(mLock); + bool mNotifyDropWindowWasCalled GUARDED_BY(mLock) = false; void notifyConfigurationChanged(nsecs_t when) override { std::scoped_lock lock(mLock); @@ -403,6 +406,7 @@ private: void notifyDropWindow(const sp<IBinder>& token, float x, float y) override { std::scoped_lock lock(mLock); + mNotifyDropWindowWasCalled = true; mDropTargetWindowToken = token; } @@ -4951,4 +4955,40 @@ TEST_F(InputDispatcherDragTests, StylusDragAndDrop) { mSecondWindow->assertNoEvents(); } +TEST_F(InputDispatcherDragTests, DragAndDrop_InvalidWindow) { + performDrag(); + + // Set second window invisible. + mSecondWindow->setVisible(false); + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mDragWindow, mWindow, mSecondWindow}}}); + + // Move on window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT, {50, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT); + mWindow->consumeDragEvent(false, 50, 50); + mSecondWindow->assertNoEvents(); + + // Move to another window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT, {150, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT); + mWindow->consumeDragEvent(true, 150, 50); + mSecondWindow->assertNoEvents(); + + // drop to another window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {150, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); + mFakePolicy->assertDropTargetEquals(nullptr); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); +} + } // namespace android::inputdispatcher |