resourcemanager: define resource model
This change:
- defines a resource model interface
- defines a base resource model that implements the current (default) resource model
- integrates the resource model with the resource manager service
This change allows extending or replacing the resource models in the future.
Bug: 294886363
Test: atest android.media.misc.cts.ResourceManagerTest
atest android.media.misc.cts.ResourceManagerMultiTest
/data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
/data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Change-Id: Ifbdd3de90bf9fc5e21f2e1eaa9993dcc0983810a
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index efb042c..3ede5d2 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -74,6 +74,7 @@
name: "libresourcemanagerservice",
srcs: [
+ "DefaultResourceModel.cpp",
"ResourceManagerMetrics.cpp",
"ResourceManagerService.cpp",
"ResourceManagerServiceNew.cpp",
diff --git a/services/mediaresourcemanager/DefaultResourceModel.cpp b/services/mediaresourcemanager/DefaultResourceModel.cpp
new file mode 100644
index 0000000..7bad715
--- /dev/null
+++ b/services/mediaresourcemanager/DefaultResourceModel.cpp
@@ -0,0 +1,145 @@
+/*
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "DefaultResourceModel"
+#include <utils/Log.h>
+
+#include "ResourceManagerServiceUtils.h"
+#include "DefaultResourceModel.h"
+#include "ResourceTracker.h"
+
+namespace android {
+
+DefaultResourceModel::DefaultResourceModel(
+ const std::shared_ptr<ResourceTracker>& resourceTracker,
+ bool supportsMultipleSecureCodecs,
+ bool supportsSecureWithNonSecureCodec)
+ : mSupportsMultipleSecureCodecs(supportsMultipleSecureCodecs),
+ mSupportsSecureWithNonSecureCodec(supportsSecureWithNonSecureCodec),
+ mResourceTracker(resourceTracker) {
+}
+
+DefaultResourceModel::~DefaultResourceModel() {
+}
+
+bool DefaultResourceModel::getAllClients(
+ const ReclaimRequestInfo& reclimRequestInfo,
+ std::vector<ClientInfo>& clients) {
+
+ clients.clear();
+ MediaResourceParcel mediaResource{.type = reclimRequestInfo.mResources[0].type,
+ .subType = reclimRequestInfo.mResources[0].subType};
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+
+ // Resolve the secure-unsecure codec conflicts if there is any.
+ switch (reclimRequestInfo.mResources[0].type) {
+ case MediaResource::Type::kSecureCodec:
+ // Looking to start a secure codec.
+ // #1. Make sure if multiple secure codecs can coexist
+ if (!mSupportsMultipleSecureCodecs) {
+ if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+ // A higher priority process owns an instance of a secure codec.
+ // So this request can't be fulfilled.
+ return false;
+ }
+ }
+ // #2. Make sure a secure codec can coexist if there is an instance
+ // of non-secure codec running already.
+ if (!mSupportsSecureWithNonSecureCodec) {
+ mediaResource.type = MediaResource::Type::kNonSecureCodec;
+ if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+ // A higher priority process owns an instance of a non-secure codec.
+ // So this request can't be fulfilled.
+ return false;
+ }
+ }
+ break;
+ case MediaResource::Type::kNonSecureCodec:
+ // Looking to start a non-secure codec.
+ // Make sure a non-secure codec can coexist if there is an instance
+ // of secure codec running already.
+ if (!mSupportsSecureWithNonSecureCodec) {
+ mediaResource.type = MediaResource::Type::kSecureCodec;
+ if (!mResourceTracker->getNonConflictingClients(resourceRequestInfo, clients)) {
+ // A higher priority process owns an instance of a secure codec.
+ // So this request can't be fulfilled.
+ return false;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!clients.empty()) {
+ // There is secure/unsecure codec co-existence conflict
+ // and we have only found processes with lower priority holding the
+ // resources. So, all of these need to be reclaimed.
+ return false;
+ }
+
+ // No more resource conflicts.
+ switch (reclimRequestInfo.mResources[0].type) {
+ case MediaResource::Type::kSecureCodec:
+ case MediaResource::Type::kNonSecureCodec:
+ // Handling Codec resource reclaim
+ return getCodecClients(reclimRequestInfo, clients);
+ case MediaResource::Type::kGraphicMemory:
+ case MediaResource::Type::kDrmSession:
+ // Handling DRM and GraphicMemory resource reclaim
+ mediaResource.id = reclimRequestInfo.mResources[0].id;
+ mediaResource.value = reclimRequestInfo.mResources[0].value;
+ return mResourceTracker->getAllClients(resourceRequestInfo, clients);
+ default:
+ break;
+ }
+
+ return !clients.empty();
+}
+
+bool DefaultResourceModel::getCodecClients(
+ const ReclaimRequestInfo& reclimRequestInfo,
+ std::vector<ClientInfo>& clients) {
+ MediaResourceParcel mediaResource;
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+
+ // 1. Look to find the client(s) with the other resources, for the given
+ // primary type.
+ MediaResource::SubType primarySubType = reclimRequestInfo.mResources[0].subType;
+ for (size_t index = 1; index < reclimRequestInfo.mResources.size(); index++) {
+ mediaResource.type = reclimRequestInfo.mResources[index].type;
+ mediaResource.subType = reclimRequestInfo.mResources[index].subType;
+ mResourceTracker->getAllClients(resourceRequestInfo, clients, primarySubType);
+ }
+
+ // 2. Get all clients of the same type.
+ mediaResource.type = reclimRequestInfo.mResources[0].type;
+ mediaResource.subType = reclimRequestInfo.mResources[0].subType;
+ mResourceTracker->getAllClients(resourceRequestInfo, clients);
+
+ // 3. Get all cliends of the different type.
+ MediaResourceType otherType =
+ (reclimRequestInfo.mResources[0].type == MediaResource::Type::kSecureCodec) ?
+ MediaResource::Type::kNonSecureCodec : MediaResource::Type::kSecureCodec;
+ mediaResource.type = otherType;
+ mResourceTracker->getAllClients(resourceRequestInfo, clients);
+
+ return !clients.empty();
+}
+
+} // namespace android
diff --git a/services/mediaresourcemanager/DefaultResourceModel.h b/services/mediaresourcemanager/DefaultResourceModel.h
new file mode 100644
index 0000000..1891eda
--- /dev/null
+++ b/services/mediaresourcemanager/DefaultResourceModel.h
@@ -0,0 +1,73 @@
+/*
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_MEDIA_DEFAULTRESOURCEMODEL_H_
+#define ANDROID_MEDIA_DEFAULTRESOURCEMODEL_H_
+
+#include "IResourceModel.h"
+
+namespace android {
+
+class ResourceTracker;
+
+/*
+ * Implements the Default Resource Model that handles:
+ * - coexistence of secure codec with another secure/non-secure codecs
+ * - sharing resources among other codecs
+ */
+class DefaultResourceModel : public IResourceModel {
+public:
+ DefaultResourceModel(const std::shared_ptr<ResourceTracker>& resourceTracker,
+ bool supportsMultipleSecureCodecs = true,
+ bool supportsSecureWithNonSecureCodec = true);
+ virtual ~DefaultResourceModel();
+
+ /*
+ * Set the codec co-existence properties
+ */
+ void config(bool supportsMultipleSecureCodecs, bool supportsSecureWithNonSecureCodec) {
+ mSupportsMultipleSecureCodecs = supportsMultipleSecureCodecs;
+ mSupportsSecureWithNonSecureCodec = supportsSecureWithNonSecureCodec;
+ }
+
+ /*
+ * Get a list of all clients that holds the resources requested.
+ * This implementation uses the ResourceModel to select the clients.
+ *
+ * @param[in] reclaimRequestInfo Information about the Reclaim request
+ * @param[out] cliens The list of clients that hold the resources in question.
+ *
+ * @return true if there aren't any resource conflicts and false otherwise.
+ */
+ bool getAllClients(const ReclaimRequestInfo& reclaimRequestInfo,
+ std::vector<ClientInfo>& clients) override;
+
+protected:
+ bool getCodecClients(const ReclaimRequestInfo& reclaimRequestInfo,
+ std::vector<ClientInfo>& clients);
+
+protected:
+ // Keeping these protected to allow extending this implementation
+ // by other resource models.
+ bool mSupportsMultipleSecureCodecs;
+ bool mSupportsSecureWithNonSecureCodec;
+ std::shared_ptr<ResourceTracker> mResourceTracker;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_DEFAULTRESOURCEMODEL_H_
diff --git a/services/mediaresourcemanager/IResourceModel.h b/services/mediaresourcemanager/IResourceModel.h
new file mode 100644
index 0000000..f865f54
--- /dev/null
+++ b/services/mediaresourcemanager/IResourceModel.h
@@ -0,0 +1,67 @@
+/*
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_MEDIA_IRESOURCEMODEL_H_
+#define ANDROID_MEDIA_IRESOURCEMODEL_H_
+
+#include <memory>
+#include <vector>
+
+#include <aidl/android/media/IResourceManagerClient.h>
+#include <aidl/android/media/MediaResourceParcel.h>
+
+namespace android {
+
+struct ClientInfo;
+struct ReclaimRequestInfo;
+
+/*
+ * Interface that defines Resource Model.
+ *
+ * This provides an interface that manages the resource model.
+ * The primary functionality of the implementation of this resource model is to:
+ * 1. Define a resource model for a device (or family of devices)
+ * For example (and not limited to):
+ * - Can a secure codec coexist with another secure or unsecured codec?
+ * - How many codecs can coexist?
+ * - Can one type of codecs (for example avc) coexist with another type of codec
+ * (for example hevc) independently? OR are they sharing the common
+ * resource pool?
+ * 2. Provide a list of clients that hold requesting resources.
+ */
+class IResourceModel {
+public:
+ IResourceModel() {}
+
+ virtual ~IResourceModel() {}
+
+ /*
+ * Get a list of all clients that holds the resources requested.
+ * This implementation uses the ResourceModel to select the clients.
+ *
+ * @param[in] reclaimRequestInfo Information about the Reclaim request
+ * @param[out] clients The list of clients that hold the resources in question.
+ *
+ * @return true if there aren't any resource conflicts and false otherwise.
+ */
+ virtual bool getAllClients(const ReclaimRequestInfo& reclaimRequestInfo,
+ std::vector<ClientInfo>& clients) = 0;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_IRESOURCEMODEL_H_
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 3e0ac84..4bdb6e1 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -491,6 +491,111 @@
}
}
+bool ResourceManagerService::getTargetClients(
+ int32_t callingPid,
+ const std::vector<MediaResourceParcel>& resources,
+ std::vector<ClientInfo>& targetClients) {
+ std::scoped_lock lock{mLock};
+ if (!mProcessInfo->isPidTrusted(callingPid)) {
+ pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
+ callingPid, actualCallingPid);
+ callingPid = actualCallingPid;
+ }
+ const MediaResourceParcel *secureCodec = NULL;
+ const MediaResourceParcel *nonSecureCodec = NULL;
+ const MediaResourceParcel *graphicMemory = NULL;
+ const MediaResourceParcel *drmSession = NULL;
+ for (size_t i = 0; i < resources.size(); ++i) {
+ switch (resources[i].type) {
+ case MediaResource::Type::kSecureCodec:
+ secureCodec = &resources[i];
+ break;
+ case MediaResource::Type::kNonSecureCodec:
+ nonSecureCodec = &resources[i];
+ break;
+ case MediaResource::Type::kGraphicMemory:
+ graphicMemory = &resources[i];
+ break;
+ case MediaResource::Type::kDrmSession:
+ drmSession = &resources[i];
+ break;
+ default:
+ break;
+ }
+ }
+
+ // first pass to handle secure/non-secure codec conflict
+ if (secureCodec != NULL) {
+ MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
+ .subType = secureCodec->subType};
+ ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ if (!mSupportsMultipleSecureCodecs) {
+ if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+ return false;
+ }
+ }
+ if (!mSupportsSecureWithNonSecureCodec) {
+ mediaResource.type = MediaResource::Type::kNonSecureCodec;
+ if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+ return false;
+ }
+ }
+ }
+ if (nonSecureCodec != NULL) {
+ if (!mSupportsSecureWithNonSecureCodec) {
+ MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
+ .subType = nonSecureCodec->subType};
+ ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ if (!getAllClients_l(resourceRequestInfo, targetClients)) {
+ return false;
+ }
+ }
+ }
+
+ if (drmSession != NULL) {
+ ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ if (targetClients.size() == 0) {
+ return false;
+ }
+ }
+
+ if (targetClients.size() == 0 && graphicMemory != nullptr) {
+ // if no secure/non-secure codec conflict, run second pass to handle other resources.
+ ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ }
+
+ if (targetClients.size() == 0) {
+ // if we are here, run the third pass to free one codec with the same type.
+ if (secureCodec != nullptr) {
+ ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ }
+ if (nonSecureCodec != nullptr) {
+ ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ }
+ }
+
+ if (targetClients.size() == 0) {
+ // if we are here, run the fourth pass to free one codec with the different type.
+ if (secureCodec != nullptr) {
+ MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
+ ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ }
+ if (nonSecureCodec != nullptr) {
+ MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
+ ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ getClientForResource_l(resourceRequestInfo, targetClients);
+ }
+ }
+
+ return !targetClients.empty();
+}
+
Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
int32_t callingPid = clientInfo.pid;
@@ -500,105 +605,16 @@
mServiceLog->add(log);
*_aidl_return = false;
+ // Check if there are any resources to be reclaimed before processing.
+ if (resources.empty()) {
+ return Status::ok();
+ }
+
std::vector<ClientInfo> targetClients;
- {
- std::scoped_lock lock{mLock};
- if (!mProcessInfo->isPidTrusted(callingPid)) {
- pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
- ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
- callingPid, actualCallingPid);
- callingPid = actualCallingPid;
- }
- const MediaResourceParcel *secureCodec = NULL;
- const MediaResourceParcel *nonSecureCodec = NULL;
- const MediaResourceParcel *graphicMemory = NULL;
- const MediaResourceParcel *drmSession = NULL;
- for (size_t i = 0; i < resources.size(); ++i) {
- switch (resources[i].type) {
- case MediaResource::Type::kSecureCodec:
- secureCodec = &resources[i];
- break;
- case MediaResource::Type::kNonSecureCodec:
- nonSecureCodec = &resources[i];
- break;
- case MediaResource::Type::kGraphicMemory:
- graphicMemory = &resources[i];
- break;
- case MediaResource::Type::kDrmSession:
- drmSession = &resources[i];
- break;
- default:
- break;
- }
- }
-
- // first pass to handle secure/non-secure codec conflict
- if (secureCodec != NULL) {
- MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
- .subType = secureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
- if (!mSupportsMultipleSecureCodecs) {
- if (!getAllClients_l(resourceRequestInfo, targetClients)) {
- return Status::ok();
- }
- }
- if (!mSupportsSecureWithNonSecureCodec) {
- mediaResource.type = MediaResource::Type::kNonSecureCodec;
- if (!getAllClients_l(resourceRequestInfo, targetClients)) {
- return Status::ok();
- }
- }
- }
- if (nonSecureCodec != NULL) {
- if (!mSupportsSecureWithNonSecureCodec) {
- MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
- .subType = nonSecureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
- if (!getAllClients_l(resourceRequestInfo, targetClients)) {
- return Status::ok();
- }
- }
- }
-
- if (drmSession != NULL) {
- ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
- getClientForResource_l(resourceRequestInfo, targetClients);
- if (targetClients.size() == 0) {
- return Status::ok();
- }
- }
-
- if (targetClients.size() == 0 && graphicMemory != nullptr) {
- // if no secure/non-secure codec conflict, run second pass to handle other resources.
- ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
- getClientForResource_l(resourceRequestInfo, targetClients);
- }
-
- if (targetClients.size() == 0) {
- // if we are here, run the third pass to free one codec with the same type.
- if (secureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
- getClientForResource_l(resourceRequestInfo, targetClients);
- }
- if (nonSecureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
- getClientForResource_l(resourceRequestInfo, targetClients);
- }
- }
-
- if (targetClients.size() == 0) {
- // if we are here, run the fourth pass to free one codec with the different type.
- if (secureCodec != nullptr) {
- MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
- getClientForResource_l(resourceRequestInfo, targetClients);
- }
- if (nonSecureCodec != nullptr) {
- MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
- getClientForResource_l(resourceRequestInfo, targetClients);
- }
- }
+ if (!getTargetClients(callingPid, resources, targetClients)) {
+ // Nothing to reclaim from.
+ ALOGI("%s: There aren't any clients to reclaim from", __func__);
+ return Status::ok();
}
*_aidl_return = reclaimUnconditionallyFrom(targetClients);
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index dcc0bb5..44ed005 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -137,22 +137,30 @@
friend class DeathNotifier;
friend class OverrideProcessInfoDeathNotifier;
- // Gets the client who owns specified resource type from lowest possible priority process.
- // Returns false if the calling process priority is not higher than the lowest process
- // priority. The client will remain unchanged if returns false.
- bool getLowestPriorityBiggestClient_l(
- const ResourceRequestInfo& resourceRequestInfo,
- ClientInfo& clientInfo);
+ // Gets the client who owns biggest piece of specified resource type from pid.
+ // Returns false with no change to client if there are no clients holding resources of this
+ // type.
+ bool getBiggestClient_l(int pid, MediaResource::Type type,
+ MediaResource::SubType subType,
+ ClientInfo& clientsInfo,
+ bool pendingRemovalOnly = false);
- // Same method as above, but with pendingRemovalOnly as true.
+ // A helper function that gets the biggest clients of the process pid that
+ // is marked to be (pending) removed and has the needed resources.
bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
MediaResource::SubType subType,
ClientInfo& clientsInfo);
- // A helper function basically calls getLowestPriorityBiggestClient_l and adds
- // the result client to the given Vector.
+ // From the list of clients, pick/select client(s) based on the reclaim policy.
void getClientForResource_l(const ResourceRequestInfo& resourceRequestInfo,
std::vector<ClientInfo>& clientsInfo);
+ // A helper function that pushes Reclaim Atom (for metric collection).
+ void pushReclaimAtom(const ClientInfoParcel& clientInfo,
+ const std::vector<ClientInfo>& targetClients,
+ bool reclaimed);
+
+ // Remove the override info for the given process
+ void removeProcessInfoOverride_l(int pid);
// Eventually we want to phase out this implementation of IResourceManagerService
// (ResourceManagerService) and replace that with the newer implementation
@@ -163,22 +171,30 @@
// Initializes the internal state of the ResourceManagerService
virtual void init();
+ // Gets the list of all the clients who own the list of specified resource type
+ // and satisfy the resource model and the reclaim policy.
+ virtual bool getTargetClients(
+ int32_t callingPid,
+ const std::vector<MediaResourceParcel>& resources,
+ std::vector<ClientInfo>& targetClients);
+
// Gets the list of all the clients who own the specified resource type.
// Returns false if any client belongs to a process with higher priority than the
// calling process. The clients will remain unchanged if returns false.
virtual bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
std::vector<ClientInfo>& clientsInfo);
- // Gets the client who owns biggest piece of specified resource type from pid.
- // Returns false with no change to client if there are no clients holding resources of this
- // type.
- virtual bool getBiggestClient_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType,
- ClientInfo& clientsInfo,
- bool pendingRemovalOnly = false);
+ // Gets the client who owns specified resource type from lowest possible priority process.
+ // Returns false if the calling process priority is not higher than the lowest process
+ // priority. The client will remain unchanged if returns false.
+ virtual bool getLowestPriorityBiggestClient_l(
+ const ResourceRequestInfo& resourceRequestInfo,
+ ClientInfo& clientInfo);
+ // override the pid of given process
virtual bool overridePid_l(int32_t originalPid, int32_t newPid);
+ // override the process info of given process
virtual bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
int pid, int procState, int oomScore);
@@ -203,14 +219,8 @@
// Get all the resource status for dump
virtual void getResourceDump(std::string& resourceLog) const;
- void removeProcessInfoOverride_l(int pid);
-
- // A helper function that pushes Reclaim Atom (for metric collection).
- void pushReclaimAtom(const ClientInfoParcel& clientInfo,
- const std::vector<ClientInfo>& targetClients,
- bool reclaimed);
-
// The following utility functions are used only for testing by ResourceManagerServiceTest
+ // START: TEST only functions
// Get the peak concurrent pixel count (associated with the video codecs) for the process.
long getPeakConcurrentPixelCount(int pid) const;
// Get the current concurrent pixel count (associated with the video codecs) for the process.
@@ -223,6 +233,7 @@
virtual const std::map<int, ResourceInfos>& getResourceMap() const {
return mMap;
}
+ // END: TEST only functions
protected:
mutable std::mutex mLock;
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
index 045aa3d..a819237 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
@@ -18,7 +18,10 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "ResourceManagerServiceNew"
#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <mediautils/ProcessInfo.h>
+#include "DefaultResourceModel.h"
#include "ResourceManagerServiceNew.h"
#include "ResourceTracker.h"
#include "ServiceLog.h"
@@ -36,10 +39,29 @@
// Create the Resource Tracker
mResourceTracker = std::make_shared<ResourceTracker>(ref<ResourceManagerServiceNew>(),
mProcessInfo);
+ setUpResourceModels();
+}
+
+void ResourceManagerServiceNew::setUpResourceModels() {
+ std::scoped_lock lock{mLock};
+ // Create/Configure the default resource model.
+ if (mDefaultResourceModel == nullptr) {
+ mDefaultResourceModel = std::make_unique<DefaultResourceModel>(
+ mResourceTracker,
+ mSupportsMultipleSecureCodecs,
+ mSupportsSecureWithNonSecureCodec);
+ } else {
+ DefaultResourceModel* resourceModel =
+ static_cast<DefaultResourceModel*>(mDefaultResourceModel.get());
+ resourceModel->config(mSupportsMultipleSecureCodecs, mSupportsSecureWithNonSecureCodec);
+ }
}
Status ResourceManagerServiceNew::config(const std::vector<MediaResourcePolicyParcel>& policies) {
- return ResourceManagerService::config(policies);
+ Status status = ResourceManagerService::config(policies);
+ // Change in the config dictates update to the resource model.
+ setUpResourceModels();
+ return status;
}
void ResourceManagerServiceNew::setObserverService(
@@ -194,6 +216,120 @@
return ResourceManagerService::dump(fd, args, numArgs);
}
+bool ResourceManagerServiceNew::getTargetClients(
+ int callingPid,
+ const std::vector<MediaResourceParcel>& resources,
+ std::vector<ClientInfo>& targetClients) {
+ std::scoped_lock lock{mLock};
+ if (!mProcessInfo->isPidTrusted(callingPid)) {
+ pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
+ callingPid, actualCallingPid);
+ callingPid = actualCallingPid;
+ }
+
+ // Use the Resource Model to get a list of all the clients that hold the
+ // needed/requested resources.
+ ReclaimRequestInfo reclaimRequestInfo{callingPid, resources};
+ std::vector<ClientInfo> clients;
+ if (!mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients)) {
+ if (clients.empty()) {
+ ALOGI("%s: There aren't any clients with given resources. Nothing to reclaim",
+ __func__);
+ return false;
+ }
+ // Since there was a conflict, we need to reclaim all elements.
+ targetClients = std::move(clients);
+ } else {
+ getClientForResource_l(reclaimRequestInfo, clients, targetClients);
+ }
+ return !targetClients.empty();
+}
+
+void ResourceManagerServiceNew::getClientForResource_l(
+ const ReclaimRequestInfo& reclaimRequestInfo,
+ const std::vector<ClientInfo>& clients,
+ std::vector<ClientInfo>& targetClients) {
+ int callingPid = reclaimRequestInfo.mCallingPid;
+
+ // Before looking into other processes, check if we have clients marked for
+ // pending removal in the same process.
+ ClientInfo targetClient;
+ for (const MediaResourceParcel& resource : reclaimRequestInfo.mResources) {
+ if (mResourceTracker->getBiggestClientPendingRemoval(callingPid, resource.type,
+ resource.subType, targetClient)) {
+ targetClients.emplace_back(targetClient);
+ return;
+ }
+ }
+
+ // Now find client(s) from a lowest priority process that has needed resources.
+ ResourceRequestInfo resourceRequestInfo {callingPid, nullptr};
+ for (const MediaResourceParcel& resource : reclaimRequestInfo.mResources) {
+ resourceRequestInfo.mResource = &resource;
+ if (getLowestPriorityProcessBiggestClient_l(resourceRequestInfo, clients, targetClient)) {
+ targetClients.emplace_back(targetClient);
+ return;
+ }
+ }
+}
+
+// Process priority (oom score) based reclaim:
+// - Find a process with lowest priority (than that of calling process).
+// - Find the bigegst client (with required resources) from that process.
+bool ResourceManagerServiceNew::getLowestPriorityProcessBiggestClient_l(
+ const ResourceRequestInfo& resourceRequestInfo,
+ const std::vector<ClientInfo>& clients,
+ ClientInfo& clientInfo) {
+ int callingPid = resourceRequestInfo.mCallingPid;
+ MediaResource::Type type = resourceRequestInfo.mResource->type;
+ MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
+ int lowestPriorityPid;
+ int lowestPriority;
+ int callingPriority;
+
+ if (!mResourceTracker->getPriority(callingPid, &callingPriority)) {
+ ALOGE("%s: can't get process priority for pid %d", __func__, callingPid);
+ return false;
+ }
+
+ // Find the lowest priority process among all the clients.
+ if (!mResourceTracker->getLowestPriorityPid(clients, lowestPriorityPid, lowestPriority)) {
+ ALOGE("%s: can't find a process with lower priority than that of the process[%d:%d]",
+ __func__, callingPid, callingPriority);
+ return false;
+ }
+
+ if (lowestPriority <= callingPriority) {
+ ALOGE("%s: lowest priority %d vs caller priority %d",
+ __func__, lowestPriority, callingPriority);
+ return false;
+ }
+
+ // Get the biggest client from this process.
+ if (!mResourceTracker->getBiggestClient(lowestPriorityPid, type, subType, clientInfo)) {
+ return false;
+ }
+
+ ALOGI("%s: CallingProcess(%d:%d) will reclaim from the lowestPriorityProcess(%d:%d)",
+ __func__, callingPid, callingPriority, lowestPriorityPid, lowestPriority);
+ return true;
+}
+
+bool ResourceManagerServiceNew::getLowestPriorityBiggestClient_l(
+ const ResourceRequestInfo& resourceRequestInfo,
+ ClientInfo& clientInfo) {
+ //NOTE: This function is used only by the test: ResourceManagerServiceTest
+ if (resourceRequestInfo.mResource == nullptr) {
+ return false;
+ }
+ std::vector<MediaResourceParcel> resources{*resourceRequestInfo.mResource};
+ ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid, resources};
+ std::vector<ClientInfo> clients;
+ mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients);
+ return getLowestPriorityProcessBiggestClient_l(resourceRequestInfo, clients, clientInfo);
+}
+
bool ResourceManagerServiceNew::getPriority_l(int pid, int* priority) const {
return mResourceTracker->getPriority(pid, priority);
}
@@ -201,22 +337,18 @@
bool ResourceManagerServiceNew::getLowestPriorityPid_l(
MediaResource::Type type, MediaResource::SubType subType,
int* lowestPriorityPid, int* lowestPriority) {
+ //NOTE: This function is used only by the test: ResourceManagerServiceTest
return mResourceTracker->getLowestPriorityPid(type, subType,
*lowestPriorityPid,
*lowestPriority);
}
-bool ResourceManagerServiceNew::getBiggestClient_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, ClientInfo& clientInfo, bool pendingRemovalOnly) {
- return mResourceTracker->getBiggestClient(pid, type, subType,
- clientInfo, pendingRemovalOnly);
-}
-
bool ResourceManagerServiceNew::getAllClients_l(
const ResourceRequestInfo& resourceRequestInfo,
std::vector<ClientInfo>& clientsInfo) {
+ //NOTE: This function is used only by the test: ResourceManagerServiceTest
MediaResource::Type type = resourceRequestInfo.mResource->type;
- // Get list of all the clients that has requested resources.
+ // Get the list of all clients that has requested resources.
std::vector<ClientInfo> clients;
mResourceTracker->getAllClients(resourceRequestInfo, clients);
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.h b/services/mediaresourcemanager/ResourceManagerServiceNew.h
index cd781e4..8522c4b 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.h
@@ -22,6 +22,7 @@
namespace android {
+class IResourceModel;
class ResourceTracker;
//
@@ -82,12 +83,37 @@
private:
+ // Set up the Resource models.
+ void setUpResourceModels();
+
+ // From the list of clients, pick/select client(s) based on the reclaim policy.
+ void getClientForResource_l(
+ const ReclaimRequestInfo& reclaimRequestInfo,
+ const std::vector<ClientInfo>& clients,
+ std::vector<ClientInfo>& targetClients);
+
+ // Gets the client who owns specified resource type from lowest possible priority process.
+ // Returns false if the calling process priority is not higher than the lowest process
+ // priority. The client will remain unchanged if returns false.
+ bool getLowestPriorityProcessBiggestClient_l(
+ const ResourceRequestInfo& resourceRequestInfo,
+ const std::vector<ClientInfo>& clients,
+ ClientInfo& clientInfo);
+
// Initializes the internal state of the ResourceManagerService
void init() override;
void setObserverService(
const std::shared_ptr<ResourceObserverService>& observerService) override;
+ // Gets the list of all the clients who own the specified resource type.
+ // Returns false if any client belongs to a process with higher priority than the
+ // calling process. The clients will remain unchanged if returns false.
+ bool getTargetClients(
+ int32_t callingPid,
+ const std::vector<MediaResourceParcel>& resources,
+ std::vector<ClientInfo>& targetClients) override;
+
// Removes the pid from the override map.
void removeProcessInfoOverride(int pid) override;
@@ -97,16 +123,18 @@
bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
std::vector<ClientInfo>& clientsInfo) override;
- // Gets the client who owns biggest piece of specified resource type from pid.
- // Returns false with no change to client if there are no clients holding resources of this
- // type.
- bool getBiggestClient_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType,
- ClientInfo& clientsInfo,
- bool pendingRemovalOnly = false) override;
+ // Gets the client who owns specified resource type from lowest possible priority process.
+ // Returns false if the calling process priority is not higher than the lowest process
+ // priority. The client will remain unchanged if returns false.
+ // This function is used only by the unit test.
+ bool getLowestPriorityBiggestClient_l(
+ const ResourceRequestInfo& resourceRequestInfo,
+ ClientInfo& clientInfo) override;
+ // override the pid of given process
bool overridePid_l(int32_t originalPid, int32_t newPid) override;
+ // override the process info of given process
bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
int pid, int procState, int oomScore) override;
@@ -135,6 +163,7 @@
private:
std::shared_ptr<ResourceTracker> mResourceTracker;
+ std::unique_ptr<IResourceModel> mDefaultResourceModel;
};
// ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
index 8d03143..55ea149 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -18,6 +18,8 @@
#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
+#include <map>
+#include <memory>
#include <vector>
#include <aidl/android/media/BnResourceManagerService.h>
@@ -123,6 +125,16 @@
};
/*
+ * Resource Reclaim request info that encapsulates
+ * - the calling/requesting process pid.
+ * - the list of resources requesting (to be reclaimed from others)
+ */
+struct ReclaimRequestInfo {
+ int mCallingPid = -1;
+ const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
+};
+
+/*
* Resource request info that encapsulates
* - the calling/requesting process pid.
* - the resource requesting (to be reclaimed from others)
diff --git a/services/mediaresourcemanager/ResourceTracker.cpp b/services/mediaresourcemanager/ResourceTracker.cpp
index c6255a2..2f93571 100644
--- a/services/mediaresourcemanager/ResourceTracker.cpp
+++ b/services/mediaresourcemanager/ResourceTracker.cpp
@@ -27,6 +27,45 @@
namespace android {
+inline bool isHwCodec(MediaResource::SubType subType) {
+ return subType == MediaResource::SubType::kHwImageCodec ||
+ subType == MediaResource::SubType::kHwVideoCodec;
+}
+
+// Check whether a given resource (of type and subtype) is found in given resource list
+// that also has the given Primary SubType.
+static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ const ResourceList& resources, MediaResource::SubType primarySubType) {
+ bool foundResource = false;
+ bool matchedPrimary =
+ (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ? true : false;
+ for (auto it = resources.begin(); it != resources.end(); it++) {
+ if (hasResourceType(type, subType, it->second)) {
+ foundResource = true;
+ } else if (it->second.subType == primarySubType) {
+ matchedPrimary = true;
+ } else if (isHwCodec(it->second.subType) == isHwCodec(primarySubType)) {
+ matchedPrimary = true;
+ }
+ if (matchedPrimary && foundResource) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// See if the given client is already in the list of clients.
+inline bool contains(const std::vector<ClientInfo>& clients, const int64_t& clientId) {
+ std::vector<ClientInfo>::const_iterator found =
+ std::find_if(clients.begin(), clients.end(),
+ [clientId](const ClientInfo& client) -> bool {
+ return client.mClientId == clientId;
+ });
+
+ return found != clients.end();
+}
+
+
ResourceTracker::ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew>& service,
const sp<ProcessInfoInterface>& processInfo) :
mService(service),
@@ -297,8 +336,10 @@
MediaResource::SubType::kHwImageCodec,
MediaResource::SubType::kSwImageCodec}) {
ClientInfo clientInfo;
- if (getBiggestClient(pid, type, subType, clientInfo, true)) {
- targetClients.emplace_back(clientInfo);
+ if (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
+ if (!contains(targetClients, clientInfo.mClientId)) {
+ targetClients.emplace_back(clientInfo);
+ }
continue;
}
}
@@ -307,8 +348,10 @@
default:
ClientInfo clientInfo;
MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
- if (getBiggestClient(pid, type, subType, clientInfo, true)) {
- targetClients.emplace_back(clientInfo);
+ if (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
+ if (!contains(targetClients, clientInfo.mClientId)) {
+ targetClients.emplace_back(clientInfo);
+ }
}
break;
}
@@ -358,16 +401,19 @@
}
bool ResourceTracker::getAllClients(const ResourceRequestInfo& resourceRequestInfo,
- std::vector<ClientInfo>& clients) {
+ std::vector<ClientInfo>& clients,
+ MediaResource::SubType primarySubType) {
MediaResource::Type type = resourceRequestInfo.mResource->type;
MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
bool foundClient = false;
for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
for (auto& [id, /* ResourceInfo */ info] : infos) {
- if (hasResourceType(type, subType, info.resources)) {
- clients.emplace_back(info.pid, info.uid, info.clientId);
- foundClient = true;
+ if (hasResourceType(type, subType, info.resources, primarySubType)) {
+ if (!contains(clients, info.clientId)) {
+ clients.emplace_back(info.pid, info.uid, info.clientId);
+ foundClient = true;
+ }
}
}
}
@@ -410,12 +456,38 @@
return success;
}
-bool ResourceTracker::getBiggestClient(int pid, MediaResource::Type type,
- MediaResource::SubType subType,
- ClientInfo& clientInfo, bool pendingRemovalOnly) {
+bool ResourceTracker::getLowestPriorityPid(const std::vector<ClientInfo>& clients,
+ int& lowestPriorityPid, int& lowestPriority) {
+ int pid = -1;
+ int priority = -1;
+ for (const ClientInfo& client : clients) {
+ int tempPriority = -1;
+ if (!getPriority(client.mPid, &tempPriority)) {
+ ALOGV("%s: can't get priority of pid %d, skipped", __func__, client.mPid);
+ // TODO: remove this pid from mMap?
+ continue;
+ }
+ if (pid == -1 || tempPriority > priority) {
+ // initial the value
+ pid = client.mPid;
+ priority = tempPriority;
+ }
+ }
+
+ bool success = (pid != -1);
+
+ if (success) {
+ lowestPriorityPid = pid;
+ lowestPriority = priority;
+ }
+ return success;
+}
+
+bool ResourceTracker::getBiggestClientPendingRemoval(int pid, MediaResource::Type type,
+ MediaResource::SubType subType,
+ ClientInfo& clientInfo) {
std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
if (found == mMap.end()) {
- ALOGE_IF(!pendingRemovalOnly, "%s: can't find resource info for pid %d", __func__, pid);
return false;
}
@@ -425,10 +497,48 @@
const ResourceInfos& infos = found->second;
for (const auto& [id, /* ResourceInfo */ info] : infos) {
const ResourceList& resources = info.resources;
- if (pendingRemovalOnly && !info.pendingRemoval) {
+ // Skip if the client is not marked pending removal.
+ if (!info.pendingRemoval) {
continue;
}
for (auto it = resources.begin(); it != resources.end(); it++) {
+ const MediaResourceParcel& resource = it->second;
+ if (hasResourceType(type, subType, resource)) {
+ if (resource.value > largestValue) {
+ largestValue = resource.value;
+ clientId = info.clientId;
+ uid = info.uid;
+ }
+ }
+ }
+ }
+
+ if (clientId == -1) {
+ return false;
+ }
+
+ clientInfo.mPid = pid;
+ clientInfo.mUid = uid;
+ clientInfo.mClientId = clientId;
+ return true;
+}
+
+bool ResourceTracker::getBiggestClient(int pid, MediaResource::Type type,
+ MediaResource::SubType subType,
+ ClientInfo& clientInfo) {
+ std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+ if (found == mMap.end()) {
+ ALOGE("%s: can't find resource info for pid %d", __func__, pid);
+ return false;
+ }
+
+ uid_t uid = -1;
+ int64_t clientId = -1;
+ uint64_t largestValue = 0;
+ const ResourceInfos& infos = found->second;
+ for (const auto& [id, info] : infos) {
+ const ResourceList& resources = info.resources;
+ for (auto it = resources.begin(); it != resources.end(); it++) {
const MediaResourceParcel &resource = it->second;
if (hasResourceType(type, subType, resource)) {
if (resource.value > largestValue) {
@@ -441,9 +551,8 @@
}
if (clientId == -1) {
- ALOGE_IF(!pendingRemovalOnly,
- "%s: can't find resource type %s and subtype %s for pid %d",
- __func__, asString(type), asString(subType), pid);
+ ALOGE("%s: can't find resource type %s and subtype %s for pid %d",
+ __func__, asString(type), asString(subType), pid);
return false;
}
diff --git a/services/mediaresourcemanager/ResourceTracker.h b/services/mediaresourcemanager/ResourceTracker.h
index 06fb914..eb89d12 100644
--- a/services/mediaresourcemanager/ResourceTracker.h
+++ b/services/mediaresourcemanager/ResourceTracker.h
@@ -109,12 +109,15 @@
void removeProcessInfoOverride(int pid);
// Find all clients that have given resources.
+ // If applicable, match the primary type too.
// The |clients| (list) isn't cleared by this function to allow calling this
// function multiple times for different resources.
// returns true upon finding at lease one client with the given resource request info,
// false otherwise (no clients)
- bool getAllClients(const ResourceRequestInfo& resourceRequestInfo,
- std::vector<ClientInfo>& clients);
+ bool getAllClients(
+ const ResourceRequestInfo& resourceRequestInfo,
+ std::vector<ClientInfo>& clients,
+ MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType);
// Look for the lowest priority process with the given resources.
// Upon success lowestPriorityPid and lowestPriority are
@@ -124,6 +127,18 @@
bool getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
int& lowestPriorityPid, int& lowestPriority);
+ // Look for the lowest priority process with the given client list.
+ // returns true on success, false otherwise.
+ bool getLowestPriorityPid(const std::vector<ClientInfo>& clients,
+ int& lowestPriorityPid, int& lowestPriority);
+
+ // Find the biggest client of the given process with given resources,
+ // that is marked as pending to be removed.
+ // returns true on success, false otherwise.
+ bool getBiggestClientPendingRemoval(
+ int pid, MediaResource::Type type, MediaResource::SubType subType,
+ ClientInfo& clientInfo);
+
// Find the biggest client of the given process with given resources.
// If pendingRemovalOnly is set, then it will look for only those clients
// that are marked for removing.
@@ -131,7 +146,7 @@
// Upon failure to find a client, it will return false without updating
// clientInfo.
bool getBiggestClient(int pid, MediaResource::Type type, MediaResource::SubType subType,
- ClientInfo& clientInfo, bool pendingRemovalOnly = false);
+ ClientInfo& clientInfo);
// Find the client that belongs to given process(pid) and with the given clientId.
// A nullptr is returned upon failure to find the client.
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 58ddf1a..9d4beef 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -79,6 +79,18 @@
public:
ResourceManagerServiceTest(bool newRM = false) : ResourceManagerServiceTestBase(newRM) {}
+ void updateConfig(bool bSupportsMultipleSecureCodecs, bool bSupportsSecureWithNonSecureCodec) {
+ std::vector<MediaResourcePolicyParcel> policies;
+ policies.push_back(
+ MediaResourcePolicy(
+ IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
+ bSupportsMultipleSecureCodecs ? "true" : "false"));
+ policies.push_back(
+ MediaResourcePolicy(
+ IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
+ bSupportsSecureWithNonSecureCodec ? "true" : "false"));
+ mService->config(policies);
+ }
// test set up
// ---------------------------------------------------------------------------------
@@ -213,29 +225,11 @@
EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
- std::vector<MediaResourcePolicyParcel> policies1;
- policies1.push_back(
- MediaResourcePolicy(
- IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
- "true"));
- policies1.push_back(
- MediaResourcePolicy(
- IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
- "false"));
- mService->config(policies1);
+ updateConfig(true, false);
EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
- std::vector<MediaResourcePolicyParcel> policies2;
- policies2.push_back(
- MediaResourcePolicy(
- IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
- "false"));
- policies2.push_back(
- MediaResourcePolicy(
- IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
- "true"));
- mService->config(policies2);
+ updateConfig(false, true);
EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
}
@@ -339,8 +333,7 @@
// ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = false;
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(false, true);
// priority too low to reclaim resource
ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
@@ -374,7 +367,7 @@
.name = "none"};
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -402,7 +395,7 @@
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -428,7 +421,7 @@
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
mService->markClientForPendingRemoval(client2Info);
@@ -520,8 +513,7 @@
// ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = false;
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(false, true);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -546,8 +538,7 @@
// ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = false;
- mService->mSupportsSecureWithNonSecureCodec = false;
+ updateConfig(false, false);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -567,8 +558,7 @@
// ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = true;
- mService->mSupportsSecureWithNonSecureCodec = false;
+ updateConfig(true, false);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -599,8 +589,7 @@
// ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = true;
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -630,8 +619,7 @@
// ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsMultipleSecureCodecs = true;
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -677,7 +665,7 @@
// ### secure codec can't coexist with non-secure codec ###
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = false;
+ updateConfig(true, false);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -703,7 +691,7 @@
// ### secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
// priority too low
CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
@@ -733,7 +721,7 @@
// ### secure codec can coexist with non-secure codec ###
{
addResource();
- mService->mSupportsSecureWithNonSecureCodec = true;
+ updateConfig(true, true);
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));