xref: /aosp_15_r20/frameworks/native/services/inputflinger/tests/LatencyTracker_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "../dispatcher/LatencyTracker.h"
18 #include "../InputDeviceMetricsSource.h"
19 #include "NotifyArgsBuilders.h"
20 #include "android/input.h"
21 
22 #include <android-base/logging.h>
23 #include <android-base/properties.h>
24 #include <binder/Binder.h>
25 #include <gtest/gtest.h>
26 #include <input/PrintTools.h>
27 #include <inttypes.h>
28 #include <linux/input.h>
29 #include <log/log.h>
30 
31 #define TAG "LatencyTracker_test"
32 
33 using android::base::HwTimeoutMultiplier;
34 using android::inputdispatcher::InputEventTimeline;
35 using android::inputdispatcher::LatencyTracker;
36 
37 namespace android::inputdispatcher {
38 
39 namespace {
40 
41 constexpr DeviceId DEVICE_ID = 100;
42 
generateTestDeviceInfo(uint16_t vendorId,uint16_t productId,DeviceId deviceId)43 static InputDeviceInfo generateTestDeviceInfo(uint16_t vendorId, uint16_t productId,
44                                               DeviceId deviceId) {
45     InputDeviceIdentifier identifier;
46     identifier.vendor = vendorId;
47     identifier.product = productId;
48     auto info = InputDeviceInfo();
49     info.initialize(deviceId, /*generation=*/1, /*controllerNumber=*/1, identifier, "Test Device",
50                     /*isExternal=*/false, /*hasMic=*/false, ui::LogicalDisplayId::INVALID);
51     return info;
52 }
53 
setDefaultInputDeviceInfo(LatencyTracker & tracker)54 void setDefaultInputDeviceInfo(LatencyTracker& tracker) {
55     InputDeviceInfo deviceInfo = generateTestDeviceInfo(/*vendorId=*/0, /*productId=*/0, DEVICE_ID);
56     tracker.setInputDevices({deviceInfo});
57 }
58 
59 const auto FIRST_TOUCH_POINTER = PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200);
60 
61 /**
62  * This is a convenience method for comparing timelines that also prints the difference between
63  * the two structures. This helps debugging when the timelines don't match.
64  * @param received the timeline that was actually received
65  * @param expected the timeline that we expected to receive
66  * @return true if the two timelines match, false otherwise.
67  */
timelinesAreEqual(const InputEventTimeline & received,const InputEventTimeline & expected)68 bool timelinesAreEqual(const InputEventTimeline& received, const InputEventTimeline& expected) {
69     LOG_IF(ERROR, expected.eventTime != received.eventTime)
70             << "Received timeline with eventTime=" << received.eventTime
71             << " instead of expected eventTime=" << expected.eventTime;
72     LOG_IF(ERROR, expected.readTime != received.readTime)
73             << "Received timeline with readTime=" << received.readTime
74             << " instead of expected readTime=" << expected.readTime;
75     LOG_IF(ERROR, expected.vendorId != received.vendorId)
76             << "Received timeline with vendorId=" << received.vendorId
77             << " instead of expected vendorId=" << expected.vendorId;
78     LOG_IF(ERROR, expected.productId != received.productId)
79             << "Received timeline with productId=" << received.productId
80             << " instead of expected productId=" << expected.productId;
81     LOG_IF(ERROR, expected.sources != received.sources)
82             << "Received timeline with sources=" << dumpSet(received.sources, ftl::enum_string)
83             << " instead of expected sources=" << dumpSet(expected.sources, ftl::enum_string);
84     LOG_IF(ERROR, expected.inputEventActionType != received.inputEventActionType)
85             << "Received timeline with inputEventActionType="
86             << ftl::enum_string(received.inputEventActionType)
87             << " instead of expected inputEventActionType="
88             << ftl::enum_string(expected.inputEventActionType);
89 
90     return received == expected;
91 }
92 
93 } // namespace
94 
95 const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds(
96         android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
97         HwTimeoutMultiplier());
98 
getTestTimeline()99 InputEventTimeline getTestTimeline() {
100     InputEventTimeline t(
101             /*eventTime=*/2,
102             /*readTime=*/3,
103             /*vendorId=*/0,
104             /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
105             /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
106     ConnectionTimeline expectedCT(/*deliveryTime=*/6, /*consumeTime=*/7, /*finishTime=*/8);
107     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline{};
108     graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 9;
109     graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 10;
110     expectedCT.setGraphicsTimeline(graphicsTimeline);
111     t.connectionTimelines.emplace(sp<BBinder>::make(), expectedCT);
112     return t;
113 }
114 
115 // --- LatencyTrackerTest ---
116 class LatencyTrackerTest : public testing::Test, public InputEventTimelineProcessor {
117 protected:
118     std::unique_ptr<LatencyTracker> mTracker;
119     sp<IBinder> connection1;
120     sp<IBinder> connection2;
121 
SetUp()122     void SetUp() override {
123         connection1 = sp<BBinder>::make();
124         connection2 = sp<BBinder>::make();
125 
126         mTracker = std::make_unique<LatencyTracker>(*this);
127         setDefaultInputDeviceInfo(*mTracker);
128     }
TearDown()129     void TearDown() override {}
130 
131     void triggerEventReporting(nsecs_t lastEventTime);
132 
133     void assertReceivedTimeline(const InputEventTimeline& timeline);
134     /**
135      * Timelines can be received in any order (order is not guaranteed). So if we are expecting more
136      * than 1 timeline, use this function to check that the set of received timelines matches
137      * what we expected.
138      */
139     void assertReceivedTimelines(const std::vector<InputEventTimeline>& timelines);
140 
141 private:
processTimeline(const InputEventTimeline & timeline)142     void processTimeline(const InputEventTimeline& timeline) override {
143         mReceivedTimelines.push_back(timeline);
144     }
pushLatencyStatistics()145     void pushLatencyStatistics() override {}
dump(const char * prefix) const146     std::string dump(const char* prefix) const { return ""; };
147     std::deque<InputEventTimeline> mReceivedTimelines;
148 };
149 
150 /**
151  * Send an event that would trigger the reporting of all of the events that are at least as old as
152  * the provided 'lastEventTime'.
153  */
triggerEventReporting(nsecs_t lastEventTime)154 void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) {
155     const nsecs_t triggerEventTime =
156             lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
157     mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
158                                               AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/1)
159                                     .eventTime(triggerEventTime)
160                                     .readTime(3)
161                                     .deviceId(DEVICE_ID)
162                                     .pointer(FIRST_TOUCH_POINTER)
163                                     .build());
164 }
165 
assertReceivedTimeline(const InputEventTimeline & expectedTimeline)166 void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& expectedTimeline) {
167     ASSERT_FALSE(mReceivedTimelines.empty());
168     const InputEventTimeline& received = mReceivedTimelines.front();
169     ASSERT_TRUE(timelinesAreEqual(received, expectedTimeline));
170     mReceivedTimelines.pop_front();
171 }
172 
173 /**
174  * We are essentially comparing two multisets, but without constructing them.
175  * This comparison is inefficient, but it avoids having to construct a set, and also avoids the
176  * declaration of copy constructor for ConnectionTimeline.
177  * We ensure that collections A and B have the same size, that for every element in A, there is an
178  * equal element in B, and for every element in B there is an equal element in A.
179  */
assertReceivedTimelines(const std::vector<InputEventTimeline> & timelines)180 void LatencyTrackerTest::assertReceivedTimelines(const std::vector<InputEventTimeline>& timelines) {
181     ASSERT_EQ(timelines.size(), mReceivedTimelines.size());
182     for (const InputEventTimeline& expectedTimeline : timelines) {
183         bool found = false;
184         for (const InputEventTimeline& receivedTimeline : mReceivedTimelines) {
185             if (receivedTimeline == expectedTimeline) {
186                 found = true;
187                 break;
188             }
189         }
190         if (!found) {
191             for (const InputEventTimeline& receivedTimeline : mReceivedTimelines) {
192                 LOG(ERROR) << "Received timeline with eventTime=" << receivedTimeline.eventTime;
193             }
194         }
195         ASSERT_TRUE(found) << "Could not find expected timeline with eventTime="
196                            << expectedTimeline.eventTime;
197     }
198     for (const InputEventTimeline& receivedTimeline : mReceivedTimelines) {
199         bool found = false;
200         for (const InputEventTimeline& expectedTimeline : timelines) {
201             if (receivedTimeline == expectedTimeline) {
202                 found = true;
203                 break;
204             }
205         }
206         ASSERT_TRUE(found) << "Could not find received timeline with eventTime="
207                            << receivedTimeline.eventTime;
208     }
209     mReceivedTimelines.clear();
210 }
211 
212 /**
213  * Ensure that calling 'trackListener' in isolation only creates an inputflinger timeline, without
214  * any additional ConnectionTimeline's.
215  */
TEST_F(LatencyTrackerTest,TrackListener_DoesNotTriggerReporting)216 TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
217     mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
218                                               AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/1)
219                                     .eventTime(2)
220                                     .readTime(3)
221                                     .deviceId(DEVICE_ID)
222                                     .pointer(FIRST_TOUCH_POINTER)
223                                     .build());
224     triggerEventReporting(/*eventTime=*/2);
225     assertReceivedTimeline(
226             InputEventTimeline{/*eventTime=*/2,
227                                /*readTime=*/3,
228                                /*vendorId=*/0,
229                                /*productID=*/0,
230                                {InputDeviceUsageSource::TOUCHSCREEN},
231                                /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT});
232 }
233 
234 /**
235  * A single call to trackFinishedEvent should not cause a timeline to be reported.
236  */
TEST_F(LatencyTrackerTest,TrackFinishedEvent_DoesNotTriggerReporting)237 TEST_F(LatencyTrackerTest, TrackFinishedEvent_DoesNotTriggerReporting) {
238     mTracker->trackFinishedEvent(/*inputEventId=*/1, connection1, /*deliveryTime=*/2,
239                                  /*consumeTime=*/3, /*finishTime=*/4);
240     triggerEventReporting(/*eventTime=*/4);
241     assertReceivedTimelines({});
242 }
243 
244 /**
245  * A single call to trackGraphicsLatency should not cause a timeline to be reported.
246  */
TEST_F(LatencyTrackerTest,TrackGraphicsLatency_DoesNotTriggerReporting)247 TEST_F(LatencyTrackerTest, TrackGraphicsLatency_DoesNotTriggerReporting) {
248     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
249     graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 2;
250     graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 3;
251     mTracker->trackGraphicsLatency(/*inputEventId=*/1, connection2, graphicsTimeline);
252     triggerEventReporting(/*eventTime=*/3);
253     assertReceivedTimelines({});
254 }
255 
TEST_F(LatencyTrackerTest,TrackAllParameters_ReportsFullTimeline)256 TEST_F(LatencyTrackerTest, TrackAllParameters_ReportsFullTimeline) {
257     constexpr int32_t inputEventId = 1;
258     InputEventTimeline expected = getTestTimeline();
259 
260     const auto& [connectionToken, expectedCT] = *expected.connectionTimelines.begin();
261 
262     mTracker->trackListener(
263             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
264                     .eventTime(expected.eventTime)
265                     .readTime(expected.readTime)
266                     .deviceId(DEVICE_ID)
267                     .pointer(FIRST_TOUCH_POINTER)
268                     .build());
269     mTracker->trackFinishedEvent(inputEventId, connectionToken, expectedCT.deliveryTime,
270                                  expectedCT.consumeTime, expectedCT.finishTime);
271     mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
272 
273     triggerEventReporting(expected.eventTime);
274     assertReceivedTimeline(expected);
275 }
276 
277 /**
278  * Send 2 events with the same inputEventId, but different eventTime's. Ensure that no crash occurs,
279  * and that the tracker drops such events completely.
280  */
TEST_F(LatencyTrackerTest,WhenDuplicateEventsAreReported_DoesNotCrash)281 TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) {
282     constexpr nsecs_t inputEventId = 1;
283     constexpr nsecs_t readTime = 3; // does not matter for this test
284 
285     // In the following 2 calls to trackListener, the inputEventId's are the same, but event times
286     // are different.
287     mTracker->trackListener(
288             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
289                     .eventTime(1)
290                     .readTime(readTime)
291                     .deviceId(DEVICE_ID)
292                     .pointer(FIRST_TOUCH_POINTER)
293                     .build());
294     mTracker->trackListener(
295             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
296                     .eventTime(2)
297                     .readTime(readTime)
298                     .deviceId(DEVICE_ID)
299                     .pointer(FIRST_TOUCH_POINTER)
300                     .build());
301 
302     triggerEventReporting(/*eventTime=*/2);
303     // Since we sent duplicate input events, the tracker should just delete all of them, because it
304     // does not have enough information to properly track them.
305     assertReceivedTimelines({});
306 }
307 
TEST_F(LatencyTrackerTest,MultipleEvents_AreReportedConsistently)308 TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) {
309     constexpr int32_t inputEventId1 = 1;
310     InputEventTimeline timeline1(
311             /*eventTime*/ 2,
312             /*readTime*/ 3,
313             /*vendorId=*/0,
314             /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
315             /*inputEventType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
316     timeline1.connectionTimelines.emplace(connection1,
317                                           ConnectionTimeline(/*deliveryTime*/ 6, /*consumeTime*/ 7,
318                                                              /*finishTime*/ 8));
319     ConnectionTimeline& connectionTimeline1 = timeline1.connectionTimelines.begin()->second;
320     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline1;
321     graphicsTimeline1[GraphicsTimeline::GPU_COMPLETED_TIME] = 9;
322     graphicsTimeline1[GraphicsTimeline::PRESENT_TIME] = 10;
323     connectionTimeline1.setGraphicsTimeline(std::move(graphicsTimeline1));
324 
325     constexpr int32_t inputEventId2 = 10;
326     InputEventTimeline timeline2(
327             /*eventTime=*/20,
328             /*readTime=*/30,
329             /*vendorId=*/0,
330             /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
331             /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
332     timeline2.connectionTimelines.emplace(connection2,
333                                           ConnectionTimeline(/*deliveryTime=*/60,
334                                                              /*consumeTime=*/70,
335                                                              /*finishTime=*/80));
336     ConnectionTimeline& connectionTimeline2 = timeline2.connectionTimelines.begin()->second;
337     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline2;
338     graphicsTimeline2[GraphicsTimeline::GPU_COMPLETED_TIME] = 90;
339     graphicsTimeline2[GraphicsTimeline::PRESENT_TIME] = 100;
340     connectionTimeline2.setGraphicsTimeline(std::move(graphicsTimeline2));
341 
342     // Start processing first event
343     mTracker->trackListener(
344             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId1)
345                     .eventTime(timeline1.eventTime)
346                     .readTime(timeline1.readTime)
347                     .deviceId(DEVICE_ID)
348                     .pointer(FIRST_TOUCH_POINTER)
349                     .build());
350     // Start processing second event
351     mTracker->trackListener(
352             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId2)
353                     .eventTime(timeline2.eventTime)
354                     .readTime(timeline2.readTime)
355                     .deviceId(DEVICE_ID)
356                     .pointer(FIRST_TOUCH_POINTER)
357                     .build());
358     mTracker->trackFinishedEvent(inputEventId1, connection1, connectionTimeline1.deliveryTime,
359                                  connectionTimeline1.consumeTime, connectionTimeline1.finishTime);
360 
361     mTracker->trackFinishedEvent(inputEventId2, connection2, connectionTimeline2.deliveryTime,
362                                  connectionTimeline2.consumeTime, connectionTimeline2.finishTime);
363     mTracker->trackGraphicsLatency(inputEventId1, connection1,
364                                    connectionTimeline1.graphicsTimeline);
365     mTracker->trackGraphicsLatency(inputEventId2, connection2,
366                                    connectionTimeline2.graphicsTimeline);
367     // Now both events should be completed
368     triggerEventReporting(timeline2.eventTime);
369     assertReceivedTimelines({timeline1, timeline2});
370 }
371 
372 /**
373  * Check that LatencyTracker consistently tracks events even if there are many incomplete events.
374  */
TEST_F(LatencyTrackerTest,IncompleteEvents_AreHandledConsistently)375 TEST_F(LatencyTrackerTest, IncompleteEvents_AreHandledConsistently) {
376     InputEventTimeline timeline = getTestTimeline();
377     std::vector<InputEventTimeline> expectedTimelines;
378     const ConnectionTimeline& expectedCT = timeline.connectionTimelines.begin()->second;
379     const sp<IBinder>& token = timeline.connectionTimelines.begin()->first;
380 
381     for (size_t i = 1; i <= 100; i++) {
382         mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
383                                                   AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/i)
384                                         .eventTime(timeline.eventTime)
385                                         .readTime(timeline.readTime)
386                                         .deviceId(DEVICE_ID)
387                                         .pointer(FIRST_TOUCH_POINTER)
388                                         .build());
389         expectedTimelines.push_back(InputEventTimeline{timeline.eventTime, timeline.readTime,
390                                                        timeline.vendorId, timeline.productId,
391                                                        timeline.sources,
392                                                        timeline.inputEventActionType});
393     }
394     // Now, complete the first event that was sent.
395     mTracker->trackFinishedEvent(/*inputEventId=*/1, token, expectedCT.deliveryTime,
396                                  expectedCT.consumeTime, expectedCT.finishTime);
397     mTracker->trackGraphicsLatency(/*inputEventId=*/1, token, expectedCT.graphicsTimeline);
398 
399     expectedTimelines[0].connectionTimelines.emplace(token, std::move(expectedCT));
400     triggerEventReporting(timeline.eventTime);
401     assertReceivedTimelines(expectedTimelines);
402 }
403 
404 /**
405  * For simplicity of the implementation, LatencyTracker only starts tracking an event when
406  * 'trackListener' is invoked.
407  * Both 'trackFinishedEvent' and 'trackGraphicsLatency' should not start a new event.
408  * If they are received before 'trackListener' (which should not be possible), they are ignored.
409  */
TEST_F(LatencyTrackerTest,EventsAreTracked_WhenTrackListenerIsCalledFirst)410 TEST_F(LatencyTrackerTest, EventsAreTracked_WhenTrackListenerIsCalledFirst) {
411     constexpr int32_t inputEventId = 1;
412     InputEventTimeline expected = getTestTimeline();
413     const ConnectionTimeline& expectedCT = expected.connectionTimelines.begin()->second;
414     mTracker->trackFinishedEvent(inputEventId, connection1, expectedCT.deliveryTime,
415                                  expectedCT.consumeTime, expectedCT.finishTime);
416     mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
417 
418     mTracker->trackListener(
419             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
420                     .eventTime(expected.eventTime)
421                     .readTime(expected.readTime)
422                     .deviceId(DEVICE_ID)
423                     .pointer(FIRST_TOUCH_POINTER)
424                     .build());
425     triggerEventReporting(expected.eventTime);
426     assertReceivedTimeline(InputEventTimeline{expected.eventTime, expected.readTime,
427                                               expected.vendorId, expected.productId,
428                                               expected.sources, expected.inputEventActionType});
429 }
430 
431 /**
432  * Check that LatencyTracker has the received timeline that contains the correctly
433  * resolved product ID, vendor ID and source for a particular device ID from
434  * among a list of devices.
435  */
TEST_F(LatencyTrackerTest,TrackListenerCheck_DeviceInfoFieldsInputEventTimeline)436 TEST_F(LatencyTrackerTest, TrackListenerCheck_DeviceInfoFieldsInputEventTimeline) {
437     constexpr int32_t inputEventId = 1;
438     InputEventTimeline timeline(
439             /*eventTime*/ 2, /*readTime*/ 3,
440             /*vendorId=*/50, /*productId=*/60, {InputDeviceUsageSource::STYLUS_DIRECT},
441             /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
442     InputDeviceInfo deviceInfo1 = generateTestDeviceInfo(
443             /*vendorId=*/5, /*productId=*/6, /*deviceId=*/DEVICE_ID + 1);
444     InputDeviceInfo deviceInfo2 = generateTestDeviceInfo(
445             /*vendorId=*/50, /*productId=*/60, /*deviceId=*/DEVICE_ID);
446     deviceInfo2.addSource(AINPUT_SOURCE_TOUCHSCREEN);
447     deviceInfo2.addSource(AINPUT_SOURCE_STYLUS);
448 
449     mTracker->setInputDevices({deviceInfo1, deviceInfo2});
450     mTracker->trackListener(
451             MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
452                               AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, inputEventId)
453 
454                     .eventTime(timeline.eventTime)
455                     .readTime(timeline.readTime)
456                     .deviceId(DEVICE_ID)
457                     .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(100).y(200))
458                     .build());
459     triggerEventReporting(timeline.eventTime);
460     assertReceivedTimeline(timeline);
461 }
462 
463 /**
464  * Check that InputEventActionType is correctly assigned to InputEventTimeline in trackListener.
465  */
TEST_F(LatencyTrackerTest,TrackListenerCheck_InputEventActionTypeFieldInputEventTimeline)466 TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEventTimeline) {
467     constexpr int32_t inputEventId = 1;
468     // Create timelines for different event types (Motion, Key)
469     InputEventTimeline motionDownTimeline(
470             /*eventTime*/ 2, /*readTime*/ 3,
471             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
472             InputEventActionType::MOTION_ACTION_DOWN);
473 
474     InputEventTimeline motionMoveTimeline(
475             /*eventTime*/ 4, /*readTime*/ 5,
476             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
477             InputEventActionType::MOTION_ACTION_MOVE);
478 
479     InputEventTimeline motionUpTimeline(
480             /*eventTime*/ 6, /*readTime*/ 7,
481             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
482             InputEventActionType::MOTION_ACTION_UP);
483 
484     InputEventTimeline keyDownTimeline(
485             /*eventTime*/ 8, /*readTime*/ 9,
486             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::BUTTONS},
487             InputEventActionType::KEY);
488 
489     InputEventTimeline keyUpTimeline(
490             /*eventTime*/ 10, /*readTime*/ 11,
491             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::BUTTONS},
492             InputEventActionType::KEY);
493 
494     InputEventTimeline unknownTimeline(
495             /*eventTime*/ 12, /*readTime*/ 13,
496             /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
497             InputEventActionType::UNKNOWN_INPUT_EVENT);
498 
499     mTracker->trackListener(
500             MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
501                     .eventTime(motionDownTimeline.eventTime)
502                     .readTime(motionDownTimeline.readTime)
503                     .deviceId(DEVICE_ID)
504                     .pointer(FIRST_TOUCH_POINTER)
505                     .build());
506     mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
507                                               inputEventId + 1)
508                                     .eventTime(motionMoveTimeline.eventTime)
509                                     .readTime(motionMoveTimeline.readTime)
510                                     .deviceId(DEVICE_ID)
511                                     .pointer(FIRST_TOUCH_POINTER)
512                                     .build());
513     mTracker->trackListener(
514             MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 2)
515                     .eventTime(motionUpTimeline.eventTime)
516                     .readTime(motionUpTimeline.readTime)
517                     .deviceId(DEVICE_ID)
518                     .pointer(FIRST_TOUCH_POINTER)
519                     .build());
520     mTracker->trackListener(
521             KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD, inputEventId + 3)
522                     .eventTime(keyDownTimeline.eventTime)
523                     .readTime(keyDownTimeline.readTime)
524                     .deviceId(DEVICE_ID)
525                     .build());
526     mTracker->trackListener(
527             KeyArgsBuilder(AKEY_EVENT_ACTION_UP, AINPUT_SOURCE_KEYBOARD, inputEventId + 4)
528                     .eventTime(keyUpTimeline.eventTime)
529                     .readTime(keyUpTimeline.readTime)
530                     .deviceId(DEVICE_ID)
531                     .build());
532     mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_POINTER_DOWN,
533                                               AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 5)
534                                     .eventTime(unknownTimeline.eventTime)
535                                     .readTime(unknownTimeline.readTime)
536                                     .deviceId(DEVICE_ID)
537                                     .pointer(FIRST_TOUCH_POINTER)
538                                     .build());
539 
540     triggerEventReporting(unknownTimeline.eventTime);
541 
542     std::vector<InputEventTimeline> expectedTimelines = {motionDownTimeline, motionMoveTimeline,
543                                                          motionUpTimeline,   keyDownTimeline,
544                                                          keyUpTimeline,      unknownTimeline};
545     assertReceivedTimelines(expectedTimelines);
546 }
547 
548 } // namespace android::inputdispatcher
549