InputReader_tests: Fix tests to work with per-window-input-rotation

The per-window-input-rotation flag makes InputReader work in the
un-rotated coordinate space. This means rotation affects input devices
in the opposite way as without the flag. Devices that were previously
affected by rotation (orientation-aware devices) are no longer affected,
and vice versa.

We update the tests to take this into account and test the case when the
flag is enabled.

Bug: 179274888
Test: atest inputflinger_tests
Change-Id: I9901cc065409b7d414d09d77f8f8e9f2a99994e4
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 778f6e6..43f14bd 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -16,6 +16,7 @@
 
 #include <CursorInputMapper.h>
 #include <InputDevice.h>
+#include <InputFlingerProperties.sysprop.h>
 #include <InputMapper.h>
 #include <InputReader.h>
 #include <InputReaderBase.h>
@@ -95,6 +96,17 @@
                                                                   {"green", LightColor::GREEN},
                                                                   {"blue", LightColor::BLUE}};
 
+static int32_t getInverseRotation(int32_t orientation) {
+    switch (orientation) {
+        case DISPLAY_ORIENTATION_90:
+            return DISPLAY_ORIENTATION_270;
+        case DISPLAY_ORIENTATION_270:
+            return DISPLAY_ORIENTATION_90;
+        default:
+            return orientation;
+    }
+}
+
 // --- FakePointerController ---
 
 class FakePointerController : public PointerControllerInterface {
@@ -2660,6 +2672,7 @@
     static const int32_t DEVICE_CONTROLLER_NUMBER;
     static const Flags<InputDeviceClass> DEVICE_CLASSES;
     static const int32_t EVENTHUB_ID;
+    static const std::optional<bool> INITIAL_PER_WINDOW_INPUT_ROTATION_FLAG_VALUE;
 
     std::shared_ptr<FakeEventHub> mFakeEventHub;
     sp<FakeInputReaderPolicy> mFakePolicy;
@@ -2676,11 +2689,19 @@
         mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
     }
 
-    void SetUp() override { SetUp(DEVICE_CLASSES); }
+    void SetUp() override {
+        // Ensure per_window_input_rotation is enabled.
+        sysprop::InputFlingerProperties::per_window_input_rotation(true);
+
+        SetUp(DEVICE_CLASSES);
+    }
 
     void TearDown() override {
         mFakeListener.clear();
         mFakePolicy.clear();
+
+        sysprop::InputFlingerProperties::per_window_input_rotation(
+                INITIAL_PER_WINDOW_INPUT_ROTATION_FLAG_VALUE);
     }
 
     void addConfigurationProperty(const char* key, const char* value) {
@@ -2792,6 +2813,8 @@
 const Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
         Flags<InputDeviceClass>(0); // not needed for current tests
 const int32_t InputMapperTest::EVENTHUB_ID = 1;
+const std::optional<bool> InputMapperTest::INITIAL_PER_WINDOW_INPUT_ROTATION_FLAG_VALUE =
+        sysprop::InputFlingerProperties::per_window_input_rotation();
 
 // --- SwitchInputMapperTest ---
 
@@ -4088,8 +4111,11 @@
     ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
 }
 
-TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
+TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
     addConfigurationProperty("cursor.mode", "navigation");
+    // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
+    // need to be rotated.
+    addConfigurationProperty("cursor.orientationAware", "1");
     CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
 
     prepareDisplay(DISPLAY_ORIENTATION_90);
@@ -4103,9 +4129,10 @@
     ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
 }
 
-TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) {
+TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
     addConfigurationProperty("cursor.mode", "navigation");
-    addConfigurationProperty("cursor.orientationAware", "1");
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
     CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
 
     prepareDisplay(DISPLAY_ORIENTATION_0);
@@ -4119,14 +4146,14 @@
     ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
 
     prepareDisplay(DISPLAY_ORIENTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1, -1));
 
     prepareDisplay(DISPLAY_ORIENTATION_180);
     ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0, -1));
@@ -4139,14 +4166,14 @@
     ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1, -1));
 
     prepareDisplay(DISPLAY_ORIENTATION_270);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1,  1));
 }
 
 TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
@@ -5368,11 +5395,12 @@
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
 }
 
-TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareButtons();
     prepareAxes(POSITION);
-    addConfigurationProperty("touch.orientationAware", "0");
+    // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
+    // need to be rotated. Touchscreens are orientation-aware by default.
     SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
 
     NotifyMotionArgs args;
@@ -5391,10 +5419,13 @@
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
 }
 
-TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
+TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareButtons();
     prepareAxes(POSITION);
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
     SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
 
     NotifyMotionArgs args;
@@ -5416,7 +5447,7 @@
     // Rotation 90.
     clearViewports();
     prepareDisplay(DISPLAY_ORIENTATION_90);
-    processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
+    processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
     processSync(mapper);
 
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
@@ -5444,7 +5475,7 @@
     // Rotation 270.
     clearViewports();
     prepareDisplay(DISPLAY_ORIENTATION_270);
-    processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
+    processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
     processSync(mapper);
 
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
@@ -7806,7 +7837,7 @@
     ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
 }
 
-TEST_F(MultiTouchInputMapperTest, VideoFrames_AreRotated) {
+TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
     prepareAxes(POSITION);
     addConfigurationProperty("touch.deviceType", "touchScreen");
     MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
@@ -7816,6 +7847,32 @@
 
     // Test all 4 orientations
     for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
+                                DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
+        SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
+        clearViewports();
+        prepareDisplay(orientation);
+        std::vector<TouchVideoFrame> frames{frame};
+        mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
+        processPosition(mapper, 100, 200);
+        processSync(mapper);
+        ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+        ASSERT_EQ(frames, motionArgs.videoFrames);
+    }
+}
+
+TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+    // Unrotated video frame
+    TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
+    NotifyMotionArgs motionArgs;
+
+    // Test all 4 orientations
+    for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
              DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
         SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
         clearViewports();
@@ -7825,12 +7882,16 @@
         processPosition(mapper, 100, 200);
         processSync(mapper);
         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-        frames[0].rotate(orientation);
+        // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
+        // compared to the display. This is so that when the window transform (which contains the
+        // display rotation) is applied later by InputDispatcher, the coordinates end up in the
+        // window's coordinate space.
+        frames[0].rotate(getInverseRotation(orientation));
         ASSERT_EQ(frames, motionArgs.videoFrames);
     }
 }
 
-TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreRotated) {
+TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
     prepareAxes(POSITION);
     addConfigurationProperty("touch.deviceType", "touchScreen");
     MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
@@ -7847,8 +7908,36 @@
     processPosition(mapper, 100, 200);
     processSync(mapper);
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    std::for_each(frames.begin(), frames.end(),
-            [](TouchVideoFrame& frame) { frame.rotate(DISPLAY_ORIENTATION_90); });
+    ASSERT_EQ(frames, motionArgs.videoFrames);
+}
+
+TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+    // Unrotated video frames. There's no rule that they must all have the same dimensions,
+    // so mix these.
+    TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
+    TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
+    TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
+    std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
+    NotifyMotionArgs motionArgs;
+
+    prepareDisplay(DISPLAY_ORIENTATION_90);
+    mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
+    processPosition(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
+        // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
+        // compared to the display. This is so that when the window transform (which contains the
+        // display rotation) is applied later by InputDispatcher, the coordinates end up in the
+        // window's coordinate space.
+        frame.rotate(getInverseRotation(DISPLAY_ORIENTATION_90));
+    });
     ASSERT_EQ(frames, motionArgs.videoFrames);
 }
 
@@ -8402,18 +8491,25 @@
     // Reset.
     mapper.reset(ARBITRARY_TIME);
 
-    // Let physical display be different to device, and make surface and physical could be 1:1.
-    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_0);
+    // Let physical display be different to device, and make surface and physical could be 1:1 in
+    // all four orientations.
+    for (int orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
+                            DISPLAY_ORIENTATION_270}) {
+        halfDisplayToCenterHorizontal(orientation);
 
-    const int32_t xExpected = (x + 1) - (DISPLAY_WIDTH / 4);
-    const int32_t yExpected = y;
-    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+        const int32_t xExpected = (x + 1) - (DISPLAY_WIDTH / 4);
+        const int32_t yExpected = y;
+        processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+    }
 }
 
-TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_90) {
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_90_NotOrientationAware) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
     MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
 
     // Half display to (width/4, 0, width * 3/4, height) and rotate 90-degrees.
@@ -8422,34 +8518,40 @@
     const int32_t x = DISPLAY_WIDTH / 4;
     const int32_t y = DISPLAY_HEIGHT / 2;
 
-    // expect x/y = swap x/y then reverse y.
-    const int32_t xExpected = y;
-    const int32_t yExpected = (DISPLAY_WIDTH * 3 / 4) - (x + 1);
-    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
-}
-
-TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_270) {
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION);
-    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
-
-    // Half display to (width/4, 0, width * 3/4, height) and rotate 270-degrees.
-    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_270);
-
-    const int32_t x = DISPLAY_WIDTH / 4;
-    const int32_t y = DISPLAY_HEIGHT / 2;
-
     // expect x/y = swap x/y then reverse x.
     constexpr int32_t xExpected = DISPLAY_HEIGHT - y;
     constexpr int32_t yExpected = (x + 1) - DISPLAY_WIDTH / 4;
     processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
 }
 
-TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_Corner) {
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_270_NotOrientationAware) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+    // Half display to (width/4, 0, width * 3/4, height) and rotate 270-degrees.
+    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_270);
+
+    const int32_t x = DISPLAY_WIDTH / 4;
+    const int32_t y = DISPLAY_HEIGHT / 2;
+
+    // expect x/y = swap x/y then reverse y.
+    const int32_t xExpected = y;
+    const int32_t yExpected = (DISPLAY_WIDTH * 3 / 4) - (x + 1);
+    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+}
+
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_Corner_NotOrientationAware) {
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    // Since InputReader works in the un-rotated coordinate space, only devices that are not
+    // orientation-aware are affected by display rotation.
+    addConfigurationProperty("touch.orientationAware", "0");
     MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
 
     const int32_t x = 0;
@@ -8461,16 +8563,16 @@
 
     clearViewports();
     prepareDisplay(DISPLAY_ORIENTATION_90);
-    // expect x/y = swap x/y then reverse y.
-    const int32_t xExpected90 = y;
-    const int32_t yExpected90 = DISPLAY_WIDTH - 1;
+    // expect x/y = swap x/y then reverse x.
+    const int32_t xExpected90 = DISPLAY_HEIGHT - 1;
+    const int32_t yExpected90 = x;
     processPositionAndVerify(mapper, x - 1, y, x, y, xExpected90, yExpected90);
 
     clearViewports();
     prepareDisplay(DISPLAY_ORIENTATION_270);
-    // expect x/y = swap x/y then reverse x.
-    const int32_t xExpected270 = DISPLAY_HEIGHT - 1;
-    const int32_t yExpected270 = x;
+    // expect x/y = swap x/y then reverse y.
+    const int32_t xExpected270 = y;
+    const int32_t yExpected270 = DISPLAY_WIDTH - 1;
     processPositionAndVerify(mapper, x - 1, y, x, y, xExpected270, yExpected270);
 }