1 /*
2 **
3 ** Copyright 2023, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "ClientImportanceReclaimPolicy"
20 #include <utils/Log.h>
21
22 #include "ResourceTracker.h"
23 #include "ResourceManagerService.h"
24 #include "ClientImportanceReclaimPolicy.h"
25
26 namespace android {
27
28 using aidl::android::media::IResourceManagerClient;
29
ClientImportanceReclaimPolicy(const std::shared_ptr<ResourceTracker> & resourceTracker)30 ClientImportanceReclaimPolicy::ClientImportanceReclaimPolicy(
31 const std::shared_ptr<ResourceTracker>& resourceTracker)
32 : mResourceTracker(resourceTracker) {
33 }
34
~ClientImportanceReclaimPolicy()35 ClientImportanceReclaimPolicy::~ClientImportanceReclaimPolicy() {
36 }
37
38 // Find the biggest client from the same process with the lowest importance
39 // than that of the requesting client.
getClients(const ReclaimRequestInfo & reclaimRequestInfo,const std::vector<ClientInfo> & clients,std::vector<ClientInfo> & targetClients)40 bool ClientImportanceReclaimPolicy::getClients(const ReclaimRequestInfo& reclaimRequestInfo,
41 const std::vector<ClientInfo>& clients,
42 std::vector<ClientInfo>& targetClients) {
43 pid_t callingPid = reclaimRequestInfo.mCallingPid;
44 int32_t callingImportance = reclaimRequestInfo.mCallingClientImportance;
45 MediaResource::Type type = reclaimRequestInfo.mResources[0].type;
46 MediaResource::SubType subType = reclaimRequestInfo.mResources[0].subType;
47 ClientInfo targetClient;
48 // Look to find the biggest client with lowest importance from the same process that
49 // has the other resources and with the given primary type.
50 bool found = false;
51 MediaResource::SubType primarySubType = subType;
52 for (size_t index = 1; !found && (index < reclaimRequestInfo.mResources.size()); index++) {
53 MediaResource::Type type = reclaimRequestInfo.mResources[index].type;
54 MediaResource::SubType subType = reclaimRequestInfo.mResources[index].subType;
55 found = mResourceTracker->getLeastImportantBiggestClient(
56 callingPid, callingImportance,
57 type, subType, primarySubType,
58 clients, targetClient);
59 }
60 // If no success, then select the biggest client of primary type with lowest importance
61 // from the same process.
62 if (!found) {
63 found = mResourceTracker->getLeastImportantBiggestClient(
64 callingPid, callingImportance,
65 type, subType, MediaResource::SubType::kUnspecifiedSubType,
66 clients, targetClient);
67 }
68 // If we haven't found a client yet, then select the biggest client of different type
69 // with lowest importance from the same process.
70 // This is applicable for codec type only.
71 if (!found) {
72 if (type != MediaResource::Type::kSecureCodec &&
73 type != MediaResource::Type::kNonSecureCodec) {
74 return false;
75 }
76 MediaResourceType otherType = (type == MediaResource::Type::kSecureCodec) ?
77 MediaResource::Type::kNonSecureCodec : MediaResource::Type::kSecureCodec;
78 if (!mResourceTracker->getLeastImportantBiggestClient(
79 callingPid, callingImportance,
80 otherType, subType, MediaResource::SubType::kUnspecifiedSubType,
81 clients, targetClient)) {
82 return false;
83 }
84 }
85 targetClients.emplace_back(targetClient);
86 return true;
87 }
88 } // namespace android
89