• 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 
24 #include <binder/IBinder.h>
25 #include <input/Input.h>
26 
27 #include "InputEventTimeline.h"
28 #include "NotifyArgs.h"
29 
30 namespace android::inputdispatcher {
31 
32 /**
33  * Maintain a record for input events that are received by InputDispatcher, sent out to the apps,
34  * and processed by the apps. Once an event becomes "mature" (older than the ANR timeout), report
35  * the entire input event latency history to the reporting function.
36  *
37  * All calls to LatencyTracker should come from the same thread. It is not thread-safe.
38  */
39 class LatencyTracker {
40 public:
41     /**
42      * Create a LatencyTracker.
43      * param reportingFunction: the function that will be called in order to report full latency.
44      */
45     LatencyTracker(InputEventTimelineProcessor* processor);
46     /**
47      * Start keeping track of an event identified by inputEventId. This must be called first.
48      * If duplicate events are encountered (events that have the same eventId), none of them will be
49      * tracked. This is because there is not enough information to correctly track them. The api's
50      * 'trackFinishedEvent' and 'trackGraphicsLatency' only contain the inputEventId, and not the
51      * eventTime. Even if eventTime was provided, there would still be a possibility of having
52      * duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
53      * must drop all duplicate data.
54      */
55     void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime,
56                        DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources);
57     void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
58                             nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
59     void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
60                               std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
61 
62     std::string dump(const char* prefix) const;
63     void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices);
64 
65 private:
66     /**
67      * A collection of InputEventTimelines keyed by inputEventId. An InputEventTimeline is first
68      * created when 'trackListener' is called.
69      * When either 'trackFinishedEvent' or 'trackGraphicsLatency' is called for this input event,
70      * the corresponding InputEventTimeline will be updated for that token.
71      */
72     std::unordered_map<int32_t /*inputEventId*/, InputEventTimeline> mTimelines;
73     /**
74      * The collection of eventTimes will help us quickly find the events that we should prune
75      * from the 'mTimelines'. Since 'mTimelines' is keyed by inputEventId, it would be inefficient
76      * to walk through it directly to find the oldest input events to get rid of.
77      * There is a 1:1 mapping between 'mTimelines' and 'mEventTimes'.
78      * We are using 'multimap' instead of 'map' because there could be more than 1 event with the
79      * same eventTime.
80      */
81     std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes;
82 
83     InputEventTimelineProcessor* mTimelineProcessor;
84     std::vector<InputDeviceInfo> mInputDevices;
85     void reportAndPruneMatureRecords(nsecs_t newEventTime);
86 };
87 
88 } // namespace android::inputdispatcher
89