Set touch and tool resolution in TouchInputMapper
Currently, the resolution is not propagated from the raw axes to the
oriented axes. That means that the upper layers can't learn about the
physical size of the touch.
In this CL, the resolution is populated from the raw axes. This is done
both for TOOL_MAJOR / MINOR and TOUCH_MAJOR / MINOR.
Bug: 198472780
Test: atest inputflinger_tests
Change-Id: I29893df281f65c792277b405362f803f746526a5
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index f1c0e5a..d83d74d 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -45,7 +45,7 @@
inline int32_t getDeviceId() { return mDeviceContext.getId(); }
inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
- inline const std::string getDeviceName() { return mDeviceContext.getName(); }
+ inline const std::string getDeviceName() const { return mDeviceContext.getName(); }
inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }
inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
inline InputListenerInterface& getListener() { return getContext()->getListener(); }
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index 6bdb121..ad11b05 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -32,8 +32,7 @@
void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- for (std::pair<const int32_t, Axis>& pair : mAxes) {
- const Axis& axis = pair.second;
+ for (const auto& [_, axis] : mAxes) {
addMotionRange(axis.axisInfo.axis, axis, info);
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 046323d..0a5de27 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -609,6 +609,15 @@
return std::make_optional(newViewport);
}
+int32_t TouchInputMapper::clampResolution(const char* axisName, int32_t resolution) const {
+ if (resolution < 0) {
+ ALOGE("Invalid %s resolution %" PRId32 " for device %s", axisName, resolution,
+ getDeviceName().c_str());
+ return 0;
+ }
+ return resolution;
+}
+
void TouchInputMapper::initializeSizeRanges() {
if (mCalibration.sizeCalibration == Calibration::SizeCalibration::NONE) {
mSizeScale = 0.0f;
@@ -638,9 +647,19 @@
mOrientedRanges.touchMajor.flat = 0;
mOrientedRanges.touchMajor.fuzz = 0;
mOrientedRanges.touchMajor.resolution = 0;
+ if (mRawPointerAxes.touchMajor.valid) {
+ mRawPointerAxes.touchMajor.resolution =
+ clampResolution("touchMajor", mRawPointerAxes.touchMajor.resolution);
+ mOrientedRanges.touchMajor.resolution = mRawPointerAxes.touchMajor.resolution;
+ }
mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
+ if (mRawPointerAxes.touchMinor.valid) {
+ mRawPointerAxes.touchMinor.resolution =
+ clampResolution("touchMinor", mRawPointerAxes.touchMinor.resolution);
+ mOrientedRanges.touchMinor.resolution = mRawPointerAxes.touchMinor.resolution;
+ }
mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
mOrientedRanges.toolMajor.source = mSource;
@@ -649,9 +668,31 @@
mOrientedRanges.toolMajor.flat = 0;
mOrientedRanges.toolMajor.fuzz = 0;
mOrientedRanges.toolMajor.resolution = 0;
+ if (mRawPointerAxes.toolMajor.valid) {
+ mRawPointerAxes.toolMajor.resolution =
+ clampResolution("toolMajor", mRawPointerAxes.toolMajor.resolution);
+ mOrientedRanges.toolMajor.resolution = mRawPointerAxes.toolMajor.resolution;
+ }
mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
+ if (mRawPointerAxes.toolMinor.valid) {
+ mRawPointerAxes.toolMinor.resolution =
+ clampResolution("toolMinor", mRawPointerAxes.toolMinor.resolution);
+ mOrientedRanges.toolMinor.resolution = mRawPointerAxes.toolMinor.resolution;
+ }
+
+ if (mCalibration.sizeCalibration == Calibration::SizeCalibration::GEOMETRIC) {
+ mOrientedRanges.touchMajor.resolution *= mGeometricScale;
+ mOrientedRanges.touchMinor.resolution *= mGeometricScale;
+ mOrientedRanges.toolMajor.resolution *= mGeometricScale;
+ mOrientedRanges.toolMinor.resolution *= mGeometricScale;
+ } else {
+ // Support for other calibrations can be added here.
+ ALOGW("%s calibration is not supported for size ranges at the moment. "
+ "Using raw resolution instead",
+ ftl::enum_string(mCalibration.sizeCalibration).c_str());
+ }
mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
mOrientedRanges.size.source = mSource;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 6f15b90..9fd30e4 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -733,6 +733,7 @@
void resetExternalStylus();
void clearStylusDataPendingFlags();
+ int32_t clampResolution(const char* axisName, int32_t resolution) const;
void initializeOrientedRanges();
void initializeSizeRanges();
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 336afc6..41ce116 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -106,6 +106,24 @@
}
}
+static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+
+ const InputDeviceInfo::MotionRange* motionRange =
+ info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
+ ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
+}
+
+static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+
+ const InputDeviceInfo::MotionRange* motionRange =
+ info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
+ ASSERT_EQ(nullptr, motionRange);
+}
+
// --- FakePointerController ---
class FakePointerController : public PointerControllerInterface {
@@ -6488,7 +6506,7 @@
mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
0, 0);
if (axes & MINOR) {
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MAX,
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
RAW_TOOL_MAX, 0, 0);
}
}
@@ -6855,6 +6873,57 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
+TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
+ /*fuzz*/ 0, /*resolution*/ 10);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
+ /*fuzz*/ 0, /*resolution*/ 11);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
+ /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
+ /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
+ /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
+ /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
+
+ MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+ // X and Y axes
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
+ // Touch major and minor
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
+ // Tool major and minor
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
+ assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
+}
+
+TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
+ /*fuzz*/ 0, /*resolution*/ 10);
+ mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
+ /*fuzz*/ 0, /*resolution*/ 11);
+
+ // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
+
+ MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+ // Touch major and minor
+ assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
+ assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
+ // Tool major and minor
+ assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
+ assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
+}
+
TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);