1 /* 2 ** 3 ** Copyright 2023, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_ 19 #define ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_ 20 21 #include "ResourceManagerService.h" 22 23 namespace android { 24 25 using ::aidl::android::media::ClientInfoParcel; 26 using ::aidl::android::media::ClientConfigParcel; 27 using ::aidl::android::media::IResourceManagerClient; 28 29 struct ProcessInfoInterface; 30 31 class UidObserver; 32 33 // 34 // Enumeration for Codec bucket based on: 35 // - Encoder or Decoder 36 // - hardware implementation or not 37 // - Audio/Video/Image codec 38 // 39 enum CodecBucket { 40 CodecBucketUnspecified = 0, 41 HwAudioEncoder = 1, 42 HwAudioDecoder = 2, 43 HwVideoEncoder = 3, 44 HwVideoDecoder = 4, 45 HwImageEncoder = 5, 46 HwImageDecoder = 6, 47 SwAudioEncoder = 7, 48 SwAudioDecoder = 8, 49 SwVideoEncoder = 9, 50 SwVideoDecoder = 10, 51 SwImageEncoder = 11, 52 SwImageDecoder = 12, 53 CodecBucketMaxSize = 13, 54 }; 55 56 // Map of client id and client configuration, when it was started last. 57 typedef std::map<int64_t, ClientConfigParcel> ClientConfigMap; 58 59 // Map of pid and the uid. 60 typedef std::map<int32_t, uid_t> PidUidMap; 61 62 // Map of concurrent codes by Codec type bucket. 63 struct ConcurrentCodecsMap { 64 int& operator[](CodecBucket index) { 65 return mCodec[index]; 66 } 67 68 const int& operator[](CodecBucket index) const { 69 return mCodec[index]; 70 } 71 72 private: 73 int mCodec[CodecBucketMaxSize] = {0}; 74 }; 75 76 // Current and Peak ConcurrentCodecMap for a process. 77 struct ConcurrentCodecs { 78 ConcurrentCodecsMap mCurrent; 79 ConcurrentCodecsMap mPeak; 80 // concurrent HW Video codecs. 81 int mHWVideoCodecs; 82 // concurrent SW Video codecs. 83 int mSWVideoCodecs; 84 // concurrent Video codecs. 85 int mVideoCodecs; 86 // concurrent Audio codecs. 87 int mAudioCodecs; 88 // concurrent Image codecs. 89 int mImageCodecs; 90 }; 91 92 // Current and Peak pixel count for a process. 93 struct PixelCount { 94 long mCurrent = 0; 95 long mPeak = 0; 96 }; 97 98 // 99 // Resource Manager Metrics is designed to answer some of the questions like: 100 // - What apps are causing reclaim and what apps are targeted (reclaimed from) in the process? 101 // - which apps use the most codecs and the most codec memory? 102 // - What is the % of total successful reclaims? 103 // 104 // Though, it's not in the context of this class, metrics should also answer: 105 // - what % of codec errors are due to codec being reclaimed? 106 // - What % of successful codec creation(start) requires codec reclaims? 107 // - How often codec start fails even after successful reclaim? 108 // 109 // The metrics are collected to analyze and understand the codec resource usage 110 // and use that information to help with: 111 // - minimize the no of reclaims 112 // - reduce the codec start delays by minimizing no of times we try to reclaim 113 // - minimize the reclaim errors in codec records 114 // 115 // Success metrics for Resource Manager Service could be defined as: 116 // - increase in sucecssful codec creation for the foreground apps 117 // - reduce the number of reclaims for codecs 118 // - reduce the time to create codec 119 // 120 // We would like to use this data to come up with a better resource management that would: 121 // - increase the successful codec creation (for all kind of apps) 122 // - decrease the codec errors due to resources 123 // 124 // This class that maintains concurrent codec counts based on: 125 // 126 // 1. # of concurrent active codecs (initialized, but aren't released yet) of given 127 // implementation (by codec name) across the system. 128 // 129 // 2. # of concurrent codec usage (started, but not stopped yet), which is 130 // measured using codec type bucket (CodecBucket) for: 131 // - each process/application. 132 // - across the system. 133 // Also the peak count of the same for each process/application is maintained. 134 // 135 // 3. # of Peak Concurrent Pixels for each process/application. 136 // This should help with understanding the (video) memory usage per 137 // application. 138 // 139 140 class ResourceManagerMetrics { 141 public: 142 ResourceManagerMetrics(const sp<ProcessInfoInterface>& processInfo); 143 ~ResourceManagerMetrics(); 144 145 // To be called when a client is created. 146 void notifyClientCreated(const ClientInfoParcel& clientInfo); 147 148 // To be called when a client is released. 149 void notifyClientReleased(const ClientInfoParcel& clientInfo); 150 151 // To be called when a client is started. 152 void notifyClientStarted(const ClientConfigParcel& clientConfig); 153 154 // To be called when a client is stopped. 155 void notifyClientStopped(const ClientConfigParcel& clientConfig); 156 157 // To be called when a client's configuration has changed. 158 void notifyClientConfigChanged(const ClientConfigParcel& clientConfig); 159 160 // To be called when after a reclaim event. 161 void pushReclaimAtom(const ClientInfoParcel& clientInfo, 162 const std::vector<int>& priorities, 163 const std::vector<ClientInfo>& targetClients, 164 bool reclaimed); 165 166 // Add this pid/uid set to monitor for the process termination state. 167 void addPid(int pid, uid_t uid = 0); 168 169 // Get the peak concurrent pixel count (associated with the video codecs) for the process. 170 long getPeakConcurrentPixelCount(int pid) const; 171 // Get the current concurrent pixel count (associated with the video codecs) for the process. 172 long getCurrentConcurrentPixelCount(int pid) const; 173 174 // retrieves metrics log. 175 std::string dump() const; 176 177 private: 178 ResourceManagerMetrics(const ResourceManagerMetrics&) = delete; 179 ResourceManagerMetrics(ResourceManagerMetrics&&) = delete; 180 ResourceManagerMetrics& operator=(const ResourceManagerMetrics&) = delete; 181 ResourceManagerMetrics& operator=(ResourceManagerMetrics&&) = delete; 182 183 // To increase/decrease the concurrent codec usage for a given CodecBucket. 184 void increaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket); 185 void decreaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket); 186 187 // To increase/update/decrease the concurrent pixels usage for a process. 188 void increasePixelCount(int32_t pid, long pixels); 189 void updatePixelCount(int32_t pid, long newPixels, long lastPixels); 190 void decreasePixelCount(int32_t pid, long pixels); 191 192 // Issued when the process/application with given pid/uid is terminated. 193 void onProcessTerminated(int32_t pid, uid_t uid); 194 195 // To push conccuret codec usage of a process/application. 196 void pushConcurrentUsageReport(int32_t pid, uid_t uid); 197 198 private: 199 std::mutex mLock; 200 201 // Map of client id and the configuration. 202 ClientConfigMap mClientConfigMap; 203 204 // Concurrent and Peak Pixel count for each process/application. 205 std::map<int32_t, PixelCount> mProcessPixelsMap; 206 207 // Map of resources (name) and number of concurrent instances 208 std::map<std::string, int> mConcurrentResourceCountMap; 209 210 // Map of concurrent codecs by CodecBucket across the system. 211 ConcurrentCodecsMap mConcurrentCodecsMap; 212 // Map of concurrent and peak codecs by CodecBucket for each process/application. 213 std::map<int32_t, ConcurrentCodecs> mProcessConcurrentCodecsMap; 214 215 // Uid Observer to monitor the application termination. 216 sp<UidObserver> mUidObserver; 217 }; 218 219 } // namespace android 220 221 #endif // ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_ 222