InputDispatcher: Check injection permission in tests
- Forwards the unused parameters injectionTimeout and injectionMode to
the test helper method.
- Checks injection permission in the test against the default PID and
UID used for injection. Adding this caused a regression in many tests.
Since the tests never gave Dispatcher permission for injection, none of
the input events were marked with the TRUSTED flag, which, for tests
that inject a key DOWN event, disqualified key repeats from taking
place. Now that injected events are TRUSTED, the dispatcher can never
idle after a key DOWN because it needs to wake up to process the key
repeat. Therefore we need to disable key repeats with the policy flag
when injecting a key DOWN in tests that need the Dispatcher to idle.
Bug: 173733166
Test: atest inputflinger_tests
Change-Id: Ie5084ae3e8f2a0b77930bf3943cce0d7bd21d3a6
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 32f9b69..2a8c1bd 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -379,7 +379,9 @@
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);
@@ -1078,7 +1080,8 @@
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);
@@ -1087,10 +1090,13 @@
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,
@@ -1098,6 +1104,16 @@
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);
@@ -1242,7 +1258,7 @@
.build();
// Inject event until dispatch out.
- return injectMotionEvent(dispatcher, event);
+ return injectMotionEvent(dispatcher, event, injectionTimeout, injectionMode);
}
static InputEventInjectionResult injectMotionDown(const sp<InputDispatcher>& dispatcher,
@@ -2737,13 +2753,14 @@
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);
@@ -2756,7 +2773,7 @@
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);
@@ -2978,7 +2995,8 @@
// 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);
@@ -3259,7 +3277,7 @@
// 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();
@@ -3272,7 +3290,8 @@
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.
@@ -3308,7 +3327,7 @@
// 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);
@@ -3335,7 +3354,7 @@
// 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);
@@ -3354,7 +3373,7 @@
// 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);
@@ -3943,7 +3962,8 @@
// 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,