summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/input/InputEventBuilders.h16
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp4
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp48
3 files changed, 61 insertions, 7 deletions
diff --git a/include/input/InputEventBuilders.h b/include/input/InputEventBuilders.h
index 25d35e9fe7..55e058332d 100644
--- a/include/input/InputEventBuilders.h
+++ b/include/input/InputEventBuilders.h
@@ -127,7 +127,7 @@ public:
return *this;
}
- MotionEvent build() {
+ MotionEvent build() const {
std::vector<PointerProperties> pointerProperties;
std::vector<PointerCoords> pointerCoords;
for (const PointerBuilder& pointer : mPointers) {
@@ -135,20 +135,22 @@ public:
pointerCoords.push_back(pointer.buildCoords());
}
+ auto [xCursorPosition, yCursorPosition] =
+ std::make_pair(mRawXCursorPosition, mRawYCursorPosition);
// Set mouse cursor position for the most common cases to avoid boilerplate.
if (mSource == AINPUT_SOURCE_MOUSE &&
- !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) {
- mRawXCursorPosition = pointerCoords[0].getX();
- mRawYCursorPosition = pointerCoords[0].getY();
+ !MotionEvent::isValidCursorPosition(xCursorPosition, yCursorPosition)) {
+ xCursorPosition = pointerCoords[0].getX();
+ yCursorPosition = pointerCoords[0].getY();
}
MotionEvent event;
event.initialize(InputEvent::nextId(), mDeviceId, mSource, mDisplayId, INVALID_HMAC,
mAction, mActionButton, mFlags, /*edgeFlags=*/0, AMETA_NONE, mButtonState,
MotionClassification::NONE, mTransform,
- /*xPrecision=*/0, /*yPrecision=*/0, mRawXCursorPosition,
- mRawYCursorPosition, mRawTransform, mDownTime, mEventTime,
- mPointers.size(), pointerProperties.data(), pointerCoords.data());
+ /*xPrecision=*/0, /*yPrecision=*/0, xCursorPosition, yCursorPosition,
+ mRawTransform, mDownTime, mEventTime, mPointers.size(),
+ pointerProperties.data(), pointerCoords.data());
return event;
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index af4a04d9eb..faafa50eb8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4879,6 +4879,10 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
logDispatchStateLocked();
LOG(ERROR) << "Inconsistent event: " << motionEvent
<< ", reason: " << result.error();
+ if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
+ mLock.unlock();
+ return InputEventInjectionResult::FAILED;
+ }
}
}
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index e5058507eb..d418a9b5ec 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -5037,6 +5037,54 @@ TEST_F_WITH_FLAGS(InputDispatcherTest, InvalidA11yHoverStreamDoesNotCrash,
}
/**
+ * Invalid events injected by input filter are rejected.
+ */
+TEST_F(InputDispatcherTest, InvalidA11yEventsGetRejected) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window",
+ ui::LogicalDisplayId::DEFAULT);
+
+ mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, application);
+
+ mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
+
+ // a11y sets 'POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY' policy flag during injection, so define
+ // a custom injection function here for convenience.
+ auto injectFromAccessibility = [&](int32_t action, float x, float y) {
+ MotionEvent event = MotionEventBuilder(action, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(x).y(y))
+ .addFlag(AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT)
+ .build();
+ return injectMotionEvent(*mDispatcher, event, 100ms,
+ InputEventInjectionSync::WAIT_FOR_RESULT, /*targetUid=*/{},
+ POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_FILTERED |
+ POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY);
+ };
+
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectFromAccessibility(ACTION_DOWN, /*x=*/300, /*y=*/400));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectFromAccessibility(ACTION_MOVE, /*x=*/310, /*y=*/420));
+ window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+ window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
+ // finger is still down, so a new DOWN event should be rejected!
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
+ injectFromAccessibility(ACTION_DOWN, /*x=*/340, /*y=*/410));
+
+ // if the gesture is correctly finished, new down event will succeed
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectFromAccessibility(ACTION_MOVE, /*x=*/320, /*y=*/430));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectFromAccessibility(ACTION_UP, /*x=*/320, /*y=*/430));
+ window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
+ window->consumeMotionEvent(WithMotionAction(ACTION_UP));
+
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectFromAccessibility(ACTION_DOWN, /*x=*/350, /*y=*/460));
+ window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+}
+
+/**
* If mouse is hovering when the touch goes down, the hovering should be stopped via HOVER_EXIT.
*/
TEST_F(InputDispatcherTest, TouchDownAfterMouseHover_legacy) {