diff options
author | 2025-01-24 15:24:27 -0800 | |
---|---|---|
committer | 2025-01-29 13:38:28 -0800 | |
commit | e7ffef74e0b965e4d0240bc9b3809cdc10785361 (patch) | |
tree | a4b53a0baffc2fe792431e7d67f885086600c32c | |
parent | 07978260d95c59b6fab022650ddd7162ff35a84b (diff) |
Move external MultiTouch test into InputMapperUnitTest
This test is broken because it relies on an incorrect ACTION_CANCEL
event being generated. Move this test over to the new
InputMapperUnitTest infra before fixing it in subsequent CLs.
Bug: 378308551
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Flag: TEST_ONLY
Change-Id: I016fb66f7fcbe957cd5b6e8ca86513cb8c372cd3
-rw-r--r-- | include/input/PrintTools.h | 15 | ||||
-rw-r--r-- | libs/input/InputConsumerNoResampling.cpp | 1 | ||||
-rw-r--r-- | services/inputflinger/NotifyArgs.cpp | 5 | ||||
-rw-r--r-- | services/inputflinger/PreferStylusOverTouchBlocker.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/UnwantedInteractionBlocker.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/include/NotifyArgs.h | 2 | ||||
-rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 35 | ||||
-rw-r--r-- | services/inputflinger/tests/LatencyTracker_test.cpp | 5 | ||||
-rw-r--r-- | services/inputflinger/tests/MultiTouchInputMapper_test.cpp | 81 | ||||
-rw-r--r-- | services/inputflinger/tests/TestEventMatchers.h | 12 |
11 files changed, 109 insertions, 61 deletions
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h index 3470be4dce..71c215f723 100644 --- a/include/input/PrintTools.h +++ b/include/input/PrintTools.h @@ -19,13 +19,18 @@ #include <bitset> #include <map> #include <optional> -#include <set> +#include <ranges> #include <sstream> #include <string> #include <vector> namespace android { +namespace internal { +template <typename T> +concept Container = std::ranges::range<T>; +} + template <size_t N> std::string bitsetToString(const std::bitset<N>& bitset) { if (bitset.none()) { @@ -72,10 +77,12 @@ inline std::string toString(const std::optional<T>& optional, /** * Convert a set of integral types to string. */ -template <typename T> -std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) { +template <internal::Container T> +std::string dumpContainer( + const T& container, + std::string (*toString)(const std::ranges::range_value_t<T>&) = constToString) { std::string out; - for (const T& entry : v) { + for (const auto& entry : container) { out += out.empty() ? "{" : ", "; out += toString(entry); } diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp index cd8582182a..6087461f6c 100644 --- a/libs/input/InputConsumerNoResampling.cpp +++ b/libs/input/InputConsumerNoResampling.cpp @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_INPUT #include <inttypes.h> +#include <set> #include <android-base/logging.h> #include <android-base/properties.h> diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp index b2680a2139..3de639f36c 100644 --- a/services/inputflinger/NotifyArgs.cpp +++ b/services/inputflinger/NotifyArgs.cpp @@ -206,4 +206,9 @@ const char* toString(const NotifyArgs& args) { return std::visit(toStringVisitor, args); } +std::ostream& operator<<(std::ostream& out, const NotifyArgs& args) { + out << toString(args); + return out; +} + } // namespace android diff --git a/services/inputflinger/PreferStylusOverTouchBlocker.cpp b/services/inputflinger/PreferStylusOverTouchBlocker.cpp index d9d0450148..6864947615 100644 --- a/services/inputflinger/PreferStylusOverTouchBlocker.cpp +++ b/services/inputflinger/PreferStylusOverTouchBlocker.cpp @@ -216,10 +216,10 @@ static std::string dumpArgs(const NotifyMotionArgs& args) { std::string PreferStylusOverTouchBlocker::dump() const { std::string out; - out += "mActiveStyli: " + dumpSet(mActiveStyli) + "\n"; + out += "mActiveStyli: " + dumpContainer(mActiveStyli) + "\n"; out += "mLastTouchEvents: " + dumpMap(mLastTouchEvents, constToString, dumpArgs) + "\n"; - out += "mDevicesWithMixedToolType: " + dumpSet(mDevicesWithMixedToolType) + "\n"; - out += "mCanceledDevices: " + dumpSet(mCanceledDevices) + "\n"; + out += "mDevicesWithMixedToolType: " + dumpContainer(mDevicesWithMixedToolType) + "\n"; + out += "mCanceledDevices: " + dumpContainer(mCanceledDevices) + "\n"; return out; } diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp index 0e9ec914b7..29de635a40 100644 --- a/services/inputflinger/UnwantedInteractionBlocker.cpp +++ b/services/inputflinger/UnwantedInteractionBlocker.cpp @@ -727,7 +727,7 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs if (!std::includes(oldSuppressedIds.begin(), oldSuppressedIds.end(), mSuppressedPointerIds.begin(), mSuppressedPointerIds.end())) { ALOGI("Palm detected, removing pointer ids %s after %" PRId64 "ms from %s", - dumpSet(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime), + dumpContainer(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime), args.dump().c_str()); } @@ -748,7 +748,7 @@ std::string PalmRejector::dump() const { out += "mSlotState:\n"; out += addLinePrefix(mSlotState.dump(), " "); out += "mSuppressedPointerIds: "; - out += dumpSet(mSuppressedPointerIds) + "\n"; + out += dumpContainer(mSuppressedPointerIds) + "\n"; std::stringstream state; state << *mSharedPalmState; out += "mSharedPalmState: " + state.str() + "\n"; diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index beb4c924de..0412dc5aba 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -5802,8 +5802,8 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s } std::set<DeviceId> deviceIds = touchedWindow->getTouchingDeviceIds(); if (deviceIds.size() != 1) { - LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds) - << " for window: " << touchedWindow->dump(); + LOG(INFO) << "Can't transfer touch. Currently touching devices: " + << dumpContainer(deviceIds) << " for window: " << touchedWindow->dump(); return false; } const DeviceId deviceId = *deviceIds.begin(); diff --git a/services/inputflinger/include/NotifyArgs.h b/services/inputflinger/include/NotifyArgs.h index 14487fe04e..c513bfcf50 100644 --- a/services/inputflinger/include/NotifyArgs.h +++ b/services/inputflinger/include/NotifyArgs.h @@ -225,4 +225,6 @@ using NotifyArgs = const char* toString(const NotifyArgs& args); +std::ostream& operator<<(std::ostream& out, const NotifyArgs& args); + } // namespace android diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index a8e4736aea..d9a75a5309 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -8441,41 +8441,6 @@ TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) { WithToolType(ToolType::STYLUS)))); } -// --- MultiTouchInputMapperTest_ExternalDevice --- - -class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest { -protected: - void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); } -}; - -/** - * Expect fallback to internal viewport if device is external and external viewport is not present. - */ -TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) { - prepareAxes(POSITION); - addConfigurationProperty("touch.deviceType", "touchScreen"); - prepareDisplay(ui::ROTATION_0); - MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); - - ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources()); - - NotifyMotionArgs motionArgs; - - // Expect the event to be sent to the internal viewport, - // because an external viewport is not present. - processPosition(mapper, 100, 100); - processSync(mapper); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); - ASSERT_EQ(ui::LogicalDisplayId::DEFAULT, motionArgs.displayId); - - // Expect the event to be sent to the external viewport if it is present. - prepareSecondaryDisplay(ViewportType::EXTERNAL); - processPosition(mapper, 100, 100); - processSync(mapper); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); - ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId); -} - // TODO(b/281840344): Remove the test when the old touchpad stack is removed. It is currently // unclear what the behavior of the touchpad logic in TouchInputMapper should do after the // PointerChoreographer refactor. diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp index 1cfaaa8418..d8c5eac3c4 100644 --- a/services/inputflinger/tests/LatencyTracker_test.cpp +++ b/services/inputflinger/tests/LatencyTracker_test.cpp @@ -80,8 +80,9 @@ bool timelinesAreEqual(const InputEventTimeline& received, const InputEventTimel << "Received timeline with productId=" << received.productId << " instead of expected productId=" << expected.productId; LOG_IF(ERROR, expected.sources != received.sources) - << "Received timeline with sources=" << dumpSet(received.sources, ftl::enum_string) - << " instead of expected sources=" << dumpSet(expected.sources, ftl::enum_string); + << "Received timeline with sources=" + << dumpContainer(received.sources, ftl::enum_string) + << " instead of expected sources=" << dumpContainer(expected.sources, ftl::enum_string); LOG_IF(ERROR, expected.inputEventActionType != received.inputEventActionType) << "Received timeline with inputEventActionType=" << ftl::enum_string(received.inputEventActionType) diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp index b7cb348236..e8cca5f979 100644 --- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp +++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp @@ -37,17 +37,30 @@ using testing::Return; using testing::SetArgPointee; using testing::VariantWith; -static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT; -static constexpr int32_t DISPLAY_WIDTH = 480; -static constexpr int32_t DISPLAY_HEIGHT = 800; -static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified -static constexpr int32_t SLOT_COUNT = 5; - -static constexpr int32_t ACTION_POINTER_0_UP = +namespace { + +constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT; +constexpr ui::LogicalDisplayId SECOND_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val() + 1}; +constexpr int32_t DISPLAY_WIDTH = 480; +constexpr int32_t DISPLAY_HEIGHT = 800; +constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified +constexpr int32_t SLOT_COUNT = 5; + +constexpr int32_t ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN; +constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL; +constexpr int32_t ACTION_POINTER_0_UP = AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); -static constexpr int32_t ACTION_POINTER_1_DOWN = +constexpr int32_t ACTION_POINTER_1_DOWN = AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); +template <typename... Args> +void assertNotifyArgs(const std::list<NotifyArgs>& args, Args... matchers) { + ASSERT_THAT(args, ElementsAre(matchers...)) + << "Got instead: " << dumpContainer(args, streamableToString); +} + +} // namespace + /** * Unit tests for MultiTouchInputMapper. */ @@ -270,6 +283,58 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) { VariantWith<NotifyMotionArgs>(WithMotionAction(AMOTION_EVENT_ACTION_UP)))); } +class ExternalMultiTouchInputMapperTest : public MultiTouchInputMapperUnitTest { +protected: + void SetUp() override { MultiTouchInputMapperUnitTest::SetUp(/*bus=*/0, /*isExternal=*/true); } +}; + +/** + * Expect fallback to internal viewport if device is external and external viewport is not present. + */ +TEST_F(ExternalMultiTouchInputMapperTest, Viewports_Fallback) { + std::list<NotifyArgs> args; + + // Expect the event to be sent to the internal viewport, + // because an external viewport is not present. + args += processKey(BTN_TOUCH, 1); + args += processId(1); + args += processPosition(100, 200); + args += processSync(); + + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID)))); + + // Expect the event to be sent to the external viewport if it is present. + DisplayViewport externalViewport = + createViewport(SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:1", NO_PORT, ViewportType::EXTERNAL); + mFakePolicy->addDisplayViewport(externalViewport); + std::optional<DisplayViewport> internalViewport = + mFakePolicy->getDisplayViewportByUniqueId("local:0"); + mReaderConfiguration.setDisplayViewports({*internalViewport, externalViewport}); + args = mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration, + InputReaderConfiguration::Change::DISPLAY_INFO); + + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_CANCEL), + WithDisplayId(SECOND_DISPLAY_ID))), + VariantWith<NotifyDeviceResetArgs>(WithDeviceId(DEVICE_ID))); + // Lift up the old pointer. + processKey(BTN_TOUCH, 0); + args = processId(-1); + args += processSync(); + + // Send new pointer + args += processKey(BTN_TOUCH, 1); + args += processId(2); + args += processPosition(111, 211); + args += processSync(); + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_DOWN), + WithDisplayId(SECOND_DISPLAY_ID)))); +} + class MultiTouchInputMapperPointerModeUnitTest : public MultiTouchInputMapperUnitTest { protected: void SetUp() override { diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h index 7fb8895719..65bc278549 100644 --- a/services/inputflinger/tests/TestEventMatchers.h +++ b/services/inputflinger/tests/TestEventMatchers.h @@ -505,8 +505,8 @@ public: } if (mPointerIds != actualPointerIds) { - *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got " - << dumpSet(actualPointerIds); + *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got " + << dumpContainer(actualPointerIds); return false; } return true; @@ -519,14 +519,16 @@ public: } if (mPointerIds != actualPointerIds) { - *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got " - << dumpSet(actualPointerIds); + *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got " + << dumpContainer(actualPointerIds); return false; } return true; } - void DescribeTo(std::ostream* os) const { *os << "with pointer ids " << dumpSet(mPointerIds); } + void DescribeTo(std::ostream* os) const { + *os << "with pointer ids " << dumpContainer(mPointerIds); + } void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer ids"; } |