xref: /aosp_15_r20/frameworks/native/services/inputflinger/dispatcher/InputEventTimeline.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include "../InputDeviceMetricsSource.h"
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IBinder.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker namespace android {
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker namespace inputdispatcher {
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker /**
30*38e8c45fSAndroid Build Coastguard Worker  * Describes the input event timeline for each connection.
31*38e8c45fSAndroid Build Coastguard Worker  * An event with the same inputEventId can go to more than 1 connection simultaneously.
32*38e8c45fSAndroid Build Coastguard Worker  * For each connection that the input event goes to, there will be a separate ConnectionTimeline
33*38e8c45fSAndroid Build Coastguard Worker  * created.
34*38e8c45fSAndroid Build Coastguard Worker  * To create a complete ConnectionTimeline, we must receive two calls:
35*38e8c45fSAndroid Build Coastguard Worker  * 1) setDispatchTimeline
36*38e8c45fSAndroid Build Coastguard Worker  * 2) setGraphicsTimeline
37*38e8c45fSAndroid Build Coastguard Worker  *
38*38e8c45fSAndroid Build Coastguard Worker  * In a typical scenario, the dispatch timeline is known first. Later, if a frame is produced, the
39*38e8c45fSAndroid Build Coastguard Worker  * graphics timeline is available.
40*38e8c45fSAndroid Build Coastguard Worker  */
41*38e8c45fSAndroid Build Coastguard Worker struct ConnectionTimeline {
42*38e8c45fSAndroid Build Coastguard Worker     // DispatchTimeline
43*38e8c45fSAndroid Build Coastguard Worker     nsecs_t deliveryTime; // time at which the event was sent to the receiver
44*38e8c45fSAndroid Build Coastguard Worker     nsecs_t consumeTime;  // time at which the receiver read the event
45*38e8c45fSAndroid Build Coastguard Worker     nsecs_t finishTime;   // time at which the finish event was received
46*38e8c45fSAndroid Build Coastguard Worker     // GraphicsTimeline
47*38e8c45fSAndroid Build Coastguard Worker     std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
48*38e8c45fSAndroid Build Coastguard Worker 
49*38e8c45fSAndroid Build Coastguard Worker     ConnectionTimeline(nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
50*38e8c45fSAndroid Build Coastguard Worker     ConnectionTimeline(std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline);
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker     /**
53*38e8c45fSAndroid Build Coastguard Worker      * True if all contained timestamps are valid, false otherwise.
54*38e8c45fSAndroid Build Coastguard Worker      */
55*38e8c45fSAndroid Build Coastguard Worker     bool isComplete() const;
56*38e8c45fSAndroid Build Coastguard Worker     /**
57*38e8c45fSAndroid Build Coastguard Worker      * Set the dispatching-related times. Return true if the operation succeeded, false if the
58*38e8c45fSAndroid Build Coastguard Worker      * dispatching times have already been set. If this function returns false, it likely indicates
59*38e8c45fSAndroid Build Coastguard Worker      * an error from the app side.
60*38e8c45fSAndroid Build Coastguard Worker      */
61*38e8c45fSAndroid Build Coastguard Worker     bool setDispatchTimeline(nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
62*38e8c45fSAndroid Build Coastguard Worker     /**
63*38e8c45fSAndroid Build Coastguard Worker      * Set the graphics-related times. Return true if the operation succeeded, false if the
64*38e8c45fSAndroid Build Coastguard Worker      * graphics times have already been set. If this function returns false, it likely indicates
65*38e8c45fSAndroid Build Coastguard Worker      * an error from the app side.
66*38e8c45fSAndroid Build Coastguard Worker      */
67*38e8c45fSAndroid Build Coastguard Worker     bool setGraphicsTimeline(std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline);
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker     inline bool operator==(const ConnectionTimeline& rhs) const;
70*38e8c45fSAndroid Build Coastguard Worker     inline bool operator!=(const ConnectionTimeline& rhs) const;
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker private:
73*38e8c45fSAndroid Build Coastguard Worker     bool mHasDispatchTimeline = false;
74*38e8c45fSAndroid Build Coastguard Worker     bool mHasGraphicsTimeline = false;
75*38e8c45fSAndroid Build Coastguard Worker };
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker enum class InputEventActionType : int32_t {
78*38e8c45fSAndroid Build Coastguard Worker     UNKNOWN_INPUT_EVENT = 0,
79*38e8c45fSAndroid Build Coastguard Worker     MOTION_ACTION_DOWN = 1,
80*38e8c45fSAndroid Build Coastguard Worker     // Motion events for ACTION_MOVE (characterizes scrolling motion)
81*38e8c45fSAndroid Build Coastguard Worker     MOTION_ACTION_MOVE = 2,
82*38e8c45fSAndroid Build Coastguard Worker     // Motion events for ACTION_UP (when the pointer first goes up)
83*38e8c45fSAndroid Build Coastguard Worker     MOTION_ACTION_UP = 3,
84*38e8c45fSAndroid Build Coastguard Worker     // Motion events for ACTION_HOVER_MOVE (pointer position on screen changes but pointer is not
85*38e8c45fSAndroid Build Coastguard Worker     // down)
86*38e8c45fSAndroid Build Coastguard Worker     MOTION_ACTION_HOVER_MOVE = 4,
87*38e8c45fSAndroid Build Coastguard Worker     // Motion events for ACTION_SCROLL (moving the mouse wheel)
88*38e8c45fSAndroid Build Coastguard Worker     MOTION_ACTION_SCROLL = 5,
89*38e8c45fSAndroid Build Coastguard Worker     // Key events for both ACTION_DOWN and ACTION_UP (key press and key release)
90*38e8c45fSAndroid Build Coastguard Worker     KEY = 6,
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker     ftl_first = UNKNOWN_INPUT_EVENT,
93*38e8c45fSAndroid Build Coastguard Worker     ftl_last = KEY,
94*38e8c45fSAndroid Build Coastguard Worker     // Used by latency fuzzer
95*38e8c45fSAndroid Build Coastguard Worker     kMaxValue = ftl_last
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker };
98*38e8c45fSAndroid Build Coastguard Worker 
99*38e8c45fSAndroid Build Coastguard Worker struct InputEventTimeline {
100*38e8c45fSAndroid Build Coastguard Worker     InputEventTimeline(nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId, uint16_t productId,
101*38e8c45fSAndroid Build Coastguard Worker                        const std::set<InputDeviceUsageSource>& sources,
102*38e8c45fSAndroid Build Coastguard Worker                        InputEventActionType inputEventActionType);
103*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t eventTime;
104*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t readTime;
105*38e8c45fSAndroid Build Coastguard Worker     const uint16_t vendorId;
106*38e8c45fSAndroid Build Coastguard Worker     const uint16_t productId;
107*38e8c45fSAndroid Build Coastguard Worker     const std::set<InputDeviceUsageSource> sources;
108*38e8c45fSAndroid Build Coastguard Worker     const InputEventActionType inputEventActionType;
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker     struct IBinderHash {
operatorInputEventTimeline::IBinderHash111*38e8c45fSAndroid Build Coastguard Worker         std::size_t operator()(const sp<IBinder>& b) const {
112*38e8c45fSAndroid Build Coastguard Worker             return std::hash<IBinder*>{}(b.get());
113*38e8c45fSAndroid Build Coastguard Worker         }
114*38e8c45fSAndroid Build Coastguard Worker     };
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<sp<IBinder>, ConnectionTimeline, IBinderHash> connectionTimelines;
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker     bool operator==(const InputEventTimeline& rhs) const;
119*38e8c45fSAndroid Build Coastguard Worker };
120*38e8c45fSAndroid Build Coastguard Worker 
121*38e8c45fSAndroid Build Coastguard Worker class InputEventTimelineProcessor {
122*38e8c45fSAndroid Build Coastguard Worker protected:
InputEventTimelineProcessor()123*38e8c45fSAndroid Build Coastguard Worker     InputEventTimelineProcessor() {}
124*38e8c45fSAndroid Build Coastguard Worker 
125*38e8c45fSAndroid Build Coastguard Worker public:
~InputEventTimelineProcessor()126*38e8c45fSAndroid Build Coastguard Worker     virtual ~InputEventTimelineProcessor() {}
127*38e8c45fSAndroid Build Coastguard Worker 
128*38e8c45fSAndroid Build Coastguard Worker     /**
129*38e8c45fSAndroid Build Coastguard Worker      * Process the provided timeline
130*38e8c45fSAndroid Build Coastguard Worker      */
131*38e8c45fSAndroid Build Coastguard Worker     virtual void processTimeline(const InputEventTimeline& timeline) = 0;
132*38e8c45fSAndroid Build Coastguard Worker 
133*38e8c45fSAndroid Build Coastguard Worker     /**
134*38e8c45fSAndroid Build Coastguard Worker      * Trigger a push for the input event latency statistics
135*38e8c45fSAndroid Build Coastguard Worker      */
136*38e8c45fSAndroid Build Coastguard Worker     virtual void pushLatencyStatistics() = 0;
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker     virtual std::string dump(const char* prefix) const = 0;
139*38e8c45fSAndroid Build Coastguard Worker };
140*38e8c45fSAndroid Build Coastguard Worker 
141*38e8c45fSAndroid Build Coastguard Worker } // namespace inputdispatcher
142*38e8c45fSAndroid Build Coastguard Worker } // namespace android
143