diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 5582528..803bfec 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -26,31 +26,24 @@
 #include <cutils/sched_policy.h>
 #include <dirent.h>
 #include <media/MediaResourcePolicy.h>
-#include <media/stagefright/ProcessInfo.h>
+#include <media/stagefright/foundation/ABase.h>
 #include <mediautils/BatteryNotifier.h>
+#include <mediautils/ProcessInfo.h>
 #include <mediautils/SchedulingPolicyService.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <unistd.h>
-#include <stats_media_metrics.h>
 
 #include "IMediaResourceMonitor.h"
+#include "ResourceManagerMetrics.h"
 #include "ResourceManagerService.h"
 #include "ResourceObserverService.h"
 #include "ServiceLog.h"
 
 namespace android {
 
-using stats::media_metrics::stats_write;
-using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED;
-using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
-using stats::media_metrics::\
-    MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
-using stats::media_metrics::\
-    MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
-
 //static
 std::mutex ResourceManagerService::sCookieLock;
 //static
@@ -60,8 +53,8 @@
 
 class DeathNotifier : public RefBase {
 public:
-    DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid,
-            int64_t clientId);
+    DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
+                  const ClientInfoParcel& clientInfo);
 
     virtual ~DeathNotifier() {}
 
@@ -71,13 +64,12 @@
 
 protected:
     std::weak_ptr<ResourceManagerService> mService;
-    int mPid;
-    int64_t mClientId;
+    const ClientInfoParcel mClientInfo;
 };
 
 DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
-        int pid, int64_t clientId)
-    : mService(service), mPid(pid), mClientId(clientId) {}
+                             const ClientInfoParcel& clientInfo)
+    : mService(service), mClientInfo(clientInfo) {}
 
 //static
 void DeathNotifier::BinderDiedCallback(void* cookie) {
@@ -104,16 +96,16 @@
         return;
     }
 
-    service->overridePid(mPid, -1);
+    service->overridePid(mClientInfo.pid, -1);
     // thiz is freed in the call below, so it must be last call referring thiz
-    ClientInfoParcel clientInfo{.pid = mPid, .id = mClientId};
-    service->removeResource(clientInfo, false /*checkValid*/);
+    service->removeResource(mClientInfo, false /*checkValid*/);
 }
 
 class OverrideProcessInfoDeathNotifier : public DeathNotifier {
 public:
     OverrideProcessInfoDeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
-            int pid) : DeathNotifier(service, pid, 0) {}
+                                     const ClientInfoParcel& clientInfo)
+            : DeathNotifier(service, clientInfo) {}
 
     virtual ~OverrideProcessInfoDeathNotifier() {}
 
@@ -128,7 +120,7 @@
         return;
     }
 
-    service->removeProcessInfoOverride(mPid);
+    service->removeProcessInfoOverride(mClientInfo.pid);
 }
 
 template <typename T>
@@ -201,7 +193,11 @@
         ResourceInfo info;
         info.uid = uid;
         info.clientId = clientId;
-        info.name = name;
+        if (name.empty()) {
+            info.name = "<unknown client>";
+        } else {
+            info.name = name;
+        }
         info.client = client;
         info.cookie = 0;
         info.pendingRemoval = false;
@@ -291,10 +287,7 @@
             snprintf(buffer, SIZE, "        Id: %lld\n", (long long)infos[j].clientId);
             result.append(buffer);
 
-            std::string clientName = "<unknown client>";
-            if (infos[j].client != nullptr) {
-                clientName = infos[j].name;
-            }
+            std::string clientName = infos[j].name;
             snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
             result.append(buffer);
 
@@ -356,6 +349,8 @@
       mCpuBoostCount(0),
       mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
     mSystemCB->noteResetVideo();
+    // Create ResourceManagerMetrics that handles all the metrics.
+    mResourceManagerMetrics = std::make_unique<ResourceManagerMetrics>(mProcessInfo);
 }
 
 //static
@@ -509,49 +504,16 @@
     }
     if (info.cookie == 0 && client != nullptr) {
         info.cookie = addCookieAndLink_l(client,
-                new DeathNotifier(ref<ResourceManagerService>(), pid, clientId));
+                new DeathNotifier(ref<ResourceManagerService>(), clientInfo));
     }
     if (mObserverService != nullptr && !resourceAdded.empty()) {
         mObserverService->onResourceAdded(uid, pid, resourceAdded);
     }
     notifyResourceGranted(pid, resources);
 
-    // Increase the instance count of the resource associated with this client.
-    increaseResourceInstanceCount(clientId, name);
-
     return Status::ok();
 }
 
-void ResourceManagerService::increaseResourceInstanceCount(int64_t clientId,
-                                                           const std::string& name) {
-    // Check whether this client has been looked into already.
-    if (mClientIdSet.find(clientId) == mClientIdSet.end()) {
-        mClientIdSet.insert(clientId);
-        // Update the resource instance count.
-        auto found = mConcurrentResourceCountMap.find(name);
-        if (found == mConcurrentResourceCountMap.end()) {
-            mConcurrentResourceCountMap[name] = 1;
-        } else {
-            found->second++;
-        }
-    }
-}
-
-void ResourceManagerService::decreaseResourceInstanceCount(int64_t clientId,
-                                                           const std::string& name) {
-    // Since this client has been removed, remove it from mClientIdSet
-    mClientIdSet.erase(clientId);
-    // Update the resource instance count also.
-    auto found = mConcurrentResourceCountMap.find(name);
-    if (found != mConcurrentResourceCountMap.end()) {
-        if (found->second == 1) {
-            mConcurrentResourceCountMap.erase(found);
-        } else {
-            found->second--;
-        }
-    }
-}
-
 Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo,
         const std::vector<MediaResourceParcel>& resources) {
     int32_t pid = clientInfo.pid;
@@ -656,9 +618,8 @@
         onLastRemoved(it->second, info);
     }
 
-    // Since this client has been removed, decrease the corresponding
-    // resources instance count.
-    decreaseResourceInstanceCount(clientId, info.name);
+    // Since this client has been removed, update the metrics collector.
+    mResourceManagerMetrics->notifyClientReleased(clientInfo);
 
     removeCookieAndUnlink_l(info.client, info.cookie);
 
@@ -790,73 +751,19 @@
 void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
                         const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
                         const PidUidVector& idVector, bool reclaimed) {
-    // Construct the metrics for codec reclaim as a pushed atom.
-    // 1. Information about the requester.
-    //  - UID and the priority (oom score)
     int32_t callingPid = clientInfo.pid;
-    int32_t requesterUid = clientInfo.uid;
-    std::string clientName = clientInfo.name;
     int requesterPriority = -1;
     getPriority_l(callingPid, &requesterPriority);
+    std::vector<int> priorities;
+    priorities.push_back(requesterPriority);
 
-    //  2. Information about the codec.
-    //  - Name of the codec requested
-    //  - Number of concurrent codecs running.
-    int32_t noOfConcurrentCodecs = 0;
-    auto found = mConcurrentResourceCountMap.find(clientName);
-    if (found != mConcurrentResourceCountMap.end()) {
-        noOfConcurrentCodecs = found->second;
-    }
-
-    // 3. Information about the Reclaim:
-    // - Status of reclaim request
-    // - How many codecs are reclaimed
-    // - For each codecs reclaimed, information of the process that it belonged to:
-    //    - UID and the Priority (oom score)
-    int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
-    if (!reclaimed) {
-      if (clients.size() == 0) {
-        // No clients to reclaim from
-        reclaimStatus =
-            MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
-      } else {
-        // Couldn't reclaim resources from the clients
-        reclaimStatus =
-            MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
-      }
-    }
-    int32_t noOfCodecsReclaimed = clients.size();
-    int32_t targetIndex = 1;
-    for (const auto& id : idVector) {
-        int32_t targetUid = id.second;
+    for (PidUidVector::const_reference id : idVector) {
         int targetPriority = -1;
         getPriority_l(id.first, &targetPriority);
-        // Post the pushed atom
-        int result = stats_write(
-            MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
-            requesterUid,
-            requesterPriority,
-            clientName.c_str(),
-            noOfConcurrentCodecs,
-            reclaimStatus,
-            noOfCodecsReclaimed,
-            targetIndex,
-            targetUid,
-            targetPriority);
-        ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
-              "Requester[pid(%d): uid(%d): priority(%d)] "
-              "Codec: [%s] "
-              "No of concurrent codecs: %d "
-              "Reclaim Status: %d "
-              "No of codecs reclaimed: %d "
-              "Target[%d][pid(%d): uid(%d): priority(%d)] "
-              "Atom Size: %d",
-              __func__, callingPid, requesterUid, requesterPriority,
-              clientName.c_str(), noOfConcurrentCodecs,
-              reclaimStatus, noOfCodecsReclaimed,
-              targetIndex, id.first, targetUid, targetPriority, result);
-        targetIndex++;
+        priorities.push_back(targetPriority);
     }
+    mResourceManagerMetrics->pushReclaimAtom(clientInfo, priorities, clients,
+                                             idVector, reclaimed);
 }
 
 bool ResourceManagerService::reclaimUnconditionallyFrom(
@@ -932,6 +839,7 @@
         mOverridePidMap.erase(originalPid);
         if (newPid != -1) {
             mOverridePidMap.emplace(originalPid, newPid);
+            mResourceManagerMetrics->addPid(newPid);
         }
     }
 
@@ -965,8 +873,12 @@
         return Status::fromServiceSpecificError(BAD_VALUE);
     }
 
+    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
+                                .uid = 0,
+                                .id = 0,
+                                .name = "<unknown client>"};
     uintptr_t cookie = addCookieAndLink_l(client,
-            new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), pid));
+            new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), clientInfo));
 
     mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{cookie, client});
 
@@ -1281,4 +1193,27 @@
     return true;
 }
 
+Status ResourceManagerService::notifyClientCreated(const ClientInfoParcel& clientInfo) {
+    mResourceManagerMetrics->notifyClientCreated(clientInfo);
+    return Status::ok();
+}
+
+Status ResourceManagerService::notifyClientStarted(const ClientConfigParcel& clientConfig) {
+    mResourceManagerMetrics->notifyClientStarted(clientConfig);
+    return Status::ok();
+}
+
+Status ResourceManagerService::notifyClientStopped(const ClientConfigParcel& clientConfig) {
+    mResourceManagerMetrics->notifyClientStopped(clientConfig);
+    return Status::ok();
+}
+
+long ResourceManagerService::getPeakConcurrentPixelCount(int pid) const {
+    return mResourceManagerMetrics->getPeakConcurrentPixelCount(pid);
+}
+
+long ResourceManagerService::getCurrentConcurrentPixelCount(int pid) const {
+    return mResourceManagerMetrics->getCurrentConcurrentPixelCount(pid);
+}
+
 } // namespace android
