diff options
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 19 |
2 files changed, 23 insertions, 2 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 1cc4589eb9..5d8df5fdf0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -1421,8 +1421,10 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked( // Enable Pointer Capture. if (haveWindowWithPointerCapture && (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) { - LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched " - "to the window."); + // This can happen if pointer capture is disabled and re-enabled before we notify the + // app of the state change, so there is no need to notify the app. + ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change."); + return; } if (!mCurrentPointerCaptureRequest.enable) { // This can happen if a window requests capture and immediately releases capture. diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index a167271c4d..b688898022 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -5671,6 +5671,25 @@ TEST_F(InputDispatcherPointerCaptureTests, EnableRequestFollowsSequenceNumbers) mWindow->consumeCaptureEvent(true); } +TEST_F(InputDispatcherPointerCaptureTests, RapidToggleRequests) { + requestAndVerifyPointerCapture(mWindow, true); + + // App toggles pointer capture off and on. + mDispatcher->requestPointerCapture(mWindow->getToken(), false); + mFakePolicy->assertSetPointerCaptureCalled(false); + + mDispatcher->requestPointerCapture(mWindow->getToken(), true); + auto enableRequest = mFakePolicy->assertSetPointerCaptureCalled(true); + + // InputReader notifies that the latest "enable" request was processed, while skipping over the + // preceding "disable" request. + notifyPointerCaptureChanged(enableRequest); + + // Since pointer capture was never disabled during the rapid toggle, the window does not receive + // any notifications. + mWindow->assertNoEvents(); +} + class InputDispatcherUntrustedTouchesTest : public InputDispatcherTest { protected: constexpr static const float MAXIMUM_OBSCURING_OPACITY = 0.8; |