/* ** ** Copyright 2023, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #ifndef ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_ #define ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_ #include "ResourceManagerService.h" namespace android { using ::aidl::android::media::ClientInfoParcel; using ::aidl::android::media::ClientConfigParcel; using ::aidl::android::media::IResourceManagerClient; struct ProcessInfoInterface; class UidObserver; // // Enumeration for Codec bucket based on: // - Encoder or Decoder // - hardware implementation or not // - Audio/Video/Image codec // enum CodecBucket { CodecBucketUnspecified = 0, HwAudioEncoder = 1, HwAudioDecoder = 2, HwVideoEncoder = 3, HwVideoDecoder = 4, HwImageEncoder = 5, HwImageDecoder = 6, SwAudioEncoder = 7, SwAudioDecoder = 8, SwVideoEncoder = 9, SwVideoDecoder = 10, SwImageEncoder = 11, SwImageDecoder = 12, CodecBucketMaxSize = 13, }; // Map of client id and client configuration, when it was started last. typedef std::map ClientConfigMap; // Map of pid and the uid. typedef std::map PidUidMap; // Map of concurrent codes by Codec type bucket. struct ConcurrentCodecsMap { int& operator[](CodecBucket index) { return mCodec[index]; } const int& operator[](CodecBucket index) const { return mCodec[index]; } private: int mCodec[CodecBucketMaxSize] = {0}; }; // Current and Peak ConcurrentCodecMap for a process. struct ConcurrentCodecs { ConcurrentCodecsMap mCurrent; ConcurrentCodecsMap mPeak; // concurrent HW Video codecs. int mHWVideoCodecs; // concurrent SW Video codecs. int mSWVideoCodecs; // concurrent Video codecs. int mVideoCodecs; // concurrent Audio codecs. int mAudioCodecs; // concurrent Image codecs. int mImageCodecs; }; // Current and Peak pixel count for a process. struct PixelCount { long mCurrent = 0; long mPeak = 0; }; // // Resource Manager Metrics is designed to answer some of the questions like: // - What apps are causing reclaim and what apps are targeted (reclaimed from) in the process? // - which apps use the most codecs and the most codec memory? // - What is the % of total successful reclaims? // // Though, it's not in the context of this class, metrics should also answer: // - what % of codec errors are due to codec being reclaimed? // - What % of successful codec creation(start) requires codec reclaims? // - How often codec start fails even after successful reclaim? // // The metrics are collected to analyze and understand the codec resource usage // and use that information to help with: // - minimize the no of reclaims // - reduce the codec start delays by minimizing no of times we try to reclaim // - minimize the reclaim errors in codec records // // Success metrics for Resource Manager Service could be defined as: // - increase in sucecssful codec creation for the foreground apps // - reduce the number of reclaims for codecs // - reduce the time to create codec // // We would like to use this data to come up with a better resource management that would: // - increase the successful codec creation (for all kind of apps) // - decrease the codec errors due to resources // // This class that maintains concurrent codec counts based on: // // 1. # of concurrent active codecs (initialized, but aren't released yet) of given // implementation (by codec name) across the system. // // 2. # of concurrent codec usage (started, but not stopped yet), which is // measured using codec type bucket (CodecBucket) for: // - each process/application. // - across the system. // Also the peak count of the same for each process/application is maintained. // // 3. # of Peak Concurrent Pixels for each process/application. // This should help with understanding the (video) memory usage per // application. // class ResourceManagerMetrics { public: ResourceManagerMetrics(const sp& processInfo); ~ResourceManagerMetrics(); // To be called when a client is created. void notifyClientCreated(const ClientInfoParcel& clientInfo); // To be called when a client is released. void notifyClientReleased(const ClientInfoParcel& clientInfo); // To be called when a client is started. void notifyClientStarted(const ClientConfigParcel& clientConfig); // To be called when a client is stopped. void notifyClientStopped(const ClientConfigParcel& clientConfig); // To be called when a client's configuration has changed. void notifyClientConfigChanged(const ClientConfigParcel& clientConfig); // To be called when after a reclaim event. void pushReclaimAtom(const ClientInfoParcel& clientInfo, const std::vector& priorities, const std::vector& targetClients, bool reclaimed); // Add this pid/uid set to monitor for the process termination state. void addPid(int pid, uid_t uid = 0); // Get the peak concurrent pixel count (associated with the video codecs) for the process. long getPeakConcurrentPixelCount(int pid) const; // Get the current concurrent pixel count (associated with the video codecs) for the process. long getCurrentConcurrentPixelCount(int pid) const; // retrieves metrics log. std::string dump() const; private: ResourceManagerMetrics(const ResourceManagerMetrics&) = delete; ResourceManagerMetrics(ResourceManagerMetrics&&) = delete; ResourceManagerMetrics& operator=(const ResourceManagerMetrics&) = delete; ResourceManagerMetrics& operator=(ResourceManagerMetrics&&) = delete; // To increase/decrease the concurrent codec usage for a given CodecBucket. void increaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket); void decreaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket); // To increase/update/decrease the concurrent pixels usage for a process. void increasePixelCount(int32_t pid, long pixels); void updatePixelCount(int32_t pid, long newPixels, long lastPixels); void decreasePixelCount(int32_t pid, long pixels); // Issued when the process/application with given pid/uid is terminated. void onProcessTerminated(int32_t pid, uid_t uid); // To push conccuret codec usage of a process/application. void pushConcurrentUsageReport(int32_t pid, uid_t uid); private: std::mutex mLock; // Map of client id and the configuration. ClientConfigMap mClientConfigMap; // Concurrent and Peak Pixel count for each process/application. std::map mProcessPixelsMap; // Map of resources (name) and number of concurrent instances std::map mConcurrentResourceCountMap; // Map of concurrent codecs by CodecBucket across the system. ConcurrentCodecsMap mConcurrentCodecsMap; // Map of concurrent and peak codecs by CodecBucket for each process/application. std::map mProcessConcurrentCodecsMap; // Uid Observer to monitor the application termination. sp mUidObserver; }; } // namespace android #endif // ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_