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