Adding an InputEventActionType enum field to InputEventTimeline.

This is needed for the Per Device Input Latency metrics which will be implemented, because we would
like to filter the data per input event action type. This enum corresponds to the InputEventType
enum field that will be added to the InputEventLatency atom.

InputEventTimeline already had a bool field isDown that was true only if the Motion Event was an
ACTION_DOWN, so we were dividing the latency values into two categories: DOWN vs other types of
events. The isDown field is still needed for the InputEventLatencySketch atom, but should be
deprecated with this atom once the new atom is recording data.

Bug: b/270049345
Test: atest inputflinger_tests
Flag: EXEMPT bugfix

Change-Id: Iabccb7217820d4ed070378d8f4d8f0410a2efbdf
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index fcea0f3..d549cbc 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 @@
         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 a365003..31ceb8d 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.cpp
+++ b/services/inputflinger/dispatcher/InputEventTimeline.cpp
@@ -68,13 +68,15 @@
 
 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 @@
         }
     }
     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 1756944..6668399 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.h
+++ b/services/inputflinger/dispatcher/InputEventTimeline.h
@@ -74,15 +74,39 @@
     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 698bd9f..721d009 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -67,9 +67,10 @@
     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 @@
         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 890d61d..532f422 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -52,8 +52,9 @@
      * 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,