Set appropriate cursor position on viewport transition
This CL updates PointerChoreographer to set position of the cursor on
the destination display when cursor crosses the boundary.
Also updates the logic to lookup destination displays in topology to
account for size and offset of the display.
Test: presubmit and manual
Bug: 367660694
Flag: com.android.input.flags.connected_displays_cursor
Change-Id: I18e3bd925a44d541e34946494e7e1b9db0a2e786
diff --git a/services/inputflinger/tests/FakePointerController.cpp b/services/inputflinger/tests/FakePointerController.cpp
index c1606a7..f53e63b 100644
--- a/services/inputflinger/tests/FakePointerController.cpp
+++ b/services/inputflinger/tests/FakePointerController.cpp
@@ -195,4 +195,8 @@
mSpotsByDisplay.clear();
}
+ui::Transform FakePointerController::getDisplayTransform() const {
+ return ui::Transform();
+}
+
} // namespace android
diff --git a/services/inputflinger/tests/FakePointerController.h b/services/inputflinger/tests/FakePointerController.h
index 04adff8..0ee3123 100644
--- a/services/inputflinger/tests/FakePointerController.h
+++ b/services/inputflinger/tests/FakePointerController.h
@@ -48,6 +48,7 @@
void setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) override;
void clearSkipScreenshotFlags() override;
void fade(Transition) override;
+ ui::Transform getDisplayTransform() const override;
void assertViewportSet(ui::LogicalDisplayId displayId);
void assertViewportNotSet();
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index f427658..453c156 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -2604,8 +2604,9 @@
using PointerChoreographerDisplayTopologyTestFixtureParam =
std::tuple<std::string_view /*name*/, int32_t /*source device*/,
ControllerType /*PointerController*/, ToolType /*pointer tool type*/,
- FloatPoint /*source position */, FloatPoint /*hover move X/Y */,
- ui::LogicalDisplayId /*destination display*/>;
+ FloatPoint /*source position*/, FloatPoint /*hover move X/Y*/,
+ ui::LogicalDisplayId /*destination display*/,
+ FloatPoint /*destination position*/>;
class PointerChoreographerDisplayTopologyTestFixture
: public PointerChoreographerTest,
@@ -2616,6 +2617,7 @@
static constexpr ui::LogicalDisplayId DISPLAY_RIGHT_ID = ui::LogicalDisplayId{30};
static constexpr ui::LogicalDisplayId DISPLAY_BOTTOM_ID = ui::LogicalDisplayId{40};
static constexpr ui::LogicalDisplayId DISPLAY_LEFT_ID = ui::LogicalDisplayId{50};
+ static constexpr ui::LogicalDisplayId DISPLAY_TOP_RIGHT_CORNER_ID = ui::LogicalDisplayId{60};
PointerChoreographerDisplayTopologyTestFixture() {
com::android::input::flags::connected_displays_cursor(true);
@@ -2623,35 +2625,41 @@
protected:
std::vector<DisplayViewport> mViewports{
- createViewport(DISPLAY_CENTER_ID, /*width*/ 100, /*height*/ 100),
- createViewport(DISPLAY_TOP_ID, /*width*/ 90, /*height*/ 90),
- createViewport(DISPLAY_RIGHT_ID, /*width*/ 90, /*height*/ 90),
- createViewport(DISPLAY_BOTTOM_ID, /*width*/ 90, /*height*/ 90),
- createViewport(DISPLAY_LEFT_ID, /*width*/ 90, /*height*/ 90),
+ createViewport(DISPLAY_CENTER_ID, /*width*/ 100, /*height*/ 100, ui::ROTATION_0),
+ createViewport(DISPLAY_TOP_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_0),
+ createViewport(DISPLAY_RIGHT_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_90),
+ createViewport(DISPLAY_BOTTOM_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_180),
+ createViewport(DISPLAY_LEFT_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_270),
+ createViewport(DISPLAY_TOP_RIGHT_CORNER_ID, /*width*/ 90, /*height*/ 90,
+ ui::ROTATION_0),
};
std::unordered_map<ui::LogicalDisplayId, std::vector<PointerChoreographer::AdjacentDisplay>>
mTopology{
{DISPLAY_CENTER_ID,
- {{DISPLAY_TOP_ID, PointerChoreographer::DisplayPosition::TOP, 0.0f},
- {DISPLAY_RIGHT_ID, PointerChoreographer::DisplayPosition::RIGHT, 0.0f},
- {DISPLAY_BOTTOM_ID, PointerChoreographer::DisplayPosition::BOTTOM, 0.0f},
- {DISPLAY_LEFT_ID, PointerChoreographer::DisplayPosition::LEFT, 0.0f}}},
+ {{DISPLAY_TOP_ID, PointerChoreographer::DisplayPosition::TOP, 10.0f},
+ {DISPLAY_RIGHT_ID, PointerChoreographer::DisplayPosition::RIGHT, 10.0f},
+ {DISPLAY_BOTTOM_ID, PointerChoreographer::DisplayPosition::BOTTOM, 10.0f},
+ {DISPLAY_LEFT_ID, PointerChoreographer::DisplayPosition::LEFT, 10.0f},
+ {DISPLAY_TOP_RIGHT_CORNER_ID, PointerChoreographer::DisplayPosition::RIGHT,
+ -90.0f}}},
};
private:
- DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height) {
+ DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
+ ui::Rotation orientation) {
DisplayViewport viewport;
viewport.displayId = displayId;
viewport.logicalRight = width;
viewport.logicalBottom = height;
+ viewport.orientation = orientation;
return viewport;
}
};
TEST_P(PointerChoreographerDisplayTopologyTestFixture, PointerChoreographerDisplayTopologyTest) {
const auto& [_, device, pointerControllerType, pointerToolType, initialPosition, hoverMove,
- destinationDisplay] = GetParam();
+ destinationDisplay, destinationPosition] = GetParam();
mChoreographer.setDisplayViewports(mViewports);
mChoreographer.setDefaultMouseDisplayId(
@@ -2681,42 +2689,86 @@
.build());
// Check that the PointerController updated the position and the pointer is shown.
- // TODO(b/362719483) assert pointer controller position here
ASSERT_TRUE(pc->isPointerShown());
ASSERT_EQ(pc->getDisplayId(), destinationDisplay);
+ auto position = pc->getPosition();
+ ASSERT_EQ(position.x, destinationPosition.x);
+ ASSERT_EQ(position.y, destinationPosition.y);
// Check that x-y coordinates, displayId and cursor position are correctly updated.
- // TODO(b/362719483) assert Coords and cursor position here
- mTestListener.assertNotifyMotionWasCalled(WithDisplayId(destinationDisplay));
+ mTestListener.assertNotifyMotionWasCalled(
+ AllOf(WithCoords(destinationPosition.x, destinationPosition.y),
+ WithDisplayId(destinationDisplay),
+ WithCursorPosition(destinationPosition.x, destinationPosition.y)));
}
INSTANTIATE_TEST_SUITE_P(
PointerChoreographerTest, PointerChoreographerDisplayTopologyTestFixture,
testing::Values(
+ // Note: Upon viewport transition cursor will be positioned at the boundary of the
+ // destination, as we drop any unconsumed delta.
std::make_tuple("UnchangedDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE,
ToolType::MOUSE, FloatPoint(50, 50) /* initial x/y */,
FloatPoint(25, 25) /* delta x/y */,
- PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID),
- std::make_tuple("TransitionToRightDisplay", AINPUT_SOURCE_MOUSE,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
+ FloatPoint(75, 75) /* destination x/y */),
+ std::make_tuple(
+ "TransitionToRightDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE,
+ ToolType::MOUSE, FloatPoint(50, 50) /* initial x/y */,
+ FloatPoint(100, 25) /* delta x/y */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_RIGHT_ID,
+ FloatPoint(0, 50 + 25 - 10) /* Left edge: (0, source + delta - offset) */),
+ std::make_tuple(
+ "TransitionToLeftDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE,
+ ToolType::MOUSE, FloatPoint(50, 50) /* initial x/y */,
+ FloatPoint(-100, 25) /* delta x/y */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_LEFT_ID,
+ FloatPoint(90,
+ 50 + 25 - 10) /* Right edge: (width, source + delta - offset*/),
+ std::make_tuple(
+ "TransitionToTopDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD,
+ ControllerType::MOUSE, ToolType::FINGER,
+ FloatPoint(50, 50) /* initial x/y */, FloatPoint(25, -100) /* delta x/y */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_ID,
+ FloatPoint(50 + 25 - 10,
+ 90) /* Bottom edge: (source + delta - offset, height) */),
+ std::make_tuple(
+ "TransitionToBottomDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD,
+ ControllerType::MOUSE, ToolType::FINGER,
+ FloatPoint(50, 50) /* initial x/y */, FloatPoint(25, 100) /* delta x/y */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_BOTTOM_ID,
+ FloatPoint(50 + 25 - 10, 0) /* Top edge: (source + delta - offset, 0) */),
+ std::make_tuple("NoTransitionAtTopOffset", AINPUT_SOURCE_MOUSE,
ControllerType::MOUSE, ToolType::MOUSE,
- FloatPoint(50, 50) /* initial x/y */,
- FloatPoint(100, 25) /* delta x/y */,
- PointerChoreographerDisplayTopologyTestFixture::DISPLAY_RIGHT_ID),
- std::make_tuple("TransitionToLeftDisplay", AINPUT_SOURCE_MOUSE,
+ FloatPoint(5, 50) /* initial x/y */,
+ FloatPoint(0, -100) /* Move Up */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
+ FloatPoint(5, 0) /* Top edge */),
+ std::make_tuple("NoTransitionAtRightOffset", AINPUT_SOURCE_MOUSE,
ControllerType::MOUSE, ToolType::MOUSE,
- FloatPoint(50, 50) /* initial x/y */,
- FloatPoint(-100, 25) /* delta x/y */,
- PointerChoreographerDisplayTopologyTestFixture::DISPLAY_LEFT_ID),
- std::make_tuple("TransitionToTopDisplay",
+ FloatPoint(95, 5) /* initial x/y */,
+ FloatPoint(100, 0) /* Move Right */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
+ FloatPoint(99, 5) /* Top edge */),
+ std::make_tuple("NoTransitionAtBottomOffset",
AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE,
- ToolType::FINGER, FloatPoint(50, 50) /* initial x/y */,
- FloatPoint(25, -100) /* delta x/y */,
- PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_ID),
- std::make_tuple("TransitionToBottomDisplay",
+ ToolType::FINGER, FloatPoint(5, 95) /* initial x/y */,
+ FloatPoint(0, 100) /* Move Down */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
+ FloatPoint(5, 99) /* Bottom edge */),
+ std::make_tuple("NoTransitionAtLeftOffset",
AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE,
- ToolType::FINGER, FloatPoint(50, 50) /* initial x/y */,
- FloatPoint(25, 100) /* delta x/y */,
- PointerChoreographerDisplayTopologyTestFixture::DISPLAY_BOTTOM_ID)),
+ ToolType::FINGER, FloatPoint(5, 5) /* initial x/y */,
+ FloatPoint(-100, 0) /* Move Left */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
+ FloatPoint(0, 5) /* Left edge */),
+ std::make_tuple(
+ "TransitionAtTopRightCorner", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD,
+ ControllerType::MOUSE, ToolType::FINGER,
+ FloatPoint(95, 5) /* initial x/y */,
+ FloatPoint(10, -10) /* Move dignally to top right corner */,
+ PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_RIGHT_CORNER_ID,
+ FloatPoint(0, 90) /* bottom left corner */)),
[](const testing::TestParamInfo<PointerChoreographerDisplayTopologyTestFixtureParam>& p) {
return std::string{std::get<0>(p.param)};
});