InputTracer: Trace events derived from other events separately
InputDispatcher goes through multiple "phases" when dispatching
new event, roughly corresponding to the following:
1. Inbound event processing (e.g. InputFilter, policy filtering,
generating key repeats, etc.)
2. Target finding (finding the touched/focused window(s) that should
receive the event)
3. Event modification (generating new events based on the original, such
as for split motions)
4. Publishing
When an event is modified in step 3, we always create a new EventEntry
with a new event ID to distinguish it from the original. These derived
events need to be traced separately, but need to share the same trace
context as the original event. For example, an event is split across
windows A and B, and the whole event is sent to spy window C. In this
case, windows A and B receive a derived event, and C receives the whole
event. If B is a trace-sensitive window, we must not leak the sensitive
info from the event by tracing the original event through C.
Since event modification (step 3) always happens after target finding
(step 2) for a dispatch entry, we will trace the derived (modified)
events separately. The modified event will never affect
target-finding, so the derived events are more limited, but they share
the same context as the original event by using the same State under the
hood.
Bug: 210460522
Test: atest inputflinger_tests
Change-Id: I772a04b7dfd0322357dd4dfa95387244ca6230e9
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 73bbed6..56b0c8f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -399,7 +399,8 @@
const InputTarget& inputTarget,
std::shared_ptr<const EventEntry> eventEntry,
ftl::Flags<InputTarget::Flags> inputTargetFlags,
- int64_t vsyncId) {
+ int64_t vsyncId,
+ trace::InputTracerInterface* tracer) {
const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS);
const sp<WindowInfoHandle> win = inputTarget.windowHandle;
const std::optional<int32_t> windowId =
@@ -462,6 +463,10 @@
motionEntry.xCursorPosition, motionEntry.yCursorPosition,
motionEntry.downTime, motionEntry.pointerProperties,
pointerCoords);
+ if (tracer) {
+ combinedMotionEntry->traceTracker =
+ tracer->traceDerivedEvent(*combinedMotionEntry, *motionEntry.traceTracker);
+ }
std::unique_ptr<DispatchEntry> dispatchEntry =
std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
@@ -3386,7 +3391,7 @@
// Enqueue a new dispatch entry onto the outbound queue for this connection.
std::unique_ptr<DispatchEntry> dispatchEntry =
createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags,
- mWindowInfosVsyncId);
+ mWindowInfosVsyncId, mTracer.get());
// Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
// different EventEntry than what was passed in.
@@ -3469,21 +3474,31 @@
usingCoords = pointerInfo->second;
}
}
- // Generate a new MotionEntry with a new eventId using the resolved action and
- // flags.
- resolvedMotion = std::make_shared<
- MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
- motionEntry.eventTime, motionEntry.deviceId,
- motionEntry.source, motionEntry.displayId,
- motionEntry.policyFlags, resolvedAction,
- motionEntry.actionButton, resolvedFlags,
- motionEntry.metaState, motionEntry.buttonState,
- motionEntry.classification, motionEntry.edgeFlags,
- motionEntry.xPrecision, motionEntry.yPrecision,
- motionEntry.xCursorPosition, motionEntry.yCursorPosition,
- motionEntry.downTime,
- usingProperties.value_or(motionEntry.pointerProperties),
- usingCoords.value_or(motionEntry.pointerCoords));
+ {
+ // Generate a new MotionEntry with a new eventId using the resolved action
+ // and flags, and set it as the resolved entry.
+ auto newEntry = std::make_shared<
+ MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
+ motionEntry.eventTime, motionEntry.deviceId,
+ motionEntry.source, motionEntry.displayId,
+ motionEntry.policyFlags, resolvedAction,
+ motionEntry.actionButton, resolvedFlags,
+ motionEntry.metaState, motionEntry.buttonState,
+ motionEntry.classification, motionEntry.edgeFlags,
+ motionEntry.xPrecision, motionEntry.yPrecision,
+ motionEntry.xCursorPosition,
+ motionEntry.yCursorPosition, motionEntry.downTime,
+ usingProperties.value_or(
+ motionEntry.pointerProperties),
+ usingCoords.value_or(motionEntry.pointerCoords));
+ if (mTracer) {
+ ensureEventTraced(motionEntry);
+ newEntry->traceTracker =
+ mTracer->traceDerivedEvent(*newEntry,
+ *motionEntry.traceTracker);
+ }
+ resolvedMotion = newEntry;
+ }
if (ATRACE_ENABLED()) {
std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
") to MotionEvent(id=0x%" PRIx32 ").",
@@ -3508,7 +3523,8 @@
<< cancelEvent->getDescription();
std::unique_ptr<DispatchEntry> cancelDispatchEntry =
createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
- ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId);
+ ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId,
+ mTracer.get());
// Send these cancel events to the queue before sending the event from the new
// device.
@@ -4316,6 +4332,10 @@
originalMotionEntry.xCursorPosition,
originalMotionEntry.yCursorPosition, splitDownTime,
pointerProperties, pointerCoords);
+ if (mTracer) {
+ splitMotionEntry->traceTracker =
+ mTracer->traceDerivedEvent(*splitMotionEntry, *originalMotionEntry.traceTracker);
+ }
return splitMotionEntry;
}
@@ -6614,6 +6634,10 @@
*fallbackKeyCode, event.getScanCode(),
event.getMetaState(), event.getRepeatCount(),
event.getDownTime());
+ if (mTracer) {
+ newEntry->traceTracker =
+ mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker);
+ }
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
ALOGD("Unhandled key event: Dispatching fallback key. "
"originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",