Use a single trackListener method in LatencyTracker
This simplifies the code for the caller (InputDispatcher) and reduces the API surface of LatencyTracker.
Bug: 270049345
Change-Id: Ia25e95a24b5e89abcfce8060893ec3cce0c7892e
Flag: EXEMPT refactor
Test: atest inputflinger_tests
diff --git a/services/inputflinger/InputDeviceMetricsSource.cpp b/services/inputflinger/InputDeviceMetricsSource.cpp
index dee4cb8..70262fb 100644
--- a/services/inputflinger/InputDeviceMetricsSource.cpp
+++ b/services/inputflinger/InputDeviceMetricsSource.cpp
@@ -50,6 +50,18 @@
return InputDeviceUsageSource::BUTTONS;
}
+std::set<InputDeviceUsageSource> getUsageSourcesForKeyArgs(
+ const NotifyKeyArgs& args, const std::vector<InputDeviceInfo>& inputDevices) {
+ int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NONE;
+ for (const InputDeviceInfo& inputDevice : inputDevices) {
+ if (args.deviceId == inputDevice.getId()) {
+ keyboardType = inputDevice.getKeyboardType();
+ break;
+ }
+ }
+ return std::set{getUsageSourceForKeyArgs(keyboardType, args)};
+}
+
std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs& motionArgs) {
LOG_ALWAYS_FATAL_IF(motionArgs.getPointerCount() < 1, "Received motion args without pointers");
std::set<InputDeviceUsageSource> sources;
diff --git a/services/inputflinger/InputDeviceMetricsSource.h b/services/inputflinger/InputDeviceMetricsSource.h
index a6be8f4..702badd 100644
--- a/services/inputflinger/InputDeviceMetricsSource.h
+++ b/services/inputflinger/InputDeviceMetricsSource.h
@@ -54,6 +54,10 @@
/** Returns the InputDeviceUsageSource that corresponds to the key event. */
InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, const NotifyKeyArgs&);
+/** Returns the InputDeviceUsageSources that correspond to the key event. */
+std::set<InputDeviceUsageSource> getUsageSourcesForKeyArgs(
+ const NotifyKeyArgs&, const std::vector<InputDeviceInfo>& inputDevices);
+
/** Returns the InputDeviceUsageSources that correspond to the motion event. */
std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs&);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 602904f..4f9d9e4 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4551,7 +4551,7 @@
if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
!mInputFilterEnabled) {
- mLatencyTracker.trackNotifyKey(args);
+ mLatencyTracker.trackListener(args);
}
}
@@ -4687,7 +4687,7 @@
if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
!mInputFilterEnabled) {
- mLatencyTracker.trackNotifyMotion(args);
+ mLatencyTracker.trackListener(args);
}
needWake = enqueueInboundEventLocked(std::move(newEntry));
diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp
index 0852026..0921e37 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -20,6 +20,7 @@
#include <inttypes.h>
+#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android/os/IInputConstants.h>
@@ -32,6 +33,8 @@
namespace android::inputdispatcher {
+namespace {
+
/**
* Events that are older than this time will be considered mature, at which point we will stop
* waiting for the apps to provide further information about them.
@@ -62,27 +65,25 @@
}
}
+} // namespace
+
LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor)
: mTimelineProcessor(&processor) {}
-void LatencyTracker::trackNotifyMotion(const NotifyMotionArgs& args) {
- std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
- trackListener(args.id, args.eventTime, args.readTime, args.deviceId, sources, args.action,
- InputEventType::MOTION);
-}
+void LatencyTracker::trackListener(const NotifyArgs& args) {
+ if (const NotifyKeyArgs* keyArgs = std::get_if<NotifyKeyArgs>(&args)) {
+ std::set<InputDeviceUsageSource> sources =
+ getUsageSourcesForKeyArgs(*keyArgs, mInputDevices);
+ trackListener(keyArgs->id, keyArgs->eventTime, keyArgs->readTime, keyArgs->deviceId,
+ sources, keyArgs->action, InputEventType::KEY);
-void LatencyTracker::trackNotifyKey(const NotifyKeyArgs& args) {
- int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NONE;
- for (auto& inputDevice : mInputDevices) {
- if (args.deviceId == inputDevice.getId()) {
- keyboardType = inputDevice.getKeyboardType();
- break;
- }
+ } else if (const NotifyMotionArgs* motionArgs = std::get_if<NotifyMotionArgs>(&args)) {
+ std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(*motionArgs);
+ trackListener(motionArgs->id, motionArgs->eventTime, motionArgs->readTime,
+ motionArgs->deviceId, sources, motionArgs->action, InputEventType::MOTION);
+ } else {
+ LOG(FATAL) << "Unexpected NotifyArgs type: " << args.index();
}
- std::set<InputDeviceUsageSource> sources =
- std::set{getUsageSourceForKeyArgs(keyboardType, args)};
- trackListener(args.id, args.eventTime, args.readTime, args.deviceId, sources, args.action,
- InputEventType::KEY);
}
void LatencyTracker::trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime,
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index eb58222..79ea14c 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -44,28 +44,20 @@
*/
LatencyTracker(InputEventTimelineProcessor& processor);
/**
- * Start keeping track of an event identified by inputEventId. This must be called first.
+ * Start keeping track of an event identified by the args. 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.
+ * tracked. This is because there is not enough information to correctly track them. It is
+ * always possible that two different events are generated with the same inputEventId and the
+ * same eventTime, so there aren't ways to distinguish those. Therefore, we must drop all
+ * duplicate data.
+ * For that reason, the APIs 'trackFinishedEvent' and 'trackGraphicsLatency' only receive the
+ * inputEventId as input.
*/
- void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId,
- const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction,
- InputEventType inputEventType);
+ void trackListener(const NotifyArgs& args);
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,
std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
- /**
- * trackNotifyMotion and trackNotifyKeys are intermediates between InputDispatcher and
- * trackListener. They compute the InputDeviceUsageSource set and call trackListener with
- * the relevant parameters for latency computation.
- */
- void trackNotifyMotion(const NotifyMotionArgs& args);
- void trackNotifyKey(const NotifyKeyArgs& args);
std::string dump(const char* prefix) const;
void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices);
@@ -90,6 +82,10 @@
InputEventTimelineProcessor* mTimelineProcessor;
std::vector<InputDeviceInfo> mInputDevices;
+
+ void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId,
+ const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction,
+ InputEventType inputEventType);
void reportAndPruneMatureRecords(nsecs_t newEventTime);
};
diff --git a/services/inputflinger/include/NotifyArgsBuilders.h b/services/inputflinger/include/NotifyArgsBuilders.h
index 5b94d57..13eaaf3 100644
--- a/services/inputflinger/include/NotifyArgsBuilders.h
+++ b/services/inputflinger/include/NotifyArgsBuilders.h
@@ -24,13 +24,15 @@
#include <input/Keyboard.h>
#include <utils/Timers.h> // for nsecs_t, systemTime
+#include <cstdint>
#include <vector>
namespace android {
class MotionArgsBuilder {
public:
- MotionArgsBuilder(int32_t action, int32_t source) : mEventId(InputEvent::nextId()) {
+ MotionArgsBuilder(int32_t action, int32_t source, int32_t eventId = InputEvent::nextId())
+ : mEventId(eventId) {
mAction = action;
if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
addFlag(AMOTION_EVENT_FLAG_CANCELED);
@@ -55,6 +57,11 @@
return *this;
}
+ MotionArgsBuilder& readTime(nsecs_t readTime) {
+ mReadTime = readTime;
+ return *this;
+ }
+
MotionArgsBuilder& displayId(ui::LogicalDisplayId displayId) {
mDisplayId = displayId;
return *this;
@@ -121,7 +128,7 @@
return {mEventId,
mEventTime,
- /*readTime=*/mEventTime,
+ mReadTime.value_or(mEventTime),
mDeviceId,
mSource,
mDisplayId,
@@ -151,6 +158,7 @@
uint32_t mSource;
nsecs_t mDownTime;
nsecs_t mEventTime;
+ std::optional<nsecs_t> mReadTime;
ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
uint32_t mPolicyFlags = DEFAULT_POLICY_FLAGS;
int32_t mActionButton{0};
@@ -165,7 +173,8 @@
class KeyArgsBuilder {
public:
- KeyArgsBuilder(int32_t action, int32_t source) : mEventId(InputEvent::nextId()) {
+ KeyArgsBuilder(int32_t action, int32_t source, int32_t eventId = InputEvent::nextId())
+ : mEventId(eventId) {
mAction = action;
mSource = source;
mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -187,6 +196,11 @@
return *this;
}
+ KeyArgsBuilder& readTime(nsecs_t readTime) {
+ mReadTime = readTime;
+ return *this;
+ }
+
KeyArgsBuilder& displayId(ui::LogicalDisplayId displayId) {
mDisplayId = displayId;
return *this;
@@ -214,18 +228,10 @@
}
NotifyKeyArgs build() const {
- return {mEventId,
- mEventTime,
- /*readTime=*/mEventTime,
- mDeviceId,
- mSource,
- mDisplayId,
- mPolicyFlags,
- mAction,
- mFlags,
- mKeyCode,
- mScanCode,
- mMetaState,
+ return {mEventId, mEventTime, mReadTime.value_or(mEventTime),
+ mDeviceId, mSource, mDisplayId,
+ mPolicyFlags, mAction, mFlags,
+ mKeyCode, mScanCode, mMetaState,
mDownTime};
}
@@ -236,6 +242,7 @@
uint32_t mSource;
nsecs_t mDownTime;
nsecs_t mEventTime;
+ std::optional<nsecs_t> mReadTime;
ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
uint32_t mPolicyFlags = DEFAULT_POLICY_FLAGS;
int32_t mFlags{0};
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index 3f14c23..ca0f1e8 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -16,10 +16,14 @@
#include "../dispatcher/LatencyTracker.h"
#include "../InputDeviceMetricsSource.h"
+#include "NotifyArgsBuilders.h"
+#include "android/input.h"
+#include <android-base/logging.h>
#include <android-base/properties.h>
#include <binder/Binder.h>
#include <gtest/gtest.h>
+#include <input/PrintTools.h>
#include <inttypes.h>
#include <linux/input.h>
#include <log/log.h>
@@ -48,11 +52,44 @@
}
void setDefaultInputDeviceInfo(LatencyTracker& tracker) {
- InputDeviceInfo deviceInfo = generateTestDeviceInfo(
- /*vendorId=*/0, /*productId=*/0, DEVICE_ID);
+ InputDeviceInfo deviceInfo = generateTestDeviceInfo(/*vendorId=*/0, /*productId=*/0, DEVICE_ID);
tracker.setInputDevices({deviceInfo});
}
+const auto FIRST_TOUCH_POINTER = PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200);
+
+/**
+ * This is a convenience method for comparing timelines that also prints the difference between
+ * the two structures. This helps debugging when the timelines don't match.
+ * @param received the timeline that was actually received
+ * @param expected the timeline that we expected to receive
+ * @return true if the two timelines match, false otherwise.
+ */
+bool timelinesAreEqual(const InputEventTimeline& received, const InputEventTimeline& expected) {
+ LOG_IF(ERROR, expected.eventTime != received.eventTime)
+ << "Received timeline with eventTime=" << received.eventTime
+ << " instead of expected eventTime=" << expected.eventTime;
+ LOG_IF(ERROR, expected.readTime != received.readTime)
+ << "Received timeline with readTime=" << received.readTime
+ << " instead of expected readTime=" << expected.readTime;
+ LOG_IF(ERROR, expected.vendorId != received.vendorId)
+ << "Received timeline with vendorId=" << received.vendorId
+ << " instead of expected vendorId=" << expected.vendorId;
+ LOG_IF(ERROR, expected.productId != received.productId)
+ << "Received timeline with productId=" << received.productId
+ << " instead of expected productId=" << expected.productId;
+ LOG_IF(ERROR, expected.sources != received.sources)
+ << "Received timeline with sources=" << dumpSet(received.sources, ftl::enum_string)
+ << " instead of expected sources=" << dumpSet(expected.sources, ftl::enum_string);
+ LOG_IF(ERROR, expected.inputEventActionType != received.inputEventActionType)
+ << "Received timeline with inputEventActionType="
+ << ftl::enum_string(received.inputEventActionType)
+ << " instead of expected inputEventActionType="
+ << ftl::enum_string(expected.inputEventActionType);
+
+ return received == expected;
+}
+
} // namespace
const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds(
@@ -64,15 +101,14 @@
/*eventTime=*/2,
/*readTime=*/3,
/*vendorId=*/0,
- /*productId=*/0,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+ /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
/*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
ConnectionTimeline expectedCT(/*deliveryTime=*/6, /*consumeTime=*/7, /*finishTime=*/8);
- std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
+ std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline{};
graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 9;
graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 10;
- expectedCT.setGraphicsTimeline(std::move(graphicsTimeline));
- t.connectionTimelines.emplace(sp<BBinder>::make(), std::move(expectedCT));
+ expectedCT.setGraphicsTimeline(graphicsTimeline);
+ t.connectionTimelines.emplace(sp<BBinder>::make(), expectedCT);
return t;
}
@@ -118,16 +154,19 @@
void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) {
const nsecs_t triggerEventTime =
lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
- mTracker->trackListener(/*inputEventId=*/1, triggerEventTime,
- /*readTime=*/3, DEVICE_ID,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
- AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
+ mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
+ AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/1)
+ .eventTime(triggerEventTime)
+ .readTime(3)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
}
-void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) {
+void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& expectedTimeline) {
ASSERT_FALSE(mReceivedTimelines.empty());
- const InputEventTimeline& t = mReceivedTimelines.front();
- ASSERT_EQ(timeline, t);
+ const InputEventTimeline& received = mReceivedTimelines.front();
+ ASSERT_TRUE(timelinesAreEqual(received, expectedTimeline));
mReceivedTimelines.pop_front();
}
@@ -148,6 +187,11 @@
break;
}
}
+ if (!found) {
+ for (const InputEventTimeline& receivedTimeline : mReceivedTimelines) {
+ LOG(ERROR) << "Received timeline with eventTime=" << receivedTimeline.eventTime;
+ }
+ }
ASSERT_TRUE(found) << "Could not find expected timeline with eventTime="
<< expectedTimeline.eventTime;
}
@@ -170,14 +214,20 @@
* any additional ConnectionTimeline's.
*/
TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
- mTracker->trackListener(/*inputEventId=*/1, /*eventTime=*/2,
- /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN},
- AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
+ mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
+ AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/1)
+ .eventTime(2)
+ .readTime(3)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
triggerEventReporting(/*eventTime=*/2);
assertReceivedTimeline(
InputEventTimeline{/*eventTime=*/2,
- /*readTime=*/3, /*vendorId=*/0, /*productID=*/0,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+ /*readTime=*/3,
+ /*vendorId=*/0,
+ /*productID=*/0,
+ {InputDeviceUsageSource::TOUCHSCREEN},
/*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT});
}
@@ -209,9 +259,13 @@
const auto& [connectionToken, expectedCT] = *expected.connectionTimelines.begin();
- mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID,
- {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
- InputEventType::MOTION);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
+ .eventTime(expected.eventTime)
+ .readTime(expected.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
mTracker->trackFinishedEvent(inputEventId, connectionToken, expectedCT.deliveryTime,
expectedCT.consumeTime, expectedCT.finishTime);
mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
@@ -230,12 +284,20 @@
// In the following 2 calls to trackListener, the inputEventId's are the same, but event times
// are different.
- 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);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
+ .eventTime(1)
+ .readTime(readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
+ .eventTime(2)
+ .readTime(readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
triggerEventReporting(/*eventTime=*/2);
// Since we sent duplicate input events, the tracker should just delete all of them, because it
@@ -249,8 +311,7 @@
/*eventTime*/ 2,
/*readTime*/ 3,
/*vendorId=*/0,
- /*productId=*/0,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+ /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
/*inputEventType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
timeline1.connectionTimelines.emplace(connection1,
ConnectionTimeline(/*deliveryTime*/ 6, /*consumeTime*/ 7,
@@ -266,8 +327,7 @@
/*eventTime=*/20,
/*readTime=*/30,
/*vendorId=*/0,
- /*productId=*/0,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
+ /*productId=*/0, {InputDeviceUsageSource::TOUCHSCREEN},
/*inputEventActionType=*/InputEventActionType::UNKNOWN_INPUT_EVENT);
timeline2.connectionTimelines.emplace(connection2,
ConnectionTimeline(/*deliveryTime=*/60,
@@ -280,13 +340,21 @@
connectionTimeline2.setGraphicsTimeline(std::move(graphicsTimeline2));
// Start processing first event
- mTracker->trackListener(inputEventId1, timeline1.eventTime, timeline1.readTime, DEVICE_ID,
- {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
- InputEventType::MOTION);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId1)
+ .eventTime(timeline1.eventTime)
+ .readTime(timeline1.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
// Start processing second event
- mTracker->trackListener(inputEventId2, timeline2.eventTime, timeline2.readTime, DEVICE_ID,
- {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
- InputEventType::MOTION);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId2)
+ .eventTime(timeline2.eventTime)
+ .readTime(timeline2.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
mTracker->trackFinishedEvent(inputEventId1, connection1, connectionTimeline1.deliveryTime,
connectionTimeline1.consumeTime, connectionTimeline1.finishTime);
@@ -311,10 +379,13 @@
const sp<IBinder>& token = timeline.connectionTimelines.begin()->first;
for (size_t i = 1; i <= 100; i++) {
- mTracker->trackListener(/*inputEventId=*/i, timeline.eventTime, timeline.readTime,
- /*deviceId=*/DEVICE_ID,
- /*sources=*/{InputDeviceUsageSource::UNKNOWN},
- AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
+ mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
+ AINPUT_SOURCE_TOUCHSCREEN, /*inputEventId=*/i)
+ .eventTime(timeline.eventTime)
+ .readTime(timeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
expectedTimelines.push_back(InputEventTimeline{timeline.eventTime, timeline.readTime,
timeline.vendorId, timeline.productId,
timeline.sources,
@@ -344,9 +415,13 @@
expectedCT.consumeTime, expectedCT.finishTime);
mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
- mTracker->trackListener(inputEventId, expected.eventTime, expected.readTime, DEVICE_ID,
- {InputDeviceUsageSource::UNKNOWN}, AMOTION_EVENT_ACTION_CANCEL,
- InputEventType::MOTION);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
+ .eventTime(expected.eventTime)
+ .readTime(expected.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
triggerEventReporting(expected.eventTime);
assertReceivedTimeline(InputEventTimeline{expected.eventTime, expected.readTime,
expected.vendorId, expected.productId,
@@ -362,20 +437,25 @@
constexpr int32_t inputEventId = 1;
InputEventTimeline timeline(
/*eventTime*/ 2, /*readTime*/ 3,
- /*vendorId=*/50, /*productId=*/60,
- /*sources=*/
- {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT},
+ /*vendorId=*/50, /*productId=*/60, {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);
+ deviceInfo2.addSource(AINPUT_SOURCE_TOUCHSCREEN);
+ deviceInfo2.addSource(AINPUT_SOURCE_STYLUS);
mTracker->setInputDevices({deviceInfo1, deviceInfo2});
- mTracker->trackListener(inputEventId, timeline.eventTime, timeline.readTime, DEVICE_ID,
- {InputDeviceUsageSource::TOUCHSCREEN,
- InputDeviceUsageSource::STYLUS_DIRECT},
- AMOTION_EVENT_ACTION_CANCEL, InputEventType::MOTION);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, inputEventId)
+
+ .eventTime(timeline.eventTime)
+ .readTime(timeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(100).y(200))
+ .build());
triggerEventReporting(timeline.eventTime);
assertReceivedTimeline(timeline);
}
@@ -388,58 +468,74 @@
// Create timelines for different event types (Motion, Key)
InputEventTimeline motionDownTimeline(
/*eventTime*/ 2, /*readTime*/ 3,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_DOWN);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
+ InputEventActionType::MOTION_ACTION_DOWN);
InputEventTimeline motionMoveTimeline(
/*eventTime*/ 4, /*readTime*/ 5,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_MOVE);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
+ InputEventActionType::MOTION_ACTION_MOVE);
InputEventTimeline motionUpTimeline(
/*eventTime*/ 6, /*readTime*/ 7,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::MOTION_ACTION_UP);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
+ InputEventActionType::MOTION_ACTION_UP);
InputEventTimeline keyDownTimeline(
/*eventTime*/ 8, /*readTime*/ 9,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::KEY);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::BUTTONS},
+ InputEventActionType::KEY);
InputEventTimeline keyUpTimeline(
/*eventTime*/ 10, /*readTime*/ 11,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::KEY);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::BUTTONS},
+ InputEventActionType::KEY);
InputEventTimeline unknownTimeline(
/*eventTime*/ 12, /*readTime*/ 13,
- /*vendorId*/ 0, /*productId*/ 0,
- /*sources*/ {InputDeviceUsageSource::UNKNOWN},
- /*inputEventActionType*/ InputEventActionType::UNKNOWN_INPUT_EVENT);
+ /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN},
+ 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);
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, inputEventId)
+ .eventTime(motionDownTimeline.eventTime)
+ .readTime(motionDownTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
+ mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
+ inputEventId + 1)
+ .eventTime(motionMoveTimeline.eventTime)
+ .readTime(motionMoveTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
+ mTracker->trackListener(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 2)
+ .eventTime(motionUpTimeline.eventTime)
+ .readTime(motionUpTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
+ mTracker->trackListener(
+ KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD, inputEventId + 3)
+ .eventTime(keyDownTimeline.eventTime)
+ .readTime(keyDownTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .build());
+ mTracker->trackListener(
+ KeyArgsBuilder(AKEY_EVENT_ACTION_UP, AINPUT_SOURCE_KEYBOARD, inputEventId + 4)
+ .eventTime(keyUpTimeline.eventTime)
+ .readTime(keyUpTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .build());
+ mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_POINTER_DOWN,
+ AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 5)
+ .eventTime(unknownTimeline.eventTime)
+ .readTime(unknownTimeline.readTime)
+ .deviceId(DEVICE_ID)
+ .pointer(FIRST_TOUCH_POINTER)
+ .build());
triggerEventReporting(unknownTimeline.eventTime);
diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
index 908fa40..157a333 100644
--- a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
@@ -19,6 +19,7 @@
#include "../../InputDeviceMetricsSource.h"
#include "../InputEventTimeline.h"
+#include "NotifyArgsBuilders.h"
#include "dispatcher/LatencyTracker.h"
namespace android {
@@ -61,40 +62,49 @@
// Make some pre-defined tokens to ensure that some timelines are complete.
std::array<sp<IBinder> /*token*/, 10> predefinedTokens;
- for (size_t i = 0; i < predefinedTokens.size(); i++) {
- predefinedTokens[i] = sp<BBinder>::make();
+ for (sp<IBinder>& token : predefinedTokens) {
+ token = sp<BBinder>::make();
}
// Randomly invoke LatencyTracker api's until randomness is exhausted.
while (fdp.remaining_bytes() > 0) {
fdp.PickValueInArray<std::function<void()>>({
[&]() -> void {
- int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
- nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
- nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
+ const int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ const nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
+ const nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
const DeviceId deviceId = fdp.ConsumeIntegral<int32_t>();
+ const int32_t source = fdp.ConsumeIntegral<int32_t>();
std::set<InputDeviceUsageSource> sources = {
fdp.ConsumeEnum<InputDeviceUsageSource>()};
const int32_t inputEventActionType = fdp.ConsumeIntegral<int32_t>();
const InputEventType inputEventType = fdp.ConsumeEnum<InputEventType>();
- tracker.trackListener(inputEventId, eventTime, readTime, deviceId, sources,
- inputEventActionType, inputEventType);
+ const NotifyMotionArgs args =
+ MotionArgsBuilder(inputEventActionType, source, inputEventId)
+ .eventTime(eventTime)
+ .readTime(readTime)
+ .deviceId(deviceId)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER)
+ .x(100)
+ .y(200))
+ .build();
+ tracker.trackListener(args);
},
[&]() -> void {
- int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ const int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
- nsecs_t deliveryTime = fdp.ConsumeIntegral<nsecs_t>();
- nsecs_t consumeTime = fdp.ConsumeIntegral<nsecs_t>();
- nsecs_t finishTime = fdp.ConsumeIntegral<nsecs_t>();
+ const nsecs_t deliveryTime = fdp.ConsumeIntegral<nsecs_t>();
+ const nsecs_t consumeTime = fdp.ConsumeIntegral<nsecs_t>();
+ const nsecs_t finishTime = fdp.ConsumeIntegral<nsecs_t>();
tracker.trackFinishedEvent(inputEventId, connectionToken, deliveryTime,
consumeTime, finishTime);
},
[&]() -> void {
- int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ const int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
- std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
- for (size_t i = 0; i < graphicsTimeline.size(); i++) {
- graphicsTimeline[i] = fdp.ConsumeIntegral<nsecs_t>();
+ std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline{};
+ for (nsecs_t& t : graphicsTimeline) {
+ t = fdp.ConsumeIntegral<nsecs_t>();
}
tracker.trackGraphicsLatency(inputEventId, connectionToken, graphicsTimeline);
},