resourcemanager: refactor resource map into an abstraction

This CL moves the resource tracking into a new abstraction
ResourceTracker by moving all the related codec from the
ResourceManagerServiceNew into this new class.

Bug: 294886363
Test: atest android.media.misc.cts.ResourceManagerTest
      atest android.media.misc.cts.ResourceManagerMultiTest
      /data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
      /data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
      /data/nativetest64/ServiceLog_test/ServiceLog_test
Change-Id: I0ac5739cbefff3756cc3a9f20a6bc6c0ddd9e732
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index 45322bb..efb042c 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -79,6 +79,7 @@
         "ResourceManagerServiceNew.cpp",
         "ResourceObserverService.cpp",
         "ResourceManagerServiceUtils.cpp",
+        "ResourceTracker.cpp",
         "ServiceLog.cpp",
         "UidObserver.cpp",
 
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 68794e4..3e0ac84 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -31,7 +31,6 @@
 #include <mediautils/SchedulingPolicyService.h>
 #include <com_android_media_codec_flags.h>
 
-#include "IMediaResourceMonitor.h"
 #include "ResourceManagerMetrics.h"
 #include "ResourceManagerServiceNew.h"
 #include "ResourceObserverService.h"
@@ -41,30 +40,53 @@
 
 namespace android {
 
-static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel>& resources) {
-    static const char* const kServiceName = "media_resource_monitor";
-    sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
-    if (binder != NULL) {
-        sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
-        for (size_t i = 0; i < resources.size(); ++i) {
-            switch (resources[i].subType) {
-                case MediaResource::SubType::kHwAudioCodec:
-                case MediaResource::SubType::kSwAudioCodec:
-                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
-                    break;
-                case MediaResource::SubType::kHwVideoCodec:
-                case MediaResource::SubType::kSwVideoCodec:
-                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
-                    break;
-                case MediaResource::SubType::kHwImageCodec:
-                case MediaResource::SubType::kSwImageCodec:
-                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC);
-                    break;
-                case MediaResource::SubType::kUnspecifiedSubType:
-                    break;
+void ResourceManagerService::getResourceDump(std::string& resourceLog) const {
+    PidResourceInfosMap mapCopy;
+    std::map<int, int> overridePidMapCopy;
+    {
+        std::scoped_lock lock{mLock};
+        mapCopy = mMap;  // Shadow copy, real copy will happen on write.
+        overridePidMapCopy = mOverridePidMap;
+    }
+
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    resourceLog.append("  Processes:\n");
+    for (const auto& [pid, infos] : mapCopy) {
+        snprintf(buffer, SIZE, "    Pid: %d\n", pid);
+        resourceLog.append(buffer);
+        int priority = 0;
+        if (getPriority_l(pid, &priority)) {
+            snprintf(buffer, SIZE, "    Priority: %d\n", priority);
+        } else {
+            snprintf(buffer, SIZE, "    Priority: <unknown>\n");
+        }
+        resourceLog.append(buffer);
+
+        for (const auto& [infoKey, info] : infos) {
+            resourceLog.append("      Client:\n");
+            snprintf(buffer, SIZE, "        Id: %lld\n", (long long)info.clientId);
+            resourceLog.append(buffer);
+
+            std::string clientName = info.name;
+            snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
+            resourceLog.append(buffer);
+
+            const ResourceList& resources = info.resources;
+            resourceLog.append("        Resources:\n");
+            for (auto it = resources.begin(); it != resources.end(); it++) {
+                snprintf(buffer, SIZE, "          %s\n", toString(it->second).c_str());
+                resourceLog.append(buffer);
             }
         }
     }
+
+    resourceLog.append("  Process Pid override:\n");
+    for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
+        snprintf(buffer, SIZE, "    Original Pid: %d,  Override Pid: %d\n",
+            it->first, it->second);
+        resourceLog.append(buffer);
+    }
 }
 
 binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
@@ -79,20 +101,20 @@
         return PERMISSION_DENIED;
     }
 
-    PidResourceInfosMap mapCopy;
     bool supportsMultipleSecureCodecs;
     bool supportsSecureWithNonSecureCodec;
-    std::map<int, int> overridePidMapCopy;
     String8 serviceLog;
     {
         std::scoped_lock lock{mLock};
-        mapCopy = mMap;  // Shadow copy, real copy will happen on write.
         supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
         supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
         serviceLog = mServiceLog->toString("    " /* linePrefix */);
-        overridePidMapCopy = mOverridePidMap;
     }
 
+    // Get all the resource (and overload pid) logs
+    std::string resourceLog;
+    getResourceDump(resourceLog);
+
     const size_t SIZE = 256;
     char buffer[SIZE];
     snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
@@ -104,41 +126,8 @@
             supportsSecureWithNonSecureCodec);
     result.append(buffer);
 
-    result.append("  Processes:\n");
-    for (const auto& [pid, infos] : mapCopy) {
-        snprintf(buffer, SIZE, "    Pid: %d\n", pid);
-        result.append(buffer);
-        int priority = 0;
-        if (getPriority_l(pid, &priority)) {
-            snprintf(buffer, SIZE, "    Priority: %d\n", priority);
-        } else {
-            snprintf(buffer, SIZE, "    Priority: <unknown>\n");
-        }
-        result.append(buffer);
+    result.append(resourceLog.c_str());
 
-        for (const auto& [infoKey, info] : infos) {
-            result.append("      Client:\n");
-            snprintf(buffer, SIZE, "        Id: %lld\n", (long long)info.clientId);
-            result.append(buffer);
-
-            std::string clientName = info.name;
-            snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
-            result.append(buffer);
-
-            const ResourceList& resources = info.resources;
-            result.append("        Resources:\n");
-            for (auto it = resources.begin(); it != resources.end(); it++) {
-                snprintf(buffer, SIZE, "          %s\n", toString(it->second).c_str());
-                result.append(buffer);
-            }
-        }
-    }
-    result.append("  Process Pid override:\n");
-    for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
-        snprintf(buffer, SIZE, "    Original Pid: %d,  Override Pid: %d\n",
-            it->first, it->second);
-        result.append(buffer);
-    }
     result.append("  Events logs (most recent at top):\n");
     result.append(serviceLog);
 
@@ -216,20 +205,35 @@
 std::shared_ptr<ResourceManagerService> ResourceManagerService::Create(
         const sp<ProcessInfoInterface>& processInfo,
         const sp<SystemCallbackInterface>& systemResource) {
+    std::shared_ptr<ResourceManagerService> service = nullptr;
     // If codec importance feature is on, create the refactored implementation.
     if (CodecFeatureFlags::codec_importance()) {
-        return ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo, systemResource);
+        service = ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo,
+                                                                        systemResource);
+    } else {
+        service = ::ndk::SharedRefBase::make<ResourceManagerService>(processInfo,
+                                                                     systemResource);
     }
-    return ::ndk::SharedRefBase::make<ResourceManagerService>(processInfo, systemResource);
+
+    if (service != nullptr) {
+        service->init();
+    }
+
+    return service;
 }
 
 // TEST only function.
 std::shared_ptr<ResourceManagerService> ResourceManagerService::CreateNew(
         const sp<ProcessInfoInterface>& processInfo,
         const sp<SystemCallbackInterface>& systemResource) {
-    return ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo, systemResource);
+    std::shared_ptr<ResourceManagerService> service =
+        ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo, systemResource);
+    service->init();
+    return service;
 }
 
+void ResourceManagerService::init() {}
+
 ResourceManagerService::~ResourceManagerService() {}
 
 void ResourceManagerService::setObserverService(
@@ -701,6 +705,16 @@
     return false;
 }
 
+bool ResourceManagerService::overridePid_l(int32_t originalPid, int32_t newPid) {
+    mOverridePidMap.erase(originalPid);
+    if (newPid != -1) {
+        mOverridePidMap.emplace(originalPid, newPid);
+        return true;
+    }
+
+    return false;
+}
+
 Status ResourceManagerService::overridePid(int originalPid, int newPid) {
     String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
             originalPid, newPid);
@@ -720,9 +734,7 @@
 
     {
         std::scoped_lock lock{mLock};
-        mOverridePidMap.erase(originalPid);
-        if (newPid != -1) {
-            mOverridePidMap.emplace(originalPid, newPid);
+        if (overridePid_l(originalPid, newPid)) {
             mResourceManagerMetrics->addPid(newPid);
         }
     }
@@ -730,6 +742,29 @@
     return Status::ok();
 }
 
+bool ResourceManagerService::overrideProcessInfo_l(
+        const std::shared_ptr<IResourceManagerClient>& client,
+        int pid,
+        int procState,
+        int oomScore) {
+    removeProcessInfoOverride_l(pid);
+
+    if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
+        // Override value is rejected by ProcessInfo.
+        return false;
+    }
+
+    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
+                                .uid = 0,
+                                .id = 0,
+                                .name = "<unknown client>"};
+    auto deathNotifier = DeathNotifier::Create(
+        client, ref<ResourceManagerService>(), clientInfo, true);
+
+    mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{deathNotifier, client});
+    return true;
+}
+
 Status ResourceManagerService::overrideProcessInfo(
         const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState,
         int oomScore) {
@@ -750,23 +785,12 @@
     }
 
     std::scoped_lock lock{mLock};
-    removeProcessInfoOverride_l(pid);
-
-    if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
+    if (!overrideProcessInfo_l(client, pid, procState, oomScore)) {
         // Override value is rejected by ProcessInfo.
         return Status::fromServiceSpecificError(BAD_VALUE);
     }
-
-    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
-                                .uid = 0,
-                                .id = 0,
-                                .name = "<unknown client>"};
-    auto deathNotifier = DeathNotifier::Create(
-        client, ref<ResourceManagerService>(), clientInfo, true);
-
-    mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{deathNotifier, client});
-
     return Status::ok();
+
 }
 
 void ResourceManagerService::removeProcessInfoOverride(int pid) {
@@ -872,11 +896,12 @@
     return Status::ok();
 }
 
-bool ResourceManagerService::getPriority_l(int pid, int* priority) {
+bool ResourceManagerService::getPriority_l(int pid, int* priority) const {
     int newPid = pid;
 
-    if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
-        newPid = mOverridePidMap[pid];
+    std::map<int, int>::const_iterator found = mOverridePidMap.find(pid);
+    if (found != mOverridePidMap.end()) {
+        newPid = found->second;
         ALOGD("getPriority_l: use override pid %d instead original pid %d",
                 newPid, pid);
     }
@@ -1068,4 +1093,8 @@
     return mResourceManagerMetrics->getCurrentConcurrentPixelCount(pid);
 }
 
+void ResourceManagerService::notifyClientReleased(const ClientInfoParcel& clientInfo) {
+    mResourceManagerMetrics->notifyClientReleased(clientInfo);
+}
+
 } // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 69ebf24..dcc0bb5 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -73,7 +73,8 @@
             const sp<SystemCallbackInterface> &systemResource);
     virtual ~ResourceManagerService();
 
-    void setObserverService(const std::shared_ptr<ResourceObserverService>& observerService);
+    virtual void setObserverService(
+            const std::shared_ptr<ResourceObserverService>& observerService);
 
     // IResourceManagerService interface
     Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
@@ -103,8 +104,6 @@
 
     Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override;
 
-    Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid);
-
     Status notifyClientCreated(const ClientInfoParcel& clientInfo) override;
 
     Status notifyClientStarted(const ClientConfigParcel& clientConfig) override;
@@ -113,23 +112,31 @@
 
     Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
 
+protected:
+    // To get notifications when a resource is added for the first time.
+    void onFirstAdded(const MediaResourceParcel& res, uid_t uid);
+    // To get notifications when a resource has been removed at last.
+    void onLastRemoved(const MediaResourceParcel& res, uid_t uid);
+
+    // Reclaims resources from |clients|. Returns true if reclaim succeeded
+    // for all clients.
+    bool reclaimUnconditionallyFrom(const std::vector<ClientInfo>& targetClients);
+
+    // A helper function that returns true if the callingPid has higher priority than pid.
+    // Returns false otherwise.
+    bool isCallingPriorityHigher_l(int callingPid, int pid);
+
+    // To notify the metrics about client being released.
+    void notifyClientReleased(const ClientInfoParcel& clientInfo);
+
+    virtual Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid);
+
 private:
     friend class ResourceManagerServiceTest;
     friend class ResourceManagerServiceTestBase;
     friend class DeathNotifier;
     friend class OverrideProcessInfoDeathNotifier;
 
-    // Reclaims resources from |clients|. Returns true if reclaim succeeded
-    // for all clients.
-    bool reclaimUnconditionallyFrom(
-        const std::vector<ClientInfo>& targetClients);
-
-    // Gets the list of all the clients who own the specified resource type.
-    // Returns false if any client belongs to a process with higher priority than the
-    // calling process. The clients will remain unchanged if returns false.
-    bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
-                         std::vector<ClientInfo>& clientsInfo);
-
     // Gets the client who owns specified resource type from lowest possible priority process.
     // Returns false if the calling process priority is not higher than the lowest process
     // priority. The client will remain unchanged if returns false.
@@ -137,51 +144,73 @@
         const ResourceRequestInfo& resourceRequestInfo,
         ClientInfo& clientInfo);
 
-    // Gets the client who owns biggest piece of specified resource type from pid.
-    // Returns false with no change to client if there are no clients holding resources of this
-    // type.
-    bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType,
-                            ClientInfo& clientsInfo,
-                            bool pendingRemovalOnly = false);
     // Same method as above, but with pendingRemovalOnly as true.
     bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
                                           MediaResource::SubType subType,
                                           ClientInfo& clientsInfo);
 
-    // A helper function that returns true if the callingPid has higher priority than pid.
-    // Returns false otherwise.
-    bool isCallingPriorityHigher_l(int callingPid, int pid);
-
     // A helper function basically calls getLowestPriorityBiggestClient_l and adds
     // the result client to the given Vector.
     void getClientForResource_l(const ResourceRequestInfo& resourceRequestInfo,
                                 std::vector<ClientInfo>& clientsInfo);
 
-    void onFirstAdded(const MediaResourceParcel& res, uid_t uid);
-    void onLastRemoved(const MediaResourceParcel& res, uid_t uid);
+    // Eventually we want to phase out this implementation of IResourceManagerService
+    // (ResourceManagerService) and replace that with the newer implementation
+    // (ResourceManagerServiceNew).
+    // So, marking the following methods as private virtual and for the newer implementation
+    // to override is the easiest way to maintain both implementation.
+
+    // Initializes the internal state of the ResourceManagerService
+    virtual void init();
+
+    // Gets the list of all the clients who own the specified resource type.
+    // Returns false if any client belongs to a process with higher priority than the
+    // calling process. The clients will remain unchanged if returns false.
+    virtual bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
+                                 std::vector<ClientInfo>& clientsInfo);
+
+    // Gets the client who owns biggest piece of specified resource type from pid.
+    // Returns false with no change to client if there are no clients holding resources of this
+    // type.
+    virtual bool getBiggestClient_l(int pid, MediaResource::Type type,
+                                    MediaResource::SubType subType,
+                                    ClientInfo& clientsInfo,
+                                    bool pendingRemovalOnly = false);
+
+    virtual bool overridePid_l(int32_t originalPid, int32_t newPid);
+
+    virtual bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
+                                       int pid, int procState, int oomScore);
 
     // Get priority from process's pid
-    bool getPriority_l(int pid, int* priority);
+    virtual bool getPriority_l(int pid, int* priority) const;
 
-    void removeProcessInfoOverride(int pid);
+    // Gets lowest priority process that has the specified resource type.
+    // Returns false if failed. The output parameters will remain unchanged if failed.
+    virtual bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType,
+                                        int* lowestPriorityPid, int* lowestPriority);
+
+    // Removes the pid from the override map.
+    virtual void removeProcessInfoOverride(int pid);
+
+    // Get the client for given pid and the clientId from the map
+    virtual std::shared_ptr<IResourceManagerClient> getClient(
+        int pid, const int64_t& clientId) const;
+
+    // Remove the client for given pid and the clientId from the map
+    virtual bool removeClient(int pid, const int64_t& clientId);
+
+    // Get all the resource status for dump
+    virtual void getResourceDump(std::string& resourceLog) const;
 
     void removeProcessInfoOverride_l(int pid);
 
+    // A helper function that pushes Reclaim Atom (for metric collection).
     void pushReclaimAtom(const ClientInfoParcel& clientInfo,
                          const std::vector<ClientInfo>& targetClients,
                          bool reclaimed);
 
-    // Get the client for given pid and the clientId from the map
-    std::shared_ptr<IResourceManagerClient> getClient(int pid, const int64_t& clientId) const;
-
-    // Remove the client for given pid and the clientId from the map
-    bool removeClient(int pid, const int64_t& clientId);
-
     // The following utility functions are used only for testing by ResourceManagerServiceTest
-    // Gets lowest priority process that has the specified resource type.
-    // Returns false if failed. The output parameters will remain unchanged if failed.
-    bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType,
-                                int* lowestPriorityPid, int* lowestPriority);
     // 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.
@@ -190,15 +219,22 @@
     static std::shared_ptr<ResourceManagerService> CreateNew(
         const sp<ProcessInfoInterface>& processInfo,
         const sp<SystemCallbackInterface>& systemResource);
+    // Returns a unmodifiable reference to the internal resource state as a map
+    virtual const std::map<int, ResourceInfos>& getResourceMap() const {
+        return mMap;
+    }
 
+protected:
     mutable std::mutex mLock;
     sp<ProcessInfoInterface> mProcessInfo;
     sp<SystemCallbackInterface> mSystemCB;
     sp<ServiceLog> mServiceLog;
-    PidResourceInfosMap mMap;
     bool mSupportsMultipleSecureCodecs;
     bool mSupportsSecureWithNonSecureCodec;
     int32_t mCpuBoostCount;
+
+private:
+    PidResourceInfosMap mMap;
     struct ProcessInfoOverride {
         std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
         std::shared_ptr<IResourceManagerClient> client;
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
index 7475af4..045aa3d 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
@@ -20,6 +20,8 @@
 #include <utils/Log.h>
 
 #include "ResourceManagerServiceNew.h"
+#include "ResourceTracker.h"
+#include "ServiceLog.h"
 
 namespace android {
 
@@ -30,30 +32,74 @@
 
 ResourceManagerServiceNew::~ResourceManagerServiceNew() {}
 
+void ResourceManagerServiceNew::init() {
+    // Create the Resource Tracker
+    mResourceTracker = std::make_shared<ResourceTracker>(ref<ResourceManagerServiceNew>(),
+                                                         mProcessInfo);
+}
+
 Status ResourceManagerServiceNew::config(const std::vector<MediaResourcePolicyParcel>& policies) {
     return ResourceManagerService::config(policies);
 }
 
+void ResourceManagerServiceNew::setObserverService(
+        const std::shared_ptr<ResourceObserverService>& observerService) {
+    ResourceManagerService::setObserverService(observerService);
+    mResourceTracker->setResourceObserverService(observerService);
+}
+
 Status ResourceManagerServiceNew::addResource(
         const ClientInfoParcel& clientInfo,
         const std::shared_ptr<IResourceManagerClient>& client,
         const std::vector<MediaResourceParcel>& resources) {
-    return ResourceManagerService::addResource(clientInfo, client, resources);
+    int32_t pid = clientInfo.pid;
+    int32_t uid = clientInfo.uid;
+    int64_t clientId = clientInfo.id;
+    String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
+            pid, uid, (long long) clientId, getString(resources).c_str());
+    mServiceLog->add(log);
+
+    std::scoped_lock lock{mLock};
+    mResourceTracker->addResource(clientInfo, client, resources);
+    notifyResourceGranted(pid, resources);
+
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::removeResource(
         const ClientInfoParcel& clientInfo,
         const std::vector<MediaResourceParcel>& resources) {
-    return ResourceManagerService::removeResource(clientInfo, resources);
+    int32_t pid = clientInfo.pid;
+    int32_t uid = clientInfo.uid;
+    int64_t clientId = clientInfo.id;
+    String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
+            pid, uid, (long long) clientId, getString(resources).c_str());
+    mServiceLog->add(log);
+
+    std::scoped_lock lock{mLock};
+    mResourceTracker->removeResource(clientInfo, resources);
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::removeClient(const ClientInfoParcel& clientInfo) {
-    return ResourceManagerService::removeClient(clientInfo);
+    removeResource(clientInfo, true /*checkValid*/);
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::removeResource(const ClientInfoParcel& clientInfo,
                                                  bool checkValid) {
-    return ResourceManagerService::removeResource(clientInfo, checkValid);
+    int32_t pid = clientInfo.pid;
+    int32_t uid = clientInfo.uid;
+    int64_t clientId = clientInfo.id;
+    String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
+            pid, uid, (long long) clientId);
+    mServiceLog->add(log);
+
+    std::scoped_lock lock{mLock};
+    if (mResourceTracker->removeResource(clientInfo, checkValid)) {
+        notifyClientReleased(clientInfo);
+    }
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::reclaimResource(
@@ -63,10 +109,22 @@
     return ResourceManagerService::reclaimResource(clientInfo, resources, _aidl_return);
 }
 
+bool ResourceManagerServiceNew::overridePid_l(int32_t originalPid, int32_t newPid) {
+    return mResourceTracker->overridePid(originalPid, newPid);
+}
+
 Status ResourceManagerServiceNew::overridePid(int originalPid, int newPid) {
     return ResourceManagerService::overridePid(originalPid, newPid);
 }
 
+bool ResourceManagerServiceNew::overrideProcessInfo_l(
+        const std::shared_ptr<IResourceManagerClient>& client,
+        int pid,
+        int procState,
+        int oomScore) {
+    return mResourceTracker->overrideProcessInfo(client, pid, procState, oomScore);
+}
+
 Status ResourceManagerServiceNew::overrideProcessInfo(
         const std::shared_ptr<IResourceManagerClient>& client,
         int pid,
@@ -75,12 +133,39 @@
     return ResourceManagerService::overrideProcessInfo(client, pid, procState, oomScore);
 }
 
+void ResourceManagerServiceNew::removeProcessInfoOverride(int pid) {
+    std::scoped_lock lock{mLock};
+
+    mResourceTracker->removeProcessInfoOverride(pid);
+}
+
 Status ResourceManagerServiceNew::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
-    return ResourceManagerService::markClientForPendingRemoval(clientInfo);
+    int32_t pid = clientInfo.pid;
+    int64_t clientId = clientInfo.id;
+    String8 log = String8::format(
+            "markClientForPendingRemoval(pid %d, clientId %lld)",
+            pid, (long long) clientId);
+    mServiceLog->add(log);
+
+    std::scoped_lock lock{mLock};
+    mResourceTracker->markClientForPendingRemoval(clientInfo);
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::reclaimResourcesFromClientsPendingRemoval(int32_t pid) {
-    return ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(pid);
+    String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
+    mServiceLog->add(log);
+
+    std::vector<ClientInfo> targetClients;
+    {
+        std::scoped_lock lock{mLock};
+        mResourceTracker->getClientsMarkedPendingRemoval(pid, targetClients);
+    }
+
+    if (!targetClients.empty()) {
+        reclaimUnconditionallyFrom(targetClients);
+    }
+    return Status::ok();
 }
 
 Status ResourceManagerServiceNew::notifyClientCreated(const ClientInfoParcel& clientInfo) {
@@ -100,8 +185,68 @@
     return ResourceManagerService::notifyClientConfigChanged(clientConfig);
 }
 
+void ResourceManagerServiceNew::getResourceDump(std::string& resourceLog) const {
+    std::scoped_lock lock{mLock};
+    mResourceTracker->dump(resourceLog);
+}
+
 binder_status_t ResourceManagerServiceNew::dump(int fd, const char** args, uint32_t numArgs) {
     return ResourceManagerService::dump(fd, args, numArgs);
 }
 
+bool ResourceManagerServiceNew::getPriority_l(int pid, int* priority) const {
+    return mResourceTracker->getPriority(pid, priority);
+}
+
+bool ResourceManagerServiceNew::getLowestPriorityPid_l(
+        MediaResource::Type type, MediaResource::SubType subType,
+        int* lowestPriorityPid, int* lowestPriority) {
+    return mResourceTracker->getLowestPriorityPid(type, subType,
+                                                  *lowestPriorityPid,
+                                                  *lowestPriority);
+}
+
+bool ResourceManagerServiceNew::getBiggestClient_l(int pid, MediaResource::Type type,
+        MediaResource::SubType subType, ClientInfo& clientInfo, bool pendingRemovalOnly) {
+    return mResourceTracker->getBiggestClient(pid, type, subType,
+                                              clientInfo, pendingRemovalOnly);
+}
+
+bool ResourceManagerServiceNew::getAllClients_l(
+        const ResourceRequestInfo& resourceRequestInfo,
+        std::vector<ClientInfo>& clientsInfo) {
+    MediaResource::Type type = resourceRequestInfo.mResource->type;
+    // Get list of all the clients that has requested resources.
+    std::vector<ClientInfo> clients;
+    mResourceTracker->getAllClients(resourceRequestInfo, clients);
+
+    // Check is there any high priority process holding up the resources already.
+    for (const ClientInfo& info : clients) {
+        if (!isCallingPriorityHigher_l(resourceRequestInfo.mCallingPid, info.mPid)) {
+            // some higher/equal priority process owns the resource,
+            // this request can't be fulfilled.
+            ALOGE("%s: can't reclaim resource %s from pid %d", __func__, asString(type), info.mPid);
+            return false;
+        }
+        clientsInfo.emplace_back(info);
+    }
+    if (clientsInfo.size() == 0) {
+        ALOGV("%s: didn't find any resource %s", __func__, asString(type));
+    }
+    return true;
+}
+
+std::shared_ptr<IResourceManagerClient> ResourceManagerServiceNew::getClient(
+        int pid, const int64_t& clientId) const {
+    return mResourceTracker->getClient(pid, clientId);
+}
+
+bool ResourceManagerServiceNew::removeClient(int pid, const int64_t& clientId) {
+    return mResourceTracker->removeClient(pid, clientId);
+}
+
+const std::map<int, ResourceInfos>& ResourceManagerServiceNew::getResourceMap() const {
+    return mResourceTracker->getResourceMap();
+}
+
 } // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.h b/services/mediaresourcemanager/ResourceManagerServiceNew.h
index 3b052da..cd781e4 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.h
@@ -22,6 +22,8 @@
 
 namespace android {
 
+class ResourceTracker;
+
 //
 // A newer implementation of IResourceManagerService, which
 // eventually will replace the older implementation in ResourceManagerService.
@@ -66,8 +68,6 @@
 
     Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override;
 
-    Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid);
-
     Status notifyClientCreated(const ClientInfoParcel& clientInfo) override;
 
     Status notifyClientStarted(const ClientConfigParcel& clientConfig) override;
@@ -77,6 +77,64 @@
     Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
 
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    friend class ResourceTracker;
+
+private:
+
+    // Initializes the internal state of the ResourceManagerService
+    void init() override;
+
+    void setObserverService(
+            const std::shared_ptr<ResourceObserverService>& observerService) override;
+
+    // Removes the pid from the override map.
+    void removeProcessInfoOverride(int pid) override;
+
+    // Gets the list of all the clients who own the specified resource type.
+    // Returns false if any client belongs to a process with higher priority than the
+    // calling process. The clients will remain unchanged if returns false.
+    bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
+                         std::vector<ClientInfo>& clientsInfo) override;
+
+    // Gets the client who owns biggest piece of specified resource type from pid.
+    // Returns false with no change to client if there are no clients holding resources of this
+    // type.
+    bool getBiggestClient_l(int pid, MediaResource::Type type,
+                            MediaResource::SubType subType,
+                            ClientInfo& clientsInfo,
+                            bool pendingRemovalOnly = false) override;
+
+    bool overridePid_l(int32_t originalPid, int32_t newPid) override;
+
+    bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
+                               int pid, int procState, int oomScore) override;
+
+    // Get priority from process's pid
+    bool getPriority_l(int pid, int* priority) const override;
+
+    // Gets lowest priority process that has the specified resource type.
+    // Returns false if failed. The output parameters will remain unchanged if failed.
+    bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType,
+                                int* lowestPriorityPid, int* lowestPriority) override;
+
+    // Get the client for given pid and the clientId from the map
+    std::shared_ptr<IResourceManagerClient> getClient(
+        int pid, const int64_t& clientId) const override;
+
+    // Remove the client for given pid and the clientId from the map
+    bool removeClient(int pid, const int64_t& clientId) override;
+
+    // Get all the resource status for dump
+    void getResourceDump(std::string& resourceLog) const override;
+
+    // Returns a unmodifiable reference to the internal resource state as a map
+    const std::map<int, ResourceInfos>& getResourceMap() const override;
+
+    Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid) override;
+
+private:
+    std::shared_ptr<ResourceTracker> mResourceTracker;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
index de682f8..cd21327 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
@@ -19,6 +19,9 @@
 #define LOG_TAG "ResourceManagerServiceUtils"
 #include <utils/Log.h>
 
+#include <binder/IServiceManager.h>
+
+#include "IMediaResourceMonitor.h"
 #include "ResourceManagerService.h"
 #include "ResourceManagerServiceUtils.h"
 
@@ -202,4 +205,30 @@
     return deathNotifier;
 }
 
+void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel>& resources) {
+    static const char* const kServiceName = "media_resource_monitor";
+    sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
+    if (binder != NULL) {
+        sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
+        for (size_t i = 0; i < resources.size(); ++i) {
+            switch (resources[i].subType) {
+                case MediaResource::SubType::kHwAudioCodec:
+                case MediaResource::SubType::kSwAudioCodec:
+                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
+                    break;
+                case MediaResource::SubType::kHwVideoCodec:
+                case MediaResource::SubType::kSwVideoCodec:
+                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
+                    break;
+                case MediaResource::SubType::kHwImageCodec:
+                case MediaResource::SubType::kSwImageCodec:
+                    service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC);
+                    break;
+                case MediaResource::SubType::kUnspecifiedSubType:
+                    break;
+            }
+        }
+    }
+}
+
 } // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
index ac1e410..8d03143 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -170,7 +170,7 @@
 
 //Check whether a given resource (of type and subtype) is found in given resource parcel.
 bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
-                     const MediaResourceParcel& resource);
+                     const ::aidl::android::media::MediaResourceParcel& resource);
 
 //Check whether a given resource (of type and subtype) is found in given resource list.
 bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
@@ -193,7 +193,13 @@
         ResourceInfos& infos);
 
 // Merge resources from r2 into r1.
-void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
+void mergeResources(::aidl::android::media::MediaResourceParcel& r1,
+                    const ::aidl::android::media::MediaResourceParcel& r2);
+
+// To notify the media_resource_monitor about the resource being granted.
+void notifyResourceGranted(
+        int pid,
+        const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
 
 } // namespace android
 
diff --git a/services/mediaresourcemanager/ResourceTracker.cpp b/services/mediaresourcemanager/ResourceTracker.cpp
new file mode 100644
index 0000000..c6255a2
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceTracker.cpp
@@ -0,0 +1,564 @@
+/*
+**
+** 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.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ResourceTracker"
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <mediautils/ProcessInfo.h>
+#include "ResourceTracker.h"
+#include "ResourceManagerServiceNew.h"
+#include "ResourceObserverService.h"
+
+namespace android {
+
+ResourceTracker::ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew>& service,
+                                 const sp<ProcessInfoInterface>& processInfo) :
+        mService(service),
+        mProcessInfo(processInfo) {
+}
+
+ResourceTracker::~ResourceTracker() {
+}
+
+void ResourceTracker::setResourceObserverService(
+        const std::shared_ptr<ResourceObserverService>& observerService) {
+    mObserverService = observerService;
+}
+
+ResourceInfos& ResourceTracker::getResourceInfosForEdit(int pid) {
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        // new pid
+        ResourceInfos infosForPid;
+        auto [it, inserted] = mMap.emplace(pid, infosForPid);
+        found = it;
+    }
+
+    return found->second;
+}
+
+bool ResourceTracker::addResource(const ClientInfoParcel& clientInfo,
+                                  const std::shared_ptr<IResourceManagerClient>& client,
+                                  const std::vector<MediaResourceParcel>& resources) {
+    int32_t pid = clientInfo.pid;
+    int32_t uid = clientInfo.uid;
+
+    if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        ALOGW("%s called with untrusted pid %d or uid %d, using calling pid %d, uid %d",
+                __func__, pid, uid, callingPid, callingUid);
+        pid = callingPid;
+        uid = callingUid;
+    }
+    ResourceInfos& infos = getResourceInfosForEdit(pid);
+    ResourceInfo& info = getResourceInfoForEdit(clientInfo, client, infos);
+    ResourceList resourceAdded;
+
+    for (const MediaResourceParcel& res : resources) {
+        const auto resType = std::tuple(res.type, res.subType, res.id);
+
+        if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
+            ALOGV("%s: Ignoring request to remove negative value of non-drm resource", __func__);
+            continue;
+        }
+        if (info.resources.find(resType) == info.resources.end()) {
+            if (res.value <= 0) {
+                // We can't init a new entry with negative value, although it's allowed
+                // to merge in negative values after the initial add.
+                ALOGV("%s: Ignoring request to add new resource entry with value <= 0", __func__);
+                continue;
+            }
+            onFirstAdded(res, info.uid);
+            info.resources[resType] = res;
+        } else {
+            mergeResources(info.resources[resType], res);
+        }
+        // Add it to the list of added resources for observers.
+        auto it = resourceAdded.find(resType);
+        if (it == resourceAdded.end()) {
+            resourceAdded[resType] = res;
+        } else {
+            mergeResources(it->second, res);
+        }
+    }
+    if (info.deathNotifier == nullptr && client != nullptr) {
+        info.deathNotifier = DeathNotifier::Create(client, mService, clientInfo);
+    }
+    if (mObserverService != nullptr && !resourceAdded.empty()) {
+        mObserverService->onResourceAdded(uid, pid, resourceAdded);
+    }
+
+    return !resourceAdded.empty();
+}
+
+bool ResourceTracker::removeResource(const ClientInfoParcel& clientInfo,
+                                     const std::vector<MediaResourceParcel>& resources) {
+    int32_t pid = clientInfo.pid;
+    int64_t clientId = clientInfo.id;
+
+    if (!mProcessInfo->isPidTrusted(pid)) {
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
+                pid, callingPid);
+        pid = callingPid;
+    }
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+        return false;
+    }
+
+    ResourceInfos& infos = found->second;
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
+        ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+        return false;
+    }
+
+    ResourceInfo& info = foundClient->second;
+    ResourceList resourceRemoved;
+    for (const MediaResourceParcel& res : resources) {
+        const auto resType = std::tuple(res.type, res.subType, res.id);
+
+        if (res.value < 0) {
+            ALOGV("%s: Ignoring request to remove negative value of resource", __func__);
+            continue;
+        }
+        // ignore if we don't have it
+        if (info.resources.find(resType) != info.resources.end()) {
+            MediaResourceParcel& resource = info.resources[resType];
+            MediaResourceParcel actualRemoved = res;
+            if (resource.value > res.value) {
+                resource.value -= res.value;
+            } else {
+                onLastRemoved(res, info.uid);
+                actualRemoved.value = resource.value;
+                info.resources.erase(resType);
+            }
+
+            // Add it to the list of removed resources for observers.
+            auto it = resourceRemoved.find(resType);
+            if (it == resourceRemoved.end()) {
+                resourceRemoved[resType] = actualRemoved;
+            } else {
+                mergeResources(it->second, actualRemoved);
+            }
+        }
+    }
+    if (mObserverService != nullptr && !resourceRemoved.empty()) {
+        mObserverService->onResourceRemoved(info.uid, pid, resourceRemoved);
+    }
+    return true;
+}
+
+bool ResourceTracker::removeResource(const ClientInfoParcel& clientInfo, bool validateCallingPid) {
+    int32_t pid = clientInfo.pid;
+    int64_t clientId = clientInfo.id;
+
+    if (validateCallingPid && !mProcessInfo->isPidTrusted(pid)) {
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
+                pid, callingPid);
+        pid = callingPid;
+    }
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+        return false;
+    }
+
+    ResourceInfos& infos = found->second;
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
+        ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+        return false;
+    }
+
+    const ResourceInfo& info = foundClient->second;
+    for (auto& [resType, resParcel] : info.resources) {
+        onLastRemoved(resParcel, info.uid);
+    }
+
+    if (mObserverService != nullptr && !info.resources.empty()) {
+        mObserverService->onResourceRemoved(info.uid, pid, info.resources);
+    }
+
+    infos.erase(foundClient);
+    return true;
+}
+
+std::shared_ptr<IResourceManagerClient> ResourceTracker::getClient(
+        int pid, const int64_t& clientId) const {
+    std::map<int, ResourceInfos>::const_iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+        return nullptr;
+    }
+
+    const ResourceInfos& infos = found->second;
+    ResourceInfos::const_iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
+        ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+        return nullptr;
+    }
+
+    return foundClient->second.client;
+}
+
+bool ResourceTracker::removeClient(int pid, const int64_t& clientId) {
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+        return false;
+    }
+
+    ResourceInfos& infos = found->second;
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
+        ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+        return false;
+    }
+
+    infos.erase(foundClient);
+    return true;
+}
+
+bool ResourceTracker::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
+    int32_t pid = clientInfo.pid;
+    int64_t clientId = clientInfo.id;
+
+    if (!mProcessInfo->isPidTrusted(pid)) {
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
+                pid, callingPid);
+        pid = callingPid;
+    }
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long)clientId);
+        return false;
+    }
+
+    ResourceInfos& infos = found->second;
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
+        ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+        return false;
+    }
+
+    ResourceInfo& info = foundClient->second;
+    info.pendingRemoval = true;
+    return true;
+}
+
+bool ResourceTracker::getClientsMarkedPendingRemoval(int32_t pid,
+                                                     std::vector<ClientInfo>& targetClients) {
+    if (!mProcessInfo->isPidTrusted(pid)) {
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__, pid, callingPid);
+        pid = callingPid;
+    }
+
+    // Go through all the MediaResource types (and corresponding subtypes for
+    // each, if applicable) and see if the process (with given pid) holds any
+    // such resources that are marked as pending removal.
+    // Since the use-case of this function is to get all such resources (pending
+    // removal) and reclaim them all - the order in which we look for the
+    // resource type doesn't matter.
+    for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
+                                     MediaResource::Type::kNonSecureCodec,
+                                     MediaResource::Type::kGraphicMemory,
+                                     MediaResource::Type::kDrmSession}) {
+        switch (type) {
+        // Codec resources are segregated by audio, video and image domains.
+        case MediaResource::Type::kSecureCodec:
+        case MediaResource::Type::kNonSecureCodec:
+            for (MediaResource::SubType subType : {MediaResource::SubType::kHwAudioCodec,
+                                                   MediaResource::SubType::kSwAudioCodec,
+                                                   MediaResource::SubType::kHwVideoCodec,
+                                                   MediaResource::SubType::kSwVideoCodec,
+                                                   MediaResource::SubType::kHwImageCodec,
+                                                   MediaResource::SubType::kSwImageCodec}) {
+                ClientInfo clientInfo;
+                if (getBiggestClient(pid, type, subType, clientInfo, true)) {
+                    targetClients.emplace_back(clientInfo);
+                    continue;
+                }
+            }
+            break;
+        // Non-codec resources are shared by audio, video and image codecs (no subtype).
+        default:
+            ClientInfo clientInfo;
+            MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
+            if (getBiggestClient(pid, type, subType, clientInfo, true)) {
+                targetClients.emplace_back(clientInfo);
+            }
+            break;
+        }
+    }
+
+    return true;
+}
+
+bool ResourceTracker::overridePid(int originalPid, int newPid) {
+    mOverridePidMap.erase(originalPid);
+    if (newPid != -1) {
+        mOverridePidMap.emplace(originalPid, newPid);
+        return true;
+    }
+    return false;
+}
+
+bool ResourceTracker::overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client,
+                                          int pid, int procState, int oomScore) {
+    removeProcessInfoOverride(pid);
+
+    if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
+        // Override value is rejected by ProcessInfo.
+        return false;
+    }
+
+    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
+                                .uid = 0,
+                                .id = 0,
+                                .name = "<unknown client>"};
+    std::shared_ptr<DeathNotifier> deathNotifier =
+        DeathNotifier::Create(client, mService, clientInfo, true);
+
+    mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{deathNotifier, client});
+
+    return true;
+}
+
+void ResourceTracker::removeProcessInfoOverride(int pid) {
+    auto it = mProcessInfoOverrideMap.find(pid);
+    if (it == mProcessInfoOverrideMap.end()) {
+        return;
+    }
+
+    mProcessInfo->removeProcessInfoOverride(pid);
+    mProcessInfoOverrideMap.erase(pid);
+}
+
+bool ResourceTracker::getAllClients(const ResourceRequestInfo& resourceRequestInfo,
+                                    std::vector<ClientInfo>& clients) {
+    MediaResource::Type type = resourceRequestInfo.mResource->type;
+    MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
+    bool foundClient = false;
+
+    for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
+        for (auto& [id, /* ResourceInfo */ info] : infos) {
+            if (hasResourceType(type, subType, info.resources)) {
+                clients.emplace_back(info.pid, info.uid, info.clientId);
+                foundClient = true;
+            }
+        }
+    }
+
+    return foundClient;
+}
+
+bool ResourceTracker::getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
+                                           int& lowestPriorityPid, int& lowestPriority) {
+    int pid = -1;
+    int priority = -1;
+    for (auto& [tempPid, /* ResourceInfos */ infos] : mMap) {
+        if (infos.size() == 0) {
+            // no client on this process.
+            continue;
+        }
+        if (!hasResourceType(type, subType, infos)) {
+            // doesn't have the requested resource type
+            continue;
+        }
+        int tempPriority = -1;
+        if (!getPriority(tempPid, &tempPriority)) {
+            ALOGV("%s: can't get priority of pid %d, skipped", __func__, tempPid);
+            // TODO: remove this pid from mMap?
+            continue;
+        }
+        if (pid == -1 || tempPriority > priority) {
+            // initial the value
+            pid = tempPid;
+            priority = tempPriority;
+        }
+    }
+
+    bool success = (pid != -1);
+
+    if (success) {
+        lowestPriorityPid = pid;
+        lowestPriority = priority;
+    }
+    return success;
+}
+
+bool ResourceTracker::getBiggestClient(int pid, MediaResource::Type type,
+                                       MediaResource::SubType subType,
+                                       ClientInfo& clientInfo, bool pendingRemovalOnly) {
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        ALOGE_IF(!pendingRemovalOnly, "%s: can't find resource info for pid %d", __func__, pid);
+        return false;
+    }
+
+    uid_t   uid = -1;
+    int64_t clientId = -1;
+    uint64_t largestValue = 0;
+    const ResourceInfos& infos = found->second;
+    for (const auto& [id, /* ResourceInfo */ info] : infos) {
+        const ResourceList& resources = info.resources;
+        if (pendingRemovalOnly && !info.pendingRemoval) {
+            continue;
+        }
+        for (auto it = resources.begin(); it != resources.end(); it++) {
+            const MediaResourceParcel &resource = it->second;
+            if (hasResourceType(type, subType, resource)) {
+                if (resource.value > largestValue) {
+                    largestValue = resource.value;
+                    clientId = info.clientId;
+                    uid = info.uid;
+                }
+            }
+        }
+    }
+
+    if (clientId == -1) {
+        ALOGE_IF(!pendingRemovalOnly,
+                 "%s: can't find resource type %s and subtype %s for pid %d",
+                 __func__, asString(type), asString(subType), pid);
+        return false;
+    }
+
+    clientInfo.mPid = pid;
+    clientInfo.mUid = uid;
+    clientInfo.mClientId = clientId;
+    return true;
+}
+
+void ResourceTracker::dump(std::string& resourceLogs) {
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    resourceLogs.append("  Processes:\n");
+    for (const auto& [pid, /* ResourceInfos */ infos] : mMap) {
+        snprintf(buffer, SIZE, "    Pid: %d\n", pid);
+        resourceLogs.append(buffer);
+        int priority = 0;
+        if (getPriority(pid, &priority)) {
+            snprintf(buffer, SIZE, "    Priority: %d\n", priority);
+        } else {
+            snprintf(buffer, SIZE, "    Priority: <unknown>\n");
+        }
+        resourceLogs.append(buffer);
+
+        for (const auto& [infoKey, /* ResourceInfo */ info] : infos) {
+            resourceLogs.append("      Client:\n");
+            snprintf(buffer, SIZE, "        Id: %lld\n", (long long)info.clientId);
+            resourceLogs.append(buffer);
+
+            std::string clientName = info.name;
+            snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
+            resourceLogs.append(buffer);
+
+            const ResourceList& resources = info.resources;
+            resourceLogs.append("        Resources:\n");
+            for (auto it = resources.begin(); it != resources.end(); it++) {
+                snprintf(buffer, SIZE, "          %s\n", toString(it->second).c_str());
+                resourceLogs.append(buffer);
+            }
+        }
+    }
+    resourceLogs.append("  Process Pid override:\n");
+    for (const auto& [oldPid, newPid] : mOverridePidMap) {
+        snprintf(buffer, SIZE, "    Original Pid: %d,  Override Pid: %d\n", oldPid, newPid);
+        resourceLogs.append(buffer);
+    }
+}
+
+void ResourceTracker::onFirstAdded(const MediaResourceParcel& resource, uid_t uid) {
+    std::shared_ptr<ResourceManagerServiceNew> service = mService.lock();
+    if (service == nullptr) {
+        ALOGW("%s: ResourceManagerService is invalid!", __func__);
+        return;
+    }
+
+    service->onFirstAdded(resource, uid);
+}
+
+void ResourceTracker::onLastRemoved(const MediaResourceParcel& resource, uid_t uid) {
+    std::shared_ptr<ResourceManagerServiceNew> service = mService.lock();
+    if (service == nullptr) {
+        ALOGW("%s: ResourceManagerService is invalid!", __func__);
+        return;
+    }
+
+    service->onLastRemoved(resource, uid);
+}
+
+bool ResourceTracker::getPriority(int pid, int* priority) {
+    int newPid = pid;
+
+    if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
+        newPid = mOverridePidMap[pid];
+        ALOGD("%s: use override pid %d instead original pid %d", __func__, newPid, pid);
+    }
+
+    return mProcessInfo->getPriority(newPid, priority);
+}
+
+bool ResourceTracker::getNonConflictingClients(const ResourceRequestInfo& resourceRequestInfo,
+                                               std::vector<ClientInfo>& clients) {
+    MediaResource::Type type = resourceRequestInfo.mResource->type;
+    MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
+    for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
+        for (const auto& [id, /* ResourceInfo */ info] : infos) {
+            if (hasResourceType(type, subType, info.resources)) {
+                if (!isCallingPriorityHigher(resourceRequestInfo.mCallingPid, pid)) {
+                    // some higher/equal priority process owns the resource,
+                    // this is a conflict.
+                    ALOGE("%s: The resource (%s) request from pid %d is conflicting",
+                          __func__, asString(type), pid);
+                    clients.clear();
+                    return false;
+                } else {
+                    clients.emplace_back(info.pid, info.uid, info.clientId);
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+bool ResourceTracker::isCallingPriorityHigher(int callingPid, int pid) {
+    int callingPidPriority;
+    if (!getPriority(callingPid, &callingPidPriority)) {
+        return false;
+    }
+
+    int priority;
+    if (!getPriority(pid, &priority)) {
+        return false;
+    }
+
+    return (callingPidPriority < priority);
+}
+
+} // namespace android
diff --git a/services/mediaresourcemanager/ResourceTracker.h b/services/mediaresourcemanager/ResourceTracker.h
new file mode 100644
index 0000000..06fb914
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceTracker.h
@@ -0,0 +1,212 @@
+/*
+**
+** 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_RESOURCETRACKER_H_
+#define ANDROID_MEDIA_RESOURCETRACKER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+#include <media/MediaResource.h>
+#include <aidl/android/media/ClientInfoParcel.h>
+#include <aidl/android/media/IResourceManagerClient.h>
+#include <aidl/android/media/MediaResourceParcel.h>
+
+#include "ResourceManagerServiceUtils.h"
+
+namespace android {
+
+class DeathNotifier;
+class ResourceManagerServiceNew;
+class ResourceObserverService;
+struct ProcessInfoInterface;
+struct ResourceRequestInfo;
+struct ClientInfo;
+
+/*
+ * ResourceTracker abstracts the resources managed by the ResourceManager.
+ * It keeps track of the resource used by the clients (clientid) and by the process (pid)
+ */
+class ResourceTracker {
+public:
+    ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew>& service,
+                    const sp<ProcessInfoInterface>& processInfo);
+    ~ResourceTracker();
+
+    /**
+     * Add or update resources for |clientInfo|.
+     *
+     * If |clientInfo| is not tracked yet, it records its associated |client| and adds
+     * |resources| to the tracked resources. If |clientInfo| is already tracked,
+     * it updates the tracked resources by adding |resources| to them (|client| in
+     * this case is unused and unchecked).
+     *
+     * @param clientInfo Info of the calling client.
+     * @param client Interface for the client.
+     * @param resources An array of resources to be added.
+     *
+     * @return true upon successfully adding/updating the resources, false
+     * otherwise.
+     */
+    bool addResource(const aidl::android::media::ClientInfoParcel& clientInfo,
+                     const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
+                     const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
+
+    // Remove a set of resources from the given client.
+    // returns true on success, false otherwise.
+    bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo,
+                        const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
+
+    /**
+     * Remove all resources tracked for |clientInfo|.
+     *
+     * If |validateCallingPid| is true, the (pid of the) calling process is validated that it
+     * is from a trusted process.
+     * Returns true on success (|clientInfo| was tracked and optionally the caller
+     * was a validated trusted process), false otherwise (|clientInfo| was not tracked,
+     * or the caller was not a trusted process)
+     */
+    bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo,
+                        bool validateCallingPid);
+
+    // Mark the client for pending removal.
+    // Such clients are primary candidate for reclaim.
+    // returns true on success, false otherwise.
+    bool markClientForPendingRemoval(const aidl::android::media::ClientInfoParcel& clientInfo);
+
+    // Get a list of clients that belong to process with given pid and are maked to be
+    // pending removal by markClientForPendingRemoval.
+    // returns true on success, false otherwise.
+    bool getClientsMarkedPendingRemoval(int32_t pid, std::vector<ClientInfo>& targetClients);
+
+    // Override the pid of originalPid with newPid
+    // To remove the pid entry from the override list, set newPid as -1
+    // returns true on successful override, false otherwise.
+    bool overridePid(int originalPid, int newPid);
+
+    // Override the process info {state, oom score} of the process with pid.
+    // returns true on success, false otherwise.
+    bool overrideProcessInfo(
+        const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
+        int pid, int procState, int oomScore);
+
+    // Remove the overridden process info.
+    void removeProcessInfoOverride(int pid);
+
+    // Find all clients that have given resources.
+    // The |clients| (list) isn't cleared by this function to allow calling this
+    // function multiple times for different resources.
+    // returns true upon finding at lease one client with the given resource request info,
+    // false otherwise (no clients)
+    bool getAllClients(const ResourceRequestInfo& resourceRequestInfo,
+                       std::vector<ClientInfo>& clients);
+
+    // Look for the lowest priority process with the given resources.
+    // Upon success lowestPriorityPid and lowestPriority are
+    // set accordingly and it returns true.
+    // If there isn't a lower priority process with the given resources, it will return false
+    // with out updating lowestPriorityPid and lowerPriority.
+    bool getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
+                              int& lowestPriorityPid, int& lowestPriority);
+
+    // Find the biggest client of the given process with given resources.
+    // If pendingRemovalOnly is set, then it will look for only those clients
+    // that are marked for removing.
+    // Returns true when a client is found and clientInfo is updated accordingly.
+    // Upon failure to find a client, it will return false without updating
+    // clientInfo.
+    bool getBiggestClient(int pid, MediaResource::Type type, MediaResource::SubType subType,
+                          ClientInfo& clientInfo, bool pendingRemovalOnly = false);
+
+    // Find the client that belongs to given process(pid) and with the given clientId.
+    // A nullptr is returned upon failure to find the client.
+    std::shared_ptr<::aidl::android::media::IResourceManagerClient> getClient(
+        int pid, const int64_t& clientId) const;
+
+    // Removes the client from the given process(pid) with the given clientId.
+    // returns true on success, false otherwise.
+    bool removeClient(int pid, const int64_t& clientId);
+
+    // Set the resource observer service, to which to notify when the resources
+    // are added and removed.
+    void setResourceObserverService(
+        const std::shared_ptr<ResourceObserverService>& observerService);
+
+    // Dump all the resource allocations for all the processes into a given string
+    void dump(std::string& resourceLogs);
+
+    // get the priority of the process.
+    // If we can't get the priority of the process (with given pid), it will
+    // return false.
+    bool getPriority(int pid, int* priority);
+
+    // Check if the given resource request has conflicting clients.
+    // The resource conflict is defined by the ResourceModel (such as
+    // co-existence of secure codec with another secure or non-secure codec).
+    // But here, the ResourceTracker only looks for resources from lower
+    // priority processes.
+    // If is/are only higher or same priority process/es with the given resource,
+    // it will return false.
+    // Otherwise, adds all the clients to the list of clients and return true.
+    bool getNonConflictingClients(const ResourceRequestInfo& resourceRequestInfo,
+                                  std::vector<ClientInfo>& clients);
+
+    // Returns unmodifiable reference to the resource map.
+    const std::map<int, ResourceInfos>& getResourceMap() const {
+        return mMap;
+    }
+
+private:
+    // Get ResourceInfos associated with the given process.
+    // If none exists, this method will create and associate an empty object and return it.
+    ResourceInfos& getResourceInfosForEdit(int pid);
+
+    // A helper function that returns true if the callingPid has higher priority than pid.
+    // Returns false otherwise.
+    bool isCallingPriorityHigher(int callingPid, int pid);
+
+    // Notify when a resource is added for the first time.
+    void onFirstAdded(const MediaResourceParcel& resource, uid_t uid);
+    // Notify when a resource is removed for the last time.
+    void onLastRemoved(const MediaResourceParcel& resource, uid_t uid);
+
+private:
+    // Structure that defines process info that needs to be overridden.
+    struct ProcessInfoOverride {
+        std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
+        std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
+    };
+
+    // Map of Resource information indexed through the process id.
+    std::map<int, ResourceInfos> mMap;
+    // A weak reference (to avoid cyclic dependency) to the ResourceManagerService.
+    // ResourceTracker uses this to communicate back with the ResourceManagerService.
+    std::weak_ptr<ResourceManagerServiceNew> mService;
+    // To notify the ResourceObserverService abour resources are added or removed.
+    std::shared_ptr<ResourceObserverService> mObserverService;
+    // Map of pid and their overrided id.
+    std::map<int, int> mOverridePidMap;
+    // Map of pid and their overridden process info.
+    std::map<pid_t, ProcessInfoOverride> mProcessInfoOverrideMap;
+    // Interface that gets process specific information.
+    sp<ProcessInfoInterface> mProcessInfo;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_RESOURCETRACKER_H_
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 347a4f4..58ddf1a 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -129,7 +129,7 @@
         resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
         mService->addResource(client3Info, mTestClient3, resources3);
 
-        const PidResourceInfosMap &map = mService->mMap;
+        const PidResourceInfosMap &map = mService->getResourceMap();
         EXPECT_EQ(2u, map.size());
         const auto& mapIndex1 = map.find(kTestPid1);
         EXPECT_TRUE(mapIndex1 != map.end());
@@ -159,7 +159,7 @@
         // Expected result:
         // 1) the client should have been added;
         // 2) both resource entries should have been rejected, resource list should be empty.
-        const PidResourceInfosMap &map = mService->mMap;
+        const PidResourceInfosMap &map = mService->getResourceMap();
         EXPECT_EQ(1u, map.size());
         const auto& mapIndex1 = map.find(kTestPid1);
         EXPECT_TRUE(mapIndex1 != map.end());
@@ -254,7 +254,7 @@
         resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
         mService->addResource(client1Info, mTestClient1, resources11);
 
-        const PidResourceInfosMap &map = mService->mMap;
+        const PidResourceInfosMap &map = mService->getResourceMap();
         EXPECT_EQ(1u, map.size());
         const auto& mapIndex1 = map.find(kTestPid1);
         EXPECT_TRUE(mapIndex1 != map.end());
@@ -299,7 +299,7 @@
         resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
         mService->addResource(client1Info, mTestClient1, resources11);
 
-        const PidResourceInfosMap &map = mService->mMap;
+        const PidResourceInfosMap &map = mService->getResourceMap();
         EXPECT_EQ(1u, map.size());
         const auto& mapIndex1 = map.find(kTestPid1);
         EXPECT_TRUE(mapIndex1 != map.end());
@@ -466,7 +466,7 @@
                                      .name = "none"};
         mService->removeClient(client2Info);
 
-        const PidResourceInfosMap &map = mService->mMap;
+        const PidResourceInfosMap &map = mService->getResourceMap();
         EXPECT_EQ(2u, map.size());
         const ResourceInfos &infos1 = map.at(kTestPid1);
         const ResourceInfos &infos2 = map.at(kTestPid2);