diff options
-rw-r--r-- | include/input/Input.h | 2 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputEventTimeline.cpp | 9 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputEventTimeline.h | 26 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/LatencyTracker.cpp | 43 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/LatencyTracker.h | 5 | ||||
-rw-r--r-- | services/inputflinger/tests/LatencyTracker_test.cpp | 156 | ||||
-rw-r--r-- | services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp | 8 |
8 files changed, 204 insertions, 51 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 1a3cb6a884..a8684bd19b 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -251,6 +251,8 @@ enum class InputEventType { TOUCH_MODE = AINPUT_EVENT_TYPE_TOUCH_MODE, ftl_first = KEY, ftl_last = TOUCH_MODE, + // Used by LatencyTracker fuzzer + kMaxValue = ftl_last }; std::string inputEventSourceToString(int32_t source); diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index fcea0f3d93..d549cbc2d1 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -52,6 +52,7 @@ #include "Connection.h" #include "DebugConfig.h" #include "InputDispatcher.h" +#include "InputEventTimeline.h" #include "trace/InputTracer.h" #include "trace/InputTracingPerfettoBackend.h" #include "trace/ThreadedBackend.h" @@ -4638,10 +4639,9 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID && IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER && !mInputFilterEnabled) { - const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN; std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args); - mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime, - args.deviceId, sources); + mLatencyTracker.trackListener(args.id, args.eventTime, args.readTime, args.deviceId, + sources, args.action, InputEventType::MOTION); } needWake = enqueueInboundEventLocked(std::move(newEntry)); diff --git a/services/inputflinger/dispatcher/InputEventTimeline.cpp b/services/inputflinger/dispatcher/InputEventTimeline.cpp index a3650030ac..31ceb8d4d3 100644 --- a/services/inputflinger/dispatcher/InputEventTimeline.cpp +++ b/services/inputflinger/dispatcher/InputEventTimeline.cpp @@ -68,13 +68,15 @@ bool ConnectionTimeline::operator!=(const ConnectionTimeline& rhs) const { InputEventTimeline::InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId, uint16_t productId, - const std::set<InputDeviceUsageSource>& sources) + const std::set<InputDeviceUsageSource>& sources, + InputEventActionType inputEventActionType) : isDown(isDown), eventTime(eventTime), readTime(readTime), vendorId(vendorId), productId(productId), - sources(sources) {} + sources(sources), + inputEventActionType(inputEventActionType) {} bool InputEventTimeline::operator==(const InputEventTimeline& rhs) const { if (connectionTimelines.size() != rhs.connectionTimelines.size()) { @@ -90,7 +92,8 @@ bool InputEventTimeline::operator==(const InputEventTimeline& rhs) const { } } return isDown == rhs.isDown && eventTime == rhs.eventTime && readTime == rhs.readTime && - vendorId == rhs.vendorId && productId == rhs.productId && sources == rhs.sources; + vendorId == rhs.vendorId && productId == rhs.productId && sources == rhs.sources && + inputEventActionType == rhs.inputEventActionType; } } // namespace android::inputdispatcher diff --git a/services/inputflinger/dispatcher/InputEventTimeline.h b/services/inputflinger/dispatcher/InputEventTimeline.h index 1756944d0e..6668399af3 100644 --- a/services/inputflinger/dispatcher/InputEventTimeline.h +++ b/services/inputflinger/dispatcher/InputEventTimeline.h @@ -74,15 +74,39 @@ private: bool mHasGraphicsTimeline = false; }; +enum class InputEventActionType : int32_t { + UNKNOWN_INPUT_EVENT = 0, + MOTION_ACTION_DOWN = 1, + // Motion events for ACTION_MOVE (characterizes scrolling motion) + MOTION_ACTION_MOVE = 2, + // Motion events for ACTION_UP (when the pointer first goes up) + MOTION_ACTION_UP = 3, + // Motion events for ACTION_HOVER_MOVE (pointer position on screen changes but pointer is not + // down) + MOTION_ACTION_HOVER_MOVE = 4, + // Motion events for ACTION_SCROLL (moving the mouse wheel) + MOTION_ACTION_SCROLL = 5, + // Key events for both ACTION_DOWN and ACTION_UP (key press and key release) + KEY = 6, + + ftl_first = UNKNOWN_INPUT_EVENT, + ftl_last = KEY, + // Used by latency fuzzer + kMaxValue = ftl_last + +}; + struct InputEventTimeline { InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId, - uint16_t productId, const std::set<InputDeviceUsageSource>& sources); + uint16_t productId, const std::set<InputDeviceUsageSource>& sources, + InputEventActionType inputEventActionType); const bool isDown; // True if this is an ACTION_DOWN event const nsecs_t eventTime; const nsecs_t readTime; const uint16_t vendorId; const uint16_t productId; const std::set<InputDeviceUsageSource> sources; + const InputEventActionType inputEventActionType; struct IBinderHash { std::size_t operator()(const sp<IBinder>& b) const { diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp index 698bd9ff08..721d009570 100644 --- a/services/inputflinger/dispatcher/LatencyTracker.cpp +++ b/services/inputflinger/dispatcher/LatencyTracker.cpp @@ -67,9 +67,10 @@ LatencyTracker::LatencyTracker(InputEventTimelineProcessor* processor) LOG_ALWAYS_FATAL_IF(processor == nullptr); } -void LatencyTracker::trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, - nsecs_t readTime, DeviceId deviceId, - const std::set<InputDeviceUsageSource>& sources) { +void LatencyTracker::trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, + DeviceId deviceId, + const std::set<InputDeviceUsageSource>& sources, + int inputEventAction, InputEventType inputEventType) { reportAndPruneMatureRecords(eventTime); const auto it = mTimelines.find(inputEventId); if (it != mTimelines.end()) { @@ -101,9 +102,43 @@ void LatencyTracker::trackListener(int32_t inputEventId, bool isDown, nsecs_t ev return; } + const InputEventActionType inputEventActionType = [&]() { + switch (inputEventType) { + case InputEventType::MOTION: { + switch (inputEventAction) { + case AMOTION_EVENT_ACTION_DOWN: + return InputEventActionType::MOTION_ACTION_DOWN; + case AMOTION_EVENT_ACTION_MOVE: + return InputEventActionType::MOTION_ACTION_MOVE; + case AMOTION_EVENT_ACTION_UP: + return InputEventActionType::MOTION_ACTION_UP; + case AMOTION_EVENT_ACTION_HOVER_MOVE: + return InputEventActionType::MOTION_ACTION_HOVER_MOVE; + case AMOTION_EVENT_ACTION_SCROLL: + return InputEventActionType::MOTION_ACTION_SCROLL; + default: + return InputEventActionType::UNKNOWN_INPUT_EVENT; + } + } + case InputEventType::KEY: { + switch (inputEventAction) { + case AKEY_EVENT_ACTION_DOWN: + case AKEY_EVENT_ACTION_UP: + return InputEventActionType::KEY; + default: + return InputEventActionType::UNKNOWN_INPUT_EVENT; + } + } + default: + return InputEventActionType::UNKNOWN_INPUT_EVENT; + } + }(); + + bool isDown = inputEventType == InputEventType::MOTION && + inputEventAction == AMOTION_EVENT_ACTION_DOWN; mTimelines.emplace(inputEventId, InputEventTimeline(isDown, eventTime, readTime, identifier->vendor, - identifier->product, sources)); + identifier->product, sources, inputEventActionType)); mEventTimes.emplace(eventTime, inputEventId); } diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h index 890d61d431..532f42290a 100644 --- a/services/inputflinger/dispatcher/LatencyTracker.h +++ b/services/inputflinger/dispatcher/LatencyTracker.h @@ -52,8 +52,9 @@ public: * 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, - DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources); + void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId, + const std::set<InputDeviceUsageSource>& sources, int inputEventActionType, + InputEventType inputEventType); void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken, nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime); void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken, diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp index 4fcffddee2..56502861cf 100644 --- a/services/inputflinger/tests/LatencyTracker_test.cpp +++ b/services/inputflinger/tests/LatencyTracker_test.cpp @@ -61,12 +61,13 @@ const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds( InputEventTimeline getTestTimeline() { InputEventTimeline t( - /*isDown=*/true, + /*isDown=*/false, /*eventTime=*/2, /*readTime=*/3, /*vendorId=*/0, /*productId=*/0, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}); + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT); ConnectionTimeline expectedCT(/*deliveryTime=*/6, /*consumeTime=*/7, /*finishTime=*/8); std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline; graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 9; @@ -116,9 +117,10 @@ private: void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) { const nsecs_t triggerEventTime = lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1; - mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/true, triggerEventTime, + mTracker->trackListener(/*inputEventId=*/1, triggerEventTime, /*readTime=*/3, DEVICE_ID, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}); + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION); } void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) { @@ -167,12 +169,15 @@ void LatencyTrackerTest::assertReceivedTimelines(const std::vector<InputEventTim * any additional ConnectionTimeline's. */ TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) { - mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/false, /*eventTime=*/2, - /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(/*inputEventId=*/1, /*eventTime=*/2, + /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}, + AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION); triggerEventReporting(/*eventTime=*/2); - assertReceivedTimeline(InputEventTimeline{/*isDown=*/false, /*eventTime=*/2, - /*readTime=*/3, /*vendorId=*/0, /*productID=*/0, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}}); + assertReceivedTimeline( + InputEventTimeline{/*isDown=*/false, /*eventTime=*/2, + /*readTime=*/3, /*vendorId=*/0, /*productID=*/0, + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT}); } /** @@ -203,8 +208,9 @@ TEST_F(LatencyTrackerTest, TrackAllParameters_ReportsFullTimeline) { const auto& [connectionToken, expectedCT] = *expected.connectionTimelines.begin(); - mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime, - DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); mTracker->trackFinishedEvent(inputEventId, connectionToken, expectedCT.deliveryTime, expectedCT.consumeTime, expectedCT.finishTime); mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline); @@ -220,14 +226,16 @@ TEST_F(LatencyTrackerTest, TrackAllParameters_ReportsFullTimeline) { TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) { constexpr nsecs_t inputEventId = 1; constexpr nsecs_t readTime = 3; // does not matter for this test - constexpr bool isDown = true; // does not matter for this test + constexpr bool isDown = false; // does not matter for this test // In the following 2 calls to trackListener, the inputEventId's are the same, but event times // are different. - mTracker->trackListener(inputEventId, isDown, /*eventTime=*/1, readTime, DEVICE_ID, - {InputDeviceUsageSource::UNKNOWN}); - mTracker->trackListener(inputEventId, isDown, /*eventTime=*/2, readTime, DEVICE_ID, - {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(inputEventId, /*eventTime=*/1, readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); + mTracker->trackListener(inputEventId, /*eventTime=*/2, readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); triggerEventReporting(/*eventTime=*/2); // Since we sent duplicate input events, the tracker should just delete all of them, because it @@ -238,12 +246,13 @@ TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) { TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) { constexpr int32_t inputEventId1 = 1; InputEventTimeline timeline1( - /*isDown*/ true, + /*isDown*/ false, /*eventTime*/ 2, /*readTime*/ 3, /*vendorId=*/0, /*productId=*/0, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}); + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + /*inputEventType=*/InputEventActionType::UNKNOWN_INPUT_EVENT); timeline1.connectionTimelines.emplace(connection1, ConnectionTimeline(/*deliveryTime*/ 6, /*consumeTime*/ 7, /*finishTime*/ 8)); @@ -260,7 +269,8 @@ TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) { /*readTime=*/30, /*vendorId=*/0, /*productId=*/0, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}); + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT); timeline2.connectionTimelines.emplace(connection2, ConnectionTimeline(/*deliveryTime=*/60, /*consumeTime=*/70, @@ -272,11 +282,13 @@ TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) { connectionTimeline2.setGraphicsTimeline(std::move(graphicsTimeline2)); // Start processing first event - mTracker->trackListener(inputEventId1, timeline1.isDown, timeline1.eventTime, - timeline1.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(inputEventId1, timeline1.eventTime, timeline1.readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); // Start processing second event - mTracker->trackListener(inputEventId2, timeline2.isDown, timeline2.eventTime, - timeline2.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(inputEventId2, timeline2.eventTime, timeline2.readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); mTracker->trackFinishedEvent(inputEventId1, connection1, connectionTimeline1.deliveryTime, connectionTimeline1.consumeTime, connectionTimeline1.finishTime); @@ -301,12 +313,14 @@ TEST_F(LatencyTrackerTest, IncompleteEvents_AreHandledConsistently) { const sp<IBinder>& token = timeline.connectionTimelines.begin()->first; for (size_t i = 1; i <= 100; i++) { - mTracker->trackListener(/*inputEventId=*/i, timeline.isDown, timeline.eventTime, - timeline.readTime, /*deviceId=*/DEVICE_ID, - /*sources=*/{InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(/*inputEventId=*/i, timeline.eventTime, timeline.readTime, + /*deviceId=*/DEVICE_ID, + /*sources=*/{InputDeviceUsageSource::UNKNOWN}, + AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION); expectedTimelines.push_back(InputEventTimeline{timeline.isDown, timeline.eventTime, timeline.readTime, timeline.vendorId, - timeline.productId, timeline.sources}); + timeline.productId, timeline.sources, + timeline.inputEventActionType}); } // Now, complete the first event that was sent. mTracker->trackFinishedEvent(/*inputEventId=*/1, token, expectedCT.deliveryTime, @@ -332,12 +346,14 @@ TEST_F(LatencyTrackerTest, EventsAreTracked_WhenTrackListenerIsCalledFirst) { expectedCT.consumeTime, expectedCT.finishTime); mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline); - mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime, - DEVICE_ID, {InputDeviceUsageSource::UNKNOWN}); + mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID, + {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL, + InputEventType::MOTION); triggerEventReporting(expected.eventTime); assertReceivedTimeline(InputEventTimeline{expected.isDown, expected.eventTime, expected.readTime, expected.vendorId, - expected.productId, expected.sources}); + expected.productId, expected.sources, + expected.inputEventActionType}); } /** @@ -348,22 +364,92 @@ TEST_F(LatencyTrackerTest, EventsAreTracked_WhenTrackListenerIsCalledFirst) { TEST_F(LatencyTrackerTest, TrackListenerCheck_DeviceInfoFieldsInputEventTimeline) { constexpr int32_t inputEventId = 1; InputEventTimeline timeline( - /*isDown*/ true, /*eventTime*/ 2, /*readTime*/ 3, + /*isDown*/ false, /*eventTime*/ 2, /*readTime*/ 3, /*vendorId=*/50, /*productId=*/60, /*sources=*/ - {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT}); + {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT}, + /*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT); InputDeviceInfo deviceInfo1 = generateTestDeviceInfo( /*vendorId=*/5, /*productId=*/6, /*deviceId=*/DEVICE_ID + 1); InputDeviceInfo deviceInfo2 = generateTestDeviceInfo( /*vendorId=*/50, /*productId=*/60, /*deviceId=*/DEVICE_ID); mTracker->setInputDevices({deviceInfo1, deviceInfo2}); - mTracker->trackListener(inputEventId, timeline.isDown, timeline.eventTime, timeline.readTime, - DEVICE_ID, + mTracker->trackListener(inputEventId, timeline.eventTime, timeline.readTime, DEVICE_ID, {InputDeviceUsageSource::TOUCHSCREEN, - InputDeviceUsageSource::STYLUS_DIRECT}); + InputDeviceUsageSource::STYLUS_DIRECT}, + AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION); triggerEventReporting(timeline.eventTime); assertReceivedTimeline(timeline); } +/** + * Check that InputEventActionType is correctly assigned to InputEventTimeline in trackListener. + */ +TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEventTimeline) { + constexpr int32_t inputEventId = 1; + // Create timelines for different event types (Motion, Key) + InputEventTimeline motionDownTimeline( + /*isDown*/ true, /*eventTime*/ 2, /*readTime*/ 3, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_DOWN); + + InputEventTimeline motionMoveTimeline( + /*isDown*/ false, /*eventTime*/ 4, /*readTime*/ 5, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_MOVE); + + InputEventTimeline motionUpTimeline( + /*isDown*/ false, /*eventTime*/ 6, /*readTime*/ 7, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_UP); + + InputEventTimeline keyDownTimeline( + /*isDown*/ false, /*eventTime*/ 8, /*readTime*/ 9, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::KEY); + + InputEventTimeline keyUpTimeline( + /*isDown*/ false, /*eventTime*/ 10, /*readTime*/ 11, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::KEY); + + InputEventTimeline unknownTimeline( + /*isDown*/ false, /*eventTime*/ 12, /*readTime*/ 13, + /*vendorId*/ 0, /*productId*/ 0, + /*sources*/ {InputDeviceUsageSource::UNKNOWN}, + /*inputEventActionType*/ InputEventActionType::UNKNOWN_INPUT_EVENT); + + mTracker->trackListener(inputEventId, motionDownTimeline.eventTime, motionDownTimeline.readTime, + DEVICE_ID, motionDownTimeline.sources, AMOTION_EVENT_ACTION_DOWN, + InputEventType::MOTION); + mTracker->trackListener(inputEventId + 1, motionMoveTimeline.eventTime, + motionMoveTimeline.readTime, DEVICE_ID, motionMoveTimeline.sources, + AMOTION_EVENT_ACTION_MOVE, InputEventType::MOTION); + mTracker->trackListener(inputEventId + 2, motionUpTimeline.eventTime, motionUpTimeline.readTime, + DEVICE_ID, motionUpTimeline.sources, AMOTION_EVENT_ACTION_UP, + InputEventType::MOTION); + mTracker->trackListener(inputEventId + 3, keyDownTimeline.eventTime, keyDownTimeline.readTime, + DEVICE_ID, keyDownTimeline.sources, AKEY_EVENT_ACTION_DOWN, + InputEventType::KEY); + mTracker->trackListener(inputEventId + 4, keyUpTimeline.eventTime, keyUpTimeline.readTime, + DEVICE_ID, keyUpTimeline.sources, AKEY_EVENT_ACTION_UP, + InputEventType::KEY); + mTracker->trackListener(inputEventId + 5, unknownTimeline.eventTime, unknownTimeline.readTime, + DEVICE_ID, unknownTimeline.sources, AMOTION_EVENT_ACTION_POINTER_DOWN, + InputEventType::MOTION); + + triggerEventReporting(unknownTimeline.eventTime); + + std::vector<InputEventTimeline> expectedTimelines = {motionDownTimeline, motionMoveTimeline, + motionUpTimeline, keyDownTimeline, + keyUpTimeline, unknownTimeline}; + assertReceivedTimelines(expectedTimelines); +} + } // namespace android::inputdispatcher diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp index 6daeaafbb3..80c2213482 100644 --- a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp +++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp @@ -18,6 +18,7 @@ #include <linux/input.h> #include "../../InputDeviceMetricsSource.h" +#include "../InputEventTimeline.h" #include "dispatcher/LatencyTracker.h" namespace android { @@ -65,14 +66,15 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) { fdp.PickValueInArray<std::function<void()>>({ [&]() -> void { int32_t inputEventId = fdp.ConsumeIntegral<int32_t>(); - int32_t isDown = fdp.ConsumeBool(); nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>(); nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>(); const DeviceId deviceId = fdp.ConsumeIntegral<int32_t>(); std::set<InputDeviceUsageSource> sources = { fdp.ConsumeEnum<InputDeviceUsageSource>()}; - tracker.trackListener(inputEventId, isDown, eventTime, readTime, deviceId, - sources); + int32_t inputEventActionType = fdp.ConsumeIntegral<int32_t>(); + const InputEventType inputEventType = fdp.ConsumeEnum<InputEventType>(); + tracker.trackListener(inputEventId, eventTime, readTime, deviceId, sources, + inputEventActionType, inputEventType); }, [&]() -> void { int32_t inputEventId = fdp.ConsumeIntegral<int32_t>(); |