Merge "VideoTrackTranscoderTests: start thread pool" into main
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
index 53f529e..7cba011 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
@@ -25,6 +25,7 @@
 #define AUDIO_AIDL_CONVERSION_AIDL_CONVERSION_UTIL_CPP
 #endif  // BACKEND_NDK_IMPL
 
+#include <functional>
 #include <limits>
 #include <type_traits>
 #include <utility>
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index bd508b3..234e858 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -41,11 +41,19 @@
         }
       ]
     }
-  ]
+  ],
+  "postsubmit": [
   // TODO(b/302036943): Enable once we make it pass with AIDL HAL on CF.
-  // "postsubmit": [
   //   {
   //      "name": "audioeffect_analysis"
-  //   }
-  // ]
+  //   },
+    {
+      "name": "CtsVirtualDevicesTestCases",
+      "options" : [
+        {
+          "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
+        }
+      ]
+    }
+  ]
 }
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index 63ace8c..d4024a2 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -238,6 +238,29 @@
     return OK;
 }
 
+status_t Hal2AidlMapper::createOrUpdatePortConfigRetry(
+        const AudioPortConfig& requestedPortConfig, AudioPortConfig* result, bool* created) {
+    AudioPortConfig suggestedOrAppliedPortConfig;
+    RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig,
+                    &suggestedOrAppliedPortConfig, created));
+    if (suggestedOrAppliedPortConfig.id == 0) {
+        // Try again with the suggested config
+        suggestedOrAppliedPortConfig.id = requestedPortConfig.id;
+        AudioPortConfig appliedPortConfig;
+        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(suggestedOrAppliedPortConfig,
+                        &appliedPortConfig, created));
+        if (appliedPortConfig.id == 0) {
+            ALOGE("%s: module %s did not apply suggested config %s", __func__,
+                    mInstance.c_str(), suggestedOrAppliedPortConfig.toString().c_str());
+            return NO_INIT;
+        }
+        *result = appliedPortConfig;
+    } else {
+        *result = suggestedOrAppliedPortConfig;
+    }
+    return OK;
+}
+
 void Hal2AidlMapper::eraseConnectedPort(int32_t portId) {
     mPorts.erase(portId);
     mConnectedPorts.erase(portId);
@@ -247,6 +270,7 @@
         ALOGD("%s: disconnected port replacement: %s", __func__, port.toString().c_str());
         mDisconnectedPortReplacement = std::pair<int32_t, AudioPort>();
     }
+    updateDynamicMixPorts();
 }
 
 status_t Hal2AidlMapper::findOrCreatePatch(
@@ -294,27 +318,19 @@
         if (config != nullptr) {
             setPortConfigFromConfig(&requestedPortConfig, *config);
         }
-        AudioPortConfig suggestedOrAppliedPortConfig;
-        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig,
-                        &suggestedOrAppliedPortConfig, created));
-        if (suggestedOrAppliedPortConfig.id == 0) {
-            // Try again with the suggested config
-            suggestedOrAppliedPortConfig.id = requestedPortConfig.id;
-            AudioPortConfig appliedPortConfig;
-            RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(suggestedOrAppliedPortConfig,
-                            &appliedPortConfig, created));
-            if (appliedPortConfig.id == 0) {
-                ALOGE("%s: module %s did not apply suggested config %s", __func__,
-                        mInstance.c_str(), suggestedOrAppliedPortConfig.toString().c_str());
-                return NO_INIT;
-            }
-            *portConfig = appliedPortConfig;
-        } else {
-            *portConfig = suggestedOrAppliedPortConfig;
-        }
+        return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created);
     } else {
-        *portConfig = portConfigIt->second;
-        *created = false;
+        AudioPortConfig requestedPortConfig = portConfigIt->second;
+        if (config != nullptr) {
+            setPortConfigFromConfig(&requestedPortConfig, *config);
+        }
+
+        if (requestedPortConfig != portConfigIt->second) {
+            return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created);
+        } else {
+            *portConfig = portConfigIt->second;
+            *created = false;
+        }
     }
     return OK;
 }
@@ -370,12 +386,12 @@
         return BAD_VALUE;
     } else {
         AudioPortConfig requestedPortConfig = portConfigIt->second;
-        if (requestedPortConfig.ext.getTag() == AudioPortExt::Tag::mix) {
-            AudioPortMixExt& mixExt = requestedPortConfig.ext.get<AudioPortExt::Tag::mix>();
-            if (mixExt.usecase.getTag() == AudioPortMixExtUseCase::Tag::source &&
-                    source != AudioSource::SYS_RESERVED_INVALID) {
-                mixExt.usecase.get<AudioPortMixExtUseCase::Tag::source>() = source;
-            }
+        setPortConfigFromConfig(&requestedPortConfig, config);
+
+        AudioPortMixExt& mixExt = requestedPortConfig.ext.get<AudioPortExt::Tag::mix>();
+        if (mixExt.usecase.getTag() == AudioPortMixExtUseCase::Tag::source &&
+                source != AudioSource::SYS_RESERVED_INVALID) {
+            mixExt.usecase.get<AudioPortMixExtUseCase::Tag::source>() = source;
         }
 
         if (requestedPortConfig != portConfigIt->second) {
@@ -410,9 +426,19 @@
                 requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds,
                 portConfig, created);
     } else if (requestedPortConfig.ext.getTag() == Tag::device) {
-        return findOrCreateDevicePortConfig(
-                requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
-                portConfig, created);
+        if (const auto& p = requestedPortConfig;
+                p.sampleRate.has_value() && p.channelMask.has_value() &&
+                p.format.has_value()) {
+            AudioConfig config;
+            setConfigFromPortConfig(&config, requestedPortConfig);
+            return findOrCreateDevicePortConfig(
+                    requestedPortConfig.ext.get<Tag::device>().device, &config,
+                    portConfig, created);
+        } else {
+            return findOrCreateDevicePortConfig(
+                    requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
+                    portConfig, created);
+        }
     }
     ALOGW("%s: unsupported audio port config: %s",
             __func__, requestedPortConfig.toString().c_str());
@@ -1002,6 +1028,9 @@
     if (status == OK) {
         auto portIt = mPorts.find(portId);
         if (portIt != mPorts.end()) {
+            if (port->ext.getTag() == AudioPortExt::Tag::mix && portIt->second != *port) {
+                mDynamicMixPortIds.insert(portId);
+            }
             portIt->second = *port;
         } else {
             ALOGW("%s, port(%d) returned successfully from the HAL but not it is not cached",
@@ -1050,4 +1079,15 @@
     return OK;
 }
 
+void Hal2AidlMapper::updateDynamicMixPorts() {
+    for (int32_t portId : mDynamicMixPortIds) {
+        if (auto it = mPorts.find(portId); it != mPorts.end()) {
+            updateAudioPort(portId, &it->second);
+        } else {
+            // This must not happen
+            ALOGE("%s, cannot find port for id=%d", __func__, portId);
+        }
+    }
+}
+
 } // namespace android
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.h b/media/libaudiohal/impl/Hal2AidlMapper.h
index 21cfd5a..93ce233 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.h
+++ b/media/libaudiohal/impl/Hal2AidlMapper.h
@@ -126,6 +126,9 @@
     status_t createOrUpdatePortConfig(
             const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
             ::aidl::android::media::audio::common::AudioPortConfig* result, bool *created);
+    status_t createOrUpdatePortConfigRetry(
+            const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+            ::aidl::android::media::audio::common::AudioPortConfig* result, bool *created);
     void eraseConnectedPort(int32_t portId);
     status_t findOrCreatePatch(
         const std::set<int32_t>& sourcePortConfigIds,
@@ -185,6 +188,7 @@
     status_t updateAudioPort(
             int32_t portId, ::aidl::android::media::audio::common::AudioPort* port);
     status_t updateRoutes();
+    void updateDynamicMixPorts();
 
     Ports mPorts;
     // Remote submix "template" ports (no address specified, no profiles).
@@ -202,6 +206,7 @@
     ConnectedPorts mConnectedPorts;
     std::pair<int32_t, ::aidl::android::media::audio::common::AudioPort>
             mDisconnectedPortReplacement;
+    std::set<int32_t> mDynamicMixPortIds;
 };
 
 }  // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 378d919..c2d7ee1 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -808,6 +808,7 @@
                         mOffloadMetadata.channelMask = VALUE_OR_RETURN_STATUS(
                                 ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
                                         channel_mask, false /*isInput*/));
+                        return OK;
                     }
                     return BAD_VALUE;
                 }))) {
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index 71bb2ef..bb7e4c6 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -20,6 +20,7 @@
 #define LOG_TAG "BundleContext"
 #include <android-base/logging.h>
 #include <audio_utils/power.h>
+#include <media/AidlConversionCppNdk.h>
 #include <Utils.h>
 
 #include "BundleContext.h"
@@ -36,9 +37,10 @@
               const lvm::BundleEffectType& type)
         : EffectContext(statusDepth, common), mType(type) {
     LOG(DEBUG) << __func__ << type;
-    int channelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+
+    int inputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
             common.input.base.channelMask);
-    mSamplesPerSecond = common.input.base.sampleRate * channelCount;
+    mSamplesPerSecond = common.input.base.sampleRate * inputChannelCount;
 }
 
 BundleContext::~BundleContext() {
@@ -50,9 +52,15 @@
     std::lock_guard lg(mMutex);
     // init with pre-defined preset NORMAL
     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
-        mBandGainMdB[i] = lvm::kSoftPresets[0 /* normal */][i] * 100;
+        mBandGainmB[i] = lvm::kSoftPresets[0 /* normal */][i] * 100;
     }
 
+    // Initialise control params
+    LVM_ControlParams_t controlParams;
+    RetCode retStatus = initControlParameter(controlParams);
+    RETURN_VALUE_IF(retStatus != RetCode::SUCCESS, RetCode::ERROR_ILLEGAL_PARAMETER,
+                    " UnsupportedParams");
+
     // allocate lvm instance
     LVM_ReturnStatus_en status;
     LVM_InstParams_t params = {.BufferMode = LVM_UNMANAGED_BUFFERS,
@@ -63,8 +71,6 @@
     GOTO_IF_LVM_ERROR(status, deinit, "LVM_GetInstanceHandleFailed");
 
     // set control
-    LVM_ControlParams_t controlParams;
-    initControlParameter(controlParams);
     status = LVM_SetControlParameters(mInstance, &controlParams);
     GOTO_IF_LVM_ERROR(status, deinit, "LVM_SetControlParametersFailed");
 
@@ -227,8 +233,8 @@
         bool viEnabled = params.VirtualizerOperatingMode == LVM_MODE_ON;
 
         if (eqEnabled) {
-            for (size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
-                float bandFactor = mBandGainMdB[i] / 1500.0;
+            for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+                float bandFactor = mBandGainmB[i] / 1500.0;
                 float bandCoefficient = lvm::kBandEnergyCoefficient[i];
                 float bandEnergy = bandFactor * bandCoefficient * bandCoefficient;
                 if (bandEnergy > 0) energyContribution += bandEnergy;
@@ -236,9 +242,9 @@
 
             // cross EQ coefficients
             float bandFactorSum = 0;
-            for (size_t i = 0; i < lvm::MAX_NUM_BANDS - 1; i++) {
-                float bandFactor1 = mBandGainMdB[i] / 1500.0;
-                float bandFactor2 = mBandGainMdB[i + 1] / 1500.0;
+            for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS - 1; i++) {
+                float bandFactor1 = mBandGainmB[i] / 1500.0;
+                float bandFactor2 = mBandGainmB[i + 1] / 1500.0;
 
                 if (bandFactor1 > 0 && bandFactor2 > 0) {
                     float crossEnergy =
@@ -259,8 +265,8 @@
             energyContribution += boostFactor * boostCoefficient * boostCoefficient;
 
             if (eqEnabled) {
-                for (size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
-                    float bandFactor = mBandGainMdB[i] / 1500.0;
+                for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+                    float bandFactor = mBandGainmB[i] / 1500.0;
                     float bandCrossCoefficient = lvm::kBassBoostEnergyCrossCoefficient[i];
                     float bandEnergy = boostFactor * bandFactor * bandCrossCoefficient;
                     if (bandEnergy > 0) energyBassBoost += bandEnergy;
@@ -312,7 +318,9 @@
             device != AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
                                              AudioDeviceDescription::CONNECTION_BT_SCO} &&
             device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
-                                             AudioDeviceDescription::CONNECTION_BT_A2DP}) {
+                                             AudioDeviceDescription::CONNECTION_BT_A2DP} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_SUBMIX,
+                                             AudioDeviceDescription::CONNECTION_VIRTUAL}) {
             return false;
         }
     }
@@ -329,7 +337,9 @@
             device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
                                              AudioDeviceDescription::CONNECTION_BT_A2DP} &&
             device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
-                                             AudioDeviceDescription::CONNECTION_USB}) {
+                                             AudioDeviceDescription::CONNECTION_USB} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_SUBMIX,
+                                             AudioDeviceDescription::CONNECTION_VIRTUAL}) {
             return false;
         }
     }
@@ -469,6 +479,7 @@
 RetCode BundleContext::setEqualizerBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
     RETURN_VALUE_IF(bandLevels.size() > lvm::MAX_NUM_BANDS || bandLevels.empty(),
                     RetCode::ERROR_ILLEGAL_PARAMETER, "sizeExceedMax");
+
     RetCode ret = updateControlParameter(bandLevels);
     if (RetCode::SUCCESS == ret) {
         mCurPresetIdx = lvm::PRESET_CUSTOM;
@@ -483,15 +494,13 @@
     std::vector<Equalizer::BandLevel> bandLevels;
     bandLevels.reserve(lvm::MAX_NUM_BANDS);
     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
-        bandLevels.emplace_back(
-                Equalizer::BandLevel{static_cast<int32_t>(i), mBandGainMdB[i]});
+        bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i), mBandGainmB[i]});
     }
     return bandLevels;
 }
 
 std::vector<int32_t> BundleContext::getEqualizerCenterFreqs() {
     std::vector<int32_t> freqs;
-
     LVM_ControlParams_t params;
     {
         std::lock_guard lg(mMutex);
@@ -518,7 +527,7 @@
     RETURN_VALUE_IF(!isBandLevelIndexInRange(bandLevels), RetCode::ERROR_ILLEGAL_PARAMETER,
                     "indexOutOfRange");
 
-    std::array<int, lvm::MAX_NUM_BANDS> tempLevel(mBandGainMdB);
+    std::array<int, lvm::MAX_NUM_BANDS> tempLevel(mBandGainmB);
     for (const auto& it : bandLevels) {
         tempLevel[it.index] = it.levelMb;
     }
@@ -539,8 +548,8 @@
         RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
                         RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
     }
-    mBandGainMdB = tempLevel;
-    LOG(DEBUG) << __func__ << " update bandGain to " << ::android::internal::ToString(mBandGainMdB)
+    mBandGainmB = tempLevel;
+    LOG(DEBUG) << __func__ << " update bandGain to " << ::android::internal::ToString(mBandGainmB)
                << "mdB";
 
     return RetCode::SUCCESS;
@@ -618,11 +627,30 @@
     return RetCode::SUCCESS;
 }
 
-void BundleContext::initControlParameter(LVM_ControlParams_t& params) const {
+RetCode BundleContext::initControlParameter(LVM_ControlParams_t& params) const {
+    int outputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+            mCommon.output.base.channelMask);
+    auto outputChannelMaskConv = aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+            mCommon.output.base.channelMask, /*isInput*/ false);
+    RETURN_VALUE_IF(!outputChannelMaskConv.ok(), RetCode::ERROR_ILLEGAL_PARAMETER,
+                    " outputChannelMaskNotValid");
+
+    params.NrChannels = outputChannelCount;
+    params.ChMask = outputChannelMaskConv.value();
+    params.SampleRate = lvmFsForSampleRate(mCommon.input.base.sampleRate);
+
+    int inputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+            mCommon.input.base.channelMask);
+    if (inputChannelCount == 1) {
+        params.SourceFormat = LVM_MONO;
+    } else if (inputChannelCount == 2) {
+        params.SourceFormat = LVM_STEREO;
+    } else if (inputChannelCount > 2 && inputChannelCount <= LVM_MAX_CHANNELS) {
+        params.SourceFormat = LVM_MULTICHANNEL;
+    }
+
     /* General parameters */
     params.OperatingMode = LVM_MODE_ON;
-    params.SampleRate = LVM_FS_44100;
-    params.SourceFormat = LVM_STEREO;
     params.SpeakerType = LVM_HEADPHONES;
 
     /* Concert Sound parameters */
@@ -657,13 +685,7 @@
     params.PSA_Enable = LVM_PSA_OFF;
     params.PSA_PeakDecayRate = LVM_PSA_SPEED_MEDIUM;
 
-    /* TE Control parameters */
-    params.TE_OperatingMode = LVM_TE_OFF;
-    params.TE_EffectLevel = 0;
-
-    params.NrChannels = audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
-    params.ChMask = AUDIO_CHANNEL_OUT_STEREO;
-    params.SourceFormat = LVM_STEREO;
+    return RetCode::SUCCESS;
 }
 
 void BundleContext::initHeadroomParameter(LVM_HeadroomParams_t& params) const {
@@ -832,13 +854,13 @@
             LOG(DEBUG) << "Effect_process() processing last frame";
         }
         mNumberEffectsCalled = 0;
-        LVM_UINT16 frames = samples * sizeof(float) / frameSize;
         float* outTmp = (accumulate ? getWorkBuffer() : out);
         /* Process the samples */
         LVM_ReturnStatus_en lvmStatus;
         {
             std::lock_guard lg(mMutex);
-            lvmStatus = LVM_Process(mInstance, in, outTmp, frames, 0);
+
+            lvmStatus = LVM_Process(mInstance, in, outTmp, inputFrameCount, 0);
             if (lvmStatus != LVM_SUCCESS) {
                 LOG(ERROR) << __func__ << lvmStatus;
                 return {EX_UNSUPPORTED_OPERATION, 0, 0};
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index 779d53a..809f402 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -41,15 +41,6 @@
     RetCode disable();
     RetCode disableOperatingMode();
 
-    void setSampleRate(const int sampleRate) { mSampleRate = sampleRate; }
-    int getSampleRate() const { return mSampleRate; }
-
-    void setChannelMask(const aidl::android::media::audio::common::AudioChannelLayout& chMask) {
-        mChMask = chMask;
-    }
-    aidl::android::media::audio::common::AudioChannelLayout getChannelMask() const {
-        return mChMask;
-    }
     bool isDeviceSupportedBassBoost(
             const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
                     devices);
@@ -105,9 +96,7 @@
     LVM_Handle_t mInstance GUARDED_BY(mMutex);
 
     aidl::android::media::audio::common::AudioDeviceDescription mVirtualizerForcedDevice;
-    aidl::android::media::audio::common::AudioChannelLayout mChMask;
 
-    int mSampleRate = LVM_FS_44100;
     int mSamplesPerSecond = 0;
     int mSamplesToExitCountEq = 0;
     int mSamplesToExitCountBb = 0;
@@ -129,7 +118,7 @@
     int mBassStrengthSaved = 0;
     // Equalizer
     int mCurPresetIdx = lvm::PRESET_CUSTOM; /* Current preset being used */
-    std::array<int, lvm::MAX_NUM_BANDS> mBandGainMdB; /* band gain in millibels */
+    std::array<int, lvm::MAX_NUM_BANDS> mBandGainmB; /* band gain in millibels */
     // Virtualizer
     int mVirtStrengthSaved = 0; /* Conversion between Get/Set */
     bool mVirtualizerTempDisabled = false;
@@ -139,7 +128,7 @@
     float mVolume = 0;
     bool mMuteEnabled = false; /* Must store as mute = -96dB level */
 
-    void initControlParameter(LVM_ControlParams_t& params) const;
+    RetCode initControlParameter(LVM_ControlParams_t& params) const;
     void initHeadroomParameter(LVM_HeadroomParams_t& params) const;
     RetCode limitLevel();
     static float VolToDb(float vol);
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index 5fb3966..da5346f 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -118,10 +118,15 @@
         "libhardware_headers",
     ],
     shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
+        "libaudioutils",
+        "libbinder",
         "liblog",
+        "libstagefright_foundation",
     ],
     cflags: [
         "-Wthread-safety",
+        "-DBACKEND_NDK",
     ],
     relative_install_path: "soundfx",
     visibility: [
diff --git a/media/utils/include/mediautils/StaticStringView.h b/media/utils/include/mediautils/StaticStringView.h
index 14be240..e9a5deb 100644
--- a/media/utils/include/mediautils/StaticStringView.h
+++ b/media/utils/include/mediautils/StaticStringView.h
@@ -21,15 +21,15 @@
 
 #pragma push_macro("EXPLICIT_CONVERSION_GENERATE_OPERATOR")
 #undef EXPLICIT_CONVERSION_GENERATE_OPERATOR
-#define EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, op)               \
-    friend constexpr bool operator op(T lhs, T rhs) {                 \
-        return operator op(static_cast<U>(lhs), static_cast<U>(rhs)); \
-    }                                                                 \
-    friend constexpr bool operator op(T lhs, U rhs) {                 \
-        return operator op(static_cast<U>(lhs), rhs);                 \
-    }                                                                 \
-    friend constexpr bool operator op(U lhs, T rhs) {                 \
-        return operator op(lhs, static_cast<U>(rhs));                 \
+#define EXPLICIT_CONVERSION_GENERATE_OPERATOR(T, U, op)    \
+    friend constexpr bool operator op(T lhs, T rhs) {      \
+        return static_cast<U>(lhs) op static_cast<U>(rhs); \
+    }                                                      \
+    friend constexpr bool operator op(T lhs, U rhs) {      \
+        return static_cast<U>(lhs) op rhs;                 \
+    }                                                      \
+    friend constexpr bool operator op(U lhs, T rhs) {      \
+        return lhs op static_cast<U>(rhs);                 \
     }
 
 #pragma push_macro("EXPLICIT_CONVERSION_GENERATE_COMPARISON_OPERATORS")
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 58e5311..2fd908f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3225,7 +3225,8 @@
         ALOGD("%s: no group matching with %s", __FUNCTION__, toString(attributes).c_str());
         return BAD_VALUE;
     }
-    ALOGV("%s: group %d matching with %s", __FUNCTION__, group, toString(attributes).c_str());
+    ALOGV("%s: group %d matching with %s index %d",
+            __FUNCTION__, group, toString(attributes).c_str(), index);
     status_t status = NO_ERROR;
     IVolumeCurves &curves = getVolumeCurves(attributes);
     VolumeSource vs = toVolumeSource(group);
@@ -3342,6 +3343,21 @@
             status = volStatus;
         }
     }
+
+    // update voice volume if the an active call route exists
+    if (mCallRxSourceClient != nullptr && mCallRxSourceClient->isConnected()
+            && (curSrcDevices.find(
+                Volume::getDeviceForVolume({mCallRxSourceClient->sinkDevice()->type()}))
+                != curSrcDevices.end())) {
+        bool isVoiceVolSrc;
+        bool isBtScoVolSrc;
+        if (isVolumeConsistentForCalls(vs, {mCallRxSourceClient->sinkDevice()->type()},
+                isVoiceVolSrc, isBtScoVolSrc, __func__)
+                && (isVoiceVolSrc || isBtScoVolSrc)) {
+            setVoiceVolume(index, curves, isVoiceVolSrc, 0);
+        }
+    }
+
     mpClientInterface->onAudioVolumeGroupChanged(group, 0 /*flags*/);
     return status;
 }
@@ -7815,26 +7831,16 @@
                outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
         return NO_ERROR;
     }
-    VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
-    VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO, false);
-    bool isVoiceVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (callVolSrc == volumeSource);
-    bool isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);
 
-    bool isScoRequested = isScoRequestedForComm();
-    bool isHAUsed = isHearingAidUsedForComm();
-
-    // do not change in call volume if bluetooth is connected and vice versa
-    // if sco and call follow same curves, bypass forceUseForComm
-    if ((callVolSrc != btScoVolSrc) &&
-            ((isVoiceVolSrc && isScoRequested) ||
-             (isBtScoVolSrc && !(isScoRequested || isHAUsed))) &&
-            !isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
-        ALOGV("%s cannot set volume group %d volume when is%srequested for comm", __func__,
-             volumeSource, isScoRequested ? " " : " not ");
+    bool isVoiceVolSrc;
+    bool isBtScoVolSrc;
+    if (!isVolumeConsistentForCalls(
+            volumeSource, deviceTypes, isVoiceVolSrc, isBtScoVolSrc, __func__)) {
         // Do not return an error here as AudioService will always set both voice call
-        // and bluetooth SCO volumes due to stream aliasing.
+        // and Bluetooth SCO volumes due to stream aliasing.
         return NO_ERROR;
     }
+
     if (deviceTypes.empty()) {
         deviceTypes = outputDesc->devices().types();
         index = curves.getVolumeIndex(deviceTypes);
@@ -7859,21 +7865,51 @@
             deviceTypes, delayMs, force, isVoiceVolSrc);
 
     if (outputDesc == mPrimaryOutput && (isVoiceVolSrc || isBtScoVolSrc)) {
-        float voiceVolume;
-        // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed by the headset
-        if (isVoiceVolSrc) {
-            voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
-        } else {
-            voiceVolume = index == 0 ? 0.0 : 1.0;
-        }
-        if (voiceVolume != mLastVoiceVolume) {
-            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
-            mLastVoiceVolume = voiceVolume;
-        }
+        setVoiceVolume(index, curves, isVoiceVolSrc, delayMs);
     }
     return NO_ERROR;
 }
 
+void AudioPolicyManager::setVoiceVolume(
+        int index, IVolumeCurves &curves, bool isVoiceVolSrc, int delayMs) {
+    float voiceVolume;
+    // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed
+    // by the headset
+    if (isVoiceVolSrc) {
+        voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
+    } else {
+        voiceVolume = index == 0 ? 0.0 : 1.0;
+    }
+    if (voiceVolume != mLastVoiceVolume) {
+        mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
+        mLastVoiceVolume = voiceVolume;
+    }
+}
+
+bool AudioPolicyManager::isVolumeConsistentForCalls(VolumeSource volumeSource,
+                                                   const DeviceTypeSet& deviceTypes,
+                                                   bool& isVoiceVolSrc,
+                                                   bool& isBtScoVolSrc,
+                                                   const char* caller) {
+    const VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
+    const VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO, false);
+    const bool isScoRequested = isScoRequestedForComm();
+    const bool isHAUsed = isHearingAidUsedForComm();
+
+    isVoiceVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (callVolSrc == volumeSource);
+    isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);
+
+    if ((callVolSrc != btScoVolSrc) &&
+            ((isVoiceVolSrc && isScoRequested) ||
+             (isBtScoVolSrc && !(isScoRequested || isHAUsed))) &&
+            !isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
+        ALOGV("%s cannot set volume group %d volume when is%srequested for comm", caller,
+             volumeSource, isScoRequested ? " " : " not ");
+        return false;
+    }
+    return true;
+}
+
 void AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
                                             const DeviceTypeSet& deviceTypes,
                                             int delayMs,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 5b9f6ad..8f8550c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -575,6 +575,20 @@
                                            DeviceTypeSet deviceTypes,
                                            int delayMs = 0, bool force = false);
 
+        void setVoiceVolume(int index, IVolumeCurves &curves, bool isVoiceVolSrc, int delayMs);
+
+        // returns true if the supplied set of volume source and devices are consistent with
+        // call volume rules:
+        // if Bluetooth SCO and voice call use different volume curves:
+        // - do not apply voice call volume if Bluetooth SCO is used for call
+        // - do not apply Bluetooth SCO volume if SCO or Hearing Aid is not used for call.
+        // Also updates the booleans isVoiceVolSrc and isBtScoVolSrc according to the
+        // volume source supplied.
+        bool isVolumeConsistentForCalls(VolumeSource volumeSource,
+                                       const DeviceTypeSet& deviceTypes,
+                                       bool& isVoiceVolSrc,
+                                       bool& isBtScoVolSrc,
+                                       const char* caller);
         // apply all stream volumes to the specified output and device
         void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
                                 const DeviceTypeSet& deviceTypes,
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy
index a55c3eb..0c6aafd 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy
@@ -52,6 +52,9 @@
 getdents64: 1
 ppoll: 1
 
+clock_gettime: 1
+pipe2: 1
+
 # Required by AddressSanitizer
 gettid: 1
 sched_yield: 1
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index 73a96e9..794bda0 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -74,10 +74,14 @@
     name: "libresourcemanagerservice",
 
     srcs: [
+        "DefaultResourceModel.cpp",
+        "ProcessPriorityReclaimPolicy.cpp",
         "ResourceManagerMetrics.cpp",
         "ResourceManagerService.cpp",
+        "ResourceManagerServiceNew.cpp",
         "ResourceObserverService.cpp",
         "ResourceManagerServiceUtils.cpp",
+        "ResourceTracker.cpp",
         "ServiceLog.cpp",
         "UidObserver.cpp",
 
@@ -97,6 +101,7 @@
         "libstatssocket",
         "libprotobuf-cpp-lite",
         "libactivitymanager_aidl",
+        "aconfig_mediacodec_flags_c_lib",
     ],
 
     static_libs: [
diff --git a/services/mediaresourcemanager/DefaultResourceModel.cpp b/services/mediaresourcemanager/DefaultResourceModel.cpp
new file mode 100644
index 0000000..7bad715
--- /dev/null
+++ b/services/mediaresourcemanager/DefaultResourceModel.cpp
@@ -0,0 +1,145 @@
+/*
+**
+** 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 "DefaultResourceModel"
+#include <utils/Log.h>
+
+#include "ResourceManagerServiceUtils.h"
+#include "DefaultResourceModel.h"
+#include "ResourceTracker.h"
+
+namespace android {
+
+DefaultResourceModel::DefaultResourceModel(
+        const std::shared_ptr<ResourceTracker>& resourceTracker,
+        bool supportsMultipleSecureCodecs,
+        bool supportsSecureWithNonSecureCodec)
+    : mSupportsMultipleSecureCodecs(supportsMultipleSecureCodecs),
+      mSupportsSecureWithNonSecureCodec(supportsSecureWithNonSecureCodec),
+      mResourceTracker(resourceTracker) {
+}
+
+DefaultResourceModel::~DefaultResourceModel() {
+}
+
+bool DefaultResourceModel::getAllClients(
+        const ReclaimRequestInfo& reclimRequestInfo,
+        std::vector<ClientInfo>& clients) {
+
+    clients.clear();
+    MediaResourceParcel mediaResource{.type = reclimRequestInfo.mResources[0].type,
+                                      .subType = reclimRequestInfo.mResources[0].subType};
+    ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+
+    // Resolve the secure-unsecure codec conflicts if there is any.
+    switch (reclimRequestInfo.mResources[0].type) {
+    case MediaResource::Type::kSecureCodec:
+        // Looking to start a secure codec.
+        // #1. Make sure if multiple secure codecs can coexist
+        if (!mSupportsMultipleSecureCodecs) {
+            if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+                // A higher priority process owns an instance of a secure codec.
+                // So this request can't be fulfilled.
+                return false;
+            }
+        }
+        // #2. Make sure a secure codec can coexist if there is an instance
+        // of non-secure codec running already.
+        if (!mSupportsSecureWithNonSecureCodec) {
+            mediaResource.type = MediaResource::Type::kNonSecureCodec;
+            if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+                // A higher priority process owns an instance of a non-secure codec.
+                // So this request can't be fulfilled.
+                return false;
+            }
+        }
+        break;
+    case MediaResource::Type::kNonSecureCodec:
+        // Looking to start a non-secure codec.
+        // Make sure a non-secure codec can coexist if there is an instance
+        // of secure codec running already.
+        if (!mSupportsSecureWithNonSecureCodec) {
+            mediaResource.type = MediaResource::Type::kSecureCodec;
+            if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+                // A higher priority process owns an instance of a secure codec.
+                // So this request can't be fulfilled.
+                return false;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!clients.empty()) {
+        // There is secure/unsecure codec co-existence conflict
+        // and we have only found processes with lower priority holding the
+        // resources. So, all of these need to be reclaimed.
+        return false;
+    }
+
+    // No more resource conflicts.
+    switch (reclimRequestInfo.mResources[0].type) {
+    case MediaResource::Type::kSecureCodec:
+    case MediaResource::Type::kNonSecureCodec:
+        // Handling Codec resource reclaim
+        return getCodecClients(reclimRequestInfo, clients);
+    case MediaResource::Type::kGraphicMemory:
+    case MediaResource::Type::kDrmSession:
+        // Handling DRM and GraphicMemory resource reclaim
+        mediaResource.id = reclimRequestInfo.mResources[0].id;
+        mediaResource.value = reclimRequestInfo.mResources[0].value;
+        return mResourceTracker->getAllClients(resourceRequestInfo, clients);
+    default:
+        break;
+    }
+
+    return !clients.empty();
+}
+
+bool DefaultResourceModel::getCodecClients(
+        const ReclaimRequestInfo& reclimRequestInfo,
+        std::vector<ClientInfo>& clients) {
+    MediaResourceParcel mediaResource;
+    ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+
+    // 1. Look to find the client(s) with the other resources, for the given
+    // primary type.
+    MediaResource::SubType primarySubType = reclimRequestInfo.mResources[0].subType;
+    for (size_t index = 1; index < reclimRequestInfo.mResources.size(); index++) {
+        mediaResource.type = reclimRequestInfo.mResources[index].type;
+        mediaResource.subType = reclimRequestInfo.mResources[index].subType;
+        mResourceTracker->getAllClients(resourceRequestInfo, clients, primarySubType);
+    }
+
+    // 2. Get all clients of the same type.
+    mediaResource.type = reclimRequestInfo.mResources[0].type;
+    mediaResource.subType = reclimRequestInfo.mResources[0].subType;
+    mResourceTracker->getAllClients(resourceRequestInfo, clients);
+
+    // 3. Get all cliends of the different type.
+    MediaResourceType otherType =
+        (reclimRequestInfo.mResources[0].type == MediaResource::Type::kSecureCodec) ?
+        MediaResource::Type::kNonSecureCodec : MediaResource::Type::kSecureCodec;
+    mediaResource.type = otherType;
+    mResourceTracker->getAllClients(resourceRequestInfo, clients);
+
+    return !clients.empty();
+}
+
+} // namespace android
diff --git a/services/mediaresourcemanager/DefaultResourceModel.h b/services/mediaresourcemanager/DefaultResourceModel.h
new file mode 100644
index 0000000..1891eda
--- /dev/null
+++ b/services/mediaresourcemanager/DefaultResourceModel.h
@@ -0,0 +1,73 @@
+/*
+**
+** 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_DEFAULTRESOURCEMODEL_H_
+#define ANDROID_MEDIA_DEFAULTRESOURCEMODEL_H_
+
+#include "IResourceModel.h"
+
+namespace android {
+
+class ResourceTracker;
+
+/*
+ * Implements the Default Resource Model that handles:
+ *   - coexistence of secure codec with another secure/non-secure codecs
+ *   - sharing resources among other codecs
+ */
+class DefaultResourceModel : public IResourceModel {
+public:
+    DefaultResourceModel(const std::shared_ptr<ResourceTracker>& resourceTracker,
+                         bool supportsMultipleSecureCodecs = true,
+                         bool supportsSecureWithNonSecureCodec = true);
+    virtual ~DefaultResourceModel();
+
+    /*
+     * Set the codec co-existence properties
+     */
+    void config(bool supportsMultipleSecureCodecs, bool supportsSecureWithNonSecureCodec) {
+        mSupportsMultipleSecureCodecs = supportsMultipleSecureCodecs;
+        mSupportsSecureWithNonSecureCodec = supportsSecureWithNonSecureCodec;
+    }
+
+    /*
+     * Get a list of all clients that holds the resources requested.
+     * This implementation uses the ResourceModel to select the clients.
+     *
+     * @param[in]  reclaimRequestInfo Information about the Reclaim request
+     * @param[out] cliens The list of clients that hold the resources in question.
+     *
+     * @return true if there aren't any resource conflicts and false otherwise.
+     */
+    bool getAllClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                       std::vector<ClientInfo>& clients) override;
+
+protected:
+    bool getCodecClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                         std::vector<ClientInfo>& clients);
+
+protected:
+    // Keeping these protected to allow extending this implementation
+    // by other resource models.
+    bool mSupportsMultipleSecureCodecs;
+    bool mSupportsSecureWithNonSecureCodec;
+    std::shared_ptr<ResourceTracker> mResourceTracker;
+};
+
+} // namespace android
+
+#endif  // ANDROID_MEDIA_DEFAULTRESOURCEMODEL_H_
diff --git a/services/mediaresourcemanager/IReclaimPolicy.h b/services/mediaresourcemanager/IReclaimPolicy.h
new file mode 100644
index 0000000..dfbfc12
--- /dev/null
+++ b/services/mediaresourcemanager/IReclaimPolicy.h
@@ -0,0 +1,58 @@
+/*
+**
+** 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_IRECLAIMPOLICY_H_
+#define ANDROID_MEDIA_IRECLAIMPOLICY_H_
+
+#include <memory>
+#include <aidl/android/media/IResourceManagerClient.h>
+
+namespace android {
+
+struct ClientInfo;
+struct ReclaimRequestInfo;
+
+/*
+ * Interface that defines Reclaim Policy.
+ *
+ * This provides an interface to select/identify a client based on a specific
+ * Reclaim policy.
+ */
+class IReclaimPolicy {
+public:
+    IReclaimPolicy() {}
+
+    virtual ~IReclaimPolicy() {}
+
+    /*
+     * Based on the Reclaim policy, identify and return a client from the list
+     * of given clients that satisfy the resource requested.
+     *
+     * @param[in]  reclaimRequestInfo Information about the resource request
+     * @param[in]  client List of clients to select from.
+     * @param[out] targetClients Upon success, this will have the list of identified client(s).
+     *
+     * @return true on success, false otherwise
+     */
+    virtual bool getClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                            const std::vector<ClientInfo>& clients,
+                            std::vector<ClientInfo>& targetClients) = 0;
+};
+
+} // namespace android
+
+#endif  // ANDROID_MEDIA_IRECLAIMPOLICY_H_
diff --git a/services/mediaresourcemanager/IResourceModel.h b/services/mediaresourcemanager/IResourceModel.h
new file mode 100644
index 0000000..f865f54
--- /dev/null
+++ b/services/mediaresourcemanager/IResourceModel.h
@@ -0,0 +1,67 @@
+/*
+**
+** 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_IRESOURCEMODEL_H_
+#define ANDROID_MEDIA_IRESOURCEMODEL_H_
+
+#include <memory>
+#include <vector>
+
+#include <aidl/android/media/IResourceManagerClient.h>
+#include <aidl/android/media/MediaResourceParcel.h>
+
+namespace android {
+
+struct ClientInfo;
+struct ReclaimRequestInfo;
+
+/*
+ * Interface that defines Resource Model.
+ *
+ * This provides an interface that manages the resource model.
+ * The primary functionality of the implementation of this resource model is to:
+ *  1. Define a resource model for a device (or family of devices)
+ *    For example (and not limited to):
+ *      - Can a secure codec coexist with another secure or unsecured codec?
+ *      - How many codecs can coexist?
+ *      - Can one type of codecs (for example avc) coexist with another type of codec
+ *        (for example hevc) independently? OR are they sharing the common
+ *        resource pool?
+ *  2. Provide a list of clients that hold requesting resources.
+ */
+class IResourceModel {
+public:
+    IResourceModel() {}
+
+    virtual ~IResourceModel() {}
+
+    /*
+     * Get a list of all clients that holds the resources requested.
+     * This implementation uses the ResourceModel to select the clients.
+     *
+     * @param[in]  reclaimRequestInfo Information about the Reclaim request
+     * @param[out] clients The list of clients that hold the resources in question.
+     *
+     * @return true if there aren't any resource conflicts and false otherwise.
+     */
+    virtual bool getAllClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                               std::vector<ClientInfo>& clients) = 0;
+};
+
+} // namespace android
+
+#endif  // ANDROID_MEDIA_IRESOURCEMODEL_H_
diff --git a/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.cpp b/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.cpp
new file mode 100644
index 0000000..5b776a6
--- /dev/null
+++ b/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.cpp
@@ -0,0 +1,135 @@
+/*
+**
+** 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 "ProcessPriorityReclaimPolicy"
+#include <utils/Log.h>
+
+#include "ResourceTracker.h"
+#include "ResourceManagerService.h"
+#include "ProcessPriorityReclaimPolicy.h"
+
+namespace android {
+
+using aidl::android::media::IResourceManagerClient;
+
+ProcessPriorityReclaimPolicy::ProcessPriorityReclaimPolicy(
+        const std::shared_ptr<ResourceTracker>& resourceTracker)
+    : mResourceTracker(resourceTracker) {
+}
+
+ProcessPriorityReclaimPolicy::~ProcessPriorityReclaimPolicy() {
+}
+
+// Process priority (oom score) based reclaim:
+//   - Find a process with lowest priority (than that of calling process).
+//   - Find the bigegst client (with required resources) from that process.
+bool ProcessPriorityReclaimPolicy::getClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                                              const std::vector<ClientInfo>& clients,
+                                              std::vector<ClientInfo>& targetClients) {
+    // NOTE: This is the behavior of the existing reclaim policy.
+    // We can alter it to select more than one client to reclaim from, depending
+    // on the reclaim polocy.
+
+    MediaResource::Type type = reclaimRequestInfo.mResources[0].type;
+    MediaResource::SubType subType = reclaimRequestInfo.mResources[0].subType;
+    // Find one client to reclaim the needed resources from.
+    // 1. Get the priority of the (reclaim) requesting process.
+    int callingPid = reclaimRequestInfo.mCallingPid;
+    int callingPriority = -1;
+    if (!mResourceTracker->getPriority(callingPid, &callingPriority)) {
+        ALOGE("%s: can't get process priority for pid %d", __func__, callingPid);
+        return false;
+    }
+
+    ClientInfo clientInfo;
+    // 2 Look to find the biggest client from the lowest priority process that
+    // has the other resources and with the given primary type.
+    bool found = false;
+    int lowestPriority = -1;
+    MediaResource::SubType primarySubType = subType;
+    for (size_t index = 1; !found && (index < reclaimRequestInfo.mResources.size()); index++) {
+        MediaResource::Type type = reclaimRequestInfo.mResources[index].type;
+        MediaResource::SubType subType = reclaimRequestInfo.mResources[index].subType;
+        found = getBiggestClientFromLowestPriority(callingPid, callingPriority,
+                                                   type, subType, primarySubType,
+                                                   clients, clientInfo, lowestPriority);
+    }
+    // 3 If we haven't found a client yet, then select the biggest client of primary type.
+    if (!found) {
+        found = getBiggestClientFromLowestPriority(callingPid, callingPriority,
+                                                   type, subType,
+                                                   MediaResource::SubType::kUnspecifiedSubType,
+                                                   clients, clientInfo, lowestPriority);
+    }
+    // 4 If we haven't found a client yet, then select the biggest client of different type.
+    // This is applicable for code type only.
+    if (!found) {
+        if (type != MediaResource::Type::kSecureCodec &&
+            type != MediaResource::Type::kNonSecureCodec) {
+            return false;
+        }
+        MediaResourceType otherType = (type == MediaResource::Type::kSecureCodec) ?
+            MediaResource::Type::kNonSecureCodec : MediaResource::Type::kSecureCodec;
+        if (!getBiggestClientFromLowestPriority(callingPid, callingPriority,
+                                                otherType, subType,
+                                                MediaResource::SubType::kUnspecifiedSubType,
+                                                clients, clientInfo, lowestPriority)) {
+            return false;
+        }
+    }
+
+    targetClients.emplace_back(clientInfo);
+    ALOGI("%s: CallingProcess(%d:%d) will reclaim from the lowestPriorityProcess(%d:%d)",
+          __func__, callingPid, callingPriority, clientInfo.mPid, lowestPriority);
+
+    return true;
+}
+
+bool ProcessPriorityReclaimPolicy::getBiggestClientFromLowestPriority(
+        pid_t callingPid,
+        int callingPriority,
+        MediaResource::Type type, MediaResource::SubType subType,
+        MediaResource::SubType primarySubType,
+        const std::vector<ClientInfo>& clients,
+        ClientInfo& targetClient,
+        int& lowestPriority) {
+    // 1. Find the lowest priority process among all the clients with the
+    // requested resource type.
+    int lowestPriorityPid = -1;
+    lowestPriority = -1;
+    if (!mResourceTracker->getLowestPriorityPid(type, subType, primarySubType, clients,
+                                                lowestPriorityPid, lowestPriority)) {
+        ALOGD("%s: can't find a process with lower priority than that of the process[%d:%d]",
+              __func__, callingPid, callingPriority);
+        return false;
+    }
+
+    // 2. Make sure that the priority of the target process is less than
+    // requesting process.
+    if (lowestPriority <= callingPriority) {
+        ALOGD("%s: lowest priority %d vs caller priority %d",
+              __func__, lowestPriority, callingPriority);
+        return false;
+    }
+
+    // 3. Look to find the biggest client from that process for the given resources
+    return mResourceTracker->getBiggestClient(lowestPriorityPid, type, subType,
+                                              clients, targetClient, primarySubType);
+}
+
+} // namespace android
diff --git a/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.h b/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.h
new file mode 100644
index 0000000..77bf7e1
--- /dev/null
+++ b/services/mediaresourcemanager/ProcessPriorityReclaimPolicy.h
@@ -0,0 +1,89 @@
+/*
+**
+** 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_PROCESSPRIORITYRECLAIMPOLICY_H_
+#define ANDROID_MEDIA_PROCESSPRIORITYRECLAIMPOLICY_H_
+
+#include <media/MediaResource.h>
+#include "IReclaimPolicy.h"
+
+namespace android {
+
+class ResourceTracker;
+struct ClientInfo;
+
+/*
+ * Implementation of the Reclaim Policy based on the process priority.
+ *
+ * Find the lowest priority process (lower than the calling/requesting process’s priority)
+ * that has the required resources.
+ * From that process, find the biggest client and return the same for reclaiming.
+ * If there is a codec co-existence policy, that is addressed as below:
+ *   - if these are any conflicting codecs, reclaim all those conflicting clients.
+ * If no conflicting codecs, the reclaim policy will select a client in the order of:
+ *   - Find the biggest client from the lowest priority process that
+ *     has the other resources and with the given primary type.
+ *   - select the biggest client from the lower priority process that
+ *     has the primary type.
+ *   - If it's a codec reclaim request, then:
+ *      - select the biggest client from the lower priority process that
+ *        has the othe type (for example secure for a non-secure and vice versa).
+ */
+class ProcessPriorityReclaimPolicy : public IReclaimPolicy {
+public:
+    ProcessPriorityReclaimPolicy(const std::shared_ptr<ResourceTracker>& resourceTracker);
+
+    virtual ~ProcessPriorityReclaimPolicy();
+
+    /*
+     * Based on the process priority, identify and return a client from the list
+     * of given clients that satisfy the resource requested.
+     *
+     * @param[in]  reclaimRequestInfo Information about the resource request
+     * @param[in]  client List of clients to select from.
+     * @param[out] targetClients Upon success, this will have the list of identified client(s).
+     *
+     * @return true on success, false otherwise
+     */
+    bool getClients(const ReclaimRequestInfo& reclaimRequestInfo,
+                    const std::vector<ClientInfo>& clients,
+                    std::vector<ClientInfo>& targetClients) override;
+
+private:
+
+    // Get the biggest client with the given resources from the given list of clients.
+    // The client should belong to lowest possible priority than that of the
+    // calling/requesting process.
+    // returns true on success, false otherwise
+    //
+    bool getBiggestClientFromLowestPriority(
+        pid_t callingPid,
+        int callingPriority,
+        MediaResource::Type type,
+        MediaResource::SubType subType,
+        MediaResource::SubType primarySubType,
+        const std::vector<ClientInfo>& clients,
+        ClientInfo& targetClient,
+        int& lowestPriority);
+
+private:
+    std::shared_ptr<ResourceTracker> mResourceTracker;
+};
+
+} // namespace android
+
+#endif  // ANDROID_MEDIA_PROCESSPRIORITYRECLAIMPOLICY_H_
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 1953237..4bdb6e1 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -29,38 +29,64 @@
 #include <mediautils/BatteryNotifier.h>
 #include <mediautils/ProcessInfo.h>
 #include <mediautils/SchedulingPolicyService.h>
+#include <com_android_media_codec_flags.h>
 
-#include "IMediaResourceMonitor.h"
 #include "ResourceManagerMetrics.h"
+#include "ResourceManagerServiceNew.h"
 #include "ResourceObserverService.h"
 #include "ServiceLog.h"
 
+namespace CodecFeatureFlags = com::android::media::codec::flags;
+
 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*/) {
@@ -75,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);
@@ -100,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);
 
@@ -212,9 +205,35 @@
 std::shared_ptr<ResourceManagerService> ResourceManagerService::Create(
         const sp<ProcessInfoInterface>& processInfo,
         const sp<SystemCallbackInterface>& systemResource) {
-    return ::ndk::SharedRefBase::make<ResourceManagerService>(processInfo, systemResource);
+    std::shared_ptr<ResourceManagerService> service = nullptr;
+    // If codec importance feature is on, create the refactored implementation.
+    if (CodecFeatureFlags::codec_importance()) {
+        service = ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo,
+                                                                        systemResource);
+    } else {
+        service = ::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) {
+    std::shared_ptr<ResourceManagerService> service =
+        ::ndk::SharedRefBase::make<ResourceManagerServiceNew>(processInfo, systemResource);
+    service->init();
+    return service;
+}
+
+void ResourceManagerService::init() {}
+
 ResourceManagerService::~ResourceManagerService() {}
 
 void ResourceManagerService::setObserverService(
@@ -472,6 +491,111 @@
     }
 }
 
+bool ResourceManagerService::getTargetClients(
+        int32_t callingPid,
+        const std::vector<MediaResourceParcel>& resources,
+        std::vector<ClientInfo>& targetClients) {
+    std::scoped_lock lock{mLock};
+    if (!mProcessInfo->isPidTrusted(callingPid)) {
+        pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
+                callingPid, actualCallingPid);
+        callingPid = actualCallingPid;
+    }
+    const MediaResourceParcel *secureCodec = NULL;
+    const MediaResourceParcel *nonSecureCodec = NULL;
+    const MediaResourceParcel *graphicMemory = NULL;
+    const MediaResourceParcel *drmSession = NULL;
+    for (size_t i = 0; i < resources.size(); ++i) {
+        switch (resources[i].type) {
+            case MediaResource::Type::kSecureCodec:
+                secureCodec = &resources[i];
+                break;
+            case MediaResource::Type::kNonSecureCodec:
+                nonSecureCodec = &resources[i];
+                break;
+            case MediaResource::Type::kGraphicMemory:
+                graphicMemory = &resources[i];
+                break;
+            case MediaResource::Type::kDrmSession:
+                drmSession = &resources[i];
+                break;
+            default:
+                break;
+        }
+    }
+
+    // first pass to handle secure/non-secure codec conflict
+    if (secureCodec != NULL) {
+        MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
+                                          .subType = secureCodec->subType};
+        ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+        if (!mSupportsMultipleSecureCodecs) {
+            if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+                return false;
+            }
+        }
+        if (!mSupportsSecureWithNonSecureCodec) {
+            mediaResource.type = MediaResource::Type::kNonSecureCodec;
+            if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+                return false;
+            }
+        }
+    }
+    if (nonSecureCodec != NULL) {
+        if (!mSupportsSecureWithNonSecureCodec) {
+            MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
+                                              .subType = nonSecureCodec->subType};
+            ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+            if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+                return false;
+            }
+        }
+    }
+
+    if (drmSession != NULL) {
+        ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
+        getClientForResource_l(resourceRequestInfo, targetClients);
+        if (targetClients.size() == 0) {
+            return false;
+        }
+    }
+
+    if (targetClients.size() == 0 && graphicMemory != nullptr) {
+        // if no secure/non-secure codec conflict, run second pass to handle other resources.
+        ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
+        getClientForResource_l(resourceRequestInfo, targetClients);
+    }
+
+    if (targetClients.size() == 0) {
+        // if we are here, run the third pass to free one codec with the same type.
+        if (secureCodec != nullptr) {
+            ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
+            getClientForResource_l(resourceRequestInfo, targetClients);
+        }
+        if (nonSecureCodec != nullptr) {
+            ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
+            getClientForResource_l(resourceRequestInfo, targetClients);
+        }
+    }
+
+    if (targetClients.size() == 0) {
+        // if we are here, run the fourth pass to free one codec with the different type.
+        if (secureCodec != nullptr) {
+            MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
+            ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+            getClientForResource_l(resourceRequestInfo, targetClients);
+        }
+        if (nonSecureCodec != nullptr) {
+            MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
+            ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+            getClientForResource_l(resourceRequestInfo, targetClients);
+        }
+    }
+
+    return !targetClients.empty();
+}
+
 Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
         const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
     int32_t callingPid = clientInfo.pid;
@@ -481,105 +605,16 @@
     mServiceLog->add(log);
     *_aidl_return = false;
 
+    // Check if there are any resources to be reclaimed before processing.
+    if (resources.empty()) {
+        return Status::ok();
+    }
+
     std::vector<ClientInfo> targetClients;
-    {
-        std::scoped_lock lock{mLock};
-        if (!mProcessInfo->isPidTrusted(callingPid)) {
-            pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
-            ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
-                    callingPid, actualCallingPid);
-            callingPid = actualCallingPid;
-        }
-        const MediaResourceParcel *secureCodec = NULL;
-        const MediaResourceParcel *nonSecureCodec = NULL;
-        const MediaResourceParcel *graphicMemory = NULL;
-        const MediaResourceParcel *drmSession = NULL;
-        for (size_t i = 0; i < resources.size(); ++i) {
-            switch (resources[i].type) {
-                case MediaResource::Type::kSecureCodec:
-                    secureCodec = &resources[i];
-                    break;
-                case MediaResource::Type::kNonSecureCodec:
-                    nonSecureCodec = &resources[i];
-                    break;
-                case MediaResource::Type::kGraphicMemory:
-                    graphicMemory = &resources[i];
-                    break;
-                case MediaResource::Type::kDrmSession:
-                    drmSession = &resources[i];
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        // first pass to handle secure/non-secure codec conflict
-        if (secureCodec != NULL) {
-            MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
-                                              .subType = secureCodec->subType};
-            ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
-            if (!mSupportsMultipleSecureCodecs) {
-                if (!getAllClients_l(resourceRequestInfo, targetClients)) {
-                    return Status::ok();
-                }
-            }
-            if (!mSupportsSecureWithNonSecureCodec) {
-                mediaResource.type = MediaResource::Type::kNonSecureCodec;
-                if (!getAllClients_l(resourceRequestInfo, targetClients)) {
-                    return Status::ok();
-                }
-            }
-        }
-        if (nonSecureCodec != NULL) {
-            if (!mSupportsSecureWithNonSecureCodec) {
-                MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
-                                                  .subType = nonSecureCodec->subType};
-                ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
-                if (!getAllClients_l(resourceRequestInfo, targetClients)) {
-                    return Status::ok();
-                }
-            }
-        }
-
-        if (drmSession != NULL) {
-            ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
-            getClientForResource_l(resourceRequestInfo, targetClients);
-            if (targetClients.size() == 0) {
-                return Status::ok();
-            }
-        }
-
-        if (targetClients.size() == 0 && graphicMemory != nullptr) {
-            // if no secure/non-secure codec conflict, run second pass to handle other resources.
-            ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
-            getClientForResource_l(resourceRequestInfo, targetClients);
-        }
-
-        if (targetClients.size() == 0) {
-            // if we are here, run the third pass to free one codec with the same type.
-            if (secureCodec != nullptr) {
-                ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
-                getClientForResource_l(resourceRequestInfo, targetClients);
-            }
-            if (nonSecureCodec != nullptr) {
-                ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
-                getClientForResource_l(resourceRequestInfo, targetClients);
-            }
-        }
-
-        if (targetClients.size() == 0) {
-            // if we are here, run the fourth pass to free one codec with the different type.
-            if (secureCodec != nullptr) {
-                MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
-                ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
-                getClientForResource_l(resourceRequestInfo, targetClients);
-            }
-            if (nonSecureCodec != nullptr) {
-                MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
-                ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
-                getClientForResource_l(resourceRequestInfo, targetClients);
-            }
-        }
+    if (!getTargetClients(callingPid, resources, targetClients)) {
+        // Nothing to reclaim from.
+        ALOGI("%s: There aren't any clients to reclaim from", __func__);
+        return Status::ok();
     }
 
     *_aidl_return = reclaimUnconditionallyFrom(targetClients);
@@ -686,6 +721,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);
@@ -705,9 +750,7 @@
 
     {
         std::scoped_lock lock{mLock};
-        mOverridePidMap.erase(originalPid);
-        if (newPid != -1) {
-            mOverridePidMap.emplace(originalPid, newPid);
+        if (overridePid_l(originalPid, newPid)) {
             mResourceManagerMetrics->addPid(newPid);
         }
     }
@@ -715,6 +758,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) {
@@ -735,23 +801,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) {
@@ -857,11 +912,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);
     }
@@ -1053,4 +1109,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 e22a6b3..44ed005 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,88 +112,140 @@
 
     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.
-    bool getLowestPriorityBiggestClient_l(
-        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,
+    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.
+
+    // A helper function that gets the biggest clients of the process pid that
+    // is marked to be (pending) removed and has the needed resources.
     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.
+    // From the list of clients, pick/select client(s) based on the reclaim policy.
     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);
-
-    // Get priority from process's pid
-    bool getPriority_l(int pid, int* priority);
-
-    void removeProcessInfoOverride(int pid);
-
-    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 override info for the given process
+    void removeProcessInfoOverride_l(int pid);
 
-    // Remove the client for given pid and the clientId from the map
-    bool removeClient(int pid, const int64_t& clientId);
+    // 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.
 
-    // The following utility functions are used only for testing by ResourceManagerServiceTest
+    // Initializes the internal state of the ResourceManagerService
+    virtual void init();
+
+    // Gets the list of all the clients who own the list of specified resource type
+    // and satisfy the resource model and the reclaim policy.
+    virtual bool getTargetClients(
+        int32_t callingPid,
+        const std::vector<MediaResourceParcel>& resources,
+        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.
+    virtual 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.
+    virtual bool getLowestPriorityBiggestClient_l(
+        const ResourceRequestInfo& resourceRequestInfo,
+        ClientInfo& clientInfo);
+
+    // override the pid of given process
+    virtual bool overridePid_l(int32_t originalPid, int32_t newPid);
+
+    // override the process info of given process
+    virtual bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
+                                       int pid, int procState, int oomScore);
+
+    // Get priority from process's pid
+    virtual bool getPriority_l(int pid, int* priority) const;
+
     // 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);
+    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;
+
+    // The following utility functions are used only for testing by ResourceManagerServiceTest
+    // START: TEST only functions
     // Get the peak concurrent pixel count (associated with the video codecs) for the process.
     long getPeakConcurrentPixelCount(int pid) const;
     // Get the current concurrent pixel count (associated with the video codecs) for the process.
     long getCurrentConcurrentPixelCount(int pid) const;
+    // To create object of type ResourceManagerServiceNew
+    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;
+    }
+    // END: TEST only functions
 
+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
new file mode 100644
index 0000000..dde389a
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
@@ -0,0 +1,362 @@
+/*
+**
+** 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 "ResourceManagerServiceNew"
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <mediautils/ProcessInfo.h>
+
+#include "DefaultResourceModel.h"
+#include "ProcessPriorityReclaimPolicy.h"
+#include "ResourceManagerServiceNew.h"
+#include "ResourceTracker.h"
+#include "ServiceLog.h"
+
+namespace android {
+
+ResourceManagerServiceNew::ResourceManagerServiceNew(
+        const sp<ProcessInfoInterface>& processInfo,
+        const sp<SystemCallbackInterface>& systemResource) :
+  ResourceManagerService(processInfo, systemResource) {}
+
+ResourceManagerServiceNew::~ResourceManagerServiceNew() {}
+
+void ResourceManagerServiceNew::init() {
+    // Create the Resource Tracker
+    mResourceTracker = std::make_shared<ResourceTracker>(ref<ResourceManagerServiceNew>(),
+                                                         mProcessInfo);
+    setUpResourceModels();
+    setUpReclaimPolicies();
+}
+
+void ResourceManagerServiceNew::setUpResourceModels() {
+    std::scoped_lock lock{mLock};
+    // Create/Configure the default resource model.
+    if (mDefaultResourceModel == nullptr) {
+        mDefaultResourceModel = std::make_unique<DefaultResourceModel>(
+                mResourceTracker,
+                mSupportsMultipleSecureCodecs,
+                mSupportsSecureWithNonSecureCodec);
+    } else {
+        DefaultResourceModel* resourceModel =
+            static_cast<DefaultResourceModel*>(mDefaultResourceModel.get());
+        resourceModel->config(mSupportsMultipleSecureCodecs, mSupportsSecureWithNonSecureCodec);
+    }
+}
+
+void ResourceManagerServiceNew::setUpReclaimPolicies() {
+    mReclaimPolicies.clear();
+    // Process priority (oom score) as the Default reclaim policy.
+    mReclaimPolicies.push_back(std::make_unique<ProcessPriorityReclaimPolicy>(mResourceTracker));
+}
+
+Status ResourceManagerServiceNew::config(const std::vector<MediaResourcePolicyParcel>& policies) {
+    Status status = ResourceManagerService::config(policies);
+    // Change in the config dictates update to the resource model.
+    setUpResourceModels();
+    return status;
+}
+
+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) {
+    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) {
+    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) {
+    removeResource(clientInfo, true /*checkValid*/);
+    return Status::ok();
+}
+
+Status ResourceManagerServiceNew::removeResource(const ClientInfoParcel& clientInfo,
+                                                 bool 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(
+        const ClientInfoParcel& clientInfo,
+        const std::vector<MediaResourceParcel>& resources,
+        bool* _aidl_return) {
+    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,
+        int procState,
+        int oomScore) {
+    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) {
+    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) {
+    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) {
+    return ResourceManagerService::notifyClientCreated(clientInfo);
+}
+
+Status ResourceManagerServiceNew::notifyClientStarted(const ClientConfigParcel& clientConfig) {
+    return ResourceManagerService::notifyClientStarted(clientConfig);
+}
+
+Status ResourceManagerServiceNew::notifyClientStopped(const ClientConfigParcel& clientConfig) {
+    return ResourceManagerService::notifyClientStopped(clientConfig);
+}
+
+Status ResourceManagerServiceNew::notifyClientConfigChanged(
+        const ClientConfigParcel& clientConfig) {
+    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::getTargetClients(
+        int callingPid,
+        const std::vector<MediaResourceParcel>& resources,
+        std::vector<ClientInfo>& targetClients) {
+    std::scoped_lock lock{mLock};
+    if (!mProcessInfo->isPidTrusted(callingPid)) {
+        pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
+                callingPid, actualCallingPid);
+        callingPid = actualCallingPid;
+    }
+
+    // Use the Resource Model to get a list of all the clients that hold the
+    // needed/requested resources.
+    ReclaimRequestInfo reclaimRequestInfo{callingPid, resources};
+    std::vector<ClientInfo> clients;
+    if (!mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients)) {
+        if (clients.empty()) {
+            ALOGI("%s: There aren't any clients with given resources. Nothing to reclaim",
+                  __func__);
+            return false;
+        }
+        // Since there was a conflict, we need to reclaim all elements.
+        targetClients = std::move(clients);
+    } else {
+        // Select a client among those have the needed resources.
+        getClientForResource_l(reclaimRequestInfo, clients, targetClients);
+    }
+    return !targetClients.empty();
+}
+
+void ResourceManagerServiceNew::getClientForResource_l(
+        const ReclaimRequestInfo& reclaimRequestInfo,
+        const std::vector<ClientInfo>& clients,
+        std::vector<ClientInfo>& targetClients) {
+    int callingPid = reclaimRequestInfo.mCallingPid;
+
+    // Before looking into other processes, check if we have clients marked for
+    // pending removal in the same process.
+    ClientInfo targetClient;
+    for (const MediaResourceParcel& resource : reclaimRequestInfo.mResources) {
+        if (mResourceTracker->getBiggestClientPendingRemoval(callingPid, resource.type,
+                                                             resource.subType, targetClient)) {
+            targetClients.emplace_back(targetClient);
+            return;
+        }
+    }
+
+    // Run through all the reclaim policies until a client to reclaim from is identified.
+    for (std::unique_ptr<IReclaimPolicy>& reclaimPolicy : mReclaimPolicies) {
+        if (reclaimPolicy->getClients(reclaimRequestInfo, clients, targetClients)) {
+            return;
+        }
+    }
+}
+
+bool ResourceManagerServiceNew::getLowestPriorityBiggestClient_l(
+        const ResourceRequestInfo& resourceRequestInfo,
+        ClientInfo& clientInfo) {
+    //NOTE: This function is used only by the test: ResourceManagerServiceTest
+    if (resourceRequestInfo.mResource == nullptr) {
+        return false;
+    }
+
+    // Use the DefaultResourceModel to get all the clients with the resources requested.
+    std::vector<MediaResourceParcel> resources{*resourceRequestInfo.mResource};
+    ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid, resources};
+    std::vector<ClientInfo> clients;
+    mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients);
+
+    // Use the ProcessPriorityReclaimPolicy to select a client to reclaim from.
+    std::unique_ptr<IReclaimPolicy> reclaimPolicy
+        = std::make_unique<ProcessPriorityReclaimPolicy>(mResourceTracker);
+    std::vector<ClientInfo> targetClients;
+    if (reclaimPolicy->getClients(reclaimRequestInfo, clients, targetClients)) {
+        if (!targetClients.empty()) {
+            clientInfo = targetClients[0];
+            return true;
+        }
+    }
+
+    return false;
+}
+
+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) {
+    //NOTE: This function is used only by the test: ResourceManagerServiceTest
+    return mResourceTracker->getLowestPriorityPid(type, subType,
+                                                  *lowestPriorityPid,
+                                                  *lowestPriority);
+}
+
+bool ResourceManagerServiceNew::getAllClients_l(
+        const ResourceRequestInfo& resourceRequestInfo,
+        std::vector<ClientInfo>& clientsInfo) {
+    //NOTE: This function is used only by the test: ResourceManagerServiceTest
+    MediaResource::Type type = resourceRequestInfo.mResource->type;
+    // Get the list of all 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
new file mode 100644
index 0000000..20c3d6e
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.h
@@ -0,0 +1,169 @@
+/*
+**
+** 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_RESOURCEMANAGERSERVICENEW_H
+#define ANDROID_MEDIA_RESOURCEMANAGERSERVICENEW_H
+
+#include "ResourceManagerService.h"
+
+namespace android {
+
+class IReclaimPolicy;
+class IResourceModel;
+class ResourceTracker;
+
+//
+// A newer implementation of IResourceManagerService, which
+// eventually will replace the older implementation in ResourceManagerService.
+//
+// To make the transition easier, this implementation overrides the
+// private virtual methods from ResourceManagerService.
+//
+// This implementation is devised to abstract and integrate:
+//   - resources into an independent abstraction
+//   - resource model as a separate interface (and implementation)
+//   - reclaim policy as a separate interface (and implementation)
+//
+class ResourceManagerServiceNew : public ResourceManagerService {
+public:
+
+    explicit ResourceManagerServiceNew(const sp<ProcessInfoInterface>& processInfo,
+                                       const sp<SystemCallbackInterface>& systemResource);
+    virtual ~ResourceManagerServiceNew();
+
+    // IResourceManagerService interface
+    Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
+
+    Status addResource(const ClientInfoParcel& clientInfo,
+                       const std::shared_ptr<IResourceManagerClient>& client,
+                       const std::vector<MediaResourceParcel>& resources) override;
+
+    Status removeResource(const ClientInfoParcel& clientInfo,
+                          const std::vector<MediaResourceParcel>& resources) override;
+
+    Status removeClient(const ClientInfoParcel& clientInfo) override;
+
+    Status reclaimResource(const ClientInfoParcel& clientInfo,
+                           const std::vector<MediaResourceParcel>& resources,
+                           bool* _aidl_return) override;
+
+    Status overridePid(int32_t originalPid, int32_t newPid) override;
+
+    Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client,
+                               int32_t pid, int32_t procState, int32_t oomScore) override;
+
+    Status markClientForPendingRemoval(const ClientInfoParcel& clientInfo) override;
+
+    Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override;
+
+    Status notifyClientCreated(const ClientInfoParcel& clientInfo) override;
+
+    Status notifyClientStarted(const ClientConfigParcel& clientConfig) override;
+
+    Status notifyClientStopped(const ClientConfigParcel& clientConfig) override;
+
+    Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    friend class ResourceTracker;
+
+private:
+
+    // Set up the Resource models.
+    void setUpResourceModels();
+
+    // Set up the Reclaim Policies.
+    void setUpReclaimPolicies();
+
+    // From the list of clients, pick/select client(s) based on the reclaim policy.
+    void getClientForResource_l(
+        const ReclaimRequestInfo& reclaimRequestInfo,
+        const std::vector<ClientInfo>& clients,
+        std::vector<ClientInfo>& targetClients);
+
+    // Initializes the internal state of the ResourceManagerService
+    void init() override;
+
+    void setObserverService(
+            const std::shared_ptr<ResourceObserverService>& observerService) 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 getTargetClients(
+        int32_t callingPid,
+        const std::vector<MediaResourceParcel>& resources,
+        std::vector<ClientInfo>& targetClients) 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 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.
+    // This function is used only by the unit test.
+    bool getLowestPriorityBiggestClient_l(
+        const ResourceRequestInfo& resourceRequestInfo,
+        ClientInfo& clientInfo) override;
+
+    // override the pid of given process
+    bool overridePid_l(int32_t originalPid, int32_t newPid) override;
+
+    // override the process info of given process
+    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;
+    std::unique_ptr<IResourceModel> mDefaultResourceModel;
+    std::vector<std::unique_ptr<IReclaimPolicy>> mReclaimPolicies;
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICENEW_H
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..55ea149 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -18,6 +18,8 @@
 #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
 #define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
 
+#include <map>
+#include <memory>
 #include <vector>
 
 #include <aidl/android/media/BnResourceManagerService.h>
@@ -123,6 +125,16 @@
 };
 
 /*
+ * Resource Reclaim request info that encapsulates
+ *  - the calling/requesting process pid.
+ *  - the list of resources requesting (to be reclaimed from others)
+ */
+struct ReclaimRequestInfo {
+    int mCallingPid = -1;
+    const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
+};
+
+/*
  * Resource request info that encapsulates
  *  - the calling/requesting process pid.
  *  - the resource requesting (to be reclaimed from others)
@@ -170,7 +182,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 +205,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..8dc13cc
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceTracker.cpp
@@ -0,0 +1,720 @@
+/*
+**
+** 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 {
+
+inline bool isHwCodec(MediaResource::SubType subType) {
+    return subType == MediaResource::SubType::kHwImageCodec ||
+           subType == MediaResource::SubType::kHwVideoCodec;
+}
+
+// Check whether a given resource (of type and subtype) is found in given resource list
+// that also has the given Primary SubType.
+static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+                            const ResourceList& resources, MediaResource::SubType primarySubType) {
+    bool foundResource = false;
+    bool matchedPrimary =
+        (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ?  true : false;
+    for (auto it = resources.begin(); it != resources.end(); it++) {
+        if (hasResourceType(type, subType, it->second)) {
+            foundResource = true;
+        } else if (it->second.subType == primarySubType) {
+            matchedPrimary = true;
+        } else if (isHwCodec(it->second.subType) == isHwCodec(primarySubType)) {
+            matchedPrimary = true;
+        }
+        if (matchedPrimary && foundResource) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// See if the given client is already in the list of clients.
+inline bool contains(const std::vector<ClientInfo>& clients, const int64_t& clientId) {
+    std::vector<ClientInfo>::const_iterator found =
+        std::find_if(clients.begin(), clients.end(),
+                     [clientId](const ClientInfo& client) -> bool {
+                         return client.mClientId == clientId;
+                     });
+
+    return found != clients.end();
+}
+
+
+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 (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
+                    if (!contains(targetClients, clientInfo.mClientId)) {
+                        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 (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
+                if (!contains(targetClients, clientInfo.mClientId)) {
+                    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::SubType primarySubType) {
+    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, primarySubType)) {
+                if (!contains(clients, info.clientId)) {
+                    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::getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
+                                           MediaResource::SubType primarySubType,
+                                           const std::vector<ClientInfo>& clients,
+                                           int& lowestPriorityPid, int& lowestPriority) {
+    int pid = -1;
+    int priority = -1;
+    for (const ClientInfo& client : clients) {
+        const ResourceInfo* info = getResourceInfo(client.mPid, client.mClientId);
+        if (info == nullptr) {
+            continue;
+        }
+        if (!hasResourceType(type, subType, info->resources, primarySubType)) {
+            // doesn't have the requested resource type
+            continue;
+        }
+        int tempPriority = -1;
+        if (!getPriority(client.mPid, &tempPriority)) {
+            ALOGV("%s: can't get priority of pid %d, skipped", __func__, client.mPid);
+            // TODO: remove this pid from mMap?
+            continue;
+        }
+        if (pid == -1 || tempPriority > priority) {
+            // initial the value
+            pid = client.mPid;
+            priority = tempPriority;
+        }
+    }
+
+    bool success = (pid != -1);
+
+    if (success) {
+        lowestPriorityPid = pid;
+        lowestPriority = priority;
+    }
+    return success;
+}
+
+bool ResourceTracker::getBiggestClientPendingRemoval(int pid, MediaResource::Type type,
+                                                     MediaResource::SubType subType,
+                                                     ClientInfo& clientInfo) {
+    std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
+        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;
+        // Skip if the client is not marked pending removal.
+        if (!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) {
+        return false;
+    }
+
+    clientInfo.mPid = pid;
+    clientInfo.mUid = uid;
+    clientInfo.mClientId = clientId;
+    return true;
+}
+
+bool ResourceTracker::getBiggestClient(int targetPid,
+                                       MediaResource::Type type, MediaResource::SubType subType,
+                                       const std::vector<ClientInfo>& clients,
+                                       ClientInfo& clientInfo,
+                                       MediaResource::SubType primarySubType) {
+    uid_t   uid = -1;
+    int64_t clientId = -1;
+    uint64_t largestValue = 0;
+
+    for (const ClientInfo& client : clients) {
+        // Skip the clients that doesn't belong go the targetPid
+        if (client.mPid != targetPid) {
+            continue;
+        }
+        const ResourceInfo* info = getResourceInfo(client.mPid, client.mClientId);
+        if (info == nullptr) {
+            continue;
+        }
+
+        const ResourceList& resources = info->resources;
+        bool matchedPrimary =
+            (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ?  true : false;
+        for (auto it = resources.begin(); !matchedPrimary && it != resources.end(); it++) {
+            if (it->second.subType == primarySubType) {
+                matchedPrimary = true;
+            } else if (isHwCodec(it->second.subType) == isHwCodec(primarySubType)) {
+                matchedPrimary = true;
+            }
+        }
+        // Primary type doesn't match, skip the client
+        if (!matchedPrimary) {
+            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("%s: can't find resource type %s and subtype %s for pid %d",
+                 __func__, asString(type), asString(subType), targetPid);
+        return false;
+    }
+
+    clientInfo.mPid = targetPid;
+    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 {
+                    if (!contains(clients, info.clientId)) {
+                        clients.emplace_back(info.pid, info.uid, info.clientId);
+                    }
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+const ResourceInfo* ResourceTracker::getResourceInfo(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;
+}
+
+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..e5f33ec
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceTracker.h
@@ -0,0 +1,242 @@
+/*
+**
+** 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.
+    // If applicable, match the primary type too.
+    // 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,
+            MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType);
+
+    // 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);
+
+    // Look for the lowest priority process with the given resources
+    // among the given client list.
+    // If applicable, match the primary type too.
+    // returns true on success, false otherwise.
+    bool getLowestPriorityPid(
+            MediaResource::Type type, MediaResource::SubType subType,
+            MediaResource::SubType primarySubType,
+            const std::vector<ClientInfo>& clients,
+            int& lowestPriorityPid, int& lowestPriority);
+
+    // Find the biggest client of the given process with given resources,
+    // that is marked as pending to be removed.
+    // returns true on success, false otherwise.
+    bool getBiggestClientPendingRemoval(
+            int pid, MediaResource::Type type,
+            MediaResource::SubType subType,
+            ClientInfo& clientInfo);
+
+    // Find the biggest client from the process pid, selecting them from the list of clients.
+    // If applicable, match the primary type too.
+    // 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.
+    // Upon failure to find a client, it will return false.
+    bool getBiggestClient(
+            int targetPid,
+            MediaResource::Type type,
+            MediaResource::SubType subType,
+            const std::vector<ClientInfo>& clients,
+            ClientInfo& clientInfo,
+            MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType);
+
+    // 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);
+
+    // Locate the resource info corresponding to the process pid and
+    // the client clientId.
+    const ResourceInfo* getResourceInfo(int pid, const int64_t& clientId) const;
+
+    // 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/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index a46d87a..b0db12b 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -46,6 +46,7 @@
         "libstatspull",
         "libstatssocket",
         "libactivitymanager_aidl",
+        "aconfig_mediacodec_flags_c_lib",
     ],
     fuzz_config: {
         cc: [
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index f903c62..6a64823 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -12,7 +12,10 @@
     name: "ResourceManagerService_test",
     srcs: ["ResourceManagerService_test.cpp"],
     test_suites: ["device-tests"],
-    static_libs: ["libresourcemanagerservice"],
+    static_libs: [
+        "libresourcemanagerservice",
+        "aconfig_mediacodec_flags_c_lib",
+    ],
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
@@ -24,6 +27,7 @@
         "libstatspull",
         "libstatssocket",
         "libactivitymanager_aidl",
+        "server_configurable_flags",
     ],
     include_dirs: [
         "frameworks/av/include",
@@ -62,6 +66,7 @@
     static_libs: [
         "libresourcemanagerservice",
         "resourceobserver_aidl_interface-V1-ndk",
+        "aconfig_mediacodec_flags_c_lib",
     ],
     shared_libs: [
         "libbinder",
@@ -74,6 +79,7 @@
         "libstatspull",
         "libstatssocket",
         "libactivitymanager_aidl",
+        "server_configurable_flags",
     ],
     include_dirs: [
         "frameworks/av/include",
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 52d82b8..58dbb8d 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -198,8 +198,8 @@
         return static_cast<TestClient*>(testClient.get());
     }
 
-    ResourceManagerServiceTestBase() {
-        ALOGI("ResourceManagerServiceTestBase created");
+    ResourceManagerServiceTestBase(bool newRM = false) : mNewRM(newRM) {
+        ALOGI("ResourceManagerServiceTestBase created with %s RM", newRM ? "new" : "old");
     }
 
     void SetUp() override {
@@ -207,7 +207,11 @@
         // silently ignored.
         ABinderProcess_startThreadPool();
         mSystemCB = new TestSystemCallback();
-        mService = ResourceManagerService::Create(new TestProcessInfo, mSystemCB);
+        if (mNewRM) {
+            mService = ResourceManagerService::CreateNew(new TestProcessInfo, mSystemCB);
+        } else {
+            mService = ResourceManagerService::Create(new TestProcessInfo, mSystemCB);
+        }
         mTestClient1 = ::ndk::SharedRefBase::make<TestClient>(kTestPid1, kTestUid1, mService);
         mTestClient2 = ::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService);
         mTestClient3 = ::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService);
@@ -244,6 +248,8 @@
         EXPECT_EQ(client, info.client);
         EXPECT_TRUE(isEqualResources(resources, info.resources));
     }
+
+    bool mNewRM = false;
 };
 
 } // namespace android
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 8f05b13..9d4beef 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -77,8 +77,20 @@
     }
 
 public:
-    ResourceManagerServiceTest() : ResourceManagerServiceTestBase() {}
+    ResourceManagerServiceTest(bool newRM = false) : ResourceManagerServiceTestBase(newRM) {}
 
+    void updateConfig(bool bSupportsMultipleSecureCodecs, bool bSupportsSecureWithNonSecureCodec) {
+        std::vector<MediaResourcePolicyParcel> policies;
+        policies.push_back(
+                MediaResourcePolicy(
+                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
+                        bSupportsMultipleSecureCodecs ? "true" : "false"));
+        policies.push_back(
+                MediaResourcePolicy(
+                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
+                        bSupportsSecureWithNonSecureCodec ? "true" : "false"));
+        mService->config(policies);
+    }
 
     // test set up
     // ---------------------------------------------------------------------------------
@@ -129,7 +141,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 +171,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());
@@ -213,29 +225,11 @@
         EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
 
-        std::vector<MediaResourcePolicyParcel> policies1;
-        policies1.push_back(
-                MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
-                        "true"));
-        policies1.push_back(
-                MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
-                        "false"));
-        mService->config(policies1);
+        updateConfig(true, false);
         EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
 
-        std::vector<MediaResourcePolicyParcel> policies2;
-        policies2.push_back(
-                MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
-                        "false"));
-        policies2.push_back(
-                MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
-                        "true"));
-        mService->config(policies2);
+        updateConfig(false, true);
         EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
     }
@@ -254,7 +248,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 +293,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());
@@ -339,8 +333,7 @@
         // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = false;
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(false, true);
 
             // priority too low to reclaim resource
             ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
@@ -374,7 +367,7 @@
                                      .name = "none"};
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             std::vector<MediaResourceParcel> resources;
             resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -402,7 +395,7 @@
 
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             std::vector<MediaResourceParcel> resources;
             resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -428,7 +421,7 @@
 
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             mService->markClientForPendingRemoval(client2Info);
 
@@ -466,7 +459,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);
@@ -520,8 +513,7 @@
         // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = false;
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(false, true);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -546,8 +538,7 @@
         // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = false;
-            mService->mSupportsSecureWithNonSecureCodec = false;
+            updateConfig(false, false);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -567,8 +558,7 @@
         // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = true;
-            mService->mSupportsSecureWithNonSecureCodec = false;
+            updateConfig(true, false);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -599,8 +589,7 @@
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = true;
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -630,8 +619,7 @@
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsMultipleSecureCodecs = true;
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             std::vector<MediaResourceParcel> resources;
             resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -677,7 +665,7 @@
         // ### secure codec can't coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = false;
+            updateConfig(true, false);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -703,7 +691,7 @@
         // ### secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             // priority too low
             CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -733,7 +721,7 @@
         // ### secure codec can coexist with non-secure codec ###
         {
             addResource();
-            mService->mSupportsSecureWithNonSecureCodec = true;
+            updateConfig(true, true);
 
             std::vector<MediaResourceParcel> resources;
             resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -1512,6 +1500,11 @@
     }
 };
 
+class ResourceManagerServiceNewTest : public ResourceManagerServiceTest {
+public:
+    ResourceManagerServiceNewTest(bool newRM = true) : ResourceManagerServiceTest(newRM) {}
+};
+
 TEST_F(ResourceManagerServiceTest, config) {
     testConfig();
 }
@@ -1598,4 +1591,91 @@
     testConcurrentCodecs();
 }
 
+/////// test cases for ResourceManagerServiceNew ////
+TEST_F(ResourceManagerServiceNewTest, config) {
+    testConfig();
+}
+
+TEST_F(ResourceManagerServiceNewTest, addResource) {
+    addResource();
+}
+
+TEST_F(ResourceManagerServiceNewTest, combineResource) {
+    testCombineResource();
+}
+
+TEST_F(ResourceManagerServiceNewTest, combineResourceNegative) {
+    testCombineResourceWithNegativeValues();
+}
+
+TEST_F(ResourceManagerServiceNewTest, removeResource) {
+    testRemoveResource();
+}
+
+TEST_F(ResourceManagerServiceNewTest, removeClient) {
+    testRemoveClient();
+}
+
+TEST_F(ResourceManagerServiceNewTest, reclaimResource) {
+    testReclaimResourceSecure();
+    testReclaimResourceNonSecure();
+}
+
+TEST_F(ResourceManagerServiceNewTest, getAllClients_l) {
+    testGetAllClients();
+}
+
+TEST_F(ResourceManagerServiceNewTest, getLowestPriorityBiggestClient_l) {
+    testGetLowestPriorityBiggestClient();
+}
+
+TEST_F(ResourceManagerServiceNewTest, getLowestPriorityPid_l) {
+    testGetLowestPriorityPid();
+}
+
+TEST_F(ResourceManagerServiceNewTest, isCallingPriorityHigher_l) {
+    testIsCallingPriorityHigher();
+}
+
+TEST_F(ResourceManagerServiceNewTest, batteryStats) {
+    testBatteryStats();
+}
+
+TEST_F(ResourceManagerServiceNewTest, cpusetBoost) {
+    testCpusetBoost();
+}
+
+TEST_F(ResourceManagerServiceNewTest, overridePid) {
+    testOverridePid();
+}
+
+TEST_F(ResourceManagerServiceNewTest, markClientForPendingRemoval) {
+    testMarkClientForPendingRemoval();
+}
+
+TEST_F(ResourceManagerServiceNewTest, reclaimResources_withVideoCodec_reclaimsOnlyVideoCodec) {
+    testReclaimResources_withVideoCodec_reclaimsOnlyVideoCodec();
+}
+
+TEST_F(ResourceManagerServiceNewTest, reclaimResources_withAudioCodec_reclaimsOnlyAudioCodec) {
+    testReclaimResources_withAudioCodec_reclaimsOnlyAudioCodec();
+}
+
+TEST_F(ResourceManagerServiceNewTest, reclaimResources_withImageCodec_reclaimsOnlyImageCodec) {
+    testReclaimResources_withImageCodec_reclaimsOnlyImageCodec();
+}
+
+TEST_F(ResourceManagerServiceNewTest, reclaimResources_whenPartialResourceMatch_reclaims) {
+    testReclaimResources_whenPartialResourceMatch_reclaims();
+}
+
+TEST_F(ResourceManagerServiceNewTest,
+        reclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources) {
+    testReclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources();
+}
+
+TEST_F(ResourceManagerServiceNewTest, concurrentCodecs) {
+    testConcurrentCodecs();
+}
+
 } // namespace android