TouchpadInputMapper: rotate pointer movement with display
Bug: 263378323
Test: Rotate device to landscape, check pointer movements are rotated
Test: atest inputflinger_tests
Change-Id: I548ec8b31a90a575253a8fe004c67cb1fbbf51e8
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index c563dba..23d7fdf 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -16,11 +16,14 @@
#include "../Macros.h"
+#include <optional>
+
#include <android/input.h>
#include <linux/input-event-codes.h>
#include <log/log_main.h>
#include "TouchCursorInputMapperCommon.h"
#include "TouchpadInputMapper.h"
+#include "ui/Rotation.h"
namespace android {
@@ -111,6 +114,22 @@
return AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD;
}
+std::list<NotifyArgs> TouchpadInputMapper::configure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ std::optional<int32_t> displayId = mPointerController->getDisplayId();
+ ui::Rotation orientation = ui::ROTATION_0;
+ if (displayId.has_value()) {
+ if (auto viewport = config->getDisplayViewportById(*displayId); viewport) {
+ orientation = getInverseRotation(viewport->orientation);
+ }
+ }
+ mGestureConverter.setOrientation(orientation);
+ }
+ return {};
+}
+
std::list<NotifyArgs> TouchpadInputMapper::reset(nsecs_t when) {
mStateConverter.reset();
mGestureConverter.reset();
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index b3bc831..3a92211 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -25,6 +25,7 @@
#include "EventHub.h"
#include "InputDevice.h"
#include "InputMapper.h"
+#include "InputReaderBase.h"
#include "NotifyArgs.h"
#include "gestures/GestureConverter.h"
#include "gestures/HardwareStateConverter.h"
@@ -39,6 +40,9 @@
~TouchpadInputMapper();
uint32_t getSources() const override;
+ [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
index 23216d3..8600065 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
@@ -72,8 +72,12 @@
props.id = 0;
props.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ float deltaX = gesture.details.move.dx;
+ float deltaY = gesture.details.move.dy;
+ rotateDelta(mOrientation, &deltaX, &deltaY);
+
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
- mPointerController->move(gesture.details.move.dx, gesture.details.move.dy);
+ mPointerController->move(deltaX, deltaY);
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
float xCursorPosition, yCursorPosition;
mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
@@ -82,8 +86,8 @@
coords.clear();
coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
- coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, gesture.details.move.dx);
- coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, gesture.details.move.dy);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
+ coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
const bool down = isPointerDown(mButtonState);
coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index dc11f24..d6a51d2 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -24,6 +24,7 @@
#include "InputReaderContext.h"
#include "NotifyArgs.h"
+#include "ui/Rotation.h"
#include "include/gestures.h"
@@ -35,6 +36,7 @@
public:
GestureConverter(InputReaderContext& readerContext, int32_t deviceId);
+ void setOrientation(ui::Rotation orientation) { mOrientation = orientation; }
void reset();
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -56,6 +58,7 @@
InputReaderContext& mReaderContext;
std::shared_ptr<PointerControllerInterface> mPointerController;
+ ui::Rotation mOrientation = ui::ROTATION_0;
// The current button state according to the gestures library, but converted into MotionEvent
// button values (AMOTION_EVENT_BUTTON_...).
uint32_t mButtonState = 0;
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index 91efd1a..74c2028 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -29,6 +29,7 @@
#include "TestInputListener.h"
#include "TestInputListenerMatchers.h"
#include "include/gestures.h"
+#include "ui/Rotation.h"
namespace android {
@@ -77,6 +78,23 @@
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(95, 210));
}
+TEST_F(GestureConverterTest, Move_Rotated) {
+ GestureConverter converter(*mReader->getContext(), DEVICE_ID);
+ converter.setOrientation(ui::ROTATION_90);
+
+ Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
+ std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
+ ASSERT_EQ(1u, args.size());
+
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X + 10, POINTER_Y + 5), WithRelativeMotion(10, 5),
+ WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithButtonState(0),
+ WithPressure(0.0f)));
+
+ ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(110, 205));
+}
+
TEST_F(GestureConverterTest, ButtonsChange) {
GestureConverter converter(*mReader->getContext(), DEVICE_ID);