Skip to content

Commit 65a071a

Browse files
committed
InputDispatcher_test: Verify all traced events match exactly
Bug: 210460522 Test: atest inputflinger_tests Change-Id: I2ab660ed0a6888c23bc711fb8494385c22b3c404
1 parent 9d5f9ce commit 65a071a

4 files changed

Lines changed: 95 additions & 8 deletions

File tree

include/input/Input.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ static constexpr size_t MAX_POINTERS = 16;
180180
* Declare a concrete type for the NDK's input event forward declaration.
181181
*/
182182
struct AInputEvent {
183-
virtual ~AInputEvent() { }
183+
virtual ~AInputEvent() {}
184+
bool operator==(const AInputEvent&) const = default;
184185
};
185186

186187
/*
@@ -545,6 +546,8 @@ class InputEvent : public AInputEvent {
545546

546547
static int32_t nextId();
547548

549+
bool operator==(const InputEvent&) const = default;
550+
548551
protected:
549552
void initialize(int32_t id, DeviceId deviceId, uint32_t source, int32_t displayId,
550553
std::array<uint8_t, 32> hmac);
@@ -598,6 +601,8 @@ class KeyEvent : public InputEvent {
598601

599602
static const char* actionToString(int32_t action);
600603

604+
bool operator==(const KeyEvent&) const = default;
605+
601606
protected:
602607
int32_t mAction;
603608
int32_t mFlags;
@@ -917,6 +922,9 @@ class MotionEvent : public InputEvent {
917922
// The rounding precision for transformed motion events.
918923
static constexpr float ROUNDING_PRECISION = 0.001f;
919924

925+
bool operator==(const MotionEvent&) const;
926+
inline bool operator!=(const MotionEvent& o) const { return !(*this == o); };
927+
920928
protected:
921929
int32_t mAction;
922930
int32_t mActionButton;

libs/input/Input.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,33 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
10071007
return out;
10081008
}
10091009

1010+
bool MotionEvent::operator==(const android::MotionEvent& o) const {
1011+
// We use NaN values to represent invalid cursor positions. Since NaN values are not equal
1012+
// to themselves according to IEEE 754, we cannot use the default equality operator to compare
1013+
// MotionEvents. Therefore we define a custom equality operator with special handling for NaNs.
1014+
// clang-format off
1015+
return InputEvent::operator==(static_cast<const InputEvent&>(o)) &&
1016+
mAction == o.mAction &&
1017+
mActionButton == o.mActionButton &&
1018+
mFlags == o.mFlags &&
1019+
mEdgeFlags == o.mEdgeFlags &&
1020+
mMetaState == o.mMetaState &&
1021+
mButtonState == o.mButtonState &&
1022+
mClassification == o.mClassification &&
1023+
mTransform == o.mTransform &&
1024+
mXPrecision == o.mXPrecision &&
1025+
mYPrecision == o.mYPrecision &&
1026+
((std::isnan(mRawXCursorPosition) && std::isnan(o.mRawXCursorPosition)) ||
1027+
mRawXCursorPosition == o.mRawXCursorPosition) &&
1028+
((std::isnan(mRawYCursorPosition) && std::isnan(o.mRawYCursorPosition)) ||
1029+
mRawYCursorPosition == o.mRawYCursorPosition) &&
1030+
mRawTransform == o.mRawTransform && mDownTime == o.mDownTime &&
1031+
mPointerProperties == o.mPointerProperties &&
1032+
mSampleEventTimes == o.mSampleEventTimes &&
1033+
mSamplePointerCoords == o.mSamplePointerCoords;
1034+
// clang-format on
1035+
}
1036+
10101037
std::ostream& operator<<(std::ostream& out, const MotionEvent& event) {
10111038
out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction());
10121039
if (event.getActionButton() != 0) {

services/inputflinger/tests/FakeInputTracingBackend.cpp

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,30 @@ inline auto getId(const trace::TracedEvent& v) {
3737
return std::visit([](const auto& event) { return event.id; }, v);
3838
}
3939

40+
MotionEvent toInputEvent(
41+
const trace::TracedMotionEvent& e,
42+
const trace::InputTracingBackendInterface::WindowDispatchArgs& dispatchArgs,
43+
const std::array<uint8_t, 32>& hmac) {
44+
MotionEvent traced;
45+
traced.initialize(e.id, e.deviceId, e.source, e.displayId, hmac, e.action, e.actionButton,
46+
dispatchArgs.resolvedFlags, e.edgeFlags, e.metaState, e.buttonState,
47+
e.classification, dispatchArgs.transform, e.xPrecision, e.yPrecision,
48+
e.xCursorPosition, e.yCursorPosition, dispatchArgs.rawTransform, e.downTime,
49+
e.eventTime, e.pointerProperties.size(), e.pointerProperties.data(),
50+
e.pointerCoords.data());
51+
return traced;
52+
}
53+
54+
KeyEvent toInputEvent(const trace::TracedKeyEvent& e,
55+
const trace::InputTracingBackendInterface::WindowDispatchArgs& dispatchArgs,
56+
const std::array<uint8_t, 32>& hmac) {
57+
KeyEvent traced;
58+
traced.initialize(e.id, e.deviceId, e.source, e.displayId, hmac, e.action,
59+
dispatchArgs.resolvedFlags, e.keyCode, e.scanCode, e.metaState, e.repeatCount,
60+
e.downTime, e.eventTime);
61+
return traced;
62+
}
63+
4064
} // namespace
4165

4266
// --- VerifyingTrace ---
@@ -55,6 +79,7 @@ void VerifyingTrace::verifyExpectedEventsTraced() {
5579
std::unique_lock lock(mLock);
5680
base::ScopedLockAssertion assumeLocked(mLock);
5781

82+
// Poll for all expected events to be traced, and keep track of the latest poll result.
5883
base::Result<void> result;
5984
mEventTracedCondition.wait_for(lock, TRACE_TIMEOUT, [&]() REQUIRES(mLock) {
6085
for (const auto& [expectedEvent, windowId] : mExpectedEvents) {
@@ -101,28 +126,55 @@ base::Result<void> VerifyingTrace::verifyEventTraced(const Event& expectedEvent,
101126
});
102127
if (tracedDispatchesIt == mTracedWindowDispatches.end()) {
103128
msg << "Expected dispatch of event with ID 0x" << std::hex << expectedEvent.getId()
104-
<< " to window with ID 0x" << expectedWindowId << " to be traced, but it was not."
105-
<< "\nExpected event: " << expectedEvent;
129+
<< " to window with ID 0x" << expectedWindowId << " to be traced, but it was not.\n"
130+
<< "Expected event: " << expectedEvent;
106131
return error(msg);
107132
}
108133

109-
return {};
134+
// Verify that the traced event matches the expected event exactly.
135+
return std::visit(
136+
[&](const auto& traced) -> base::Result<void> {
137+
Event tracedEvent;
138+
using T = std::decay_t<decltype(traced)>;
139+
if constexpr (std::is_same_v<Event, MotionEvent> &&
140+
std::is_same_v<T, trace::TracedMotionEvent>) {
141+
tracedEvent =
142+
toInputEvent(traced, *tracedDispatchesIt, expectedEvent.getHmac());
143+
} else if constexpr (std::is_same_v<Event, KeyEvent> &&
144+
std::is_same_v<T, trace::TracedKeyEvent>) {
145+
tracedEvent =
146+
toInputEvent(traced, *tracedDispatchesIt, expectedEvent.getHmac());
147+
} else {
148+
msg << "Received the wrong event type!\n"
149+
<< "Expected event: " << expectedEvent;
150+
return error(msg);
151+
}
152+
153+
const auto result = testing::internal::CmpHelperEQ("expectedEvent", "tracedEvent",
154+
expectedEvent, tracedEvent);
155+
if (!result) {
156+
msg << result.failure_message();
157+
return error(msg);
158+
}
159+
return {};
160+
},
161+
tracedEventsIt->second);
110162
}
111163

112164
// --- FakeInputTracingBackend ---
113165

114166
void FakeInputTracingBackend::traceKeyEvent(const trace::TracedKeyEvent& event) const {
115167
{
116168
std::scoped_lock lock(mTrace->mLock);
117-
mTrace->mTracedEvents.emplace(event.id);
169+
mTrace->mTracedEvents.emplace(event.id, event);
118170
}
119171
mTrace->mEventTracedCondition.notify_all();
120172
}
121173

122174
void FakeInputTracingBackend::traceMotionEvent(const trace::TracedMotionEvent& event) const {
123175
{
124176
std::scoped_lock lock(mTrace->mLock);
125-
mTrace->mTracedEvents.emplace(event.id);
177+
mTrace->mTracedEvents.emplace(event.id, event);
126178
}
127179
mTrace->mEventTracedCondition.notify_all();
128180
}

services/inputflinger/tests/FakeInputTracingBackend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <condition_variable>
2626
#include <memory>
2727
#include <mutex>
28-
#include <unordered_set>
28+
#include <unordered_map>
2929
#include <vector>
3030

3131
namespace android::inputdispatcher {
@@ -58,7 +58,7 @@ class VerifyingTrace {
5858
private:
5959
std::mutex mLock;
6060
std::condition_variable mEventTracedCondition;
61-
std::unordered_set<uint32_t /*eventId*/> mTracedEvents GUARDED_BY(mLock);
61+
std::unordered_map<uint32_t /*eventId*/, trace::TracedEvent> mTracedEvents GUARDED_BY(mLock);
6262
using WindowDispatchArgs = trace::InputTracingBackendInterface::WindowDispatchArgs;
6363
std::vector<WindowDispatchArgs> mTracedWindowDispatches GUARDED_BY(mLock);
6464
std::vector<std::pair<std::variant<KeyEvent, MotionEvent>, int32_t /*windowId*/>>

0 commit comments

Comments
 (0)