InputTracer: Track inbound events

Track whether an event is an inbound event or a synthesized event. Then
read the config flags from the perfetto backend, and decide whether to
ignore events in the trace depending on the flags that are enabled.

Bug: 210460522
Test: manual with perfetto
Change-Id: I665644f026fca4ab823221656c7b519893e2a1eb
diff --git a/services/inputflinger/dispatcher/trace/InputTracer.cpp b/services/inputflinger/dispatcher/trace/InputTracer.cpp
index 47e27be..d776249 100644
--- a/services/inputflinger/dispatcher/trace/InputTracer.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracer.cpp
@@ -30,7 +30,7 @@
     using V::operator()...;
 };
 
-TracedEvent createTracedEvent(const MotionEntry& e) {
+TracedEvent createTracedEvent(const MotionEntry& e, EventType type) {
     return TracedMotionEvent{e.id,
                              e.eventTime,
                              e.policyFlags,
@@ -50,13 +50,14 @@
                              e.yCursorPosition,
                              e.downTime,
                              e.pointerProperties,
-                             e.pointerCoords};
+                             e.pointerCoords,
+                             type};
 }
 
-TracedEvent createTracedEvent(const KeyEntry& e) {
+TracedEvent createTracedEvent(const KeyEntry& e, EventType type) {
     return TracedKeyEvent{e.id,        e.eventTime, e.policyFlags, e.deviceId, e.source,
                           e.displayId, e.action,    e.keyCode,     e.scanCode, e.metaState,
-                          e.downTime,  e.flags,     e.repeatCount};
+                          e.downTime,  e.flags,     e.repeatCount, type};
 }
 
 void writeEventToBackend(const TracedEvent& event, const TracedEventArgs args,
@@ -83,10 +84,10 @@
 
     if (entry.type == EventEntry::Type::MOTION) {
         const auto& motion = static_cast<const MotionEntry&>(entry);
-        eventState->events.emplace_back(createTracedEvent(motion));
+        eventState->events.emplace_back(createTracedEvent(motion, EventType::INBOUND));
     } else if (entry.type == EventEntry::Type::KEY) {
         const auto& key = static_cast<const KeyEntry&>(entry);
-        eventState->events.emplace_back(createTracedEvent(key));
+        eventState->events.emplace_back(createTracedEvent(key, EventType::INBOUND));
     } else {
         LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
     }
@@ -138,10 +139,10 @@
 
     if (entry.type == EventEntry::Type::MOTION) {
         const auto& motion = static_cast<const MotionEntry&>(entry);
-        eventState->events.emplace_back(createTracedEvent(motion));
+        eventState->events.emplace_back(createTracedEvent(motion, EventType::SYNTHESIZED));
     } else if (entry.type == EventEntry::Type::KEY) {
         const auto& key = static_cast<const KeyEntry&>(entry);
-        eventState->events.emplace_back(createTracedEvent(key));
+        eventState->events.emplace_back(createTracedEvent(key, EventType::SYNTHESIZED));
     } else {
         LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
     }
@@ -150,8 +151,9 @@
         // It is possible for a derived event to be dispatched some time after the original event
         // is dispatched, such as in the case of key fallback events. To account for these cases,
         // derived events can be traced after the processing is complete for the original event.
+        const auto& event = eventState->events.back();
         const TracedEventArgs traceArgs{.isSecure = eventState->isSecure};
-        writeEventToBackend(eventState->events.back(), traceArgs, *mBackend);
+        writeEventToBackend(event, traceArgs, *mBackend);
     }
     return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/true);
 }
@@ -160,26 +162,18 @@
                                      const EventTrackerInterface& cookie) {
     auto& eventState = getState(cookie);
     const EventEntry& entry = *dispatchEntry.eventEntry;
+    const int32_t eventId = entry.id;
     // TODO(b/328618922): Remove resolved key repeats after making repeatCount non-mutable.
     // The KeyEntry's repeatCount is mutable and can be modified after an event is initially traced,
     // so we need to find the repeatCount at the time of dispatching to trace it accurately.
     int32_t resolvedKeyRepeatCount = 0;
-
-    TracedEvent traced;
-    if (entry.type == EventEntry::Type::MOTION) {
-        const auto& motion = static_cast<const MotionEntry&>(entry);
-        traced = createTracedEvent(motion);
-    } else if (entry.type == EventEntry::Type::KEY) {
-        const auto& key = static_cast<const KeyEntry&>(entry);
-        resolvedKeyRepeatCount = key.repeatCount;
-        traced = createTracedEvent(key);
-    } else {
-        LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
+    if (entry.type == EventEntry::Type::KEY) {
+        resolvedKeyRepeatCount = static_cast<const KeyEntry&>(entry).repeatCount;
     }
 
     auto tracedEventIt =
             std::find_if(eventState->events.begin(), eventState->events.end(),
-                         [&traced](const auto& event) { return getId(traced) == getId(event); });
+                         [eventId](const auto& event) { return eventId == getId(event); });
     if (tracedEventIt == eventState->events.end()) {
         LOG(FATAL)
                 << __func__
@@ -191,7 +185,7 @@
     const int32_t vsyncId = dispatchEntry.windowId.has_value() ? dispatchEntry.vsyncId : 0;
 
     // TODO(b/210460522): Pass HMAC into traceEventDispatch.
-    const WindowDispatchArgs windowDispatchArgs{std::move(traced),
+    const WindowDispatchArgs windowDispatchArgs{*tracedEventIt,
                                                 dispatchEntry.deliveryTime,
                                                 dispatchEntry.resolvedFlags,
                                                 dispatchEntry.targetUid,
@@ -222,12 +216,23 @@
 
 void InputTracer::EventState::onEventProcessingComplete() {
     // Write all of the events known so far to the trace.
-    const TracedEventArgs traceArgs{.isSecure = isSecure};
     for (const auto& event : events) {
+        const TracedEventArgs traceArgs{.isSecure = isSecure};
         writeEventToBackend(event, traceArgs, *tracer.mBackend);
     }
     // Write all pending dispatch args to the trace.
     for (const auto& windowDispatchArgs : pendingDispatchArgs) {
+        auto tracedEventIt =
+                std::find_if(events.begin(), events.end(),
+                             [id = getId(windowDispatchArgs.eventEntry)](const auto& event) {
+                                 return id == getId(event);
+                             });
+        if (tracedEventIt == events.end()) {
+            LOG(FATAL) << __func__
+                       << ": Failed to find a previously traced event that matches the dispatched "
+                          "event";
+        }
+        const TracedEventArgs traceArgs{.isSecure = isSecure};
         tracer.mBackend->traceWindowDispatch(windowDispatchArgs, traceArgs);
     }
     pendingDispatchArgs.clear();
diff --git a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
index 6eef12e..4bb5799 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
+++ b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
@@ -27,6 +27,20 @@
 namespace android::inputdispatcher::trace {
 
 /**
+ * Describes the type of this event being traced, with respect to InputDispatcher.
+ */
+enum class EventType {
+    // This is an event that was reported through the InputListener interface or was injected.
+    INBOUND,
+    // This is an event that was synthesized within InputDispatcher; either being derived
+    // from an inbound event (e.g. a split motion event), or synthesized completely
+    // (e.g. a CANCEL event generated when the inbound stream is not canceled).
+    SYNTHESIZED,
+
+    ftl_last = SYNTHESIZED,
+};
+
+/**
  * A representation of an Android KeyEvent used by the tracing backend.
  */
 struct TracedKeyEvent {
@@ -43,6 +57,7 @@
     nsecs_t downTime;
     int32_t flags;
     int32_t repeatCount;
+    EventType eventType;
 };
 
 /**
@@ -69,6 +84,7 @@
     nsecs_t downTime;
     std::vector<PointerProperties> pointerProperties;
     std::vector<PointerCoords> pointerCoords;
+    EventType eventType;
 };
 
 /** A representation of a traced input event. */
diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
index e8d89e0..998ec8a 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
@@ -55,6 +55,20 @@
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) { ctx.Flush(); });
 }
 
+bool PerfettoBackend::InputEventDataSource::shouldIgnoreTracedInputEvent(
+        const EventType& type) const {
+    if (!getFlags().test(TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS)) {
+        // Ignore all input events.
+        return true;
+    }
+    if (!getFlags().test(TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH) &&
+        type != EventType::INBOUND) {
+        // When window dispatch tracing is disabled, ignore any events that are not inbound events.
+        return true;
+    }
+    return false;
+}
+
 // --- PerfettoBackend ---
 
 std::once_flag PerfettoBackend::sDataSourceRegistrationFlag{};
@@ -85,6 +99,10 @@
         return;
     }
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
+        auto dataSource = ctx.GetDataSourceLocked();
+        if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
+            return;
+        }
         auto tracePacket = ctx.NewTracePacket();
         auto* inputEvent = tracePacket->set_android_input_event();
         auto* dispatchMotion = inputEvent->set_dispatcher_motion_event();
@@ -98,6 +116,10 @@
         return;
     }
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
+        auto dataSource = ctx.GetDataSourceLocked();
+        if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
+            return;
+        }
         auto tracePacket = ctx.NewTracePacket();
         auto* inputEvent = tracePacket->set_android_input_event();
         auto* dispatchKey = inputEvent->set_dispatcher_key_event();
@@ -112,6 +134,10 @@
         return;
     }
     InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
+        auto dataSource = ctx.GetDataSourceLocked();
+        if (!dataSource->getFlags().test(TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH)) {
+            return;
+        }
         auto tracePacket = ctx.NewTracePacket();
         auto* inputEvent = tracePacket->set_android_input_event();
         auto* dispatchEvent = inputEvent->set_dispatcher_window_dispatch_event();
diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h
index 7e1e36a..920ea60 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h
+++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h
@@ -20,6 +20,7 @@
 
 #include "InputTracingPerfettoBackendConfig.h"
 
+#include <ftl/flags.h>
 #include <perfetto/tracing.h>
 #include <mutex>
 
@@ -65,6 +66,9 @@
         void OnStart(const StartArgs&) override;
         void OnStop(const StopArgs&) override;
 
+        bool shouldIgnoreTracedInputEvent(const EventType&) const;
+        inline ftl::Flags<TraceFlag> getFlags() const { return mConfig.flags; }
+
     private:
         const int32_t mInstanceId;
         TraceConfig mConfig;