Loading services/inputflinger/tests/InputDispatcher_test.cpp +35 −15 Original line number Diff line number Diff line Loading @@ -386,7 +386,9 @@ private: void pokeUserActivity(nsecs_t, int32_t, int32_t) override {} bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override { return false; } bool checkInjectEventsPermissionNonReentrant(int32_t pid, int32_t uid) override { return pid == INJECTOR_PID && uid == INJECTOR_UID; } void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override { std::scoped_lock lock(mLock); Loading Loading @@ -1090,7 +1092,8 @@ static InputEventInjectionResult injectKey( const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount, int32_t displayId = ADISPLAY_ID_NONE, InputEventInjectionSync syncMode = InputEventInjectionSync::WAIT_FOR_RESULT, std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) { std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT, bool allowKeyRepeat = true) { KeyEvent event; nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC); Loading @@ -1099,10 +1102,13 @@ static InputEventInjectionResult injectKey( INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE, repeatCount, currentTime, currentTime); int32_t policyFlags = POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER; if (!allowKeyRepeat) { policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT; } // Inject event until dispatch out. return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode, injectionTimeout, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER); injectionTimeout, policyFlags); } static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispatcher, Loading @@ -1110,6 +1116,16 @@ static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispat return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId); } // Inject a down event that has key repeat disabled. This allows InputDispatcher to idle without // sending a subsequent key up. When key repeat is enabled, the dispatcher cannot idle because it // has to be woken up to process the repeating key. static InputEventInjectionResult injectKeyDownNoRepeat(const sp<InputDispatcher>& dispatcher, int32_t displayId = ADISPLAY_ID_NONE) { return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId, InputEventInjectionSync::WAIT_FOR_RESULT, INJECT_EVENT_TIMEOUT, /* allowKeyRepeat */ false); } static InputEventInjectionResult injectKeyUp(const sp<InputDispatcher>& dispatcher, int32_t displayId = ADISPLAY_ID_NONE) { return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId); Loading Loading @@ -1254,7 +1270,7 @@ static InputEventInjectionResult injectMotionEvent( .build(); // Inject event until dispatch out. return injectMotionEvent(dispatcher, event); return injectMotionEvent(dispatcher, event, injectionTimeout, injectionMode); } static InputEventInjectionResult injectMotionDown(const sp<InputDispatcher>& dispatcher, Loading Loading @@ -2749,13 +2765,14 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) { // Test inject a key down with display id specified. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT); windowInSecondary->assertNoEvents(); // Test inject a key down without display id specified. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; windowInPrimary->assertNoEvents(); windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE); Loading @@ -2768,7 +2785,7 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) AKEY_EVENT_FLAG_CANCELED); // Test inject a key down, should timeout because of no target window. ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher)) ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDownNoRepeat(mDispatcher)) << "Inject key event should return InputEventInjectionResult::TIMED_OUT"; windowInPrimary->assertNoEvents(); windowInSecondary->consumeFocusEvent(false); Loading Loading @@ -2990,7 +3007,8 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo // Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't // have focus. Ensure no window received the onPointerDownOutsideFocus callback. TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) { ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); Loading Loading @@ -3271,7 +3289,7 @@ TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) { // Send a regular key and respond, which should not cause an ANR. TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) { ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)); mWindow->consumeKeyDown(ADISPLAY_ID_NONE); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyAnrWasNotCalled(); Loading @@ -3284,7 +3302,8 @@ TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) { InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/); InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result); // Key will not go to window because we have no focused window. // The 'no focused window' ANR timer should start instead. Loading Loading @@ -3320,7 +3339,7 @@ TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) { // Send a key to the app and have the app not respond right away. TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) { // Inject a key, and don't respond - expect that ANR is called. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)); std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); ASSERT_TRUE(sequenceNum); const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT); Loading @@ -3347,7 +3366,7 @@ TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) { // injection times out (instead of failing). const InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::WAIT_FOR_RESULT, 10ms); InputEventInjectionSync::WAIT_FOR_RESULT, 10ms, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result); const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT); mFakePolicy->assertNotifyNoFocusedWindowAnrWasCalled(timeout, mApplication); Loading @@ -3366,7 +3385,7 @@ TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DoesNotSendDuplicateAnr) // injection times out (instead of failing). const InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::WAIT_FOR_RESULT, 10ms); InputEventInjectionSync::WAIT_FOR_RESULT, 10ms, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result); const std::chrono::duration appTimeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT); Loading Loading @@ -3955,7 +3974,8 @@ TEST_F(InputDispatcherMultiWindowAnr, FocusedWindowWithoutSetFocusedApplication_ // Key will not be sent anywhere because we have no focused window. It will remain pending. InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/); InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result); // Wait until dispatcher starts the "no focused window" timer. If we don't wait here, Loading Loading
services/inputflinger/tests/InputDispatcher_test.cpp +35 −15 Original line number Diff line number Diff line Loading @@ -386,7 +386,9 @@ private: void pokeUserActivity(nsecs_t, int32_t, int32_t) override {} bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override { return false; } bool checkInjectEventsPermissionNonReentrant(int32_t pid, int32_t uid) override { return pid == INJECTOR_PID && uid == INJECTOR_UID; } void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override { std::scoped_lock lock(mLock); Loading Loading @@ -1090,7 +1092,8 @@ static InputEventInjectionResult injectKey( const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount, int32_t displayId = ADISPLAY_ID_NONE, InputEventInjectionSync syncMode = InputEventInjectionSync::WAIT_FOR_RESULT, std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) { std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT, bool allowKeyRepeat = true) { KeyEvent event; nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC); Loading @@ -1099,10 +1102,13 @@ static InputEventInjectionResult injectKey( INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE, repeatCount, currentTime, currentTime); int32_t policyFlags = POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER; if (!allowKeyRepeat) { policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT; } // Inject event until dispatch out. return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode, injectionTimeout, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER); injectionTimeout, policyFlags); } static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispatcher, Loading @@ -1110,6 +1116,16 @@ static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispat return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId); } // Inject a down event that has key repeat disabled. This allows InputDispatcher to idle without // sending a subsequent key up. When key repeat is enabled, the dispatcher cannot idle because it // has to be woken up to process the repeating key. static InputEventInjectionResult injectKeyDownNoRepeat(const sp<InputDispatcher>& dispatcher, int32_t displayId = ADISPLAY_ID_NONE) { return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId, InputEventInjectionSync::WAIT_FOR_RESULT, INJECT_EVENT_TIMEOUT, /* allowKeyRepeat */ false); } static InputEventInjectionResult injectKeyUp(const sp<InputDispatcher>& dispatcher, int32_t displayId = ADISPLAY_ID_NONE) { return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId); Loading Loading @@ -1254,7 +1270,7 @@ static InputEventInjectionResult injectMotionEvent( .build(); // Inject event until dispatch out. return injectMotionEvent(dispatcher, event); return injectMotionEvent(dispatcher, event, injectionTimeout, injectionMode); } static InputEventInjectionResult injectMotionDown(const sp<InputDispatcher>& dispatcher, Loading Loading @@ -2749,13 +2765,14 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) { // Test inject a key down with display id specified. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT); windowInSecondary->assertNoEvents(); // Test inject a key down without display id specified. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; windowInPrimary->assertNoEvents(); windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE); Loading @@ -2768,7 +2785,7 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) AKEY_EVENT_FLAG_CANCELED); // Test inject a key down, should timeout because of no target window. ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher)) ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDownNoRepeat(mDispatcher)) << "Inject key event should return InputEventInjectionResult::TIMED_OUT"; windowInPrimary->assertNoEvents(); windowInSecondary->consumeFocusEvent(false); Loading Loading @@ -2990,7 +3007,8 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo // Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't // have focus. Ensure no window received the onPointerDownOutsideFocus callback. TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) { ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return InputEventInjectionResult::SUCCEEDED"; mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); Loading Loading @@ -3271,7 +3289,7 @@ TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) { // Send a regular key and respond, which should not cause an ANR. TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) { ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)); mWindow->consumeKeyDown(ADISPLAY_ID_NONE); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyAnrWasNotCalled(); Loading @@ -3284,7 +3302,8 @@ TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) { InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/); InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result); // Key will not go to window because we have no focused window. // The 'no focused window' ANR timer should start instead. Loading Loading @@ -3320,7 +3339,7 @@ TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) { // Send a key to the app and have the app not respond right away. TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) { // Inject a key, and don't respond - expect that ANR is called. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher)); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDownNoRepeat(mDispatcher)); std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); ASSERT_TRUE(sequenceNum); const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT); Loading @@ -3347,7 +3366,7 @@ TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) { // injection times out (instead of failing). const InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::WAIT_FOR_RESULT, 10ms); InputEventInjectionSync::WAIT_FOR_RESULT, 10ms, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result); const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT); mFakePolicy->assertNotifyNoFocusedWindowAnrWasCalled(timeout, mApplication); Loading @@ -3366,7 +3385,7 @@ TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DoesNotSendDuplicateAnr) // injection times out (instead of failing). const InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::WAIT_FOR_RESULT, 10ms); InputEventInjectionSync::WAIT_FOR_RESULT, 10ms, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result); const std::chrono::duration appTimeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT); Loading Loading @@ -3955,7 +3974,8 @@ TEST_F(InputDispatcherMultiWindowAnr, FocusedWindowWithoutSetFocusedApplication_ // Key will not be sent anywhere because we have no focused window. It will remain pending. InputEventInjectionResult result = injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/); InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/, false /* allowKeyRepeat */); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result); // Wait until dispatcher starts the "no focused window" timer. If we don't wait here, Loading