1 /* 2 * Copyright 2024 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 <cstdint> 20 #include <mutex> 21 #include <unordered_map> 22 23 #include <android/gui/JankData.h> 24 #include <binder/IBinder.h> 25 #include <utils/Mutex.h> 26 27 namespace android { 28 namespace frametimeline { 29 class FrameTimelineTest; 30 } 31 32 /** 33 * JankTracker maintains a backlog of frame jank classification and manages and notififies any 34 * registered jank data listeners. 35 */ 36 class JankTracker { 37 public: 38 ~JankTracker(); 39 40 static void addJankListener(int32_t layerId, sp<IBinder> listener); 41 static void flushJankData(int32_t layerId); 42 static void removeJankListener(int32_t layerId, sp<IBinder> listener, int64_t afterVysnc); 43 44 static void onJankData(int32_t layerId, gui::JankData data); 45 46 protected: 47 // The following methods can be used to force the tracker to collect all jank data and not 48 // flush it for a short time period and should *only* be used for testing. Every call to 49 // clearAndStartCollectingAllJankDataForTesting needs to be followed by a call to 50 // clearAndStopCollectingAllJankDataForTesting. 51 static void clearAndStartCollectingAllJankDataForTesting(); 52 static std::vector<gui::JankData> getCollectedJankDataForTesting(int32_t layerId); 53 static void clearAndStopCollectingAllJankDataForTesting(); 54 55 friend class frametimeline::FrameTimelineTest; 56 57 private: JankTracker()58 JankTracker() {} 59 JankTracker(const JankTracker&) = delete; 60 JankTracker(JankTracker&&) = delete; 61 62 JankTracker& operator=(const JankTracker&) = delete; 63 JankTracker& operator=(JankTracker&&) = delete; 64 getInstance()65 static JankTracker& getInstance() { 66 static JankTracker instance; 67 return instance; 68 } 69 70 void addJankListenerLocked(int32_t layerId, sp<IBinder> listener) REQUIRES(mLock); 71 void doFlushJankData(int32_t layerId); 72 void markJankListenerForRemovalLocked(int32_t layerId, sp<IBinder> listener, int64_t afterVysnc) 73 REQUIRES(mLock); 74 75 int64_t transferAvailableJankData(int32_t layerId, std::vector<gui::JankData>& jankData); 76 void dropJankListener(int32_t layerId, sp<IBinder> listener); 77 78 struct Listener { 79 sp<IBinder> mListener; 80 int64_t mRemoveAfter; 81 ListenerListener82 Listener(sp<IBinder>&& listener) : mListener(listener), mRemoveAfter(-1) {} 83 }; 84 85 // We keep track of the current listener count, so that the onJankData call, which is on the 86 // main thread, can short-curcuit the scheduling on the background thread (which involves 87 // locking) if there are no listeners registered, which is the most common case. 88 static std::atomic<size_t> sListenerCount; 89 static std::atomic<bool> sCollectAllJankDataForTesting; 90 91 std::mutex mLock; 92 std::unordered_multimap<int32_t, Listener> mJankListeners GUARDED_BY(mLock); 93 std::mutex mJankDataLock; 94 std::unordered_multimap<int32_t, gui::JankData> mJankData GUARDED_BY(mJankDataLock); 95 96 friend class JankTrackerTest; 97 }; 98 99 } // namespace android 100