InputTracer: Create tracker for tracing synthetic events
Allow the creation of a trace tracker for a synthetic event that does
not stem from an inbound input event. This is used for any dispatching
cycle that has a non-input event root, such as ANR timers, window
removals, API interactions (e.g. pilfer pointers), etc.
Any key or motion events generated for this synthetic event should be
traced as a derived event. We achieve this by passing the trace tracker
through the dispatching pipeline, and tracing all of the synthesized
events for that root using the same tracker.
Since all synthetic events can now be traced, we can now enforce that
all dispatched events have been previously traced as either an inbound
or derived event. This makes the event cookie non-nullable.
Bug: 210460522
Test: atest inputflinger_tests
Change-Id: I3417aee300edc251e2f7cb76c1f719502a5f5b8b
diff --git a/services/inputflinger/dispatcher/trace/InputTracer.cpp b/services/inputflinger/dispatcher/trace/InputTracer.cpp
index d16cbf7..83ed452 100644
--- a/services/inputflinger/dispatcher/trace/InputTracer.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracer.cpp
@@ -65,6 +65,10 @@
event);
}
+inline auto getId(const trace::TracedEvent& v) {
+ return std::visit([](const auto& event) { return event.id; }, v);
+}
+
} // namespace
// --- InputTracer ---
@@ -89,6 +93,12 @@
return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/false);
}
+std::unique_ptr<EventTrackerInterface> InputTracer::createTrackerForSyntheticEvent() {
+ // Create a new EventState to track events derived from this tracker.
+ return std::make_unique<EventTrackerImpl>(std::make_shared<EventState>(*this),
+ /*isDerived=*/false);
+}
+
void InputTracer::dispatchToTargetHint(const EventTrackerInterface& cookie,
const InputTarget& target) {
if (isDerivedCookie(cookie)) {
@@ -140,7 +150,8 @@
}
void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry,
- const EventTrackerInterface* cookie) {
+ const EventTrackerInterface& cookie) {
+ auto& eventState = getState(cookie);
const EventEntry& entry = *dispatchEntry.eventEntry;
// TODO(b/328618922): Remove resolved key repeats after making repeatCount non-mutable.
// The KeyEntry's repeatCount is mutable and can be modified after an event is initially traced,
@@ -159,9 +170,13 @@
LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
}
- if (!cookie) {
- // This event was not tracked as an inbound event, so trace it now.
- writeEventToBackend(traced, *mBackend);
+ auto tracedEventIt =
+ std::find_if(eventState->events.begin(), eventState->events.end(),
+ [&traced](const auto& event) { return getId(traced) == getId(event); });
+ if (tracedEventIt == eventState->events.end()) {
+ LOG(FATAL)
+ << __func__
+ << ": Failed to find a previously traced event that matches the dispatched event";
}
// The vsyncId only has meaning if the event is targeting a window.