implementing concurrent codec metrics

Following changes are made in this CL:
- extend IResourceManagerService interface to allow:
  - notify create/start/stop of codecs
- implement concurrent codec metrics with different
  buckets (such as different resolution, codec type)
  for all the application/process and for the system.
- push the codec concurrency metrics to statsd
- move all metrics to a different class
- update codec reported metrics with codec id

Bug: 265488359
Test: atest cts/tests/media/misc/src/android/media/misc/cts/ResourceManagerTest.java
      /data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
      /data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
      refactoring CL. Existing unit tests still pass.
Merged-In: Ibaa1fb9607e486f2eb79bf02d79c630e09d62b4a
Change-Id: Ibaa1fb9607e486f2eb79bf02d79c630e09d62b4a
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.h b/services/mediaresourcemanager/ResourceManagerMetrics.h
new file mode 100644
index 0000000..b7810e5
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.h
@@ -0,0 +1,179 @@
+/*
+**
+** 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<int64_t, ClientConfigParcel> ClientConfigMap;
+
+// Map of pid and the uid.
+typedef std::map<int32_t, uid_t> 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;
+};
+
+// Current and Peak pixel count for a process.
+struct PixelCount {
+    long mCurrent = 0;
+    long mPeak = 0;
+};
+
+//
+// ResourceManagerMetrics class that maintaines concurrent codec count based:
+//
+//  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<ProcessInfoInterface>& 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 after a reclaim event.
+    void pushReclaimAtom(const ClientInfoParcel& clientInfo,
+                         const std::vector<int>& priorities,
+                         const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+                         const PidUidVector& idList, 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;
+
+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/decrease the concurrent pixels usage for a process.
+    void increasePixelCount(int32_t pid, long pixels);
+    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<int32_t, PixelCount> mProcessPixelsMap;
+
+    // Map of resources (name) and number of concurrent instances
+    std::map<std::string, int> mConcurrentResourceCountMap;
+
+    // Map of concurrent codes by CodecBucket across the system.
+    ConcurrentCodecsMap mConcurrentCodecsMap;
+    // Map of concurrent and peak codes by CodecBucket for each process/application.
+    std::map<int32_t, ConcurrentCodecs> mProcessConcurrentCodecsMap;
+
+    // Uid Observer to monitor the application termination.
+    sp<UidObserver> mUidObserver;
+};
+
+} // namespace android
+
+#endif  // ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_