Skip to content

Commit 2000746

Browse files
prabirmspCherrypicker Worker
authored andcommitted
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 Bug: 353128452 Test: atest inputflinger_tests Flag: EXEMPT refactor (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:31d05c4c78e7924e4bb6dc45092e612a9c7d5bfb) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:76a4212fb43aa1f6f34e5a03addc5a932defe649) Merged-In: Id7e103e1f04812c92ee8ecfdfe1e75a9949efa9e Change-Id: Id7e103e1f04812c92ee8ecfdfe1e75a9949efa9e
1 parent 4498107 commit 2000746

9 files changed

Lines changed: 84 additions & 35 deletions

services/inputflinger/reader/include/InputDevice.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class InputDevice {
4343
public:
4444
InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
4545
const InputDeviceIdentifier& identifier);
46-
~InputDevice();
46+
virtual ~InputDevice();
4747

4848
inline InputReaderContext* getContext() { return mContext; }
4949
inline int32_t getId() const { return mId; }
@@ -56,7 +56,7 @@ class InputDevice {
5656
}
5757
inline const std::string getLocation() const { return mIdentifier.location; }
5858
inline ftl::Flags<InputDeviceClass> getClasses() const { return mClasses; }
59-
inline uint32_t getSources() const { return mSources; }
59+
inline virtual uint32_t getSources() const { return mSources; }
6060
inline bool hasEventHubDevices() const { return !mDevices.empty(); }
6161

6262
inline bool isExternal() { return mIsExternal; }
@@ -132,7 +132,7 @@ class InputDevice {
132132

133133
[[nodiscard]] NotifyDeviceResetArgs notifyReset(nsecs_t when);
134134

135-
inline const PropertyMap& getConfiguration() { return mConfiguration; }
135+
inline virtual const PropertyMap& getConfiguration() const { return mConfiguration; }
136136
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
137137

138138
std::optional<ui::LogicalDisplayId> getAssociatedDisplayId();

services/inputflinger/tests/CursorInputMapper_test.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ class CursorInputMapperUnitTestBase : public InputMapperUnitTest {
157157
}
158158

159159
void createMapper() {
160-
createDevice();
161160
mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
162161
}
163162

@@ -535,7 +534,6 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldNotRotateMotionsWhenOrientationAw
535534
// need to be rotated.
536535
mPropertyMap.addProperty("cursor.mode", "navigation");
537536
mPropertyMap.addProperty("cursor.orientationAware", "1");
538-
createDevice();
539537
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation90);
540538
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
541539

@@ -553,7 +551,6 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw
553551
// Since InputReader works in the un-rotated coordinate space, only devices that are not
554552
// orientation-aware are affected by display rotation.
555553
mPropertyMap.addProperty("cursor.mode", "navigation");
556-
createDevice();
557554
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation0);
558555
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
559556

@@ -645,7 +642,6 @@ TEST_F(CursorInputMapperUnitTest, ConfigureDisplayIdWithAssociatedViewport) {
645642
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
646643
// Set up the secondary display as the display on which the pointer should be shown.
647644
// The InputDevice is not associated with any display.
648-
createDevice();
649645
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
650646
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
651647

@@ -666,7 +662,6 @@ TEST_F(CursorInputMapperUnitTest,
666662
DisplayViewport secondaryViewport = createSecondaryViewport();
667663
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
668664
// Set up the primary display as the display on which the pointer should be shown.
669-
createDevice();
670665
// Associate the InputDevice with the secondary display.
671666
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
672667
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
@@ -959,7 +954,6 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationWithAsso
959954
mPropertyMap.addProperty("cursor.mode", "pointer");
960955
DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0);
961956
mReaderConfiguration.setDisplayViewports({primaryViewport});
962-
createDevice();
963957
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, primaryViewport);
964958
mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
965959

@@ -997,7 +991,6 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla
997991
mReaderConfiguration.setDisplayViewports({primaryViewport});
998992
// Disable acceleration for the display.
999993
mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID);
1000-
createDevice();
1001994

1002995
// Don't associate the device with the display yet.
1003996
ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID,

services/inputflinger/tests/InputMapperTest.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
namespace android {
2727

2828
using testing::_;
29+
using testing::NiceMock;
2930
using testing::Return;
31+
using testing::ReturnRef;
3032

3133
void InputMapperUnitTest::SetUpWithBus(int bus) {
3234
mFakePolicy = sp<FakeInputReaderPolicy>::make();
@@ -43,16 +45,11 @@ void InputMapperUnitTest::SetUpWithBus(int bus) {
4345
EXPECT_CALL(mMockEventHub, getConfiguration(EVENTHUB_ID)).WillRepeatedly([&](int32_t) {
4446
return mPropertyMap;
4547
});
46-
}
4748

48-
void InputMapperUnitTest::createDevice() {
49-
mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
50-
/*generation=*/2, mIdentifier);
51-
mDevice->addEmptyEventHubDevice(EVENTHUB_ID);
49+
mDevice = std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID,
50+
/*generation=*/2, mIdentifier);
51+
ON_CALL((*mDevice), getConfiguration).WillByDefault(ReturnRef(mPropertyMap));
5252
mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
53-
std::list<NotifyArgs> args =
54-
mDevice->configure(systemTime(), mReaderConfiguration, /*changes=*/{});
55-
ASSERT_THAT(args, testing::ElementsAre(testing::VariantWith<NotifyDeviceResetArgs>(_)));
5653
}
5754

5855
void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,

services/inputflinger/tests/InputMapperTest.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ class InputMapperUnitTest : public testing::Test {
4343
virtual void SetUp() override { SetUpWithBus(0); }
4444
virtual void SetUpWithBus(int bus);
4545

46-
/**
47-
* Initializes mDevice and mDeviceContext. When this happens, mDevice takes a copy of
48-
* mPropertyMap, so tests that need to set configuration properties should do so before calling
49-
* this. Others will most likely want to call it in their SetUp method.
50-
*/
51-
void createDevice();
52-
5346
void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution);
5447

5548
void expectScanCodes(bool present, std::set<int> scanCodes);
@@ -65,7 +58,7 @@ class InputMapperUnitTest : public testing::Test {
6558
MockEventHubInterface mMockEventHub;
6659
sp<FakeInputReaderPolicy> mFakePolicy;
6760
MockInputReaderContext mMockInputReaderContext;
68-
std::unique_ptr<InputDevice> mDevice;
61+
std::unique_ptr<MockInputDevice> mDevice;
6962

7063
std::unique_ptr<InputDeviceContext> mDeviceContext;
7164
InputReaderConfiguration mReaderConfiguration;

services/inputflinger/tests/InterfaceMocks.h

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <vector>
2727

2828
#include <EventHub.h>
29+
#include <InputDevice.h>
2930
#include <InputReaderBase.h>
3031
#include <InputReaderContext.h>
3132
#include <NotifyArgs.h>
@@ -59,7 +60,7 @@ class MockInputReaderContext : public InputReaderContext {
5960
MOCK_METHOD(void, requestTimeoutAtTime, (nsecs_t when), (override));
6061
int32_t bumpGeneration() override { return ++mGeneration; }
6162

62-
MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo> & outDevices),
63+
MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo>& outDevices),
6364
(override));
6465
MOCK_METHOD(std::list<NotifyArgs>, dispatchExternalStylusState, (const StylusState& outState),
6566
(override));
@@ -172,7 +173,7 @@ class MockEventHubInterface : public EventHubInterface {
172173
MOCK_METHOD(void, requestReopenDevices, (), (override));
173174
MOCK_METHOD(void, wake, (), (override));
174175

175-
MOCK_METHOD(void, dump, (std::string & dump), (const, override));
176+
MOCK_METHOD(void, dump, (std::string& dump), (const, override));
176177
MOCK_METHOD(void, monitor, (), (const, override));
177178
MOCK_METHOD(bool, isDeviceEnabled, (int32_t deviceId), (const, override));
178179
MOCK_METHOD(status_t, enableDevice, (int32_t deviceId), (override));
@@ -189,4 +190,75 @@ class MockPointerChoreographerPolicyInterface : public PointerChoreographerPolic
189190
MOCK_METHOD(bool, isInputMethodConnectionActive, (), (override));
190191
};
191192

193+
class MockInputDevice : public InputDevice {
194+
public:
195+
MockInputDevice(InputReaderContext* context, int32_t id, int32_t generation,
196+
const InputDeviceIdentifier& identifier)
197+
: InputDevice(context, id, generation, identifier) {}
198+
199+
MOCK_METHOD(uint32_t, getSources, (), (const, override));
200+
MOCK_METHOD(bool, isEnabled, (), ());
201+
202+
MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ());
203+
MOCK_METHOD(void, addEmptyEventHubDevice, (int32_t eventHubId), ());
204+
MOCK_METHOD(std::list<NotifyArgs>, addEventHubDevice,
205+
(nsecs_t when, int32_t eventHubId, const InputReaderConfiguration& readerConfig),
206+
());
207+
MOCK_METHOD(void, removeEventHubDevice, (int32_t eventHubId), ());
208+
MOCK_METHOD(std::list<NotifyArgs>, configure,
209+
(nsecs_t when, const InputReaderConfiguration& readerConfig,
210+
ConfigurationChanges changes),
211+
());
212+
MOCK_METHOD(std::list<NotifyArgs>, reset, (nsecs_t when), ());
213+
MOCK_METHOD(std::list<NotifyArgs>, process, (const RawEvent* rawEvents, size_t count), ());
214+
MOCK_METHOD(std::list<NotifyArgs>, timeoutExpired, (nsecs_t when), ());
215+
MOCK_METHOD(std::list<NotifyArgs>, updateExternalStylusState, (const StylusState& state), ());
216+
217+
MOCK_METHOD(InputDeviceInfo, getDeviceInfo, (), ());
218+
MOCK_METHOD(int32_t, getKeyCodeState, (uint32_t sourceMask, int32_t keyCode), ());
219+
MOCK_METHOD(int32_t, getScanCodeState, (uint32_t sourceMask, int32_t scanCode), ());
220+
MOCK_METHOD(int32_t, getSwitchState, (uint32_t sourceMask, int32_t switchCode), ());
221+
MOCK_METHOD(int32_t, getKeyCodeForKeyLocation, (int32_t locationKeyCode), (const));
222+
MOCK_METHOD(bool, markSupportedKeyCodes,
223+
(uint32_t sourceMask, const std::vector<int32_t>& keyCodes, uint8_t* outFlags), ());
224+
MOCK_METHOD(std::list<NotifyArgs>, vibrate,
225+
(const VibrationSequence& sequence, ssize_t repeat, int32_t token), ());
226+
MOCK_METHOD(std::list<NotifyArgs>, cancelVibrate, (int32_t token), ());
227+
MOCK_METHOD(bool, isVibrating, (), ());
228+
MOCK_METHOD(std::vector<int32_t>, getVibratorIds, (), ());
229+
MOCK_METHOD(std::list<NotifyArgs>, cancelTouch, (nsecs_t when, nsecs_t readTime), ());
230+
MOCK_METHOD(bool, enableSensor,
231+
(InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod,
232+
std::chrono::microseconds maxBatchReportLatency),
233+
());
234+
235+
MOCK_METHOD(void, disableSensor, (InputDeviceSensorType sensorType), ());
236+
MOCK_METHOD(void, flushSensor, (InputDeviceSensorType sensorType), ());
237+
238+
MOCK_METHOD(std::optional<int32_t>, getBatteryEventHubId, (), (const));
239+
240+
MOCK_METHOD(bool, setLightColor, (int32_t lightId, int32_t color), ());
241+
MOCK_METHOD(bool, setLightPlayerId, (int32_t lightId, int32_t playerId), ());
242+
MOCK_METHOD(std::optional<int32_t>, getLightColor, (int32_t lightId), ());
243+
MOCK_METHOD(std::optional<int32_t>, getLightPlayerId, (int32_t lightId), ());
244+
245+
MOCK_METHOD(int32_t, getMetaState, (), ());
246+
MOCK_METHOD(void, updateMetaState, (int32_t keyCode), ());
247+
248+
MOCK_METHOD(void, addKeyRemapping, (int32_t fromKeyCode, int32_t toKeyCode), ());
249+
250+
MOCK_METHOD(void, setKeyboardType, (KeyboardType keyboardType), ());
251+
252+
MOCK_METHOD(void, bumpGeneration, (), ());
253+
254+
MOCK_METHOD(const PropertyMap&, getConfiguration, (), (const, override));
255+
256+
MOCK_METHOD(NotifyDeviceResetArgs, notifyReset, (nsecs_t when), ());
257+
258+
MOCK_METHOD(std::optional<ui::LogicalDisplayId>, getAssociatedDisplayId, (), ());
259+
260+
MOCK_METHOD(void, updateLedState, (bool reset), ());
261+
262+
MOCK_METHOD(size_t, getMapperCount, (), ());
263+
};
192264
} // namespace android

services/inputflinger/tests/KeyboardInputMapper_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class KeyboardInputMapperUnitTest : public InputMapperUnitTest {
5555

5656
void SetUp() override {
5757
InputMapperUnitTest::SetUp();
58-
createDevice();
5958

6059
// set key-codes expected in tests
6160
for (const auto& [scanCode, outKeycode] : mKeyCodeMap) {

services/inputflinger/tests/MultiTouchInputMapper_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ class MultiTouchInputMapperUnitTest : public InputMapperUnitTest {
112112
mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
113113
/*isActive=*/true, "local:0", NO_PORT,
114114
ViewportType::INTERNAL);
115-
createDevice();
116115
mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext,
117116
mFakePolicy->getReaderConfiguration());
118117
}

services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ class MultiTouchMotionAccumulatorTest : public InputMapperUnitTest {
2323
protected:
2424
static constexpr size_t SLOT_COUNT = 8;
2525

26-
void SetUp() override {
27-
InputMapperUnitTest::SetUp();
28-
createDevice();
29-
}
26+
void SetUp() override { InputMapperUnitTest::SetUp(); }
3027

3128
MultiTouchMotionAccumulator mMotionAccumulator;
3229

services/inputflinger/tests/TouchpadInputMapper_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ class TouchpadInputMapperTest : public InputMapperUnitTest {
112112
.WillRepeatedly([]() -> base::Result<std::vector<int32_t>> {
113113
return base::ResultError("Axis not supported", NAME_NOT_FOUND);
114114
});
115-
createDevice();
116115
mMapper = createInputMapper<TouchpadInputMapper>(*mDeviceContext, mReaderConfiguration);
117116
}
118117
};

0 commit comments

Comments
 (0)