Skip to content

Commit 5891fab

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Reject inconsistent globally injected events" into main
2 parents 634adac + f6abbf4 commit 5891fab

4 files changed

Lines changed: 60 additions & 26 deletions

File tree

include/input/InputEventBuilders.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ class MotionEventBuilder {
250250
public:
251251
MotionEventBuilder(int32_t action, int32_t source) {
252252
mAction = action;
253+
if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
254+
mFlags |= AMOTION_EVENT_FLAG_CANCELED;
255+
}
253256
mSource = source;
254257
mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
255258
mDownTime = mEventTime;

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4794,6 +4794,39 @@ void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChan
47944794
}
47954795
}
47964796

4797+
bool InputDispatcher::shouldRejectInjectedMotionLocked(const MotionEvent& motionEvent,
4798+
DeviceId deviceId,
4799+
ui::LogicalDisplayId displayId,
4800+
std::optional<gui::Uid> targetUid,
4801+
int32_t flags) {
4802+
// Don't verify targeted injection, since it will only affect the caller's
4803+
// window, and the windows are typically destroyed at the end of the test.
4804+
if (targetUid.has_value()) {
4805+
return false;
4806+
}
4807+
4808+
// Verify all other injected streams, whether the injection is coming from apps or from
4809+
// input filter. Print an error if the stream becomes inconsistent with this event.
4810+
// An inconsistent injected event sent could cause a crash in the later stages of
4811+
// dispatching pipeline.
4812+
auto [it, _] = mInputFilterVerifiersByDisplay.try_emplace(displayId,
4813+
std::string("Injection on ") +
4814+
displayId.toString());
4815+
InputVerifier& verifier = it->second;
4816+
4817+
Result<void> result =
4818+
verifier.processMovement(deviceId, motionEvent.getSource(), motionEvent.getAction(),
4819+
motionEvent.getPointerCount(),
4820+
motionEvent.getPointerProperties(),
4821+
motionEvent.getSamplePointerCoords(), flags);
4822+
if (!result.ok()) {
4823+
logDispatchStateLocked();
4824+
LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error();
4825+
return true;
4826+
}
4827+
return false;
4828+
}
4829+
47974830
InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
47984831
std::optional<gui::Uid> targetUid,
47994832
InputEventInjectionSync syncMode,
@@ -4904,32 +4937,10 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
49044937

49054938
mLock.lock();
49064939

4907-
{
4908-
// Verify all injected streams, whether the injection is coming from apps or from
4909-
// input filter. Print an error if the stream becomes inconsistent with this event.
4910-
// An inconsistent injected event sent could cause a crash in the later stages of
4911-
// dispatching pipeline.
4912-
auto [it, _] =
4913-
mInputFilterVerifiersByDisplay.try_emplace(displayId,
4914-
std::string("Injection on ") +
4915-
displayId.toString());
4916-
InputVerifier& verifier = it->second;
4917-
4918-
Result<void> result =
4919-
verifier.processMovement(resolvedDeviceId, motionEvent.getSource(),
4920-
motionEvent.getAction(),
4921-
motionEvent.getPointerCount(),
4922-
motionEvent.getPointerProperties(),
4923-
motionEvent.getSamplePointerCoords(), flags);
4924-
if (!result.ok()) {
4925-
logDispatchStateLocked();
4926-
LOG(ERROR) << "Inconsistent event: " << motionEvent
4927-
<< ", reason: " << result.error();
4928-
if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4929-
mLock.unlock();
4930-
return InputEventInjectionResult::FAILED;
4931-
}
4932-
}
4940+
if (shouldRejectInjectedMotionLocked(motionEvent, resolvedDeviceId, displayId,
4941+
targetUid, flags)) {
4942+
mLock.unlock();
4943+
return InputEventInjectionResult::FAILED;
49334944
}
49344945

49354946
const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();

services/inputflinger/dispatcher/InputDispatcher.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ class InputDispatcher : public android::InputDispatcherInterface {
299299

300300
// Event injection and synchronization.
301301
std::condition_variable mInjectionResultAvailable;
302+
bool shouldRejectInjectedMotionLocked(const MotionEvent& motion, DeviceId deviceId,
303+
ui::LogicalDisplayId displayId,
304+
std::optional<gui::Uid> targetUid, int32_t flags)
305+
REQUIRES(mLock);
302306
void setInjectionResult(const EventEntry& entry,
303307
android::os::InputEventInjectionResult injectionResult);
304308
void transformMotionEntryForInjectionLocked(MotionEntry&,

services/inputflinger/tests/InputDispatcher_test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12889,6 +12889,22 @@ TEST_F(InputDispatcherDragTests, DragAndDropFinishedWhenCancelCurrentTouch) {
1288912889
// Remove drag window
1289012890
mDispatcher->onWindowInfosChanged({{*mWindow->getInfo(), *mSecondWindow->getInfo()}, {}, 0, 0});
1289112891

12892+
// Complete the first event stream, even though the injection will fail because there aren't any
12893+
// valid targets to dispatch this event to. This is still needed to make the input stream
12894+
// consistent
12895+
ASSERT_EQ(InputEventInjectionResult::FAILED,
12896+
injectMotionEvent(*mDispatcher,
12897+
MotionEventBuilder(ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN)
12898+
.displayId(ui::LogicalDisplayId::DEFAULT)
12899+
.pointer(PointerBuilder(/*id=*/0, ToolType::FINGER)
12900+
.x(150)
12901+
.y(50))
12902+
.pointer(PointerBuilder(/*id=*/1, ToolType::FINGER)
12903+
.x(50)
12904+
.y(50))
12905+
.build(),
12906+
INJECT_EVENT_TIMEOUT, InputEventInjectionSync::WAIT_FOR_RESULT));
12907+
1289212908
// Inject a simple gesture, ensure dispatcher not crashed
1289312909
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
1289412910
injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN,

0 commit comments

Comments
 (0)