diff options
| -rw-r--r-- | services/inputflinger/tests/Android.bp | 1 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputMapperTest.cpp | 176 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputMapperTest.h | 95 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 193 | ||||
| -rw-r--r-- | services/inputflinger/tests/TestConstants.h | 3 |
5 files changed, 276 insertions, 192 deletions
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index 2a8b359837..53d821f197 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -44,6 +44,7 @@ cc_test { "FakeInputReaderPolicy.cpp", "FakePointerController.cpp", "FocusResolver_test.cpp", + "InputMapperTest.cpp", "InputProcessor_test.cpp", "InputProcessorConverter_test.cpp", "InputDispatcher_test.cpp", diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp new file mode 100644 index 0000000000..3cd7c1b0f2 --- /dev/null +++ b/services/inputflinger/tests/InputMapperTest.cpp @@ -0,0 +1,176 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InputMapperTest.h" + +#include <InputReaderBase.h> +#include <gtest/gtest.h> +#include <ui/Rotation.h> + +namespace android { + +const char* InputMapperTest::DEVICE_NAME = "device"; +const char* InputMapperTest::DEVICE_LOCATION = "USB1"; +const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES = + ftl::Flags<InputDeviceClass>(0); // not needed for current tests + +void InputMapperTest::SetUp(ftl::Flags<InputDeviceClass> classes, int bus) { + mFakeEventHub = std::make_unique<FakeEventHub>(); + mFakePolicy = sp<FakeInputReaderPolicy>::make(); + mFakeListener = std::make_unique<TestInputListener>(); + mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy, *mFakeListener); + mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus); + // Consume the device reset notification generated when adding a new device. + mFakeListener->assertNotifyDeviceResetWasCalled(); +} + +void InputMapperTest::SetUp() { + SetUp(DEVICE_CLASSES); +} + +void InputMapperTest::TearDown() { + mFakeListener.reset(); + mFakePolicy.clear(); +} + +void InputMapperTest::addConfigurationProperty(const char* key, const char* value) { + mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value); +} + +std::list<NotifyArgs> InputMapperTest::configureDevice(uint32_t changes) { + if (!changes || + (changes & + (InputReaderConfiguration::CHANGE_DISPLAY_INFO | + InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) { + mReader->requestRefreshConfiguration(changes); + mReader->loopOnce(); + } + std::list<NotifyArgs> out = + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes); + // Loop the reader to flush the input listener queue. + for (const NotifyArgs& args : out) { + mFakeListener->notify(args); + } + mReader->loopOnce(); + return out; +} + +std::shared_ptr<InputDevice> InputMapperTest::newDevice(int32_t deviceId, const std::string& name, + const std::string& location, + int32_t eventHubId, + ftl::Flags<InputDeviceClass> classes, + int bus) { + InputDeviceIdentifier identifier; + identifier.name = name; + identifier.location = location; + identifier.bus = bus; + std::shared_ptr<InputDevice> device = + std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION, + identifier); + mReader->pushNextDevice(device); + mFakeEventHub->addDevice(eventHubId, name, classes, bus); + mReader->loopOnce(); + return device; +} + +void InputMapperTest::setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, + ui::Rotation orientation, + const std::string& uniqueId, + std::optional<uint8_t> physicalPort, + ViewportType viewportType) { + mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /* isActive= */ true, + uniqueId, physicalPort, viewportType); + configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); +} + +void InputMapperTest::clearViewports() { + mFakePolicy->clearViewports(); +} + +std::list<NotifyArgs> InputMapperTest::process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, + int32_t type, int32_t code, int32_t value) { + RawEvent event; + event.when = when; + event.readTime = readTime; + event.deviceId = mapper.getDeviceContext().getEventHubId(); + event.type = type; + event.code = code; + event.value = value; + std::list<NotifyArgs> processArgList = mapper.process(&event); + for (const NotifyArgs& args : processArgList) { + mFakeListener->notify(args); + } + // Loop the reader to flush the input listener queue. + mReader->loopOnce(); + return processArgList; +} + +void InputMapperTest::resetMapper(InputMapper& mapper, nsecs_t when) { + const auto resetArgs = mapper.reset(when); + for (const auto args : resetArgs) { + mFakeListener->notify(args); + } + // Loop the reader to flush the input listener queue. + mReader->loopOnce(); +} + +std::list<NotifyArgs> InputMapperTest::handleTimeout(InputMapper& mapper, nsecs_t when) { + std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when); + for (const NotifyArgs& args : generatedArgs) { + mFakeListener->notify(args); + } + // Loop the reader to flush the input listener queue. + mReader->loopOnce(); + return generatedArgs; +} + +void InputMapperTest::assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source, + float min, float max, float flat, float fuzz) { + const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source); + ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source; + ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source; + ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source; + ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source; + ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source; + ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source; + ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source; +} + +void InputMapperTest::assertPointerCoords(const PointerCoords& coords, float x, float y, + float pressure, float size, float touchMajor, + float touchMinor, float toolMajor, float toolMinor, + float orientation, float distance, + float scaledAxisEpsilon) { + ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon); + ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon); + ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON); + ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON); + ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), scaledAxisEpsilon); + ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), scaledAxisEpsilon); + ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), scaledAxisEpsilon); + ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), scaledAxisEpsilon); + ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON); + ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON); +} + +void InputMapperTest::assertPosition(const FakePointerController& controller, float x, float y) { + float actualX, actualY; + controller.getPosition(&actualX, &actualY); + ASSERT_NEAR(x, actualX, 1); + ASSERT_NEAR(y, actualY, 1); +} + +} // namespace android diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h new file mode 100644 index 0000000000..b3401c37e2 --- /dev/null +++ b/services/inputflinger/tests/InputMapperTest.h @@ -0,0 +1,95 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <list> +#include <memory> + +#include <InputDevice.h> +#include <InputMapper.h> +#include <NotifyArgs.h> +#include <ftl/flags.h> +#include <utils/StrongPointer.h> + +#include "FakeEventHub.h" +#include "FakeInputReaderPolicy.h" +#include "InstrumentedInputReader.h" +#include "TestConstants.h" +#include "TestInputListener.h" + +namespace android { + +class InputMapperTest : public testing::Test { +protected: + static const char* DEVICE_NAME; + static const char* DEVICE_LOCATION; + static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000; + static constexpr int32_t DEVICE_GENERATION = 2; + static constexpr int32_t DEVICE_CONTROLLER_NUMBER = 0; + static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES; + static constexpr int32_t EVENTHUB_ID = 1; + + std::shared_ptr<FakeEventHub> mFakeEventHub; + sp<FakeInputReaderPolicy> mFakePolicy; + std::unique_ptr<TestInputListener> mFakeListener; + std::unique_ptr<InstrumentedInputReader> mReader; + std::shared_ptr<InputDevice> mDevice; + + virtual void SetUp(ftl::Flags<InputDeviceClass> classes, int bus = 0); + void SetUp() override; + void TearDown() override; + + void addConfigurationProperty(const char* key, const char* value); + std::list<NotifyArgs> configureDevice(uint32_t changes); + std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name, + const std::string& location, int32_t eventHubId, + ftl::Flags<InputDeviceClass> classes, int bus = 0); + template <class T, typename... Args> + T& addMapperAndConfigure(Args... args) { + T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...); + configureDevice(0); + std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME); + resetArgList += mapper.reset(ARBITRARY_TIME); + // Loop the reader to flush the input listener queue. + for (const NotifyArgs& loopArgs : resetArgList) { + mFakeListener->notify(loopArgs); + } + mReader->loopOnce(); + return mapper; + } + + void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, + ui::Rotation orientation, const std::string& uniqueId, + std::optional<uint8_t> physicalPort, + ViewportType viewportType); + void clearViewports(); + std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type, + int32_t code, int32_t value); + void resetMapper(InputMapper& mapper, nsecs_t when); + + std::list<NotifyArgs> handleTimeout(InputMapper& mapper, nsecs_t when); + + static void assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source, + float min, float max, float flat, float fuzz); + static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure, + float size, float touchMajor, float touchMinor, float toolMajor, + float toolMinor, float orientation, float distance, + float scaledAxisEpsilon = 1.f); + static void assertPosition(const FakePointerController& controller, float x, float y); +}; + +} // namespace android diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 58f1e1e035..eef56902c7 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -45,6 +45,7 @@ #include "FakeEventHub.h" #include "FakeInputReaderPolicy.h" #include "FakePointerController.h" +#include "InputMapperTest.h" #include "InstrumentedInputReader.h" #include "TestConstants.h" #include "android/hardware/input/InputDeviceCountryCode.h" @@ -92,9 +93,6 @@ static constexpr int32_t ACTION_POINTER_1_DOWN = static constexpr int32_t ACTION_POINTER_1_UP = AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); -// Error tolerance for floating point assertions. -static const float EPSILON = 0.001f; - // Minimum timestamp separation between subsequent input events from a Bluetooth device. static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4); // Maximum smoothing time delta so that we don't generate events too far into the future. @@ -2507,195 +2505,6 @@ TEST_F(InputDeviceTest, GetBluetoothAddress) { ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address); } -// --- InputMapperTest --- - -class InputMapperTest : public testing::Test { -protected: - static const char* DEVICE_NAME; - static const char* DEVICE_LOCATION; - static const int32_t DEVICE_ID; - static const int32_t DEVICE_GENERATION; - static const int32_t DEVICE_CONTROLLER_NUMBER; - static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES; - static const int32_t EVENTHUB_ID; - - std::shared_ptr<FakeEventHub> mFakeEventHub; - sp<FakeInputReaderPolicy> mFakePolicy; - std::unique_ptr<TestInputListener> mFakeListener; - std::unique_ptr<InstrumentedInputReader> mReader; - std::shared_ptr<InputDevice> mDevice; - - virtual void SetUp(ftl::Flags<InputDeviceClass> classes, int bus = 0) { - mFakeEventHub = std::make_unique<FakeEventHub>(); - mFakePolicy = sp<FakeInputReaderPolicy>::make(); - mFakeListener = std::make_unique<TestInputListener>(); - mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy, - *mFakeListener); - mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus); - // Consume the device reset notification generated when adding a new device. - mFakeListener->assertNotifyDeviceResetWasCalled(); - } - - void SetUp() override { - SetUp(DEVICE_CLASSES); - } - - void TearDown() override { - mFakeListener.reset(); - mFakePolicy.clear(); - } - - void addConfigurationProperty(const char* key, const char* value) { - mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value); - } - - std::list<NotifyArgs> configureDevice(uint32_t changes) { - if (!changes || - (changes & - (InputReaderConfiguration::CHANGE_DISPLAY_INFO | - InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) { - mReader->requestRefreshConfiguration(changes); - mReader->loopOnce(); - } - std::list<NotifyArgs> out = - mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes); - // Loop the reader to flush the input listener queue. - for (const NotifyArgs& args : out) { - mFakeListener->notify(args); - } - mReader->loopOnce(); - return out; - } - - std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name, - const std::string& location, int32_t eventHubId, - ftl::Flags<InputDeviceClass> classes, int bus = 0) { - InputDeviceIdentifier identifier; - identifier.name = name; - identifier.location = location; - identifier.bus = bus; - std::shared_ptr<InputDevice> device = - std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION, - identifier); - mReader->pushNextDevice(device); - mFakeEventHub->addDevice(eventHubId, name, classes, bus); - mReader->loopOnce(); - return device; - } - - template <class T, typename... Args> - T& addMapperAndConfigure(Args... args) { - T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...); - configureDevice(0); - std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME); - resetArgList += mapper.reset(ARBITRARY_TIME); - // Loop the reader to flush the input listener queue. - for (const NotifyArgs& loopArgs : resetArgList) { - mFakeListener->notify(loopArgs); - } - mReader->loopOnce(); - return mapper; - } - - void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, - ui::Rotation orientation, const std::string& uniqueId, - std::optional<uint8_t> physicalPort, - ViewportType viewportType) { - mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/, - uniqueId, physicalPort, viewportType); - configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); - } - - void clearViewports() { - mFakePolicy->clearViewports(); - } - - std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type, - int32_t code, int32_t value) { - RawEvent event; - event.when = when; - event.readTime = readTime; - event.deviceId = mapper.getDeviceContext().getEventHubId(); - event.type = type; - event.code = code; - event.value = value; - std::list<NotifyArgs> processArgList = mapper.process(&event); - for (const NotifyArgs& args : processArgList) { - mFakeListener->notify(args); - } - // Loop the reader to flush the input listener queue. - mReader->loopOnce(); - return processArgList; - } - - void resetMapper(InputMapper& mapper, nsecs_t when) { - const auto resetArgs = mapper.reset(when); - for (const auto& args : resetArgs) { - mFakeListener->notify(args); - } - // Loop the reader to flush the input listener queue. - mReader->loopOnce(); - } - - std::list<NotifyArgs> handleTimeout(InputMapper& mapper, nsecs_t when) { - std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when); - for (const NotifyArgs& args : generatedArgs) { - mFakeListener->notify(args); - } - // Loop the reader to flush the input listener queue. - mReader->loopOnce(); - return generatedArgs; - } - - static void assertMotionRange(const InputDeviceInfo& info, - int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) { - const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source); - ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source; - ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source; - ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source; - ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source; - ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source; - ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source; - ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source; - } - - static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure, - float size, float touchMajor, float touchMinor, float toolMajor, - float toolMinor, float orientation, float distance, - float scaledAxisEpsilon = 1.f) { - ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon); - ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon); - ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON); - ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON); - ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), - scaledAxisEpsilon); - ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), - scaledAxisEpsilon); - ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), - scaledAxisEpsilon); - ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), - scaledAxisEpsilon); - ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON); - ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON); - } - - static void assertPosition(const FakePointerController& controller, float x, float y) { - float actualX, actualY; - controller.getPosition(&actualX, &actualY); - ASSERT_NEAR(x, actualX, 1); - ASSERT_NEAR(y, actualY, 1); - } -}; - -const char* InputMapperTest::DEVICE_NAME = "device"; -const char* InputMapperTest::DEVICE_LOCATION = "USB1"; -const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000; -const int32_t InputMapperTest::DEVICE_GENERATION = 2; -const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0; -const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES = - ftl::Flags<InputDeviceClass>(0); // not needed for current tests -const int32_t InputMapperTest::EVENTHUB_ID = 1; - // --- SwitchInputMapperTest --- class SwitchInputMapperTest : public InputMapperTest { diff --git a/services/inputflinger/tests/TestConstants.h b/services/inputflinger/tests/TestConstants.h index 8dc9d71392..27881f6f49 100644 --- a/services/inputflinger/tests/TestConstants.h +++ b/services/inputflinger/tests/TestConstants.h @@ -27,4 +27,7 @@ static constexpr std::chrono::duration WAIT_TIMEOUT = 100ms; static constexpr nsecs_t ARBITRARY_TIME = 1234; static constexpr nsecs_t READ_TIME = 4321; +// Error tolerance for floating point assertions. +static const float EPSILON = 0.001f; + } // namespace android |