Fully delete duplicate entries inside LatencyTracker
Inside LatencyTracker, we use 2 collections that must always be in sync:
mTimelines and mEventTimes.
However, when duplicate input events are encountered, we do not treat
these collections equally. In one of them, we fully remove all data
associated with the duplicate inputEventId. In the other one, however,
we only remove the entry that matches both the inputEventId and the
eventTime. This means that the two collections will get out of sync,
because the entry with the mismatching eventTime will be kept in
mEventTimes.
To fix this, fully remove all entries with the duplicate inputEventId,
no matter what the eventTime is. Unfortunately, it means that we have to
traverse the entire collection of mEventTimes. However, since this event
should not occur often, it should not impact performance.
This issue was discovered via the use of the newly added fuzzer for
LatencyTracker. The fuzzer would hit this condition in about 2 seconds
after the run has started. This issue could have been identified the
fuzzer was in place from the start.
The removal of api 'reportNow':
The api 'reportNow' was added for convenience of writing tests. However,
this api has reduced the code coverage, since we would now short-circuit
the code around 'trackListener' that was responsible for event
reporting. This is why, when the issue was first being worked on, the
tests for duplicate events did not yield any crashes. To avoid such
problems in the future, fully remove this api and replace with a
'triggerEventReporting' method that's defined in the tests. This way,
the api's that are used by production code and by tests are identical.
Bug: 169866723
Test: m inputflinger_latencytracker_fuzzer && adb sync data && adb shell /data/fuzz/arm64/inputflinger_latencytracker_fuzzer/inputflinger_latencytracker_fuzzer
Test: atest inputflinger_tests:LatencyTrackerTest
Change-Id: I04069cf2c9eb1154e3324b25c8c4bdff32d84d3f
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index 289b8ed..4b0c618 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -43,6 +43,12 @@
LatencyTracker(InputEventTimelineProcessor* processor);
/**
* Start keeping track of an event identified by inputEventId. This must be called first.
+ * If duplicate events are encountered (events that have the same eventId), none of them will be
+ * tracked. This is because there is not enough information to correctly track them. The api's
+ * 'trackFinishedEvent' and 'trackGraphicsLatency' only contain the inputEventId, and not the
+ * eventTime. Even if eventTime was provided, there would still be a possibility of having
+ * duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
+ * must drop all duplicate data.
*/
void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime);
void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
@@ -50,14 +56,6 @@
void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
- /**
- * Report all collected events immediately, even if some of them are currently incomplete
- * and may receive 'trackFinishedEvent' or 'trackGraphicsLatency' calls in the future.
- * This is useful for tests. Otherwise, tests would have to inject additional "future" events,
- * which is not convenient.
- */
- void reportNow();
-
std::string dump(const char* prefix);
private: