Pointer icon refactor for touchpad
With PointerChoreographer enabled, touchpads work similar to mice,
using MousePointerController of the associated display.
For some gestures like scroll or multi-finger swipes,
TouchpadInputMapper sets fake finger coordinates and
PointerChoreographer combines cursor position with them.
Test: atest inputflinger_tests
Bug: 293587049
Change-Id: I0f6588c79004284df98d99351ea3c3e64b636a74
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 7aeb215..58e35a6 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -527,10 +527,8 @@
if (mEnablePointerChoreographer) {
// Always use DISPLAY_ID_NONE for mouse events.
// PointerChoreographer will make it target the correct the displayId later.
- const auto pointerViewport =
- getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
- mDisplayId = pointerViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
- resolvedViewport = pointerViewport;
+ resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
+ mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
} else {
mDisplayId = mPointerController->getDisplayId();
if (auto v = config.getDisplayViewportById(*mDisplayId); v) {
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index c76fec7..34ca0b3 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -246,7 +246,8 @@
mStateConverter(deviceContext, mMotionAccumulator),
mGestureConverter(*getContext(), deviceContext, getDeviceId()),
mCapturedEventConverter(*getContext(), deviceContext, mMotionAccumulator, getDeviceId()),
- mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())) {
+ mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())),
+ mEnablePointerChoreographer(input_flags::enable_pointer_choreographer()) {
RawAbsoluteAxisInfo slotAxisInfo;
deviceContext.getAbsoluteAxisInfo(ABS_MT_SLOT, &slotAxisInfo);
if (!slotAxisInfo.valid || slotAxisInfo.maxValue <= 0) {
@@ -331,31 +332,56 @@
if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
mDisplayId = ADISPLAY_ID_NONE;
- if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) {
+ std::optional<DisplayViewport> resolvedViewport;
+ std::optional<FloatRect> boundsInLogicalDisplay;
+ if (auto assocViewport = mDeviceContext.getAssociatedViewport(); assocViewport) {
// This InputDevice is associated with a viewport.
// Only generate events for the associated display.
- const bool mismatchedPointerDisplay =
- (viewport->displayId != mPointerController->getDisplayId());
- if (mismatchedPointerDisplay) {
- ALOGW("Touchpad \"%s\" associated viewport display does not match pointer "
- "controller",
- mDeviceContext.getName().c_str());
+ mDisplayId = assocViewport->displayId;
+ resolvedViewport = *assocViewport;
+ if (!mEnablePointerChoreographer) {
+ const bool mismatchedPointerDisplay =
+ (assocViewport->displayId != mPointerController->getDisplayId());
+ if (mismatchedPointerDisplay) {
+ ALOGW("Touchpad \"%s\" associated viewport display does not match pointer "
+ "controller",
+ mDeviceContext.getName().c_str());
+ mDisplayId.reset();
+ }
}
- mDisplayId = mismatchedPointerDisplay ? std::nullopt
- : std::make_optional(viewport->displayId);
} else {
// The InputDevice is not associated with a viewport, but it controls the mouse pointer.
- mDisplayId = mPointerController->getDisplayId();
- }
-
- ui::Rotation orientation = ui::ROTATION_0;
- if (mDisplayId.has_value()) {
- if (auto viewport = config.getDisplayViewportById(*mDisplayId); viewport) {
- orientation = getInverseRotation(viewport->orientation);
+ if (mEnablePointerChoreographer) {
+ // Always use DISPLAY_ID_NONE for touchpad events.
+ // PointerChoreographer will make it target the correct the displayId later.
+ resolvedViewport =
+ getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
+ mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
+ } else {
+ mDisplayId = mPointerController->getDisplayId();
+ if (auto v = config.getDisplayViewportById(*mDisplayId); v) {
+ resolvedViewport = *v;
+ }
+ if (auto bounds = mPointerController->getBounds(); bounds) {
+ boundsInLogicalDisplay = *bounds;
+ }
}
}
+
mGestureConverter.setDisplayId(mDisplayId);
- mGestureConverter.setOrientation(orientation);
+ mGestureConverter.setOrientation(resolvedViewport
+ ? getInverseRotation(resolvedViewport->orientation)
+ : ui::ROTATION_0);
+
+ if (!boundsInLogicalDisplay) {
+ boundsInLogicalDisplay = resolvedViewport
+ ? FloatRect{static_cast<float>(resolvedViewport->logicalLeft),
+ static_cast<float>(resolvedViewport->logicalTop),
+ static_cast<float>(resolvedViewport->logicalRight - 1),
+ static_cast<float>(resolvedViewport->logicalBottom - 1)}
+ : FloatRect{0, 0, 0, 0};
+ }
+ mGestureConverter.setBoundsInLogicalDisplay(*boundsInLogicalDisplay);
}
if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) {
mPropertyProvider.getProperty("Use Custom Touchpad Pointer Accel Curve")
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index a68ae43..ece0eca 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -107,6 +107,8 @@
// Tracking IDs for touches that have at some point been reported as palms by the touchpad.
std::set<int32_t> mPalmTrackingIds;
+ const bool mEnablePointerChoreographer;
+
// The display that events generated by this mapper should target. This can be set to
// ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e.
// std::nullopt), all events will be ignored.
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
index 4d2b66d..9552104 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
@@ -60,7 +60,8 @@
const InputDeviceContext& deviceContext, int32_t deviceId)
: mDeviceId(deviceId),
mReaderContext(readerContext),
- mPointerController(readerContext.getPointerController(deviceId)) {
+ mPointerController(readerContext.getPointerController(deviceId)),
+ mEnablePointerChoreographer(input_flags::enable_pointer_choreographer()) {
deviceContext.getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mXAxisInfo);
deviceContext.getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mYAxisInfo);
}
@@ -110,9 +111,11 @@
// TODO(b/259547750): set this using the raw axis ranges from the touchpad when pointer capture
// is enabled.
- if (std::optional<FloatRect> rect = mPointerController->getBounds(); rect.has_value()) {
- info.addMotionRange(AMOTION_EVENT_AXIS_X, SOURCE, rect->left, rect->right, 0, 0, 0);
- info.addMotionRange(AMOTION_EVENT_AXIS_Y, SOURCE, rect->top, rect->bottom, 0, 0, 0);
+ if (!mBoundsInLogicalDisplay.isEmpty()) {
+ info.addMotionRange(AMOTION_EVENT_AXIS_X, SOURCE, mBoundsInLogicalDisplay.left,
+ mBoundsInLogicalDisplay.right, 0, 0, 0);
+ info.addMotionRange(AMOTION_EVENT_AXIS_Y, SOURCE, mBoundsInLogicalDisplay.top,
+ mBoundsInLogicalDisplay.bottom, 0, 0, 0);
}
info.addMotionRange(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, SOURCE, -1.0f, 1.0f, 0, 0, 0);
@@ -172,7 +175,8 @@
mPointerController->move(deltaX, deltaY);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
PointerCoords coords;
coords.clear();
@@ -196,7 +200,8 @@
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
PointerCoords coords;
coords.clear();
@@ -273,7 +278,8 @@
std::list<NotifyArgs> GestureConverter::releaseAllButtons(nsecs_t when, nsecs_t readTime) {
std::list<NotifyArgs> out;
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
PointerCoords coords;
coords.clear();
@@ -308,7 +314,8 @@
const Gesture& gesture) {
std::list<NotifyArgs> out;
PointerCoords& coords = mFakeFingerCoords[0];
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
if (mCurrentClassification != MotionClassification::TWO_FINGER_SWIPE) {
mCurrentClassification = MotionClassification::TWO_FINGER_SWIPE;
coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
@@ -376,7 +383,8 @@
}
NotifyMotionArgs GestureConverter::endScroll(nsecs_t when, nsecs_t readTime) {
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, 0);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, 0);
NotifyMotionArgs args =
@@ -394,7 +402,8 @@
float dx, float dy) {
std::list<NotifyArgs> out = {};
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
if (mCurrentClassification != MotionClassification::MULTI_FINGER_SWIPE) {
// If the user changes the number of fingers mid-way through a swipe (e.g. they start with
// three and then put a fourth finger down), the gesture library will treat it as two
@@ -457,7 +466,8 @@
if (mCurrentClassification != MotionClassification::MULTI_FINGER_SWIPE) {
return out;
}
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET, 0);
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET, 0);
@@ -481,7 +491,8 @@
[[nodiscard]] std::list<NotifyArgs> GestureConverter::handlePinch(nsecs_t when, nsecs_t readTime,
const Gesture& gesture) {
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
// Pinch gesture phases are reported a little differently from others, in that the same details
// struct is used for all phases of the gesture, just with different zoom_state values. When
@@ -538,7 +549,8 @@
std::list<NotifyArgs> GestureConverter::endPinch(nsecs_t when, nsecs_t readTime) {
std::list<NotifyArgs> out;
- const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
+ const auto [xCursorPosition, yCursorPosition] =
+ mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0);
out.push_back(makeMotionArgs(when, readTime,
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index e6cf617..732a4b2 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -48,6 +48,8 @@
void setDisplayId(std::optional<int32_t> displayId) { mDisplayId = displayId; }
+ void setBoundsInLogicalDisplay(FloatRect bounds) { mBoundsInLogicalDisplay = bounds; }
+
void populateMotionRanges(InputDeviceInfo& info) const;
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -85,8 +87,10 @@
const int32_t mDeviceId;
InputReaderContext& mReaderContext;
std::shared_ptr<PointerControllerInterface> mPointerController;
+ const bool mEnablePointerChoreographer;
std::optional<int32_t> mDisplayId;
+ FloatRect mBoundsInLogicalDisplay{};
ui::Rotation mOrientation = ui::ROTATION_0;
RawAbsoluteAxisInfo mXAxisInfo;
RawAbsoluteAxisInfo mYAxisInfo;