• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "../InputDeviceMetricsSource.h"
20 
21 #include <map>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include <binder/IBinder.h>
26 #include <input/Input.h>
27 #include <input/InputDevice.h>
28 
29 #include "InputEventTimeline.h"
30 #include "NotifyArgs.h"
31 
32 namespace android::inputdispatcher {
33 
34 /**
35  * Maintain a record for input events that are received by InputDispatcher, sent out to the apps,
36  * and processed by the apps. Once an event becomes "mature" (older than the ANR timeout), report
37  * the entire input event latency history to the reporting function.
38  *
39  * All calls to LatencyTracker should come from the same thread. It is not thread-safe.
40  */
41 class LatencyTracker {
42 public:
43     /**
44      * Create a LatencyTracker.
45      * param reportingFunction: the function that will be called in order to report full latency.
46      * param inputDevices: input devices relevant for tracking.
47      */
48     LatencyTracker(InputEventTimelineProcessor& processor,
49                    std::vector<InputDeviceInfo>& inputDevices);
50     /**
51      * Start keeping track of an event identified by the args. This must be called first.
52      * If duplicate events are encountered (events that have the same eventId), none of them will be
53      * tracked. This is because there is not enough information to correctly track them. It is
54      * always possible that two different events are generated with the same inputEventId and the
55      * same eventTime, so there aren't ways to distinguish those. Therefore, we must drop all
56      * duplicate data.
57      * For that reason, the APIs 'trackFinishedEvent' and 'trackGraphicsLatency' only receive the
58      * inputEventId as input.
59      */
60     void trackListener(const NotifyArgs& args);
61     void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
62                             nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
63     void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
64                               std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
65 
66     std::string dump(const char* prefix) const;
67 
68 private:
69     /**
70      * A collection of InputEventTimelines keyed by inputEventId. An InputEventTimeline is first
71      * created when 'trackListener' is called.
72      * When either 'trackFinishedEvent' or 'trackGraphicsLatency' is called for this input event,
73      * the corresponding InputEventTimeline will be updated for that token.
74      */
75     std::unordered_map<int32_t /*inputEventId*/, InputEventTimeline> mTimelines;
76     /**
77      * The collection of eventTimes will help us quickly find the events that we should prune
78      * from the 'mTimelines'. Since 'mTimelines' is keyed by inputEventId, it would be inefficient
79      * to walk through it directly to find the oldest input events to get rid of.
80      * There is a 1:1 mapping between 'mTimelines' and 'mEventTimes'.
81      * We are using 'multimap' instead of 'map' because there could be more than 1 event with the
82      * same eventTime.
83      */
84     std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes;
85 
86     InputEventTimelineProcessor* mTimelineProcessor;
87     std::vector<InputDeviceInfo>& mInputDevices;
88 
89     void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId,
90                        const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction,
91                        InputEventType inputEventType);
92     void reportAndPruneMatureRecords(nsecs_t newEventTime);
93 };
94 
95 } // namespace android::inputdispatcher
96