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 <android-base/thread_annotations.h> 20 #include <kll.h> 21 #include <statslog.h> 22 #include <utils/Timers.h> 23 24 #include "InputEventTimeline.h" 25 26 namespace android::inputdispatcher { 27 28 enum SketchIndex : size_t { 29 EVENT_TO_READ = 0, 30 READ_TO_DELIVER = 1, 31 DELIVER_TO_CONSUME = 2, 32 CONSUME_TO_FINISH = 3, 33 CONSUME_TO_GPU_COMPLETE = 4, 34 GPU_COMPLETE_TO_PRESENT = 5, 35 END_TO_END = 6, // EVENT_TO_PRESENT 36 SIZE = 7, // Must be last 37 }; 38 39 // Let's create a full timeline here: 40 // eventTime 41 // readTime 42 // <---- after this point, the data becomes per-connection 43 // deliveryTime // time at which the event was sent to the receiver 44 // consumeTime // time at which the receiver read the event 45 // finishTime // time at which the finish event was received 46 // GraphicsTimeline::GPU_COMPLETED_TIME 47 // GraphicsTimeline::PRESENT_TIME 48 49 /** 50 * Keep sketches of the provided events and report slow events 51 */ 52 class LatencyAggregator final : public InputEventTimelineProcessor { 53 public: 54 LatencyAggregator(); 55 /** 56 * Record a complete event timeline 57 */ 58 void processTimeline(const InputEventTimeline& timeline) override; 59 60 void pushLatencyStatistics() override; 61 62 std::string dump(const char* prefix) const; 63 64 ~LatencyAggregator(); 65 66 private: 67 // Binder call -- called on a binder thread. This is different from the thread where the rest of 68 // the public API is called. 69 static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atom_tag, 70 AStatsEventList* data, 71 void* cookie); 72 AStatsManager_PullAtomCallbackReturn pullData(AStatsEventList* data); 73 74 // ---------- Slow event handling ---------- 75 void processSlowEvent(const InputEventTimeline& timeline); 76 nsecs_t mLastSlowEventTime = 0; 77 // How many slow events have been skipped due to rate limiting 78 size_t mNumSkippedSlowEvents = 0; 79 // How many events have been received since the last time we reported a slow event 80 size_t mNumEventsSinceLastSlowEventReport = 0; 81 82 // ---------- Statistics handling ---------- 83 // Statistics is pulled rather than pushed. It's pulled on a binder thread, and therefore will 84 // be accessed by two different threads. The lock is needed to protect the pulled data. 85 mutable std::mutex mLock; 86 void processStatistics(const InputEventTimeline& timeline); 87 // Sketches 88 std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE> 89 mDownSketches GUARDED_BY(mLock); 90 std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE> 91 mMoveSketches GUARDED_BY(mLock); 92 // How many events have been processed so far 93 size_t mNumSketchEventsProcessed GUARDED_BY(mLock) = 0; 94 }; 95 96 } // namespace android::inputdispatcher 97