diff options
5 files changed, 60 insertions, 136 deletions
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h index 1aed8a8394..93785f670d 100644 --- a/services/inputflinger/reader/include/InputDevice.h +++ b/services/inputflinger/reader/include/InputDevice.h @@ -72,7 +72,7 @@ public: inline std::optional<std::string> getDeviceTypeAssociation() const { return mAssociatedDeviceType; } - inline std::optional<DisplayViewport> getAssociatedViewport() const { + inline virtual std::optional<DisplayViewport> getAssociatedViewport() const { return mAssociatedViewport; } inline bool hasMic() const { return mHasMic; } diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp index 846eced2ab..b27d02d77c 100644 --- a/services/inputflinger/tests/CursorInputMapper_test.cpp +++ b/services/inputflinger/tests/CursorInputMapper_test.cpp @@ -17,6 +17,7 @@ #include "CursorInputMapper.h" #include <list> +#include <optional> #include <string> #include <tuple> #include <variant> @@ -93,38 +94,6 @@ DisplayViewport createSecondaryViewport() { return v; } -/** - * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper. - * - * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates - * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input - * device doesn't set its associated viewport when it's configured. - * - * TODO(b/319217713): work out a way to avoid this fake. - */ -class ViewportFakingInputDeviceContext : public InputDeviceContext { -public: - ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId, - std::optional<DisplayViewport> viewport) - : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {} - - ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId, - ui::Rotation orientation) - : ViewportFakingInputDeviceContext(device, eventHubId, - createPrimaryViewport(orientation)) {} - - std::optional<DisplayViewport> getAssociatedViewport() const override { - return mAssociatedViewport; - } - - void setViewport(const std::optional<DisplayViewport>& viewport) { - mAssociatedViewport = viewport; - } - -private: - std::optional<DisplayViewport> mAssociatedViewport; -}; - } // namespace namespace input_flags = com::android::input::flags; @@ -541,8 +510,9 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldNotRotateMotionsWhenOrientationAw // need to be rotated. mPropertyMap.addProperty("cursor.mode", "navigation"); mPropertyMap.addProperty("cursor.orientationAware", "1"); - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation90); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport) + .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90))); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, 1)); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1, 1, 1, 1)); @@ -558,8 +528,9 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw // Since InputReader works in the un-rotated coordinate space, only devices that are not // orientation-aware are affected by display rotation. mPropertyMap.addProperty("cursor.mode", "navigation"); - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation0); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport) + .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation0))); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, 1)); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1, 1, 1, 1)); @@ -570,7 +541,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, -1, 0)); ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, -1, 1)); - deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation90)); + EXPECT_CALL((*mDevice), getAssociatedViewport) + .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90))); std::list<NotifyArgs> args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::DISPLAY_INFO); @@ -583,7 +555,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, 0, -1)); ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, -1, -1)); - deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation180)); + EXPECT_CALL((*mDevice), getAssociatedViewport) + .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation180))); args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::DISPLAY_INFO); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, -1)); @@ -595,7 +568,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, 1, 0)); ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, 1, -1)); - deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation270)); + EXPECT_CALL((*mDevice), getAssociatedViewport) + .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation270))); args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::DISPLAY_INFO); ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 1, 0)); @@ -649,8 +623,8 @@ TEST_F(CursorInputMapperUnitTest, ConfigureDisplayIdWithAssociatedViewport) { mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport}); // Set up the secondary display as the display on which the pointer should be shown. // The InputDevice is not associated with any display. - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport)); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); std::list<NotifyArgs> args; // Ensure input events are generated for the secondary display. @@ -670,8 +644,8 @@ TEST_F(CursorInputMapperUnitTest, mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport}); // Set up the primary display as the display on which the pointer should be shown. // Associate the InputDevice with the secondary display. - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport)); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); // With PointerChoreographer enabled, there could be a PointerController for the associated // display even if it is different from the pointer display. So the mapper should generate an @@ -1027,8 +1001,8 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationWithAsso mPropertyMap.addProperty("cursor.mode", "pointer"); DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0); mReaderConfiguration.setDisplayViewports({primaryViewport}); - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, primaryViewport); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport)); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); std::list<NotifyArgs> args; @@ -1066,9 +1040,8 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID); // Don't associate the device with the display yet. - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, - /*viewport=*/std::nullopt); - mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(std::nullopt)); + mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration); std::list<NotifyArgs> args; @@ -1082,7 +1055,7 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla ASSERT_GT(coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y), 20.f); // Now associate the device with the display, and verify that acceleration is disabled. - deviceContext.setViewport(primaryViewport); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport)); args += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::DISPLAY_INFO); args.clear(); diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h index d51c708adb..5a3d79da5e 100644 --- a/services/inputflinger/tests/InterfaceMocks.h +++ b/services/inputflinger/tests/InterfaceMocks.h @@ -198,6 +198,7 @@ public: : InputDevice(context, id, generation, identifier) {} MOCK_METHOD(uint32_t, getSources, (), (const, override)); + MOCK_METHOD(std::optional<DisplayViewport>, getAssociatedViewport, (), (const)); MOCK_METHOD(bool, isEnabled, (), ()); MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ()); diff --git a/services/inputflinger/tests/JoystickInputMapper_test.cpp b/services/inputflinger/tests/JoystickInputMapper_test.cpp index ec7019256f..adebd72a03 100644 --- a/services/inputflinger/tests/JoystickInputMapper_test.cpp +++ b/services/inputflinger/tests/JoystickInputMapper_test.cpp @@ -16,11 +16,13 @@ #include "JoystickInputMapper.h" +#include <list> #include <optional> #include <EventHub.h> #include <NotifyArgs.h> #include <ftl/flags.h> +#include <gmock/gmock.h> #include <gtest/gtest.h> #include <input/DisplayViewport.h> #include <linux/input-event-codes.h> @@ -28,76 +30,54 @@ #include "InputMapperTest.h" #include "TestConstants.h" +#include "TestEventMatchers.h" namespace android { -namespace { - using namespace ftl::flag_operators; +using testing::ElementsAre; +using testing::IsEmpty; +using testing::Return; +using testing::VariantWith; -} // namespace - -class JoystickInputMapperTest : public InputMapperTest { +class JoystickInputMapperTest : public InputMapperUnitTest { protected: - static const int32_t RAW_X_MIN; - static const int32_t RAW_X_MAX; - static const int32_t RAW_Y_MIN; - static const int32_t RAW_Y_MAX; - - static constexpr ui::LogicalDisplayId VIRTUAL_DISPLAY_ID = ui::LogicalDisplayId{1}; - static const char* const VIRTUAL_DISPLAY_UNIQUE_ID; - void SetUp() override { - InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL); - } - void prepareAxes() { - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0); - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0); - } - - void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) { - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value); - } - - void processSync(JoystickInputMapper& mapper) { - process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0); - } - - void prepareVirtualDisplay(ui::Rotation orientation) { - setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, /*width=*/400, /*height=*/500, orientation, - VIRTUAL_DISPLAY_UNIQUE_ID, /*physicalPort=*/std::nullopt, - ViewportType::VIRTUAL); + InputMapperUnitTest::SetUp(); + EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID)) + .WillRepeatedly(Return(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL)); + + // The mapper requests info on all ABS axis IDs, including ones which aren't actually used + // (e.g. in the range from 0x0b (ABS_BRAKE) to 0x0f (ABS_HAT0X)), so just return nullopt for + // all axes we don't explicitly set up below. + EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_)) + .WillRepeatedly(Return(std::nullopt)); + + setupAxis(ABS_X, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0); + setupAxis(ABS_Y, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0); } }; -const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767; -const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767; -const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767; -const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767; -const char* const JoystickInputMapperTest::VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1"; - TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) { - prepareAxes(); - JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>(); + DisplayViewport viewport; + viewport.displayId = ui::LogicalDisplayId{1}; + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(viewport)); + mMapper = createInputMapper<JoystickInputMapper>(*mDeviceContext, + mFakePolicy->getReaderConfiguration()); - mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID); - - prepareVirtualDisplay(ui::ROTATION_0); + std::list<NotifyArgs> out; // Send an axis event - processAxis(mapper, ABS_X, 100); - processSync(mapper); - - NotifyMotionArgs args; - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); - ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId); + out = process(EV_ABS, ABS_X, 100); + ASSERT_THAT(out, IsEmpty()); + out = process(EV_SYN, SYN_REPORT, 0); + ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId)))); // Send another axis event - processAxis(mapper, ABS_Y, 100); - processSync(mapper); - - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); - ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId); + out = process(EV_ABS, ABS_Y, 100); + ASSERT_THAT(out, IsEmpty()); + out = process(EV_SYN, SYN_REPORT, 0); + ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId)))); } } // namespace android diff --git a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp index a796c49dbe..6607bc7972 100644 --- a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp +++ b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp @@ -78,36 +78,6 @@ DisplayViewport createSecondaryViewport() { return v; } -/** - * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper. - * - * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates - * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input - * device doesn't set its associated viewport when it's configured. - * - * TODO(b/319217713): work out a way to avoid this fake. - */ -class ViewportFakingInputDeviceContext : public InputDeviceContext { -public: - ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId, - std::optional<DisplayViewport> viewport) - : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {} - - ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId) - : ViewportFakingInputDeviceContext(device, eventHubId, createPrimaryViewport()) {} - - std::optional<DisplayViewport> getAssociatedViewport() const override { - return mAssociatedViewport; - } - - void setViewport(const std::optional<DisplayViewport>& viewport) { - mAssociatedViewport = viewport; - } - -private: - std::optional<DisplayViewport> mAssociatedViewport; -}; - } // namespace namespace vd_flags = android::companion::virtualdevice::flags; @@ -138,8 +108,8 @@ TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdWithAssociatedViewport) { mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport}); // Set up the secondary display as the associated viewport of the mapper. - ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport); - mMapper = createInputMapper<RotaryEncoderInputMapper>(deviceContext, mReaderConfiguration); + EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport)); + mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration); std::list<NotifyArgs> args; // Ensure input events are generated for the secondary display. |