Add tests to verify hover enter and exit are synthesized correctly
... using the correct coordinate transforms.
Bug: 299074463
Test: atest inputflinger_tests
Change-Id: I48ef7ca07f3041ba724550bb81e22c9ac37493b5
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index c3c8837..77d5391 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -184,6 +184,18 @@
return receivedX == x && receivedY == y;
}
+MATCHER_P2(WithRawCoords, x, y, "MotionEvent with specified raw coordinates") {
+ if (arg.getPointerCount() != 1) {
+ *result_listener << "Expected 1 pointer, got " << arg.getPointerCount();
+ return false;
+ }
+ const float receivedX = arg.getRawX(/*pointerIndex=*/0);
+ const float receivedY = arg.getRawY(/*pointerIndex=*/0);
+ *result_listener << "expected raw coords (" << x << ", " << y << "), but got (" << receivedX
+ << ", " << receivedY << ")";
+ return receivedX == x && receivedY == y;
+}
+
MATCHER_P(WithPointerCount, pointerCount, "MotionEvent with specified number of pointers") {
*result_listener << "expected pointerCount " << pointerCount << ", but got "
<< arg.getPointerCount();
@@ -4714,6 +4726,43 @@
secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithCoords(-100, -400)));
}
+TEST_F(InputDispatcherDisplayProjectionTest, SynthesizeHoverEnterExitWithCorrectCoordinates) {
+ auto [firstWindow, secondWindow] = setupScaledDisplayScenario();
+
+ // Send hover move to the second window, and ensure it shows up as hover enter.
+ mDispatcher->notifyMotion(generateMotionArgs(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS,
+ ADISPLAY_ID_DEFAULT, {PointF{150, 220}}));
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER),
+ WithCoords(100, 80), WithRawCoords(300, 880)));
+
+ // Touch down at the same location and ensure a hover exit is synthesized.
+ mDispatcher->notifyMotion(generateMotionArgs(ACTION_DOWN, AINPUT_SOURCE_STYLUS,
+ ADISPLAY_ID_DEFAULT, {PointF{150, 220}}));
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithCoords(100, 80),
+ WithRawCoords(300, 880)));
+ secondWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_DOWN), WithCoords(100, 80), WithRawCoords(300, 880)));
+ secondWindow->assertNoEvents();
+ firstWindow->assertNoEvents();
+}
+
+TEST_F(InputDispatcherDisplayProjectionTest, SynthesizeHoverCancelationWithCorrectCoordinates) {
+ auto [firstWindow, secondWindow] = setupScaledDisplayScenario();
+
+ // Send hover enter to second window
+ mDispatcher->notifyMotion(generateMotionArgs(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS,
+ ADISPLAY_ID_DEFAULT, {PointF{150, 220}}));
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER),
+ WithCoords(100, 80), WithRawCoords(300, 880)));
+
+ mDispatcher->cancelCurrentTouch();
+
+ secondWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithCoords(100, 80),
+ WithRawCoords(300, 880)));
+ secondWindow->assertNoEvents();
+ firstWindow->assertNoEvents();
+}
+
/** Ensure consistent behavior of InputDispatcher in all orientations. */
class InputDispatcherDisplayOrientationFixture
: public InputDispatcherDisplayProjectionTest,