summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2024-07-24 21:19:08 +0000
committer Prabir Pradhan <prabirmsp@google.com> 2024-07-25 14:13:04 +0000
commit31d05c4c78e7924e4bb6dc45092e612a9c7d5bfb (patch)
treec5d1dd9e1f7189534f1944ed0d29bebe60afd7b7
parentd2dfdc6123ffcc98c78073c633567c6f22f8d7c2 (diff)
Mock InputDevice in the InputMapper unit tests
This makes the InputMapperUnitTest subclasses easier to test, as the tests will not have to rely on the behavior of actual InputDevice implementation. Unfortunately, this means InputDevice must now be a virtual class to allow its mocked subclass to define its behavior for the methods that we want to change. In this CL, we take the approach of only marking the methods that we need to customize as virtual to avoid the overhead of vtable lookups at runtime. An alternative approach would be to introduce a type parameter to InputDeviceContext to allow us to specify a different InputDevice implementation in the tests. This would eliminate any addtional runtime overheads resulting from vtable lookups. However, this would mean every InputMapper class would need to have this new type parameter, adding verbosity and complextity to the codebase. For this reason, the virtual member approach was preferred. Bug: 354270482 Test: atest inputflinger_tests Flag: EXEMPT refactor Change-Id: Id7e103e1f04812c92ee8ecfdfe1e75a9949efa9e
-rw-r--r--services/inputflinger/reader/include/InputDevice.h6
-rw-r--r--services/inputflinger/tests/CursorInputMapper_test.cpp7
-rw-r--r--services/inputflinger/tests/InputMapperTest.cpp13
-rw-r--r--services/inputflinger/tests/InputMapperTest.h9
-rw-r--r--services/inputflinger/tests/InterfaceMocks.h76
-rw-r--r--services/inputflinger/tests/KeyboardInputMapper_test.cpp1
-rw-r--r--services/inputflinger/tests/MultiTouchInputMapper_test.cpp1
-rw-r--r--services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp5
-rw-r--r--services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp5
-rw-r--r--services/inputflinger/tests/SwitchInputMapper_test.cpp1
-rw-r--r--services/inputflinger/tests/TouchpadInputMapper_test.cpp1
-rw-r--r--services/inputflinger/tests/VibratorInputMapper_test.cpp1
12 files changed, 84 insertions, 42 deletions
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 086c26f5e2..5eb1accfbf 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -43,7 +43,7 @@ class InputDevice {
public:
InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
const InputDeviceIdentifier& identifier);
- ~InputDevice();
+ virtual ~InputDevice();
inline InputReaderContext* getContext() { return mContext; }
inline int32_t getId() const { return mId; }
@@ -56,7 +56,7 @@ public:
}
inline const std::string getLocation() const { return mIdentifier.location; }
inline ftl::Flags<InputDeviceClass> getClasses() const { return mClasses; }
- inline uint32_t getSources() const { return mSources; }
+ inline virtual uint32_t getSources() const { return mSources; }
inline bool hasEventHubDevices() const { return !mDevices.empty(); }
inline bool isExternal() { return mIsExternal; }
@@ -132,7 +132,7 @@ public:
[[nodiscard]] NotifyDeviceResetArgs notifyReset(nsecs_t when);
- inline const PropertyMap& getConfiguration() { return mConfiguration; }
+ inline virtual const PropertyMap& getConfiguration() const { return mConfiguration; }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
std::optional<ui::LogicalDisplayId> getAssociatedDisplayId();
diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp
index 727237f287..846eced2ab 100644
--- a/services/inputflinger/tests/CursorInputMapper_test.cpp
+++ b/services/inputflinger/tests/CursorInputMapper_test.cpp
@@ -163,7 +163,6 @@ protected:
}
void createMapper() {
- createDevice();
mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
}
@@ -542,7 +541,6 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldNotRotateMotionsWhenOrientationAw
// need to be rotated.
mPropertyMap.addProperty("cursor.mode", "navigation");
mPropertyMap.addProperty("cursor.orientationAware", "1");
- createDevice();
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation90);
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -560,7 +558,6 @@ 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");
- createDevice();
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation0);
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -652,7 +649,6 @@ 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.
- createDevice();
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -673,7 +669,6 @@ TEST_F(CursorInputMapperUnitTest,
DisplayViewport secondaryViewport = createSecondaryViewport();
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
// Set up the primary display as the display on which the pointer should be shown.
- createDevice();
// Associate the InputDevice with the secondary display.
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -1032,7 +1027,6 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationWithAsso
mPropertyMap.addProperty("cursor.mode", "pointer");
DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0);
mReaderConfiguration.setDisplayViewports({primaryViewport});
- createDevice();
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, primaryViewport);
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -1070,7 +1064,6 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla
mReaderConfiguration.setDisplayViewports({primaryViewport});
// Disable acceleration for the display.
mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID);
- createDevice();
// Don't associate the device with the display yet.
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID,
diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp
index 7e96d5f5d7..af1f377287 100644
--- a/services/inputflinger/tests/InputMapperTest.cpp
+++ b/services/inputflinger/tests/InputMapperTest.cpp
@@ -26,7 +26,9 @@
namespace android {
using testing::_;
+using testing::NiceMock;
using testing::Return;
+using testing::ReturnRef;
void InputMapperUnitTest::SetUpWithBus(int bus) {
mFakePolicy = sp<FakeInputReaderPolicy>::make();
@@ -43,16 +45,11 @@ void InputMapperUnitTest::SetUpWithBus(int bus) {
EXPECT_CALL(mMockEventHub, getConfiguration(EVENTHUB_ID)).WillRepeatedly([&](int32_t) {
return mPropertyMap;
});
-}
-void InputMapperUnitTest::createDevice() {
- mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
- /*generation=*/2, mIdentifier);
- mDevice->addEmptyEventHubDevice(EVENTHUB_ID);
+ mDevice = std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID,
+ /*generation=*/2, mIdentifier);
+ ON_CALL((*mDevice), getConfiguration).WillByDefault(ReturnRef(mPropertyMap));
mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
- std::list<NotifyArgs> args =
- mDevice->configure(systemTime(), mReaderConfiguration, /*changes=*/{});
- ASSERT_THAT(args, testing::ElementsAre(testing::VariantWith<NotifyDeviceResetArgs>(_)));
}
void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h
index 88057dc497..9353f8c9ff 100644
--- a/services/inputflinger/tests/InputMapperTest.h
+++ b/services/inputflinger/tests/InputMapperTest.h
@@ -43,13 +43,6 @@ protected:
virtual void SetUp() override { SetUpWithBus(0); }
virtual void SetUpWithBus(int bus);
- /**
- * Initializes mDevice and mDeviceContext. When this happens, mDevice takes a copy of
- * mPropertyMap, so tests that need to set configuration properties should do so before calling
- * this. Others will most likely want to call it in their SetUp method.
- */
- void createDevice();
-
void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution);
void expectScanCodes(bool present, std::set<int> scanCodes);
@@ -67,7 +60,7 @@ protected:
MockEventHubInterface mMockEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
MockInputReaderContext mMockInputReaderContext;
- std::unique_ptr<InputDevice> mDevice;
+ std::unique_ptr<MockInputDevice> mDevice;
std::unique_ptr<InputDeviceContext> mDeviceContext;
InputReaderConfiguration mReaderConfiguration;
diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h
index 48e0b4f516..d51c708adb 100644
--- a/services/inputflinger/tests/InterfaceMocks.h
+++ b/services/inputflinger/tests/InterfaceMocks.h
@@ -26,6 +26,7 @@
#include <vector>
#include <EventHub.h>
+#include <InputDevice.h>
#include <InputReaderBase.h>
#include <InputReaderContext.h>
#include <NotifyArgs.h>
@@ -59,7 +60,7 @@ public:
MOCK_METHOD(void, requestTimeoutAtTime, (nsecs_t when), (override));
int32_t bumpGeneration() override { return ++mGeneration; }
- MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo> & outDevices),
+ MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo>& outDevices),
(override));
MOCK_METHOD(std::list<NotifyArgs>, dispatchExternalStylusState, (const StylusState& outState),
(override));
@@ -172,7 +173,7 @@ public:
MOCK_METHOD(void, requestReopenDevices, (), (override));
MOCK_METHOD(void, wake, (), (override));
- MOCK_METHOD(void, dump, (std::string & dump), (const, override));
+ MOCK_METHOD(void, dump, (std::string& dump), (const, override));
MOCK_METHOD(void, monitor, (), (const, override));
MOCK_METHOD(bool, isDeviceEnabled, (int32_t deviceId), (const, override));
MOCK_METHOD(status_t, enableDevice, (int32_t deviceId), (override));
@@ -190,4 +191,75 @@ public:
MOCK_METHOD(void, notifyMouseCursorFadedOnTyping, (), (override));
};
+class MockInputDevice : public InputDevice {
+public:
+ MockInputDevice(InputReaderContext* context, int32_t id, int32_t generation,
+ const InputDeviceIdentifier& identifier)
+ : InputDevice(context, id, generation, identifier) {}
+
+ MOCK_METHOD(uint32_t, getSources, (), (const, override));
+ MOCK_METHOD(bool, isEnabled, (), ());
+
+ MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ());
+ MOCK_METHOD(void, addEmptyEventHubDevice, (int32_t eventHubId), ());
+ MOCK_METHOD(std::list<NotifyArgs>, addEventHubDevice,
+ (nsecs_t when, int32_t eventHubId, const InputReaderConfiguration& readerConfig),
+ ());
+ MOCK_METHOD(void, removeEventHubDevice, (int32_t eventHubId), ());
+ MOCK_METHOD(std::list<NotifyArgs>, configure,
+ (nsecs_t when, const InputReaderConfiguration& readerConfig,
+ ConfigurationChanges changes),
+ ());
+ MOCK_METHOD(std::list<NotifyArgs>, reset, (nsecs_t when), ());
+ MOCK_METHOD(std::list<NotifyArgs>, process, (const RawEvent* rawEvents, size_t count), ());
+ MOCK_METHOD(std::list<NotifyArgs>, timeoutExpired, (nsecs_t when), ());
+ MOCK_METHOD(std::list<NotifyArgs>, updateExternalStylusState, (const StylusState& state), ());
+
+ MOCK_METHOD(InputDeviceInfo, getDeviceInfo, (), ());
+ MOCK_METHOD(int32_t, getKeyCodeState, (uint32_t sourceMask, int32_t keyCode), ());
+ MOCK_METHOD(int32_t, getScanCodeState, (uint32_t sourceMask, int32_t scanCode), ());
+ MOCK_METHOD(int32_t, getSwitchState, (uint32_t sourceMask, int32_t switchCode), ());
+ MOCK_METHOD(int32_t, getKeyCodeForKeyLocation, (int32_t locationKeyCode), (const));
+ MOCK_METHOD(bool, markSupportedKeyCodes,
+ (uint32_t sourceMask, const std::vector<int32_t>& keyCodes, uint8_t* outFlags), ());
+ MOCK_METHOD(std::list<NotifyArgs>, vibrate,
+ (const VibrationSequence& sequence, ssize_t repeat, int32_t token), ());
+ MOCK_METHOD(std::list<NotifyArgs>, cancelVibrate, (int32_t token), ());
+ MOCK_METHOD(bool, isVibrating, (), ());
+ MOCK_METHOD(std::vector<int32_t>, getVibratorIds, (), ());
+ MOCK_METHOD(std::list<NotifyArgs>, cancelTouch, (nsecs_t when, nsecs_t readTime), ());
+ MOCK_METHOD(bool, enableSensor,
+ (InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod,
+ std::chrono::microseconds maxBatchReportLatency),
+ ());
+
+ MOCK_METHOD(void, disableSensor, (InputDeviceSensorType sensorType), ());
+ MOCK_METHOD(void, flushSensor, (InputDeviceSensorType sensorType), ());
+
+ MOCK_METHOD(std::optional<int32_t>, getBatteryEventHubId, (), (const));
+
+ MOCK_METHOD(bool, setLightColor, (int32_t lightId, int32_t color), ());
+ MOCK_METHOD(bool, setLightPlayerId, (int32_t lightId, int32_t playerId), ());
+ MOCK_METHOD(std::optional<int32_t>, getLightColor, (int32_t lightId), ());
+ MOCK_METHOD(std::optional<int32_t>, getLightPlayerId, (int32_t lightId), ());
+
+ MOCK_METHOD(int32_t, getMetaState, (), ());
+ MOCK_METHOD(void, updateMetaState, (int32_t keyCode), ());
+
+ MOCK_METHOD(void, addKeyRemapping, (int32_t fromKeyCode, int32_t toKeyCode), ());
+
+ MOCK_METHOD(void, setKeyboardType, (KeyboardType keyboardType), ());
+
+ MOCK_METHOD(void, bumpGeneration, (), ());
+
+ MOCK_METHOD(const PropertyMap&, getConfiguration, (), (const, override));
+
+ MOCK_METHOD(NotifyDeviceResetArgs, notifyReset, (nsecs_t when), ());
+
+ MOCK_METHOD(std::optional<ui::LogicalDisplayId>, getAssociatedDisplayId, (), ());
+
+ MOCK_METHOD(void, updateLedState, (bool reset), ());
+
+ MOCK_METHOD(size_t, getMapperCount, (), ());
+};
} // namespace android
diff --git a/services/inputflinger/tests/KeyboardInputMapper_test.cpp b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
index d3e8dee4a0..aa71e07a88 100644
--- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp
+++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
@@ -55,7 +55,6 @@ protected:
void SetUp() override {
InputMapperUnitTest::SetUp();
- createDevice();
// set key-codes expected in tests
for (const auto& [scanCode, outKeycode] : mKeyCodeMap) {
diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
index d4d3c3857f..9a6b266b21 100644
--- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
+++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
@@ -109,7 +109,6 @@ protected:
mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
/*isActive=*/true, "local:0", NO_PORT,
ViewportType::INTERNAL);
- createDevice();
mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext,
mFakePolicy->getReaderConfiguration());
}
diff --git a/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
index b441a23803..9ddb8c138d 100644
--- a/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
+++ b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
@@ -23,10 +23,7 @@ class MultiTouchMotionAccumulatorTest : public InputMapperUnitTest {
protected:
static constexpr size_t SLOT_COUNT = 8;
- void SetUp() override {
- InputMapperUnitTest::SetUp();
- createDevice();
- }
+ void SetUp() override { InputMapperUnitTest::SetUp(); }
MultiTouchMotionAccumulator mMotionAccumulator;
diff --git a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
index 366b3dcdd0..a796c49dbe 100644
--- a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
+++ b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
@@ -138,7 +138,6 @@ TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdWithAssociatedViewport) {
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
// Set up the secondary display as the associated viewport of the mapper.
- createDevice();
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
mMapper = createInputMapper<RotaryEncoderInputMapper>(deviceContext, mReaderConfiguration);
@@ -159,7 +158,6 @@ TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdNoAssociatedViewport) {
mFakePolicy->addDisplayViewport(createPrimaryViewport());
// Set up the mapper with no associated viewport.
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
// Ensure input events are generated without display ID
@@ -174,7 +172,6 @@ TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdNoAssociatedViewport) {
}
TEST_F(RotaryEncoderInputMapperTest, ProcessRegularScroll) {
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -191,7 +188,6 @@ TEST_F(RotaryEncoderInputMapperTest, ProcessHighResScroll) {
vd_flags::high_resolution_scroll(true);
EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
.WillRepeatedly(Return(true));
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -208,7 +204,6 @@ TEST_F(RotaryEncoderInputMapperTest, HighResScrollIgnoresRegularScroll) {
vd_flags::high_resolution_scroll(true);
EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
.WillRepeatedly(Return(true));
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
diff --git a/services/inputflinger/tests/SwitchInputMapper_test.cpp b/services/inputflinger/tests/SwitchInputMapper_test.cpp
index 4020e78701..ebbf10b8db 100644
--- a/services/inputflinger/tests/SwitchInputMapper_test.cpp
+++ b/services/inputflinger/tests/SwitchInputMapper_test.cpp
@@ -33,7 +33,6 @@ class SwitchInputMapperTest : public InputMapperUnitTest {
protected:
void SetUp() override {
InputMapperUnitTest::SetUp();
- createDevice();
mMapper = createInputMapper<SwitchInputMapper>(*mDeviceContext,
mFakePolicy->getReaderConfiguration());
}
diff --git a/services/inputflinger/tests/TouchpadInputMapper_test.cpp b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
index 1afb4f090a..fc8a7dafb0 100644
--- a/services/inputflinger/tests/TouchpadInputMapper_test.cpp
+++ b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
@@ -109,7 +109,6 @@ protected:
.WillRepeatedly([]() -> base::Result<std::vector<int32_t>> {
return base::ResultError("Axis not supported", NAME_NOT_FOUND);
});
- createDevice();
mMapper = createInputMapper<TouchpadInputMapper>(*mDeviceContext, mReaderConfiguration);
}
};
diff --git a/services/inputflinger/tests/VibratorInputMapper_test.cpp b/services/inputflinger/tests/VibratorInputMapper_test.cpp
index aa4a6bb382..6e3344c345 100644
--- a/services/inputflinger/tests/VibratorInputMapper_test.cpp
+++ b/services/inputflinger/tests/VibratorInputMapper_test.cpp
@@ -36,7 +36,6 @@ class VibratorInputMapperTest : public InputMapperUnitTest {
protected:
void SetUp() override {
InputMapperUnitTest::SetUp();
- createDevice();
EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
.WillRepeatedly(testing::Return(InputDeviceClass::VIBRATOR));
EXPECT_CALL(mMockEventHub, getVibratorIds(EVENTHUB_ID))