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