media: update on concurrent codec usage

This change includes:
- Calculating and passing application concurrent codec
usage for Video (Hw, SW), Audio and Image codecs to
stats.
- Updating the resource manager with change in resolution
for the video codecs

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
Merged-In: I69536f10e01f66556536812dbbe3af7831a3c722
Change-Id: I69536f10e01f66556536812dbbe3af7831a3c722
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c5da2fd..681f7a6 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -295,6 +295,7 @@
     void notifyClientCreated();
     void notifyClientStarted(ClientConfigParcel& clientConfig);
     void notifyClientStopped(ClientConfigParcel& clientConfig);
+    void notifyClientConfigChanged(ClientConfigParcel& clientConfig);
 
     inline void setCodecName(const char* name) {
         mCodecName = name;
@@ -482,7 +483,7 @@
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientStarted(
-    ClientConfigParcel& clientConfig) {
+        ClientConfigParcel& clientConfig) {
     clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
     clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
     clientConfig.clientInfo.id = getId(mClient);
@@ -491,7 +492,7 @@
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientStopped(
-    ClientConfigParcel& clientConfig) {
+        ClientConfigParcel& clientConfig) {
     clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
     clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
     clientConfig.clientInfo.id = getId(mClient);
@@ -499,6 +500,15 @@
     mService->notifyClientStopped(clientConfig);
 }
 
+void MediaCodec::ResourceManagerServiceProxy::notifyClientConfigChanged(
+        ClientConfigParcel& clientConfig) {
+    clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
+    clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
+    clientConfig.clientInfo.id = getId(mClient);
+    clientConfig.clientInfo.name = mCodecName;
+    mService->notifyClientConfigChanged(clientConfig);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {}
@@ -5097,15 +5107,28 @@
         postActivityNotificationIfPossible();
     }
 
-    // Notify mCrypto of video resolution changes
-    if (mCrypto != NULL) {
-        int32_t left, top, right, bottom, width, height;
-        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
-            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
-        } else if (mOutputFormat->findInt32("width", &width)
-                && mOutputFormat->findInt32("height", &height)) {
-            mCrypto->notifyResolution(width, height);
+    // Update the width and the height.
+    int32_t left = 0, top = 0, right = 0, bottom = 0, width = 0, height = 0;
+    bool resolutionChanged = false;
+    if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+        mWidth = right - left + 1;
+        mHeight = bottom - top + 1;
+        resolutionChanged = true;
+    } else if (mOutputFormat->findInt32("width", &width) &&
+               mOutputFormat->findInt32("height", &height)) {
+        mWidth = width;
+        mHeight = height;
+        resolutionChanged = true;
+    }
+
+    // Notify mCrypto and the RM of video resolution changes
+    if (resolutionChanged) {
+        if (mCrypto != NULL) {
+            mCrypto->notifyResolution(mWidth, mHeight);
         }
+        ClientConfigParcel clientConfig;
+        initClientConfigParcel(clientConfig);
+        mResourceManagerProxy->notifyClientConfigChanged(clientConfig);
     }
 
     updateHdrMetrics(false /* isConfig */);
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index 8d591df..f8cdb80 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -175,6 +175,22 @@
     }
 }
 
+void ResourceManagerMetrics::notifyClientConfigChanged(const ClientConfigParcel& clientConfig) {
+    std::scoped_lock lock(mLock);
+    ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id);
+    if (entry != mClientConfigMap.end() &&
+        (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
+        clientConfig.codecType == MediaResourceSubType::kImageCodec)) {
+        int pid = clientConfig.clientInfo.pid;
+        // Update the pixel count for this process
+        updatePixelCount(pid, clientConfig.width * (long)clientConfig.height,
+                         entry->second.width * (long)entry->second.height);
+        // Update the resolution in the record.
+        entry->second.width = clientConfig.width;
+        entry->second.height = clientConfig.height;
+    }
+}
+
 void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clientConfig) {
     std::scoped_lock lock(mLock);
     int pid = clientConfig.clientInfo.pid;
@@ -197,9 +213,15 @@
     }
 
     // System concurrent codec usage
-    int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket];
+    int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
     // Process/Application concurrent codec usage for this type of codec
-    int appConcurrentCodecCount = mProcessConcurrentCodecsMap[pid].mCurrent[codecBucket];
+    const ConcurrentCodecs& concurrentCodecs = mProcessConcurrentCodecsMap[pid];
+    int appConcurrentCodecs = concurrentCodecs.mCurrent[codecBucket];
+    int hwVideoCodecs = concurrentCodecs.mHWVideoCodecs;
+    int swVideoCodecs = concurrentCodecs.mSWVideoCodecs;
+    int videoCodecs = concurrentCodecs.mVideoCodecs;
+    int audioCodecs = concurrentCodecs.mAudioCodecs;
+    int imageCodecs = concurrentCodecs.mImageCodecs;
     // Process/Application's current pixel count.
     long pixelCount = 0;
     std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid);
@@ -216,9 +238,14 @@
          clientConfig.isEncoder,
          clientConfig.isHardware,
          clientConfig.width, clientConfig.height,
-         systemConcurrentCodecCount,
-         appConcurrentCodecCount,
-         pixelCount);
+         systemConcurrentCodecs,
+         appConcurrentCodecs,
+         pixelCount,
+         hwVideoCodecs,
+         swVideoCodecs,
+         videoCodecs,
+         audioCodecs,
+         imageCodecs);
 
     ALOGV("%s: Pushed MEDIA_CODEC_STARTED atom: "
           "Process[pid(%d): uid(%d)] "
@@ -226,6 +253,7 @@
           "Timestamp: %jd "
           "Resolution: %d x %d "
           "ConcurrentCodec[%d]={System: %d App: %d} "
+          "AppConcurrentCodecs{Video: %d(HW[%d] SW[%d]) Audio: %d Image: %d} "
           "result: %d",
           __func__,
           pid, clientConfig.clientInfo.uid,
@@ -236,7 +264,8 @@
           clientConfig.isEncoder? "encoder" : "decoder",
           clientConfig.timeStamp,
           clientConfig.width, clientConfig.height,
-          codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount,
+          codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
+          videoCodecs, hwVideoCodecs, swVideoCodecs, audioCodecs, imageCodecs,
           result);
 }
 
@@ -256,12 +285,12 @@
     }
 
     // System concurrent codec usage
-    int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket];
+    int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
     // Process/Application concurrent codec usage for this type of codec
-    int appConcurrentCodecCount = 0;
+    int appConcurrentCodecs = 0;
     std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
     if (found != mProcessConcurrentCodecsMap.end()) {
-        appConcurrentCodecCount = found->second.mCurrent[codecBucket];
+        appConcurrentCodecs = found->second.mCurrent[codecBucket];
     }
     // Process/Application's current pixel count.
     long pixelCount = 0;
@@ -292,8 +321,8 @@
          clientConfig.isEncoder,
          clientConfig.isHardware,
          clientConfig.width, clientConfig.height,
-         systemConcurrentCodecCount,
-         appConcurrentCodecCount,
+         systemConcurrentCodecs,
+         appConcurrentCodecs,
          pixelCount,
          usageTime);
     ALOGV("%s: Pushed MEDIA_CODEC_STOPPED atom: "
@@ -312,7 +341,7 @@
           clientConfig.isEncoder? "encoder" : "decoder",
           clientConfig.timeStamp, usageTime,
           clientConfig.width, clientConfig.height,
-          codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount,
+          codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
           result);
 }
 
@@ -484,7 +513,8 @@
         ConcurrentCodecs codecs;
         codecs.mCurrent[codecBucket] = 1;
         codecs.mPeak[codecBucket] = 1;
-        mProcessConcurrentCodecsMap.emplace(pid, codecs);
+        auto added = mProcessConcurrentCodecsMap.emplace(pid, codecs);
+        found = added.first;
     } else {
         found->second.mCurrent[codecBucket]++;
         // Check if it's the peak count for this slot.
@@ -492,6 +522,34 @@
             found->second.mPeak[codecBucket] = found->second.mCurrent[codecBucket];
         }
     }
+
+    switch (codecBucket) {
+        case HwVideoEncoder:
+        case HwVideoDecoder:
+        case SwVideoEncoder:
+        case SwVideoDecoder:
+            if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
+                found->second.mHWVideoCodecs++;
+            } else {
+                found->second.mSWVideoCodecs++;
+            }
+            found->second.mVideoCodecs++;
+            break;
+        case HwAudioEncoder:
+        case HwAudioDecoder:
+        case SwAudioEncoder:
+        case SwAudioDecoder:
+            found->second.mAudioCodecs++;
+            break;
+        case HwImageEncoder:
+        case HwImageDecoder:
+        case SwImageEncoder:
+        case SwImageDecoder:
+            found->second.mImageCodecs++;
+            break;
+        default:
+            break;
+    }
 }
 
 void ResourceManagerMetrics::decreaseConcurrentCodecs(int32_t pid,
@@ -507,6 +565,34 @@
         if (found->second.mCurrent[codecBucket] > 0) {
             found->second.mCurrent[codecBucket]--;
         }
+
+        switch (codecBucket) {
+            case HwVideoEncoder:
+            case HwVideoDecoder:
+            case SwVideoEncoder:
+            case SwVideoDecoder:
+                if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
+                    found->second.mHWVideoCodecs--;
+                } else {
+                    found->second.mSWVideoCodecs--;
+                }
+                found->second.mVideoCodecs--;
+                break;
+            case HwAudioEncoder:
+            case HwAudioDecoder:
+            case SwAudioEncoder:
+            case SwAudioDecoder:
+                found->second.mAudioCodecs--;
+                break;
+            case HwImageEncoder:
+            case HwImageDecoder:
+            case SwImageEncoder:
+            case SwImageDecoder:
+                found->second.mImageCodecs--;
+                break;
+            default:
+                break;
+        }
     }
 }
 
@@ -528,6 +614,13 @@
     }
 }
 
+void ResourceManagerMetrics::updatePixelCount(int32_t pid, long newPixels, long lastPixels) {
+    // Since there is change in resolution, decrease it by last pixels and
+    // increase it by new pixels.
+    decreasePixelCount(pid, lastPixels);
+    increasePixelCount(pid, newPixels);
+}
+
 void ResourceManagerMetrics::decreasePixelCount(int32_t pid, long pixels) {
     // Now update the current pixel usage for this (pid) process.
     std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid);
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.h b/services/mediaresourcemanager/ResourceManagerMetrics.h
index b7810e5..3124aa2 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.h
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.h
@@ -77,6 +77,16 @@
 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.
@@ -119,6 +129,9 @@
     // 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<int>& priorities,
@@ -143,8 +156,9 @@
     void increaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
     void decreaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
 
-    // To increase/decrease the concurrent pixels usage for a process.
+    // 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.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 803bfec..7446e0e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -1208,6 +1208,11 @@
     return Status::ok();
 }
 
+Status ResourceManagerService::notifyClientConfigChanged(const ClientConfigParcel& clientConfig) {
+    mResourceManagerMetrics->notifyClientConfigChanged(clientConfig);
+    return Status::ok();
+}
+
 long ResourceManagerService::getPeakConcurrentPixelCount(int pid) const {
     return mResourceManagerMetrics->getPeakConcurrentPixelCount(pid);
 }
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index b9756ae..1519e0e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -127,6 +127,8 @@
 
     Status notifyClientStopped(const ClientConfigParcel& clientConfig) override;
 
+    Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
+
 private:
     friend class ResourceManagerServiceTest;
     friend class DeathNotifier;
diff --git a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
index fcade38..5071fa3 100644
--- a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
+++ b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
@@ -156,4 +156,16 @@
      * @param clientConfig Configuration information of the client.
      */
     void notifyClientStopped(in ClientConfigParcel clientConfig);
+
+    /**
+     * Notify that the client's configuration has changed.
+     *
+     * This call is made to collect the (concurrent) metrics about the
+     * resources associated with the Codec (and also DRM sessions).
+     * This is called after notifyClientStarted (and before notifyClientStopped)
+     * to make changes to some of the configurations associated with the client.
+     *
+     * @param clientConfig Configuration information of the client.
+     */
+    void notifyClientConfigChanged(in ClientConfigParcel clientConfig);
 }