summaryrefslogtreecommitdiff
path: root/services/inputflinger/tests/InputReader_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/inputflinger/tests/InputReader_test.cpp')
-rw-r--r--services/inputflinger/tests/InputReader_test.cpp379
1 files changed, 329 insertions, 50 deletions
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 38dfe4041f..b419d9ab3d 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>
@@ -32,6 +33,7 @@
#include <VibratorInputMapper.h>
#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <inttypes.h>
#include <math.h>
@@ -94,6 +96,17 @@ const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightC
{"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 {
@@ -2662,6 +2675,7 @@ protected:
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;
@@ -2678,11 +2692,19 @@ protected:
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) {
@@ -2794,6 +2816,8 @@ const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
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 ---
@@ -4090,8 +4114,11 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
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);
@@ -4105,9 +4132,10 @@ TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMot
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);
@@ -4121,14 +4149,14 @@ TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions)
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));
@@ -4141,14 +4169,14 @@ TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions)
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) {
@@ -4634,6 +4662,8 @@ protected:
void prepareLocationCalibration();
int32_t toRawX(float displayX);
int32_t toRawY(float displayY);
+ int32_t toRotatedRawX(float displayX);
+ int32_t toRotatedRawY(float displayY);
float toCookedX(float rawX, float rawY);
float toCookedY(float rawX, float rawY);
float toDisplayX(int32_t rawX);
@@ -4716,6 +4746,14 @@ int32_t TouchInputMapperTest::toRawY(float displayY) {
return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
}
+int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
+ return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
+}
+
+int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
+ return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
+}
+
float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
AFFINE_TRANSFORM.applyTo(rawX, rawY);
return rawX;
@@ -5370,11 +5408,12 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
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;
@@ -5393,10 +5432,13 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotate
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;
@@ -5418,7 +5460,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
// 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));
@@ -5446,7 +5488,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
// 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));
@@ -5458,6 +5500,172 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
}
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareButtons();
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.orientationAware", "1");
+ addConfigurationProperty("touch.orientation", "ORIENTATION_0");
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+ NotifyMotionArgs args;
+
+ // Orientation 0.
+ processDown(mapper, toRawX(50), toRawY(75));
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareButtons();
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.orientationAware", "1");
+ addConfigurationProperty("touch.orientation", "ORIENTATION_90");
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+ NotifyMotionArgs args;
+
+ // Orientation 90.
+ processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareButtons();
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.orientationAware", "1");
+ addConfigurationProperty("touch.orientation", "ORIENTATION_180");
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+ NotifyMotionArgs args;
+
+ // Orientation 180.
+ processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareButtons();
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.orientationAware", "1");
+ addConfigurationProperty("touch.orientation", "ORIENTATION_270");
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+ NotifyMotionArgs args;
+
+ // Orientation 270.
+ processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
+ 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");
+ addConfigurationProperty("touch.orientation", "ORIENTATION_90");
+ auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+
+ NotifyMotionArgs args;
+
+ // Orientation 90, Rotation 0.
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+ // Orientation 90, Rotation 90.
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_90);
+ processDown(mapper, toRotatedRawX(50), toRotatedRawY(75));
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+ // Orientation 90, Rotation 180.
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_180);
+ processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+ // Orientation 90, Rotation 270.
+ clearViewports();
+ prepareDisplay(DISPLAY_ORIENTATION_270);
+ processDown(mapper, RAW_X_MAX - toRotatedRawX(50) + RAW_X_MIN,
+ RAW_Y_MAX - toRotatedRawY(75) + RAW_Y_MIN);
+ processSync(mapper);
+
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+ processUp(mapper);
+ processSync(mapper);
+ EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
@@ -7808,7 +8016,7 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
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>();
@@ -7818,6 +8026,32 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_AreRotated) {
// 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();
@@ -7827,12 +8061,16 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_AreRotated) {
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>();
@@ -7849,8 +8087,36 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreRotated) {
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);
}
@@ -8404,18 +8670,25 @@ TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange) {
// 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.
@@ -8424,16 +8697,19 @@ TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_90) {
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);
+ // 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_270) {
+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.
@@ -8442,16 +8718,19 @@ TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_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;
+ // 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) {
+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;
@@ -8463,16 +8742,16 @@ TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_Corner) {
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);
}