Convert IResourceManagerService to stable AIDL

Convert with minimal change to the interface itself.

Add additional test to cover DrmSessionManager's usage
of possible negative value field (which is signed now).

bug: 142396029
test: ResourceManagerService_test, DrmSessionManager_test,
CTS ResourceManagerServiceTest;
Manually check battery stats reporting.

Change-Id: I5c537a54efc2663281c96ddbdbd4ee56f23c1adf
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index bd4b521..cac90ea 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -25,6 +25,7 @@
 
 #include <android/hardware/drm/1.2/types.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/media/BnResourceManagerClient.h>
 #include <hidl/ServiceManagement.h>
 #include <media/EventMetric.h>
 #include <media/PluginMetricsReporting.h>
@@ -295,21 +296,43 @@
 
 Mutex DrmHal::mLock;
 
-bool DrmHal::DrmSessionClient::reclaimResource() {
+struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
+    explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
+      : mSessionId(sessionId),
+        mDrm(drm) {}
+
+    ::android::binder::Status reclaimResource(bool* _aidl_return) override;
+    ::android::binder::Status getName(::std::string* _aidl_return) override;
+
+    const Vector<uint8_t> mSessionId;
+
+protected:
+    virtual ~DrmSessionClient();
+
+private:
+    wp<DrmHal> mDrm;
+
+    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
+};
+
+::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
     sp<DrmHal> drm = mDrm.promote();
     if (drm == NULL) {
-        return true;
+        *_aidl_return = true;
+        return ::android::binder::Status::ok();
     }
     status_t err = drm->closeSession(mSessionId);
     if (err != OK) {
-        return false;
+        *_aidl_return = false;
+        return ::android::binder::Status::ok();
     }
     drm->sendEvent(EventType::SESSION_RECLAIMED,
             toHidlVec(mSessionId), hidl_vec<uint8_t>());
-    return true;
+    *_aidl_return = true;
+    return ::android::binder::Status::ok();
 }
 
-String8 DrmHal::DrmSessionClient::getName() {
+::android::binder::Status DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
     String8 name;
     sp<DrmHal> drm = mDrm.promote();
     if (drm == NULL) {
@@ -323,7 +346,8 @@
         name.appendFormat("%02x", mSessionId[i]);
     }
     name.append("]");
-    return name;
+    *_aidl_return = name;
+    return ::android::binder::Status::ok();
 }
 
 DrmHal::DrmSessionClient::~DrmSessionClient() {
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 0b927ef..0b91b85 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -18,11 +18,12 @@
 #define LOG_TAG "DrmSessionManager"
 #include <utils/Log.h>
 
+#include <android/media/IResourceManagerClient.h>
+#include <android/media/IResourceManagerService.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IProcessInfoService.h>
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
-#include <media/IResourceManagerClient.h>
 #include <media/MediaResource.h>
 #include <mediadrm/DrmSessionManager.h>
 #include <unistd.h>
@@ -33,6 +34,7 @@
 #include "ResourceManagerService.h"
 
 namespace android {
+using android::binder::Status;
 
 static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
     String8 sessionIdStr;
@@ -52,16 +54,16 @@
     return reinterpret_cast<int64_t>(drm.get());
 }
 
-static Vector<MediaResource> toResourceVec(const Vector<uint8_t> &sessionId) {
-    Vector<MediaResource> resources;
-    // use UINT64_MAX to decrement through addition overflow
-    resources.push_back(MediaResource(MediaResource::kDrmSession, toStdVec(sessionId), UINT64_MAX));
+static std::vector<MediaResourceParcel> toResourceVec(
+        const Vector<uint8_t> &sessionId, int64_t value) {
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(MediaResource::DrmSessionResource(toStdVec(sessionId), value));
     return resources;
 }
 
 static sp<IResourceManagerService> getResourceManagerService() {
     if (property_get_bool("persist.device_config.media_native.mediadrmserver", 1)) {
-        return new ResourceManagerService();
+        return new android::media::ResourceManagerService();
     }
     sp<IServiceManager> sm = defaultServiceManager();
     if (sm == NULL) {
@@ -131,7 +133,7 @@
 
     int64_t clientId = toClientId(drm);
     mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
-    mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId));
+    mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId, INT64_MAX));
 }
 
 void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
@@ -144,7 +146,7 @@
     }
 
     auto info = it->second;
-    mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId));
+    mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId, -1));
 }
 
 void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
@@ -157,7 +159,7 @@
     }
 
     auto info = it->second;
-    mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId));
+    mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId, INT64_MAX));
     mSessionMap.erase(it);
 }
 
@@ -176,7 +178,9 @@
     // cannot update mSessionMap because we do not know which sessionId is reclaimed;
     // we rely on IResourceManagerClient to removeSession in reclaimResource
     Vector<uint8_t> dummy;
-    return service->reclaimResource(callingPid, toResourceVec(dummy));
+    bool success;
+    Status status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
+    return status.isOk() && success;
 }
 
 size_t DrmSessionManager::getSessionCount() const {
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index 542d300..0431c93 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -26,7 +26,6 @@
 #include <android/hardware/drm/1.2/IDrmPlugin.h>
 #include <android/hardware/drm/1.2/IDrmPluginListener.h>
 
-#include <media/IResourceManagerService.h>
 #include <media/MediaAnalyticsItem.h>
 #include <mediadrm/DrmMetrics.h>
 #include <mediadrm/DrmSessionManager.h>
@@ -62,24 +61,7 @@
                 public IBinder::DeathRecipient,
                 public IDrmPluginListener_V1_2 {
 
-    struct DrmSessionClient : public BnResourceManagerClient {
-        explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
-          : mSessionId(sessionId),
-            mDrm(drm) {}
-
-        virtual bool reclaimResource();
-        virtual String8 getName();
-
-        const Vector<uint8_t> mSessionId;
-
-    protected:
-        virtual ~DrmSessionClient();
-
-    private:
-        wp<DrmHal> mDrm;
-
-        DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
-    };
+    struct DrmSessionClient;
 
     DrmHal();
     virtual ~DrmHal();
diff --git a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
index b1ad580..3258f7a 100644
--- a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
+++ b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
@@ -19,7 +19,6 @@
 #define DRM_SESSION_MANAGER_H_
 
 #include <binder/IBinder.h>
-#include <media/IResourceManagerService.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <utils/RefBase.h>
 #include <utils/KeyedVector.h>
@@ -33,7 +32,13 @@
 namespace android {
 
 class DrmSessionManagerTest;
+
+namespace media {
 class IResourceManagerClient;
+class IResourceManagerService;
+}
+using android::media::IResourceManagerClient;
+using android::media::IResourceManagerService;
 
 bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
 
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index fdab14a..ba25512 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -2,7 +2,7 @@
     name: "libmedia_headers",
     vendor_available: true,
     export_include_dirs: ["include"],
-    header_libs:[
+    header_libs: [
         "libbase_headers",
         "libgui_headers",
         "libstagefright_headers",
@@ -22,13 +22,19 @@
         enabled: true,
     },
     double_loadable: true,
-    srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
+    srcs: [
+        "AudioParameter.cpp",
+        "TypeConverter.cpp",
+    ],
     cflags: [
         "-Werror",
         "-Wno-error=deprecated-declarations",
         "-Wall",
     ],
-    shared_libs: ["libutils", "liblog"],
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
     header_libs: [
         "libmedia_headers",
         "libaudioclient_headers",
@@ -49,6 +55,21 @@
     path: "aidl",
 }
 
+aidl_interface {
+    name: "resourcemanager_aidl_interface",
+    local_include_dir: "aidl",
+    srcs: [
+        "aidl/android/media/IResourceManagerClient.aidl",
+        "aidl/android/media/IResourceManagerService.aidl",
+        "aidl/android/media/MediaResourceType.aidl",
+        "aidl/android/media/MediaResourceSubType.aidl",
+        "aidl/android/media/MediaResourceParcel.aidl",
+        "aidl/android/media/MediaResourcePolicyParcel.aidl",
+    ],
+    api_dir: "api/resourcemanager",
+    versions: ["1"],
+}
+
 cc_library_shared {
     name: "libmedia_omx",
     vendor_available: true,
@@ -127,7 +148,6 @@
     },
 }
 
-
 cc_library_shared {
     name: "libmedia_omx_client",
 
@@ -277,8 +297,6 @@
         "IMediaSource.cpp",
         "IRemoteDisplay.cpp",
         "IRemoteDisplayClient.cpp",
-        "IResourceManagerClient.cpp",
-        "IResourceManagerService.cpp",
         "IStreamSource.cpp",
         "MediaUtils.cpp",
         "Metadata.cpp",
@@ -344,7 +362,12 @@
     ],
 
     static_libs: [
-        "libc_malloc_debug_backtrace",  // for memory heap analysis
+        "libc_malloc_debug_backtrace", // for memory heap analysis
+        "resourcemanager_aidl_interface-cpp",
+    ],
+
+    export_static_lib_headers: [
+        "resourcemanager_aidl_interface-cpp",
     ],
 
     export_include_dirs: [
diff --git a/media/libmedia/IResourceManagerClient.cpp b/media/libmedia/IResourceManagerClient.cpp
deleted file mode 100644
index 1fea479..0000000
--- a/media/libmedia/IResourceManagerClient.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-**
-** Copyright 2015, 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.
-*/
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-#include <media/IResourceManagerClient.h>
-
-namespace android {
-
-enum {
-    RECLAIM_RESOURCE = IBinder::FIRST_CALL_TRANSACTION,
-    GET_NAME,
-};
-
-class BpResourceManagerClient: public BpInterface<IResourceManagerClient>
-{
-public:
-    explicit BpResourceManagerClient(const sp<IBinder> &impl)
-        : BpInterface<IResourceManagerClient>(impl)
-    {
-    }
-
-    virtual bool reclaimResource() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerClient::getInterfaceDescriptor());
-
-        bool ret = false;
-        status_t status = remote()->transact(RECLAIM_RESOURCE, data, &reply);
-        if (status == NO_ERROR) {
-            ret = (bool)reply.readInt32();
-        }
-        return ret;
-    }
-
-    virtual String8 getName() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerClient::getInterfaceDescriptor());
-
-        String8 ret;
-        status_t status = remote()->transact(GET_NAME, data, &reply);
-        if (status == NO_ERROR) {
-            ret = reply.readString8();
-        }
-        return ret;
-    }
-
-};
-
-IMPLEMENT_META_INTERFACE(ResourceManagerClient, "android.media.IResourceManagerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnResourceManagerClient::onTransact(
-    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags)
-{
-    switch (code) {
-        case RECLAIM_RESOURCE: {
-            CHECK_INTERFACE(IResourceManagerClient, data, reply);
-            bool ret = reclaimResource();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GET_NAME: {
-            CHECK_INTERFACE(IResourceManagerClient, data, reply);
-            String8 ret = getName();
-            reply->writeString8(ret);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-}; // namespace android
diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp
deleted file mode 100644
index f8a0a14..0000000
--- a/media/libmedia/IResourceManagerService.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-**
-** Copyright 2015, 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 "IResourceManagerService"
-#include <utils/Log.h>
-
-#include <media/IResourceManagerService.h>
-
-#include <binder/Parcel.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-namespace android {
-
-enum {
-    CONFIG = IBinder::FIRST_CALL_TRANSACTION,
-    ADD_RESOURCE,
-    REMOVE_RESOURCE,
-    REMOVE_CLIENT,
-    RECLAIM_RESOURCE,
-};
-
-template <typename T>
-static void writeToParcel(Parcel *data, const Vector<T> &items) {
-    size_t size = items.size();
-    // truncates size, but should be okay for this usecase
-    data->writeUint32(static_cast<uint32_t>(size));
-    for (size_t i = 0; i < size; i++) {
-        items[i].writeToParcel(data);
-    }
-}
-
-template <typename T>
-static void readFromParcel(const Parcel &data, Vector<T> *items) {
-    size_t size = (size_t)data.readUint32();
-    for (size_t i = 0; i < size && data.dataAvail() > 0; i++) {
-        T item;
-        item.readFromParcel(data);
-        items->add(item);
-    }
-}
-
-class BpResourceManagerService : public BpInterface<IResourceManagerService>
-{
-public:
-    explicit BpResourceManagerService(const sp<IBinder> &impl)
-        : BpInterface<IResourceManagerService>(impl)
-    {
-    }
-
-    virtual void config(const Vector<MediaResourcePolicy> &policies) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
-        writeToParcel(&data, policies);
-        remote()->transact(CONFIG, data, &reply);
-    }
-
-    virtual void addResource(
-            int pid,
-            int uid,
-            int64_t clientId,
-            const sp<IResourceManagerClient> client,
-            const Vector<MediaResource> &resources) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeInt32(uid);
-        data.writeInt64(clientId);
-        data.writeStrongBinder(IInterface::asBinder(client));
-        writeToParcel(&data, resources);
-
-        remote()->transact(ADD_RESOURCE, data, &reply);
-    }
-
-    virtual void removeResource(int pid, int64_t clientId, const Vector<MediaResource> &resources) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeInt64(clientId);
-        writeToParcel(&data, resources);
-
-        remote()->transact(REMOVE_RESOURCE, data, &reply);
-    }
-
-    virtual void removeClient(int pid, int64_t clientId) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeInt64(clientId);
-
-        remote()->transact(REMOVE_CLIENT, data, &reply);
-    }
-
-    virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
-        data.writeInt32(callingPid);
-        writeToParcel(&data, resources);
-
-        bool ret = false;
-        status_t status = remote()->transact(RECLAIM_RESOURCE, data, &reply);
-        if (status == NO_ERROR) {
-            ret = (bool)reply.readInt32();
-        }
-        return ret;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(ResourceManagerService, "android.media.IResourceManagerService");
-
-// ----------------------------------------------------------------------
-
-
-status_t BnResourceManagerService::onTransact(
-    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags)
-{
-    switch (code) {
-        case CONFIG: {
-            CHECK_INTERFACE(IResourceManagerService, data, reply);
-            Vector<MediaResourcePolicy> policies;
-            readFromParcel(data, &policies);
-            config(policies);
-            return NO_ERROR;
-        } break;
-
-        case ADD_RESOURCE: {
-            CHECK_INTERFACE(IResourceManagerService, data, reply);
-            int pid = data.readInt32();
-            int uid = data.readInt32();
-            int64_t clientId = data.readInt64();
-            sp<IResourceManagerClient> client(
-                    interface_cast<IResourceManagerClient>(data.readStrongBinder()));
-            if (client == NULL) {
-                return NO_ERROR;
-            }
-            Vector<MediaResource> resources;
-            readFromParcel(data, &resources);
-            addResource(pid, uid, clientId, client, resources);
-            return NO_ERROR;
-        } break;
-
-        case REMOVE_RESOURCE: {
-            CHECK_INTERFACE(IResourceManagerService, data, reply);
-            int pid = data.readInt32();
-            int64_t clientId = data.readInt64();
-            Vector<MediaResource> resources;
-            readFromParcel(data, &resources);
-            removeResource(pid, clientId, resources);
-            return NO_ERROR;
-        } break;
-
-        case REMOVE_CLIENT: {
-            CHECK_INTERFACE(IResourceManagerService, data, reply);
-            int pid = data.readInt32();
-            int64_t clientId = data.readInt64();
-            removeClient(pid, clientId);
-            return NO_ERROR;
-        } break;
-
-        case RECLAIM_RESOURCE: {
-            CHECK_INTERFACE(IResourceManagerService, data, reply);
-            int callingPid = data.readInt32();
-            Vector<MediaResource> resources;
-            readFromParcel(data, &resources);
-            bool ret = reclaimResource(callingPid, resources);
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index 8626009..fe86d27 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -23,39 +23,51 @@
 
 namespace android {
 
-MediaResource::MediaResource()
-        : mType(kUnspecified),
-          mSubType(kUnspecifiedSubType),
-          mValue(0) {}
-
-MediaResource::MediaResource(Type type, uint64_t value)
-        : mType(type),
-          mSubType(kUnspecifiedSubType),
-          mValue(value) {}
-
-MediaResource::MediaResource(Type type, SubType subType, uint64_t value)
-        : mType(type),
-          mSubType(subType),
-          mValue(value) {}
-
-MediaResource::MediaResource(Type type, const std::vector<uint8_t> &id, uint64_t value)
-        : mType(type),
-          mSubType(kUnspecifiedSubType),
-          mValue(value),
-          mId(id) {}
-
-void MediaResource::readFromParcel(const Parcel &parcel) {
-    mType = static_cast<Type>(parcel.readInt32());
-    mSubType = static_cast<SubType>(parcel.readInt32());
-    mValue = parcel.readUint64();
-    parcel.readByteVector(&mId);
+MediaResource::MediaResource(Type type, int64_t value) {
+    this->type = type;
+    this->subType = SubType::kUnspecifiedSubType;
+    this->value = value;
 }
 
-void MediaResource::writeToParcel(Parcel *parcel) const {
-    parcel->writeInt32(static_cast<int32_t>(mType));
-    parcel->writeInt32(static_cast<int32_t>(mSubType));
-    parcel->writeUint64(mValue);
-    parcel->writeByteVector(mId);
+MediaResource::MediaResource(Type type, SubType subType, int64_t value) {
+    this->type = type;
+    this->subType = subType;
+    this->value = value;
+}
+
+MediaResource::MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value) {
+    this->type = type;
+    this->subType = SubType::kUnspecifiedSubType;
+    this->id = id;
+    this->value = value;
+}
+
+//static
+MediaResource MediaResource::CodecResource(bool secure, bool video) {
+    return MediaResource(
+            secure ? Type::kSecureCodec : Type::kNonSecureCodec,
+            video ? SubType::kVideoCodec : SubType::kAudioCodec,
+            1);
+}
+
+//static
+MediaResource MediaResource::GraphicMemoryResource(int64_t value) {
+    return MediaResource(Type::kGraphicMemory, value);
+}
+
+//static
+MediaResource MediaResource::CpuBoostResource() {
+    return MediaResource(Type::kCpuBoost, 1);
+}
+
+//static
+MediaResource MediaResource::VideoBatteryResource() {
+    return MediaResource(Type::kBattery, SubType::kVideoCodec, 1);
+}
+
+//static
+MediaResource MediaResource::DrmSessionResource(const std::vector<uint8_t> &id, int64_t value) {
+    return MediaResource(Type::kDrmSession, id, value);
 }
 
 static String8 bytesToHexString(const std::vector<uint8_t> &bytes) {
@@ -66,24 +78,14 @@
     return str;
 }
 
-String8 MediaResource::toString() const {
+String8 toString(const MediaResourceParcel& resource) {
     String8 str;
-    str.appendFormat("%s/%s:[%s]:%llu",
-        asString(mType), asString(mSubType),
-        bytesToHexString(mId).c_str(),
-        (unsigned long long)mValue);
+
+    str.appendFormat("%s/%s:[%s]:%lld",
+            asString(resource.type), asString(resource.subType),
+            bytesToHexString(resource.id).c_str(),
+            (long long)resource.value);
     return str;
 }
 
-bool MediaResource::operator==(const MediaResource &other) const {
-    return (other.mType == mType)
-      && (other.mSubType == mSubType)
-      && (other.mValue == mValue)
-      && (other.mId == mId);
-}
-
-bool MediaResource::operator!=(const MediaResource &other) const {
-    return !(*this == other);
-}
-
 }; // namespace android
diff --git a/media/libmedia/MediaResourcePolicy.cpp b/media/libmedia/MediaResourcePolicy.cpp
index 5210825..c463179 100644
--- a/media/libmedia/MediaResourcePolicy.cpp
+++ b/media/libmedia/MediaResourcePolicy.cpp
@@ -18,31 +18,29 @@
 #define LOG_TAG "MediaResourcePolicy"
 #include <utils/Log.h>
 #include <media/MediaResourcePolicy.h>
+#include <android/media/IResourceManagerService.h>
 
 namespace android {
 
-const char kPolicySupportsMultipleSecureCodecs[] = "supports-multiple-secure-codecs";
-const char kPolicySupportsSecureWithNonSecureCodec[] = "supports-secure-with-non-secure-codec";
-
-MediaResourcePolicy::MediaResourcePolicy() {}
-
-MediaResourcePolicy::MediaResourcePolicy(String8 type, String8 value)
-        : mType(type),
-          mValue(value) {}
-
-void MediaResourcePolicy::readFromParcel(const Parcel &parcel) {
-    mType = parcel.readString8();
-    mValue = parcel.readString8();
+using android::media::IResourceManagerService;
+//static
+const ::std::string& MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs() {
+    return IResourceManagerService::kPolicySupportsMultipleSecureCodecs();
+}
+//static
+const ::std::string& MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec() {
+    return IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec();
 }
 
-void MediaResourcePolicy::writeToParcel(Parcel *parcel) const {
-    parcel->writeString8(mType);
-    parcel->writeString8(mValue);
+MediaResourcePolicy::MediaResourcePolicy(
+        const std::string& type, const std::string& value) {
+    this->type = type;
+    this->value = value;
 }
 
-String8 MediaResourcePolicy::toString() const {
+String8 toString(const MediaResourcePolicyParcel &policy) {
     String8 str;
-    str.appendFormat("%s:%s", mType.string(), mValue.string());
+    str.appendFormat("%s:%s", policy.type.c_str(), policy.value.c_str());
     return str;
 }
 
diff --git a/media/libmedia/aidl/android/media/IResourceManagerClient.aidl b/media/libmedia/aidl/android/media/IResourceManagerClient.aidl
new file mode 100644
index 0000000..4c3ef47
--- /dev/null
+++ b/media/libmedia/aidl/android/media/IResourceManagerClient.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+/**
+ * IResourceManagerClient interface for the ResourceManagerService to
+ * call the client.
+ *
+ * {@hide}
+ */
+interface IResourceManagerClient {
+    /**
+     * Instruct the client to reclaim its resources.
+     *
+     * @return true if the reclaim was successful and false otherwise.
+     */
+    boolean reclaimResource();
+
+    /**
+     * Retrieve the name of the client.
+     *
+     * @return name of the client.
+     */
+    @utf8InCpp String getName();
+}
diff --git a/media/libmedia/aidl/android/media/IResourceManagerService.aidl b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
new file mode 100644
index 0000000..3e6f8db
--- /dev/null
+++ b/media/libmedia/aidl/android/media/IResourceManagerService.aidl
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+import android.media.IResourceManagerClient;
+import android.media.MediaResourceParcel;
+import android.media.MediaResourcePolicyParcel;
+
+/**
+ * ResourceManagerService interface that keeps track of media resource
+ * owned by clients, and reclaims resources based on configured policies
+ * when necessary.
+ *
+ * {@hide}
+ */
+interface IResourceManagerService {
+    const @utf8InCpp String kPolicySupportsMultipleSecureCodecs
+            = "supports-multiple-secure-codecs";
+    const @utf8InCpp String kPolicySupportsSecureWithNonSecureCodec
+            = "supports-secure-with-non-secure-codec";
+
+    /**
+     * Configure the ResourceManagerService to adopted particular policies when
+     * managing the resources.
+     *
+     * @param policies an array of policies to be adopted.
+     */
+    void config(in MediaResourcePolicyParcel[] policies);
+
+    /**
+     * Add a client to a process with a list of resources.
+     *
+     * @param pid pid of the client.
+     * @param uid uid of the client.
+     * @param clientId an identifier that uniquely identifies the client within the pid.
+     * @param client interface for the ResourceManagerService to call the client.
+     * @param resources an array of resources to be added.
+     */
+    void addResource(
+            int pid,
+            int uid,
+            long clientId,
+            IResourceManagerClient client,
+            in MediaResourceParcel[] resources);
+
+    /**
+     * Remove the listed resources from a client.
+     *
+     * @param pid pid from which the list of resources will be removed.
+     * @param clientId clientId within the pid from which the list of resources will be removed.
+     * @param resources an array of resources to be removed from the client.
+     */
+    void removeResource(int pid, long clientId, in MediaResourceParcel[] resources);
+
+    /**
+     * Remove all resources from a client.
+     *
+     * @param pid pid from which the client's resources will be removed.
+     * @param clientId clientId within the pid that will be removed.
+     */
+    void removeClient(int pid, long clientId);
+
+    /**
+     * Tries to reclaim resource from processes with lower priority than the
+     * calling process according to the requested resources.
+     *
+     * @param callingPid pid of the calling process.
+     * @param resources an array of resources to be reclaimed.
+     *
+     * @return true if the reclaim was successful and false otherwise.
+     */
+    boolean reclaimResource(int callingPid, in MediaResourceParcel[] resources);
+}
diff --git a/media/libmedia/aidl/android/media/MediaResourceParcel.aidl b/media/libmedia/aidl/android/media/MediaResourceParcel.aidl
new file mode 100644
index 0000000..b0f2b71
--- /dev/null
+++ b/media/libmedia/aidl/android/media/MediaResourceParcel.aidl
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+import android.media.MediaResourceType;
+import android.media.MediaResourceSubType;
+
+/**
+ * Description of a media resource to be tracked by MediaResourceManager.
+ *
+ * {@hide}
+ */
+parcelable MediaResourceParcel {
+    // TODO: default enum value is not supported yet.
+    // Set default enum value when b/142739329 is fixed.
+
+    /**
+     * Type of the media resource.
+     */
+    MediaResourceType type;// = MediaResourceTypeEnum::kUnspecified;
+
+    /**
+     * Sub-type of the media resource.
+     */
+    MediaResourceSubType subType;// = MediaResourceSubTypeEnum::kUnspecifiedSubType;
+
+    /**
+     * Identifier of the media resource (eg. Drm session id).
+     */
+    byte[] id;
+
+    /**
+     * Number of units of the media resource (bytes of graphic memory, number of codecs, etc.).
+     */
+    long value = 0;
+}
diff --git a/media/libmedia/aidl/android/media/MediaResourcePolicyParcel.aidl b/media/libmedia/aidl/android/media/MediaResourcePolicyParcel.aidl
new file mode 100644
index 0000000..4ea859a
--- /dev/null
+++ b/media/libmedia/aidl/android/media/MediaResourcePolicyParcel.aidl
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+/**
+ * Description of a policy to be adopted by ResourceManagerService.
+ * {@hide}
+ */
+parcelable MediaResourcePolicyParcel {
+    /**
+     * Name of the policy to be adopted.
+     */
+    @utf8InCpp String type;
+
+    /**
+     * Value of the policy to be adopted.
+     */
+    @utf8InCpp String value;
+}
diff --git a/media/libmedia/aidl/android/media/MediaResourceSubType.aidl b/media/libmedia/aidl/android/media/MediaResourceSubType.aidl
new file mode 100644
index 0000000..af2ba68
--- /dev/null
+++ b/media/libmedia/aidl/android/media/MediaResourceSubType.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+/**
+ * Sub-type enums of media resources.
+ *
+ * {@hide}
+ */
+@Backing(type="int")
+enum MediaResourceSubType {
+    kUnspecifiedSubType = 0,
+    kAudioCodec = 1,
+    kVideoCodec = 2,
+}
diff --git a/media/libmedia/aidl/android/media/MediaResourceType.aidl b/media/libmedia/aidl/android/media/MediaResourceType.aidl
new file mode 100644
index 0000000..b2bb71b
--- /dev/null
+++ b/media/libmedia/aidl/android/media/MediaResourceType.aidl
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2019, 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.
+ */
+
+package android.media;
+
+/**
+ * Type enums of media resources.
+ *
+ * {@hide}
+ */
+@Backing(type="int")
+enum MediaResourceType {
+    kUnspecified = 0,
+    kSecureCodec = 1,
+    kNonSecureCodec = 2,
+    kGraphicMemory = 3,
+    kCpuBoost = 4,
+    kBattery = 5,
+    kDrmSession = 6,
+}
diff --git a/media/libmedia/api/resourcemanager/1/.hash b/media/libmedia/api/resourcemanager/1/.hash
new file mode 100644
index 0000000..e56d56b
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/.hash
@@ -0,0 +1,18 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+58fe4b26909c9c4f17b1803baa4005c10ee40750  -
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl b/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl
new file mode 100644
index 0000000..20bfe72
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+interface IResourceManagerClient {
+  boolean reclaimResource();
+  @utf8InCpp String getName();
+}
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl b/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl
new file mode 100644
index 0000000..53cf036
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+interface IResourceManagerService {
+  void config(in android.media.MediaResourcePolicyParcel[] policies);
+  void addResource(int pid, int uid, long clientId, android.media.IResourceManagerClient client, in android.media.MediaResourceParcel[] resources);
+  void removeResource(int pid, long clientId, in android.media.MediaResourceParcel[] resources);
+  void removeClient(int pid, long clientId);
+  boolean reclaimResource(int pid, in android.media.MediaResourceParcel[] resources);
+  const String kPolicySupportsMultipleSecureCodecs = "supports-multiple-secure-codecs";
+  const String kPolicySupportsSecureWithNonSecureCodec = "supports-secure-with-non-secure-codec";
+}
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl
new file mode 100644
index 0000000..47ea9bc
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+parcelable MediaResourceParcel {
+  android.media.MediaResourceType type;
+  android.media.MediaResourceSubType subType;
+  byte[] id;
+  long value = 0;
+}
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl b/media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl
new file mode 100644
index 0000000..85d2588
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+parcelable MediaResourcePolicyParcel {
+  @utf8InCpp String type;
+  @utf8InCpp String value;
+}
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl
new file mode 100644
index 0000000..19b68af
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+@Backing(type="int")
+enum MediaResourceSubType {
+  kUnspecifiedSubType = 0,
+  kAudioCodec = 1,
+  kVideoCodec = 2,
+}
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl
new file mode 100644
index 0000000..6a123fc
--- /dev/null
+++ b/media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl
@@ -0,0 +1,28 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+@Backing(type="int")
+enum MediaResourceType {
+  kUnspecified = 0,
+  kSecureCodec = 1,
+  kNonSecureCodec = 2,
+  kGraphicMemory = 3,
+  kCpuBoost = 4,
+  kBattery = 5,
+  kDrmSession = 6,
+}
diff --git a/media/libmedia/include/media/IResourceManagerClient.h b/media/libmedia/include/media/IResourceManagerClient.h
deleted file mode 100644
index aa0cd88..0000000
--- a/media/libmedia/include/media/IResourceManagerClient.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015 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_IRESOURCEMANAGERCLIENT_H
-#define ANDROID_IRESOURCEMANAGERCLIENT_H
-
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-class IResourceManagerClient: public IInterface
-{
-public:
-    DECLARE_META_INTERFACE(ResourceManagerClient);
-
-    virtual bool reclaimResource() = 0;
-    virtual String8 getName() = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnResourceManagerClient: public BnInterface<IResourceManagerClient>
-{
-public:
-    virtual status_t onTransact(uint32_t code,
-                                const Parcel &data,
-                                Parcel *reply,
-                                uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IRESOURCEMANAGERCLIENT_H
diff --git a/media/libmedia/include/media/IResourceManagerService.h b/media/libmedia/include/media/IResourceManagerService.h
deleted file mode 100644
index 8992f8b..0000000
--- a/media/libmedia/include/media/IResourceManagerService.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2015 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_IRESOURCEMANAGERSERVICE_H
-#define ANDROID_IRESOURCEMANAGERSERVICE_H
-
-#include <utils/Errors.h>  // for status_t
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-#include <media/IResourceManagerClient.h>
-#include <media/MediaResource.h>
-#include <media/MediaResourcePolicy.h>
-
-namespace android {
-
-class IResourceManagerService: public IInterface
-{
-public:
-    DECLARE_META_INTERFACE(ResourceManagerService);
-
-    virtual void config(const Vector<MediaResourcePolicy> &policies) = 0;
-
-    virtual void addResource(
-            int pid,
-            int uid,
-            int64_t clientId,
-            const sp<IResourceManagerClient> client,
-            const Vector<MediaResource> &resources) = 0;
-
-    virtual void removeResource(int pid, int64_t clientId,
-            const Vector<MediaResource> &resources) = 0;
-
-    virtual void removeClient(int pid, int64_t clientId) = 0;
-
-    virtual bool reclaimResource(
-            int callingPid,
-            const Vector<MediaResource> &resources) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnResourceManagerService: public BnInterface<IResourceManagerService>
-{
-public:
-    virtual status_t onTransact(uint32_t code,
-                                const Parcel &data,
-                                Parcel *reply,
-                                uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IRESOURCEMANAGERSERVICE_H
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h
index e9684f0..caf03b1 100644
--- a/media/libmedia/include/media/MediaResource.h
+++ b/media/libmedia/include/media/MediaResource.h
@@ -18,72 +18,55 @@
 #ifndef ANDROID_MEDIA_RESOURCE_H
 #define ANDROID_MEDIA_RESOURCE_H
 
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-#include <vector>
+#include <android/media/MediaResourceParcel.h>
 
 namespace android {
 
-class MediaResource {
+using android::media::MediaResourceParcel;
+using android::media::MediaResourceSubType;
+using android::media::MediaResourceType;
+
+class MediaResource : public MediaResourceParcel {
 public:
-    enum Type {
-        kUnspecified = 0,
-        kSecureCodec,
-        kNonSecureCodec,
-        kGraphicMemory,
-        kCpuBoost,
-        kBattery,
-        kDrmSession,
-    };
+    using Type = MediaResourceType;
+    using SubType = MediaResourceSubType;
 
-    enum SubType {
-        kUnspecifiedSubType = 0,
-        kAudioCodec,
-        kVideoCodec,
-    };
+    MediaResource() = delete;
+    MediaResource(Type type, int64_t value);
+    MediaResource(Type type, SubType subType, int64_t value);
+    MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value);
 
-    MediaResource();
-    MediaResource(Type type, uint64_t value);
-    MediaResource(Type type, SubType subType, uint64_t value);
-    MediaResource(Type type, const std::vector<uint8_t> &id, uint64_t value);
-
-    void readFromParcel(const Parcel &parcel);
-    void writeToParcel(Parcel *parcel) const;
-
-    String8 toString() const;
-
-    bool operator==(const MediaResource &other) const;
-    bool operator!=(const MediaResource &other) const;
-
-    Type mType;
-    SubType mSubType;
-    uint64_t mValue;
-    // for kDrmSession-type mId is the unique session id obtained via MediaDrm#openSession
-    std::vector<uint8_t> mId;
+    static MediaResource CodecResource(bool secure, bool video);
+    static MediaResource GraphicMemoryResource(int64_t value);
+    static MediaResource CpuBoostResource();
+    static MediaResource VideoBatteryResource();
+    static MediaResource DrmSessionResource(const std::vector<uint8_t> &id, int64_t value);
 };
 
 inline static const char *asString(MediaResource::Type i, const char *def = "??") {
     switch (i) {
-        case MediaResource::kUnspecified:    return "unspecified";
-        case MediaResource::kSecureCodec:    return "secure-codec";
-        case MediaResource::kNonSecureCodec: return "non-secure-codec";
-        case MediaResource::kGraphicMemory:  return "graphic-memory";
-        case MediaResource::kCpuBoost:       return "cpu-boost";
-        case MediaResource::kBattery:        return "battery";
-        case MediaResource::kDrmSession:     return "drm-session";
-        default:                             return def;
+        case MediaResource::Type::kUnspecified:    return "unspecified";
+        case MediaResource::Type::kSecureCodec:    return "secure-codec";
+        case MediaResource::Type::kNonSecureCodec: return "non-secure-codec";
+        case MediaResource::Type::kGraphicMemory:  return "graphic-memory";
+        case MediaResource::Type::kCpuBoost:       return "cpu-boost";
+        case MediaResource::Type::kBattery:        return "battery";
+        case MediaResource::Type::kDrmSession:     return "drm-session";
+        default:                                   return def;
     }
 }
 
 inline static const char *asString(MediaResource::SubType i, const char *def = "??") {
     switch (i) {
-        case MediaResource::kUnspecifiedSubType: return "unspecified";
-        case MediaResource::kAudioCodec:         return "audio-codec";
-        case MediaResource::kVideoCodec:         return "video-codec";
+        case MediaResource::SubType::kUnspecifiedSubType: return "unspecified";
+        case MediaResource::SubType::kAudioCodec:         return "audio-codec";
+        case MediaResource::SubType::kVideoCodec:         return "video-codec";
         default:                                 return def;
     }
 }
 
+String8 toString(const MediaResourceParcel& resource);
+
 }; // namespace android
 
 #endif  // ANDROID_MEDIA_RESOURCE_H
diff --git a/media/libmedia/include/media/MediaResourcePolicy.h b/media/libmedia/include/media/MediaResourcePolicy.h
index 9bc2eec..7ae1a73 100644
--- a/media/libmedia/include/media/MediaResourcePolicy.h
+++ b/media/libmedia/include/media/MediaResourcePolicy.h
@@ -18,28 +18,23 @@
 #ifndef ANDROID_MEDIA_RESOURCE_POLICY_H
 #define ANDROID_MEDIA_RESOURCE_POLICY_H
 
-#include <binder/Parcel.h>
-#include <utils/String8.h>
+#include <android/media/MediaResourcePolicyParcel.h>
 
 namespace android {
 
-extern const char kPolicySupportsMultipleSecureCodecs[];
-extern const char kPolicySupportsSecureWithNonSecureCodec[];
+using media::MediaResourcePolicyParcel;
 
-class MediaResourcePolicy {
+class MediaResourcePolicy : public MediaResourcePolicyParcel {
 public:
-    MediaResourcePolicy();
-    MediaResourcePolicy(String8 type, String8 value);
+    MediaResourcePolicy() = delete;
+    MediaResourcePolicy(const std::string& type, const std::string& value);
 
-    void readFromParcel(const Parcel &parcel);
-    void writeToParcel(Parcel *parcel) const;
-
-    String8 toString() const;
-
-    String8 mType;
-    String8 mValue;
+    static const ::std::string& kPolicySupportsMultipleSecureCodecs();
+    static const ::std::string& kPolicySupportsSecureWithNonSecureCodec();
 };
 
+String8 toString(const MediaResourcePolicyParcel &policy);
+
 }; // namespace android
 
 #endif  // ANDROID_MEDIA_RESOURCE_POLICY_H
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index 58e4bee..262fe32 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -20,8 +20,8 @@
 
 #include <gtest/gtest.h>
 
-#include <media/IResourceManagerService.h>
-#include <media/IResourceManagerClient.h>
+#include <android/media/BnResourceManagerClient.h>
+#include <android/media/IResourceManagerService.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
 #include <mediadrm/DrmHal.h>
@@ -35,6 +35,10 @@
 
 namespace android {
 
+using ::android::binder::Status;
+using ::android::media::BnResourceManagerClient;
+using ::android::media::ResourceManagerService;
+
 static Vector<uint8_t> toAndroidVector(const std::vector<uint8_t> &vec) {
     Vector<uint8_t> aVec;
     for (auto b : vec) {
@@ -70,19 +74,21 @@
 
     virtual ~FakeDrm() {}
 
-    virtual bool reclaimResource() {
+    Status reclaimResource(bool* _aidl_return) {
         mReclaimed = true;
         mDrmSessionManager->removeSession(mSessionId);
-        return true;
+        *_aidl_return = true;
+        return Status::ok();
     }
 
-    virtual String8 getName() {
+    Status getName(::std::string* _aidl_return) {
         String8 name("FakeDrm[");
         for (size_t i = 0; i < mSessionId.size(); ++i) {
             name.appendFormat("%02x", mSessionId[i]);
         }
         name.append("]");
-        return name;
+        *_aidl_return = name;
+        return Status::ok();
     }
 
     bool isReclaimed() const {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 77eace9..d2e884e 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -28,6 +28,8 @@
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
 
+#include <android/media/BnResourceManagerClient.h>
+#include <android/media/IResourceManagerService.h>
 #include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -37,9 +39,9 @@
 #include <gui/Surface.h>
 #include <mediadrm/ICrypto.h>
 #include <media/IOMX.h>
-#include <media/IResourceManagerService.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/MediaAnalyticsItem.h>
+#include <media/MediaResource.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -63,6 +65,10 @@
 
 namespace android {
 
+using ::android::binder::Status;
+using ::android::media::BnResourceManagerClient;
+using ::android::media::IResourceManagerService;
+
 // key for media statistics
 static const char *kCodecKeyName = "codec";
 // attrs for media statistics
@@ -123,11 +129,12 @@
 struct ResourceManagerClient : public BnResourceManagerClient {
     explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
 
-    virtual bool reclaimResource() {
+    Status reclaimResource(bool* _aidl_return) override {
         sp<MediaCodec> codec = mMediaCodec.promote();
         if (codec == NULL) {
             // codec is already gone.
-            return true;
+            *_aidl_return = true;
+            return Status::ok();
         }
         status_t err = codec->reclaim();
         if (err == WOULD_BLOCK) {
@@ -139,22 +146,23 @@
         if (err != OK) {
             ALOGW("ResourceManagerClient failed to release codec with err %d", err);
         }
-        return (err == OK);
+        *_aidl_return = (err == OK);
+        return Status::ok();
     }
 
-    virtual String8 getName() {
-        String8 ret;
+    Status getName(::std::string* _aidl_return) override {
+        _aidl_return->clear();
         sp<MediaCodec> codec = mMediaCodec.promote();
         if (codec == NULL) {
             // codec is already gone.
-            return ret;
+            return Status::ok();
         }
 
         AString name;
         if (codec->getName(&name) == OK) {
-            ret.setTo(name.c_str());
+            *_aidl_return = name.c_str();
         }
-        return ret;
+        return Status::ok();
     }
 
 protected:
@@ -166,6 +174,35 @@
     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
 };
 
+struct MediaCodec::ResourceManagerServiceProxy : public IBinder::DeathRecipient {
+    ResourceManagerServiceProxy(pid_t pid, uid_t uid);
+    ~ResourceManagerServiceProxy();
+
+    void init();
+
+    // implements DeathRecipient
+    virtual void binderDied(const wp<IBinder>& /*who*/);
+
+    void addResource(
+            int64_t clientId,
+            const sp<IResourceManagerClient> &client,
+            const std::vector<MediaResourceParcel> &resources);
+
+    void removeResource(
+            int64_t clientId,
+            const std::vector<MediaResourceParcel> &resources);
+
+    void removeClient(int64_t clientId);
+
+    bool reclaimResource(const std::vector<MediaResourceParcel> &resources);
+
+private:
+    Mutex mLock;
+    sp<android::media::IResourceManagerService> mService;
+    pid_t mPid;
+    uid_t mUid;
+};
+
 MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
         pid_t pid, uid_t uid)
         : mPid(pid), mUid(uid) {
@@ -200,7 +237,7 @@
 void MediaCodec::ResourceManagerServiceProxy::addResource(
         int64_t clientId,
         const sp<IResourceManagerClient> &client,
-        const Vector<MediaResource> &resources) {
+        const std::vector<MediaResourceParcel> &resources) {
     Mutex::Autolock _l(mLock);
     if (mService == NULL) {
         return;
@@ -210,7 +247,7 @@
 
 void MediaCodec::ResourceManagerServiceProxy::removeResource(
         int64_t clientId,
-        const Vector<MediaResource> &resources) {
+        const std::vector<MediaResourceParcel> &resources) {
     Mutex::Autolock _l(mLock);
     if (mService == NULL) {
         return;
@@ -227,12 +264,14 @@
 }
 
 bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
-        const Vector<MediaResource> &resources) {
+        const std::vector<MediaResourceParcel> &resources) {
     Mutex::Autolock _l(mLock);
     if (mService == NULL) {
         return false;
     }
-    return mService->reclaimResource(mPid, resources);
+    bool success;
+    Status status = mService->reclaimResource(mPid, resources, &success);
+    return status.isOk() && success;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -754,7 +793,7 @@
 
     if (mBatteryChecker != nullptr) {
         mBatteryChecker->onCodecActivity([this] () {
-            addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
+            addResource(MediaResource::VideoBatteryResource());
         });
     }
 
@@ -794,7 +833,7 @@
 
     if (mBatteryChecker != nullptr) {
         mBatteryChecker->onCodecActivity([this] () {
-            addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
+            addResource(MediaResource::VideoBatteryResource());
         });
     }
 
@@ -992,12 +1031,8 @@
     }
 
     status_t err;
-    Vector<MediaResource> resources;
-    MediaResource::Type type =
-            secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
-    MediaResource::SubType subtype =
-            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
-    resources.push_back(MediaResource(type, subtype, 1));
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(MediaResource::CodecResource(secureCodec, mIsVideo));
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
@@ -1108,15 +1143,11 @@
     mConfigureMsg = msg;
 
     status_t err;
-    Vector<MediaResource> resources;
-    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
-            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
-    MediaResource::SubType subtype =
-            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
-    resources.push_back(MediaResource(type, subtype, 1));
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
     // Don't know the buffer size at this point, but it's fine to use 1 because
     // the reclaimResource call doesn't consider the requester's buffer size for now.
-    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
+    resources.push_back(MediaResource::GraphicMemoryResource(1));
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
@@ -1241,18 +1272,16 @@
     return size;
 }
 
-void MediaCodec::addResource(
-        MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) {
-    Vector<MediaResource> resources;
-    resources.push_back(MediaResource(type, subtype, value));
+void MediaCodec::addResource(const MediaResourceParcel &resource) {
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
     mResourceManagerService->addResource(
             getId(mResourceManagerClient), mResourceManagerClient, resources);
 }
 
-void MediaCodec::removeResource(
-        MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) {
-    Vector<MediaResource> resources;
-    resources.push_back(MediaResource(type, subtype, value));
+void MediaCodec::removeResource(const MediaResourceParcel &resource) {
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
     mResourceManagerService->removeResource(getId(mResourceManagerClient), resources);
 }
 
@@ -1260,15 +1289,11 @@
     sp<AMessage> msg = new AMessage(kWhatStart, this);
 
     status_t err;
-    Vector<MediaResource> resources;
-    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
-            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
-    MediaResource::SubType subtype =
-            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
-    resources.push_back(MediaResource(type, subtype, 1));
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
     // Don't know the buffer size at this point, but it's fine to use 1 because
     // the reclaimResource call doesn't consider the requester's buffer size for now.
-    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
+    resources.push_back(MediaResource::GraphicMemoryResource(1));
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
@@ -1710,8 +1735,7 @@
             totalPixel = width * height;
         }
         if (totalPixel >= 1920 * 1080) {
-            addResource(MediaResource::kCpuBoost,
-                    MediaResource::kUnspecifiedSubType, 1);
+            addResource(MediaResource::CpuBoostResource());
             mCpuBoostRequested = true;
         }
     }
@@ -2056,20 +2080,17 @@
                     }
                     mOwnerName = owner;
 
-                    MediaResource::Type resourceType;
                     if (mComponentName.endsWith(".secure")) {
                         mFlags |= kFlagIsSecure;
-                        resourceType = MediaResource::kSecureCodec;
                         mediametrics_setInt32(mMetricsHandle, kCodecSecure, 1);
                     } else {
                         mFlags &= ~kFlagIsSecure;
-                        resourceType = MediaResource::kNonSecureCodec;
                         mediametrics_setInt32(mMetricsHandle, kCodecSecure, 0);
                     }
 
                     if (mIsVideo) {
                         // audio codec is currently ignored.
-                        addResource(resourceType, MediaResource::kVideoCodec, 1);
+                        addResource(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
                     }
 
                     (new AMessage)->postReply(mReplyID);
@@ -2190,10 +2211,8 @@
 
                     CHECK_EQ(mState, STARTING);
                     if (mIsVideo) {
-                        addResource(
-                                MediaResource::kGraphicMemory,
-                                MediaResource::kUnspecifiedSubType,
-                                getGraphicBufferSize());
+                        addResource(MediaResource::GraphicMemoryResource(
+                                getGraphicBufferSize()));
                     }
                     setState(STARTED);
                     (new AMessage)->postReply(mReplyID);
@@ -3132,7 +3151,7 @@
         {
             if (mBatteryChecker != nullptr) {
                 mBatteryChecker->onCheckBatteryTimer(msg, [this] () {
-                    removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
+                    removeResource(MediaResource::VideoBatteryResource());
                 });
             }
             break;
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index b027a97..6b5b50e 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -264,7 +264,9 @@
             }
         }
     }
-    global_results->add(kPolicySupportsMultipleSecureCodecs, supportMultipleSecureCodecs);
+    global_results->add(
+            MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs().c_str(),
+            supportMultipleSecureCodecs);
 }
 
 static AString globalResultsToXml(const CodecSettings &results) {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 01d0325..78d00b1 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -24,7 +24,6 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <media/hardware/CryptoAPI.h>
 #include <media/MediaCodecInfo.h>
-#include <media/MediaResource.h>
 #include <media/MediaMetrics.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <media/stagefright/FrameRenderTracker.h>
@@ -43,8 +42,6 @@
 struct ICrypto;
 class MediaCodecBuffer;
 class IMemory;
-class IResourceManagerClient;
-class IResourceManagerService;
 struct PersistentSurface;
 class SoftwareRenderer;
 class Surface;
@@ -54,7 +51,13 @@
 namespace V1_0 {
 struct IDescrambler;
 }}}}
+namespace media {
+class IResourceManagerClient;
+class MediaResourceParcel;
+}
 using hardware::cas::native::V1_0::IDescrambler;
+using media::IResourceManagerClient;
+using media::MediaResourceParcel;
 
 struct MediaCodec : public AHandler {
     enum ConfigureFlags {
@@ -284,34 +287,7 @@
         bool mOwnedByClient;
     };
 
-    struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
-        ResourceManagerServiceProxy(pid_t pid, uid_t uid);
-        ~ResourceManagerServiceProxy();
-
-        void init();
-
-        // implements DeathRecipient
-        virtual void binderDied(const wp<IBinder>& /*who*/);
-
-        void addResource(
-                int64_t clientId,
-                const sp<IResourceManagerClient> &client,
-                const Vector<MediaResource> &resources);
-
-        void removeResource(
-                int64_t clientId,
-                const Vector<MediaResource> &resources);
-
-        void removeClient(int64_t clientId);
-
-        bool reclaimResource(const Vector<MediaResource> &resources);
-
-    private:
-        Mutex mLock;
-        sp<IResourceManagerService> mService;
-        pid_t mPid;
-        uid_t mUid;
-    };
+    struct ResourceManagerServiceProxy;
 
     State mState;
     uid_t mUid;
@@ -434,8 +410,8 @@
     bool isExecuting() const;
 
     uint64_t getGraphicBufferSize();
-    void addResource(MediaResource::Type type, MediaResource::SubType subtype, uint64_t value);
-    void removeResource(MediaResource::Type type, MediaResource::SubType subtype, uint64_t value);
+    void addResource(const MediaResourceParcel &resource);
+    void removeResource(const MediaResourceParcel &resource);
     void requestCpuBoostIfNeeded();
 
     bool hasPendingBuffer(int portIndex);
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 7b22b05..1f65372 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -40,7 +40,7 @@
     ALOGI("ServiceManager: %p", sm.get());
     AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
-    ResourceManagerService::instantiate();
+    media::ResourceManagerService::instantiate();
     registerExtensions();
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 45eea0f..ae832c7 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -23,6 +23,7 @@
 #include <binder/IServiceManager.h>
 #include <cutils/sched_policy.h>
 #include <dirent.h>
+#include <media/MediaResourcePolicy.h>
 #include <media/stagefright/ProcessInfo.h>
 #include <mediautils/BatteryNotifier.h>
 #include <mediautils/SchedulingPolicyService.h>
@@ -37,7 +38,7 @@
 
 namespace android {
 
-namespace {
+namespace media {
 
 class DeathNotifier : public IBinder::DeathRecipient {
 public:
@@ -60,20 +61,18 @@
     int64_t mClientId;
 };
 
-}  // namespace
-
 template <typename T>
-static String8 getString(const Vector<T> &items) {
+static String8 getString(const std::vector<T> &items) {
     String8 itemsStr;
     for (size_t i = 0; i < items.size(); ++i) {
-        itemsStr.appendFormat("%s ", items[i].toString().string());
+        itemsStr.appendFormat("%s ", toString(items[i]).string());
     }
     return itemsStr;
 }
 
 static bool hasResourceType(MediaResource::Type type, const ResourceList& resources) {
     for (auto it = resources.begin(); it != resources.end(); it++) {
-        if (it->second.mType == type) {
+        if (it->second.type == type) {
             return true;
         }
     }
@@ -121,15 +120,15 @@
     return infos.editValueAt(index);
 }
 
-static void notifyResourceGranted(int pid, const Vector<MediaResource> &resources) {
+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) {
-            if (resources[i].mSubType == MediaResource::kAudioCodec) {
+            if (resources[i].subType == MediaResource::SubType::kAudioCodec) {
                 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
-            } else if (resources[i].mSubType == MediaResource::kVideoCodec) {
+            } else if (resources[i].subType == MediaResource::SubType::kVideoCodec) {
                 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
             }
         }
@@ -182,13 +181,18 @@
             snprintf(buffer, SIZE, "        Id: %lld\n", (long long)infos[j].clientId);
             result.append(buffer);
 
-            snprintf(buffer, SIZE, "        Name: %s\n", infos[j].client->getName().string());
+            std::string clientName;
+            Status status = infos[j].client->getName(&clientName);
+            if (!status.isOk()) {
+                clientName = "<unknown client>";
+            }
+            snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
             result.append(buffer);
 
             const ResourceList &resources = infos[j].resources;
             result.append("        Resources:\n");
             for (auto it = resources.begin(); it != resources.end(); it++) {
-                snprintf(buffer, SIZE, "          %s\n", it->second.toString().string());
+                snprintf(buffer, SIZE, "          %s\n", toString(it->second).string());
                 result.append(buffer);
             }
         }
@@ -242,27 +246,28 @@
 
 ResourceManagerService::~ResourceManagerService() {}
 
-void ResourceManagerService::config(const Vector<MediaResourcePolicy> &policies) {
+Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
     String8 log = String8::format("config(%s)", getString(policies).string());
     mServiceLog->add(log);
 
     Mutex::Autolock lock(mLock);
     for (size_t i = 0; i < policies.size(); ++i) {
-        String8 type = policies[i].mType;
-        String8 value = policies[i].mValue;
-        if (type == kPolicySupportsMultipleSecureCodecs) {
+        const std::string &type = policies[i].type;
+        const std::string &value = policies[i].value;
+        if (type == MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs()) {
             mSupportsMultipleSecureCodecs = (value == "true");
-        } else if (type == kPolicySupportsSecureWithNonSecureCodec) {
+        } else if (type == MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec()) {
             mSupportsSecureWithNonSecureCodec = (value == "true");
         }
     }
+    return Status::ok();
 }
 
 void ResourceManagerService::onFirstAdded(
-        const MediaResource& resource, const ResourceInfo& clientInfo) {
+        const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
     // first time added
-    if (resource.mType == MediaResource::kCpuBoost
-     && resource.mSubType == MediaResource::kUnspecifiedSubType) {
+    if (resource.type == MediaResource::Type::kCpuBoost
+     && resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
         // Request it on every new instance of kCpuBoost, as the media.codec
         // could have died, if we only do it the first time subsequent instances
         // never gets the boost.
@@ -270,44 +275,49 @@
             ALOGW("couldn't request cpuset boost");
         }
         mCpuBoostCount++;
-    } else if (resource.mType == MediaResource::kBattery
-            && resource.mSubType == MediaResource::kVideoCodec) {
+    } else if (resource.type == MediaResource::Type::kBattery
+            && resource.subType == MediaResource::SubType::kVideoCodec) {
         mSystemCB->noteStartVideo(clientInfo.uid);
     }
 }
 
 void ResourceManagerService::onLastRemoved(
-        const MediaResource& resource, const ResourceInfo& clientInfo) {
-    if (resource.mType == MediaResource::kCpuBoost
-            && resource.mSubType == MediaResource::kUnspecifiedSubType
+        const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
+    if (resource.type == MediaResource::Type::kCpuBoost
+            && resource.subType == MediaResource::SubType::kUnspecifiedSubType
             && mCpuBoostCount > 0) {
         if (--mCpuBoostCount == 0) {
             mSystemCB->requestCpusetBoost(false, this);
         }
-    } else if (resource.mType == MediaResource::kBattery
-            && resource.mSubType == MediaResource::kVideoCodec) {
+    } else if (resource.type == MediaResource::Type::kBattery
+            && resource.subType == MediaResource::SubType::kVideoCodec) {
         mSystemCB->noteStopVideo(clientInfo.uid);
     }
 }
 
 void ResourceManagerService::mergeResources(
-        MediaResource& r1, const MediaResource& r2) {
-    if (r1.mType == MediaResource::kDrmSession) {
-        // This means we are using a session. Each session's mValue is initialized to UINT64_MAX.
-        // The oftener a session is used the lower it's mValue. During reclaim the session with
-        // the highest mValue/lowest usage would be closed.
-        r1.mValue -= (r1.mValue == 0 ? 0 : 1);
+        MediaResourceParcel& r1, const MediaResourceParcel& r2) {
+    // The resource entry on record is maintained to be in [0,INT64_MAX].
+    // Clamp if merging in the new resource value causes it to go out of bound.
+    // Note that the new resource value could be negative, eg.DrmSession, the
+    // value goes lower when the session is used more often. During reclaim
+    // the session with the highest value (lowest usage) would be closed.
+    if (r2.value < INT64_MAX - r1.value) {
+        r1.value += r2.value;
+        if (r1.value < 0) {
+            r1.value = 0;
+        }
     } else {
-        r1.mValue += r2.mValue;
+        r1.value = INT64_MAX;
     }
 }
 
-void ResourceManagerService::addResource(
-        int pid,
-        int uid,
+Status ResourceManagerService::addResource(
+        int32_t pid,
+        int32_t uid,
         int64_t clientId,
-        const sp<IResourceManagerClient> client,
-        const Vector<MediaResource> &resources) {
+        const sp<IResourceManagerClient>& client,
+        const std::vector<MediaResourceParcel>& resources) {
     String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)",
             pid, (long long) clientId, getString(resources).string());
     mServiceLog->add(log);
@@ -315,15 +325,26 @@
     Mutex::Autolock lock(mLock);
     if (!mProcessInfo->isValidPid(pid)) {
         ALOGE("Rejected addResource call with invalid pid.");
-        return;
+        return Status::fromServiceSpecificError(BAD_VALUE);
     }
     ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
     ResourceInfo& info = getResourceInfoForEdit(uid, clientId, client, infos);
 
     for (size_t i = 0; i < resources.size(); ++i) {
         const auto &res = resources[i];
-        const auto resType = std::tuple(res.mType, res.mSubType, res.mId);
+        const auto resType = std::tuple(res.type, res.subType, res.id);
+
+        if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
+            ALOGW("Ignoring request to remove negative value of non-drm resource");
+            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.
+                ALOGW("Ignoring request to add new resource entry with value <= 0");
+                continue;
+            }
             onFirstAdded(res, info);
             info.resources[resType] = res;
         } else {
@@ -335,10 +356,12 @@
         IInterface::asBinder(client)->linkToDeath(info.deathNotifier);
     }
     notifyResourceGranted(pid, resources);
+    return Status::ok();
 }
 
-void ResourceManagerService::removeResource(int pid, int64_t clientId,
-        const Vector<MediaResource> &resources) {
+Status ResourceManagerService::removeResource(
+        int32_t pid, int64_t clientId,
+        const std::vector<MediaResourceParcel>& resources) {
     String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)",
             pid, (long long) clientId, getString(resources).string());
     mServiceLog->add(log);
@@ -346,46 +369,51 @@
     Mutex::Autolock lock(mLock);
     if (!mProcessInfo->isValidPid(pid)) {
         ALOGE("Rejected removeResource call with invalid pid.");
-        return;
+        return Status::fromServiceSpecificError(BAD_VALUE);
     }
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
         ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
-        return;
+        return Status::ok();
     }
     ResourceInfos &infos = mMap.editValueAt(index);
 
     index = infos.indexOfKey(clientId);
     if (index < 0) {
         ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
-        return;
+        return Status::ok();
     }
 
     ResourceInfo &info = infos.editValueAt(index);
 
     for (size_t i = 0; i < resources.size(); ++i) {
         const auto &res = resources[i];
-        const auto resType = std::tuple(res.mType, res.mSubType, res.mId);
+        const auto resType = std::tuple(res.type, res.subType, res.id);
+
+        if (res.value < 0) {
+            ALOGW("Ignoring request to remove negative value of resource");
+            continue;
+        }
         // ignore if we don't have it
         if (info.resources.find(resType) != info.resources.end()) {
-            MediaResource &resource = info.resources[resType];
-            if (resource.mValue > res.mValue) {
-                resource.mValue -= res.mValue;
+            MediaResourceParcel &resource = info.resources[resType];
+            if (resource.value > res.value) {
+                resource.value -= res.value;
             } else {
-                // drm sessions always take this branch because res.mValue is set
-                // to UINT64_MAX
                 onLastRemoved(res, info);
                 info.resources.erase(resType);
             }
         }
     }
+    return Status::ok();
 }
 
-void ResourceManagerService::removeClient(int pid, int64_t clientId) {
+Status ResourceManagerService::removeClient(int32_t pid, int64_t clientId) {
     removeResource(pid, clientId, true);
+    return Status::ok();
 }
 
-void ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) {
+Status ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) {
     String8 log = String8::format(
             "removeResource(pid %d, clientId %lld)",
             pid, (long long) clientId);
@@ -394,19 +422,19 @@
     Mutex::Autolock lock(mLock);
     if (checkValid && !mProcessInfo->isValidPid(pid)) {
         ALOGE("Rejected removeResource call with invalid pid.");
-        return;
+        return Status::fromServiceSpecificError(BAD_VALUE);
     }
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
         ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
-        return;
+        return Status::ok();
     }
     ResourceInfos &infos = mMap.editValueAt(index);
 
     index = infos.indexOfKey(clientId);
     if (index < 0) {
         ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
-        return;
+        return Status::ok();
     }
 
     const ResourceInfo &info = infos[index];
@@ -417,45 +445,49 @@
     IInterface::asBinder(info.client)->unlinkToDeath(info.deathNotifier);
 
     infos.removeItemsAt(index);
+    return Status::ok();
 }
 
 void ResourceManagerService::getClientForResource_l(
-        int callingPid, const MediaResource *res, Vector<sp<IResourceManagerClient>> *clients) {
+        int callingPid, const MediaResourceParcel *res, Vector<sp<IResourceManagerClient>> *clients) {
     if (res == NULL) {
         return;
     }
     sp<IResourceManagerClient> client;
-    if (getLowestPriorityBiggestClient_l(callingPid, res->mType, &client)) {
+    if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) {
         clients->push_back(client);
     }
 }
 
-bool ResourceManagerService::reclaimResource(
-        int callingPid, const Vector<MediaResource> &resources) {
+Status ResourceManagerService::reclaimResource(
+        int32_t callingPid,
+        const std::vector<MediaResourceParcel>& resources,
+        bool* _aidl_return) {
     String8 log = String8::format("reclaimResource(callingPid %d, resources %s)",
             callingPid, getString(resources).string());
     mServiceLog->add(log);
+    *_aidl_return = false;
 
     Vector<sp<IResourceManagerClient>> clients;
     {
         Mutex::Autolock lock(mLock);
         if (!mProcessInfo->isValidPid(callingPid)) {
             ALOGE("Rejected reclaimResource call with invalid callingPid.");
-            return false;
+            return Status::fromServiceSpecificError(BAD_VALUE);
         }
-        const MediaResource *secureCodec = NULL;
-        const MediaResource *nonSecureCodec = NULL;
-        const MediaResource *graphicMemory = NULL;
-        const MediaResource *drmSession = NULL;
+        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) {
-            MediaResource::Type type = resources[i].mType;
-            if (resources[i].mType == MediaResource::kSecureCodec) {
+            MediaResource::Type type = resources[i].type;
+            if (resources[i].type == MediaResource::Type::kSecureCodec) {
                 secureCodec = &resources[i];
-            } else if (type == MediaResource::kNonSecureCodec) {
+            } else if (type == MediaResource::Type::kNonSecureCodec) {
                 nonSecureCodec = &resources[i];
-            } else if (type == MediaResource::kGraphicMemory) {
+            } else if (type == MediaResource::Type::kGraphicMemory) {
                 graphicMemory = &resources[i];
-            } else if (type == MediaResource::kDrmSession) {
+            } else if (type == MediaResource::Type::kDrmSession) {
                 drmSession = &resources[i];
             }
         }
@@ -463,27 +495,27 @@
         // first pass to handle secure/non-secure codec conflict
         if (secureCodec != NULL) {
             if (!mSupportsMultipleSecureCodecs) {
-                if (!getAllClients_l(callingPid, MediaResource::kSecureCodec, &clients)) {
-                    return false;
+                if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
+                    return Status::ok();
                 }
             }
             if (!mSupportsSecureWithNonSecureCodec) {
-                if (!getAllClients_l(callingPid, MediaResource::kNonSecureCodec, &clients)) {
-                    return false;
+                if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, &clients)) {
+                    return Status::ok();
                 }
             }
         }
         if (nonSecureCodec != NULL) {
             if (!mSupportsSecureWithNonSecureCodec) {
-                if (!getAllClients_l(callingPid, MediaResource::kSecureCodec, &clients)) {
-                    return false;
+                if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
+                    return Status::ok();
                 }
             }
         }
         if (drmSession != NULL) {
             getClientForResource_l(callingPid, drmSession, &clients);
             if (clients.size() == 0) {
-                return false;
+                return Status::ok();
             }
         }
 
@@ -501,32 +533,35 @@
         if (clients.size() == 0) {
             // if we are here, run the fourth pass to free one codec with the different type.
             if (secureCodec != NULL) {
-                MediaResource temp(MediaResource::kNonSecureCodec, 1);
+                MediaResource temp(MediaResource::Type::kNonSecureCodec, 1);
                 getClientForResource_l(callingPid, &temp, &clients);
             }
             if (nonSecureCodec != NULL) {
-                MediaResource temp(MediaResource::kSecureCodec, 1);
+                MediaResource temp(MediaResource::Type::kSecureCodec, 1);
                 getClientForResource_l(callingPid, &temp, &clients);
             }
         }
     }
 
     if (clients.size() == 0) {
-        return false;
+        return Status::ok();
     }
 
     sp<IResourceManagerClient> failedClient;
     for (size_t i = 0; i < clients.size(); ++i) {
         log = String8::format("reclaimResource from client %p", clients[i].get());
         mServiceLog->add(log);
-        if (!clients[i]->reclaimResource()) {
+        bool success;
+        Status status = clients[i]->reclaimResource(&success);
+        if (!status.isOk() || !success) {
             failedClient = clients[i];
             break;
         }
     }
 
     if (failedClient == NULL) {
-        return true;
+        *_aidl_return = true;
+        return Status::ok();
     }
 
     {
@@ -551,7 +586,7 @@
         }
     }
 
-    return false;
+    return Status::ok();
 }
 
 bool ResourceManagerService::getAllClients_l(
@@ -666,10 +701,10 @@
     for (size_t i = 0; i < infos.size(); ++i) {
         const ResourceList &resources = infos[i].resources;
         for (auto it = resources.begin(); it != resources.end(); it++) {
-            const MediaResource &resource = it->second;
-            if (resource.mType == type) {
-                if (resource.mValue > largestValue) {
-                    largestValue = resource.mValue;
+            const MediaResourceParcel &resource = it->second;
+            if (resource.type == type) {
+                if (resource.value > largestValue) {
+                    largestValue = resource.value;
                     clientTemp = infos[i].client;
                 }
             }
@@ -685,4 +720,5 @@
     return true;
 }
 
+} // namespace media
 } // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 44d0c28..b5b9f86 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -15,25 +15,32 @@
 ** limitations under the License.
 */
 
-#ifndef ANDROID_RESOURCEMANAGERSERVICE_H
-#define ANDROID_RESOURCEMANAGERSERVICE_H
+#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
+#define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
 
+#include <android/media/BnResourceManagerService.h>
 #include <arpa/inet.h>
 #include <binder/BinderService.h>
+#include <media/MediaResource.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Vector.h>
 
-#include <media/IResourceManagerService.h>
-
 namespace android {
 
 class ServiceLog;
 struct ProcessInfoInterface;
 
-typedef std::map<std::tuple<MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>, MediaResource> ResourceList;
+namespace media {
+
+using android::binder::Status;
+
+typedef std::map<std::tuple<
+        MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
+        MediaResourceParcel> ResourceList;
+
 struct ResourceInfo {
     int64_t clientId;
     uid_t uid;
@@ -69,26 +76,31 @@
             const sp<SystemCallbackInterface> &systemResource);
 
     // IResourceManagerService interface
-    virtual void config(const Vector<MediaResourcePolicy> &policies);
+    Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
 
-    virtual void addResource(
-            int pid,
-            int uid,
+    Status addResource(
+            int32_t pid,
+            int32_t uid,
             int64_t clientId,
-            const sp<IResourceManagerClient> client,
-            const Vector<MediaResource> &resources);
+            const sp<IResourceManagerClient>& client,
+            const std::vector<MediaResourceParcel>& resources) override;
 
-    virtual void removeResource(int pid, int64_t clientId,
-            const Vector<MediaResource> &resources);
+    Status removeResource(
+            int32_t pid,
+            int64_t clientId,
+            const std::vector<MediaResourceParcel>& resources) override;
 
-    virtual void removeClient(int pid, int64_t clientId);
+    Status removeClient(int32_t pid, int64_t clientId) override;
 
     // Tries to reclaim resource from processes with lower priority than the calling process
     // according to the requested resources.
     // Returns true if any resource has been reclaimed, otherwise returns false.
-    virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources);
+    Status reclaimResource(
+            int32_t callingPid,
+            const std::vector<MediaResourceParcel>& resources,
+            bool* _aidl_return) override;
 
-    void removeResource(int pid, int64_t clientId, bool checkValid);
+    Status removeResource(int pid, int64_t clientId, bool checkValid);
 
 protected:
     virtual ~ResourceManagerService();
@@ -120,14 +132,14 @@
 
     // A helper function basically calls getLowestPriorityBiggestClient_l and add the result client
     // to the given Vector.
-    void getClientForResource_l(
-        int callingPid, const MediaResource *res, Vector<sp<IResourceManagerClient>> *clients);
+    void getClientForResource_l(int callingPid,
+            const MediaResourceParcel *res, Vector<sp<IResourceManagerClient>> *clients);
 
-    void onFirstAdded(const MediaResource& res, const ResourceInfo& clientInfo);
-    void onLastRemoved(const MediaResource& res, const ResourceInfo& clientInfo);
+    void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
+    void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
 
     // Merge r2 into r1
-    void mergeResources(MediaResource& r1, const MediaResource& r2);
+    void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
 
     mutable Mutex mLock;
     sp<ProcessInfoInterface> mProcessInfo;
@@ -140,7 +152,7 @@
 };
 
 // ----------------------------------------------------------------------------
+} // namespace media
+} // namespace android
 
-}; // namespace android
-
-#endif // ANDROID_RESOURCEMANAGERSERVICE_H
+#endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 9e14151..203baf5 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -21,13 +21,16 @@
 #include <gtest/gtest.h>
 
 #include "ResourceManagerService.h"
-#include <media/IResourceManagerService.h>
+#include <android/media/BnResourceManagerClient.h>
 #include <media/MediaResource.h>
 #include <media/MediaResourcePolicy.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
 
 namespace android {
+namespace media {
+
+using ::android::binder::Status;
 
 static int64_t getId(const sp<IResourceManagerClient>& client) {
     return (int64_t) client.get();
@@ -112,15 +115,17 @@
     TestClient(int pid, sp<ResourceManagerService> service)
         : mReclaimed(false), mPid(pid), mService(service) {}
 
-    virtual bool reclaimResource() {
+    Status reclaimResource(bool* _aidl_return) override {
         sp<IResourceManagerClient> client(this);
         mService->removeClient(mPid, (int64_t) client.get());
         mReclaimed = true;
-        return true;
+        *_aidl_return = true;
+        return Status::ok();
     }
 
-    virtual String8 getName() {
-        return String8("test_client");
+    Status getName(::std::string* _aidl_return) override {
+        *_aidl_return = "test_client";
+        return Status::ok();
     }
 
     bool reclaimed() const {
@@ -157,6 +162,12 @@
     return lhs.type == rhs.type && lhs.arg == rhs.arg;
 }
 
+#define CHECK_STATUS_TRUE(condition) \
+    EXPECT_TRUE((condition).isOk() && (result))
+
+#define CHECK_STATUS_FALSE(condition) \
+    EXPECT_TRUE((condition).isOk() && !(result))
+
 class ResourceManagerServiceTest : public ::testing::Test {
 public:
     ResourceManagerServiceTest()
@@ -168,13 +179,13 @@
     }
 
 protected:
-    static bool isEqualResources(const Vector<MediaResource> &resources1,
+    static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
             const ResourceList &resources2) {
         // convert resource1 to ResourceList
         ResourceList r1;
         for (size_t i = 0; i < resources1.size(); ++i) {
             const auto &res = resources1[i];
-            const auto resType = std::tuple(res.mType, res.mSubType, res.mId);
+            const auto resType = std::tuple(res.type, res.subType, res.id);
             r1[resType] = res;
         }
         return r1 == resources2;
@@ -183,7 +194,7 @@
     static void expectEqResourceInfo(const ResourceInfo &info,
             int uid,
             sp<IResourceManagerClient> client,
-            const Vector<MediaResource> &resources) {
+            const std::vector<MediaResourceParcel> &resources) {
         EXPECT_EQ(uid, info.uid);
         EXPECT_EQ(client, info.client);
         EXPECT_TRUE(isEqualResources(resources, info.resources));
@@ -219,25 +230,25 @@
     // ---------------------------------------------------------------------------------
     void addResource() {
         // kTestPid1 mTestClient1
-        Vector<MediaResource> resources1;
-        resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
-        resources1.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
-        Vector<MediaResource> resources11;
-        resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
+        resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
+        std::vector<MediaResourceParcel> resources11;
+        resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
 
         // kTestPid2 mTestClient2
-        Vector<MediaResource> resources2;
-        resources2.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
-        resources2.push_back(MediaResource(MediaResource::kGraphicMemory, 300));
+        std::vector<MediaResourceParcel> resources2;
+        resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+        resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
         mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
 
         // kTestPid2 mTestClient3
-        Vector<MediaResource> resources3;
+        std::vector<MediaResourceParcel> resources3;
         mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
-        resources3.push_back(MediaResource(MediaResource::kSecureCodec, 1));
-        resources3.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
+        resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+        resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
         mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
 
         const PidResourceInfosMap &map = mService->mMap;
@@ -256,32 +267,92 @@
         expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
     }
 
+    void testCombineResourceWithNegativeValues() {
+        // kTestPid1 mTestClient1
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -100));
+        resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -100));
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+
+        // 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;
+        EXPECT_EQ(1u, map.size());
+        ssize_t index1 = map.indexOfKey(kTestPid1);
+        ASSERT_GE(index1, 0);
+        const ResourceInfos &infos1 = map[index1];
+        EXPECT_EQ(1u, infos1.size());
+        std::vector<MediaResourceParcel> expected;
+        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+
+        resources1.clear();
+        resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
+        resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+        resources1.clear();
+        resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10));
+        resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10));
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+
+        // Expected result:
+        // Both values should saturate to INT64_MAX
+        expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
+        expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
+        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+
+        resources1.clear();
+        resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10));
+        resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -10));
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+
+        // Expected result:
+        // 1) DrmSession resource should allow negative value addition, and value should drop accordingly
+        // 2) Non-drm session resource should ignore negative value addition.
+        expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX - 10));
+        expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
+        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+
+        resources1.clear();
+        resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN));
+        expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MIN));
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+
+        // Expected result:
+        // 1) DrmSession resource value should drop to 0, but the entry shouldn't be removed.
+        // 2) Non-drm session resource should ignore negative value addition.
+        expected.clear();
+        expected.push_back(MediaResource(MediaResource::Type::kDrmSession, 0));
+        expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
+        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+    }
+
     void testConfig() {
         EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
 
-        Vector<MediaResourcePolicy> policies1;
+        std::vector<MediaResourcePolicyParcel> policies1;
         policies1.push_back(
                 MediaResourcePolicy(
-                        String8(kPolicySupportsMultipleSecureCodecs),
-                        String8("true")));
+                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs(),
+                        "true"));
         policies1.push_back(
                 MediaResourcePolicy(
-                        String8(kPolicySupportsSecureWithNonSecureCodec),
-                        String8("false")));
+                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec(),
+                        "false"));
         mService->config(policies1);
         EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
 
-        Vector<MediaResourcePolicy> policies2;
+        std::vector<MediaResourcePolicyParcel> policies2;
         policies2.push_back(
                 MediaResourcePolicy(
-                        String8(kPolicySupportsMultipleSecureCodecs),
-                        String8("false")));
+                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs(),
+                        "false"));
         policies2.push_back(
                 MediaResourcePolicy(
-                        String8(kPolicySupportsSecureWithNonSecureCodec),
-                        String8("true")));
+                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec(),
+                        "true"));
         mService->config(policies2);
         EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
         EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
@@ -289,12 +360,12 @@
 
     void testCombineResource() {
         // kTestPid1 mTestClient1
-        Vector<MediaResource> resources1;
-        resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
 
-        Vector<MediaResource> resources11;
-        resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
+        std::vector<MediaResourceParcel> resources11;
+        resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
 
         const PidResourceInfosMap &map = mService->mMap;
@@ -305,35 +376,35 @@
         EXPECT_EQ(1u, infos1.size());
 
         // test adding existing types to combine values
-        resources1.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
+        resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
 
-        Vector<MediaResource> expected;
-        expected.push_back(MediaResource(MediaResource::kSecureCodec, 2));
-        expected.push_back(MediaResource(MediaResource::kGraphicMemory, 300));
+        std::vector<MediaResourceParcel> expected;
+        expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
+        expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
         expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         // test adding new types (including types that differs only in subType)
-        resources11.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
-        resources11.push_back(MediaResource(MediaResource::kSecureCodec, MediaResource::kVideoCodec, 1));
+        resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+        resources11.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
 
         expected.clear();
-        expected.push_back(MediaResource(MediaResource::kSecureCodec, 2));
-        expected.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
-        expected.push_back(MediaResource(MediaResource::kSecureCodec, MediaResource::kVideoCodec, 1));
-        expected.push_back(MediaResource(MediaResource::kGraphicMemory, 500));
+        expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
+        expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+        expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
+        expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500));
         expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
     }
 
     void testRemoveResource() {
         // kTestPid1 mTestClient1
-        Vector<MediaResource> resources1;
-        resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
 
-        Vector<MediaResource> resources11;
-        resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
+        std::vector<MediaResourceParcel> resources11;
+        resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
 
         const PidResourceInfosMap &map = mService->mMap;
@@ -344,20 +415,26 @@
         EXPECT_EQ(1u, infos1.size());
 
         // test partial removal
-        resources11.editItemAt(0).mValue = 100;
+        resources11[0].value = 100;
         mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
 
-        Vector<MediaResource> expected;
-        expected.push_back(MediaResource(MediaResource::kSecureCodec, 1));
-        expected.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
+        std::vector<MediaResourceParcel> expected;
+        expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+        expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
+        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+
+        // test removal request with negative value, should be ignored
+        resources11[0].value = -10000;
+        mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
+
         expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         // test complete removal with overshoot value
-        resources11.editItemAt(0).mValue = 1000;
+        resources11[0].value = 1000;
         mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
 
         expected.clear();
-        expected.push_back(MediaResource(MediaResource::kSecureCodec, 1));
+        expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
         expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
     }
 
@@ -380,7 +457,7 @@
     void testGetAllClients() {
         addResource();
 
-        MediaResource::Type type = MediaResource::kSecureCodec;
+        MediaResource::Type type = MediaResource::Type::kSecureCodec;
         Vector<sp<IResourceManagerClient> > clients;
         EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
         // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
@@ -395,9 +472,10 @@
     }
 
     void testReclaimResourceSecure() {
-        Vector<MediaResource> resources;
-        resources.push_back(MediaResource(MediaResource::kSecureCodec, 1));
-        resources.push_back(MediaResource(MediaResource::kGraphicMemory, 150));
+        bool result;
+        std::vector<MediaResourceParcel> resources;
+        resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+        resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
 
         // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
         {
@@ -406,19 +484,19 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
-            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
 
             // reclaim all secure codecs
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
 
             // call again should reclaim one largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
         // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
@@ -428,15 +506,15 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
-            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
 
             // reclaim all secure and non-secure codecs
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
 
@@ -447,23 +525,23 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
-            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
 
             // reclaim all non-secure codecs
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim one largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another largest graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -473,22 +551,22 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
 
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             // one largest graphic memory from lowest process got reclaimed
             verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
         // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -497,27 +575,28 @@
             mService->mSupportsMultipleSecureCodecs = true;
             mService->mSupportsSecureWithNonSecureCodec = true;
 
-            Vector<MediaResource> resources;
-            resources.push_back(MediaResource(MediaResource::kSecureCodec, 1));
+            std::vector<MediaResourceParcel> resources;
+            resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
 
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             // secure codec from lowest process got reclaimed
             verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another secure codec from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // no more secure codec, non-secure codec will be reclaimed.
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
         }
     }
 
     void testReclaimResourceNonSecure() {
-        Vector<MediaResource> resources;
-        resources.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
-        resources.push_back(MediaResource(MediaResource::kGraphicMemory, 150));
+        bool result;
+        std::vector<MediaResourceParcel> resources;
+        resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
+        resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
 
         // ### secure codec can't coexist with non-secure codec ###
         {
@@ -525,19 +604,19 @@
             mService->mSupportsSecureWithNonSecureCodec = false;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
-            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
 
             // reclaim all secure codecs
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
 
             // call again should reclaim one graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
 
@@ -547,22 +626,22 @@
             mService->mSupportsSecureWithNonSecureCodec = true;
 
             // priority too low
-            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
 
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             // one largest graphic memory from lowest process got reclaimed
             verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // call again should reclaim another graphic memory from lowest process
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
 
             // nothing left
-            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
         }
 
         // ### secure codec can coexist with non-secure codec ###
@@ -570,15 +649,15 @@
             addResource();
             mService->mSupportsSecureWithNonSecureCodec = true;
 
-            Vector<MediaResource> resources;
-            resources.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
+            std::vector<MediaResourceParcel> resources;
+            resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
 
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             // one non secure codec from lowest process got reclaimed
             verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
 
             // no more non-secure codec, secure codec from lowest priority process will be reclaimed
-            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
+            CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
             verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
 
             // clean up client 3 which still left
@@ -587,7 +666,7 @@
     }
 
     void testGetLowestPriorityBiggestClient() {
-        MediaResource::Type type = MediaResource::kGraphicMemory;
+        MediaResource::Type type = MediaResource::Type::kGraphicMemory;
         sp<IResourceManagerClient> client;
         EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
 
@@ -596,8 +675,8 @@
         EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
         EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
 
-        // kTestPid1 is the lowest priority process with MediaResource::kGraphicMemory.
-        // mTestClient1 has the largest MediaResource::kGraphicMemory within kTestPid1.
+        // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
+        // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
         EXPECT_EQ(mTestClient1, client);
     }
 
@@ -606,7 +685,7 @@
         int priority;
         TestProcessInfo processInfo;
 
-        MediaResource::Type type = MediaResource::kGraphicMemory;
+        MediaResource::Type type = MediaResource::Type::kGraphicMemory;
         EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
 
         addResource();
@@ -617,7 +696,7 @@
         processInfo.getPriority(kTestPid1, &priority1);
         EXPECT_EQ(priority1, priority);
 
-        type = MediaResource::kNonSecureCodec;
+        type = MediaResource::Type::kNonSecureCodec;
         EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
         EXPECT_EQ(kTestPid2, pid);
         int priority2;
@@ -626,7 +705,7 @@
     }
 
     void testGetBiggestClient() {
-        MediaResource::Type type = MediaResource::kGraphicMemory;
+        MediaResource::Type type = MediaResource::Type::kGraphicMemory;
         sp<IResourceManagerClient> client;
         EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
 
@@ -648,8 +727,8 @@
         EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
 
         // new client request should cause VIDEO_ON
-        Vector<MediaResource> resources1;
-        resources1.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1));
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
         EXPECT_EQ(2u, mSystemCB->eventCount());
         EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
@@ -659,8 +738,8 @@
         EXPECT_EQ(2u, mSystemCB->eventCount());
 
         // new client request should cause VIDEO_ON
-        Vector<MediaResource> resources2;
-        resources2.push_back(MediaResource(MediaResource::kBattery, MediaResource::kVideoCodec, 2));
+        std::vector<MediaResourceParcel> resources2;
+        resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
         mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
         EXPECT_EQ(3u, mSystemCB->eventCount());
         EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
@@ -687,8 +766,8 @@
         EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
 
         // new client request should cause CPUSET_ENABLE
-        Vector<MediaResource> resources1;
-        resources1.push_back(MediaResource(MediaResource::kCpuBoost, 1));
+        std::vector<MediaResourceParcel> resources1;
+        resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
         mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
         EXPECT_EQ(2u, mSystemCB->eventCount());
         EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
@@ -698,8 +777,8 @@
         EXPECT_EQ(2u, mSystemCB->eventCount());
 
         // new client request should cause CPUSET_ENABLE
-        Vector<MediaResource> resources2;
-        resources2.push_back(MediaResource(MediaResource::kCpuBoost, 2));
+        std::vector<MediaResourceParcel> resources2;
+        resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
         mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
         EXPECT_EQ(3u, mSystemCB->eventCount());
         EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
@@ -738,6 +817,10 @@
     testCombineResource();
 }
 
+TEST_F(ResourceManagerServiceTest, combineResourceNegative) {
+    testCombineResourceWithNegativeValues();
+}
+
 TEST_F(ResourceManagerServiceTest, removeResource) {
     testRemoveResource();
 }
@@ -779,4 +862,5 @@
     testCpusetBoost();
 }
 
+} // namespace media
 } // namespace android