blob: dde389a12df3bfe97dbf8e54696297815de0fa99 [file] [log] [blame]
Girish1484e5d2023-11-20 06:00:44 +00001/*
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 "ResourceManagerServiceNew"
20#include <utils/Log.h>
Girish0ac5c212023-11-23 09:14:03 +000021#include <binder/IPCThreadState.h>
22#include <mediautils/ProcessInfo.h>
Girish1484e5d2023-11-20 06:00:44 +000023
Girish0ac5c212023-11-23 09:14:03 +000024#include "DefaultResourceModel.h"
Girish6c16adb2023-11-23 10:16:47 +000025#include "ProcessPriorityReclaimPolicy.h"
Girish1484e5d2023-11-20 06:00:44 +000026#include "ResourceManagerServiceNew.h"
Girish6a6044d2023-11-22 21:23:14 +000027#include "ResourceTracker.h"
28#include "ServiceLog.h"
Girish1484e5d2023-11-20 06:00:44 +000029
30namespace android {
31
32ResourceManagerServiceNew::ResourceManagerServiceNew(
33 const sp<ProcessInfoInterface>& processInfo,
34 const sp<SystemCallbackInterface>& systemResource) :
35 ResourceManagerService(processInfo, systemResource) {}
36
37ResourceManagerServiceNew::~ResourceManagerServiceNew() {}
38
Girish6a6044d2023-11-22 21:23:14 +000039void ResourceManagerServiceNew::init() {
40 // Create the Resource Tracker
41 mResourceTracker = std::make_shared<ResourceTracker>(ref<ResourceManagerServiceNew>(),
42 mProcessInfo);
Girish0ac5c212023-11-23 09:14:03 +000043 setUpResourceModels();
Girish6c16adb2023-11-23 10:16:47 +000044 setUpReclaimPolicies();
Girish0ac5c212023-11-23 09:14:03 +000045}
46
47void ResourceManagerServiceNew::setUpResourceModels() {
48 std::scoped_lock lock{mLock};
49 // Create/Configure the default resource model.
50 if (mDefaultResourceModel == nullptr) {
51 mDefaultResourceModel = std::make_unique<DefaultResourceModel>(
52 mResourceTracker,
53 mSupportsMultipleSecureCodecs,
54 mSupportsSecureWithNonSecureCodec);
55 } else {
56 DefaultResourceModel* resourceModel =
57 static_cast<DefaultResourceModel*>(mDefaultResourceModel.get());
58 resourceModel->config(mSupportsMultipleSecureCodecs, mSupportsSecureWithNonSecureCodec);
59 }
Girish6a6044d2023-11-22 21:23:14 +000060}
61
Girish6c16adb2023-11-23 10:16:47 +000062void ResourceManagerServiceNew::setUpReclaimPolicies() {
63 mReclaimPolicies.clear();
64 // Process priority (oom score) as the Default reclaim policy.
65 mReclaimPolicies.push_back(std::make_unique<ProcessPriorityReclaimPolicy>(mResourceTracker));
66}
67
Girish1484e5d2023-11-20 06:00:44 +000068Status ResourceManagerServiceNew::config(const std::vector<MediaResourcePolicyParcel>& policies) {
Girish0ac5c212023-11-23 09:14:03 +000069 Status status = ResourceManagerService::config(policies);
70 // Change in the config dictates update to the resource model.
71 setUpResourceModels();
72 return status;
Girish1484e5d2023-11-20 06:00:44 +000073}
74
Girish6a6044d2023-11-22 21:23:14 +000075void ResourceManagerServiceNew::setObserverService(
76 const std::shared_ptr<ResourceObserverService>& observerService) {
77 ResourceManagerService::setObserverService(observerService);
78 mResourceTracker->setResourceObserverService(observerService);
79}
80
Girish1484e5d2023-11-20 06:00:44 +000081Status ResourceManagerServiceNew::addResource(
82 const ClientInfoParcel& clientInfo,
83 const std::shared_ptr<IResourceManagerClient>& client,
84 const std::vector<MediaResourceParcel>& resources) {
Girish6a6044d2023-11-22 21:23:14 +000085 int32_t pid = clientInfo.pid;
86 int32_t uid = clientInfo.uid;
87 int64_t clientId = clientInfo.id;
88 String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
89 pid, uid, (long long) clientId, getString(resources).c_str());
90 mServiceLog->add(log);
91
92 std::scoped_lock lock{mLock};
93 mResourceTracker->addResource(clientInfo, client, resources);
94 notifyResourceGranted(pid, resources);
95
96 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +000097}
98
99Status ResourceManagerServiceNew::removeResource(
100 const ClientInfoParcel& clientInfo,
101 const std::vector<MediaResourceParcel>& resources) {
Girish6a6044d2023-11-22 21:23:14 +0000102 int32_t pid = clientInfo.pid;
103 int32_t uid = clientInfo.uid;
104 int64_t clientId = clientInfo.id;
105 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
106 pid, uid, (long long) clientId, getString(resources).c_str());
107 mServiceLog->add(log);
108
109 std::scoped_lock lock{mLock};
110 mResourceTracker->removeResource(clientInfo, resources);
111 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +0000112}
113
114Status ResourceManagerServiceNew::removeClient(const ClientInfoParcel& clientInfo) {
Girish6a6044d2023-11-22 21:23:14 +0000115 removeResource(clientInfo, true /*checkValid*/);
116 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +0000117}
118
119Status ResourceManagerServiceNew::removeResource(const ClientInfoParcel& clientInfo,
120 bool checkValid) {
Girish6a6044d2023-11-22 21:23:14 +0000121 int32_t pid = clientInfo.pid;
122 int32_t uid = clientInfo.uid;
123 int64_t clientId = clientInfo.id;
124 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
125 pid, uid, (long long) clientId);
126 mServiceLog->add(log);
127
128 std::scoped_lock lock{mLock};
129 if (mResourceTracker->removeResource(clientInfo, checkValid)) {
130 notifyClientReleased(clientInfo);
131 }
132 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +0000133}
134
135Status ResourceManagerServiceNew::reclaimResource(
136 const ClientInfoParcel& clientInfo,
137 const std::vector<MediaResourceParcel>& resources,
138 bool* _aidl_return) {
139 return ResourceManagerService::reclaimResource(clientInfo, resources, _aidl_return);
140}
141
Girish6a6044d2023-11-22 21:23:14 +0000142bool ResourceManagerServiceNew::overridePid_l(int32_t originalPid, int32_t newPid) {
143 return mResourceTracker->overridePid(originalPid, newPid);
144}
145
Girish1484e5d2023-11-20 06:00:44 +0000146Status ResourceManagerServiceNew::overridePid(int originalPid, int newPid) {
147 return ResourceManagerService::overridePid(originalPid, newPid);
148}
149
Girish6a6044d2023-11-22 21:23:14 +0000150bool ResourceManagerServiceNew::overrideProcessInfo_l(
151 const std::shared_ptr<IResourceManagerClient>& client,
152 int pid,
153 int procState,
154 int oomScore) {
155 return mResourceTracker->overrideProcessInfo(client, pid, procState, oomScore);
156}
157
Girish1484e5d2023-11-20 06:00:44 +0000158Status ResourceManagerServiceNew::overrideProcessInfo(
159 const std::shared_ptr<IResourceManagerClient>& client,
160 int pid,
161 int procState,
162 int oomScore) {
163 return ResourceManagerService::overrideProcessInfo(client, pid, procState, oomScore);
164}
165
Girish6a6044d2023-11-22 21:23:14 +0000166void ResourceManagerServiceNew::removeProcessInfoOverride(int pid) {
167 std::scoped_lock lock{mLock};
168
169 mResourceTracker->removeProcessInfoOverride(pid);
170}
171
Girish1484e5d2023-11-20 06:00:44 +0000172Status ResourceManagerServiceNew::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
Girish6a6044d2023-11-22 21:23:14 +0000173 int32_t pid = clientInfo.pid;
174 int64_t clientId = clientInfo.id;
175 String8 log = String8::format(
176 "markClientForPendingRemoval(pid %d, clientId %lld)",
177 pid, (long long) clientId);
178 mServiceLog->add(log);
179
180 std::scoped_lock lock{mLock};
181 mResourceTracker->markClientForPendingRemoval(clientInfo);
182 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +0000183}
184
185Status ResourceManagerServiceNew::reclaimResourcesFromClientsPendingRemoval(int32_t pid) {
Girish6a6044d2023-11-22 21:23:14 +0000186 String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
187 mServiceLog->add(log);
188
189 std::vector<ClientInfo> targetClients;
190 {
191 std::scoped_lock lock{mLock};
192 mResourceTracker->getClientsMarkedPendingRemoval(pid, targetClients);
193 }
194
195 if (!targetClients.empty()) {
196 reclaimUnconditionallyFrom(targetClients);
197 }
198 return Status::ok();
Girish1484e5d2023-11-20 06:00:44 +0000199}
200
201Status ResourceManagerServiceNew::notifyClientCreated(const ClientInfoParcel& clientInfo) {
202 return ResourceManagerService::notifyClientCreated(clientInfo);
203}
204
205Status ResourceManagerServiceNew::notifyClientStarted(const ClientConfigParcel& clientConfig) {
206 return ResourceManagerService::notifyClientStarted(clientConfig);
207}
208
209Status ResourceManagerServiceNew::notifyClientStopped(const ClientConfigParcel& clientConfig) {
210 return ResourceManagerService::notifyClientStopped(clientConfig);
211}
212
213Status ResourceManagerServiceNew::notifyClientConfigChanged(
214 const ClientConfigParcel& clientConfig) {
215 return ResourceManagerService::notifyClientConfigChanged(clientConfig);
216}
217
Girish6a6044d2023-11-22 21:23:14 +0000218void ResourceManagerServiceNew::getResourceDump(std::string& resourceLog) const {
219 std::scoped_lock lock{mLock};
220 mResourceTracker->dump(resourceLog);
221}
222
Girish1484e5d2023-11-20 06:00:44 +0000223binder_status_t ResourceManagerServiceNew::dump(int fd, const char** args, uint32_t numArgs) {
224 return ResourceManagerService::dump(fd, args, numArgs);
225}
226
Girish0ac5c212023-11-23 09:14:03 +0000227bool ResourceManagerServiceNew::getTargetClients(
228 int callingPid,
229 const std::vector<MediaResourceParcel>& resources,
230 std::vector<ClientInfo>& targetClients) {
231 std::scoped_lock lock{mLock};
232 if (!mProcessInfo->isPidTrusted(callingPid)) {
233 pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
234 ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
235 callingPid, actualCallingPid);
236 callingPid = actualCallingPid;
237 }
238
239 // Use the Resource Model to get a list of all the clients that hold the
240 // needed/requested resources.
241 ReclaimRequestInfo reclaimRequestInfo{callingPid, resources};
242 std::vector<ClientInfo> clients;
243 if (!mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients)) {
244 if (clients.empty()) {
245 ALOGI("%s: There aren't any clients with given resources. Nothing to reclaim",
246 __func__);
247 return false;
248 }
249 // Since there was a conflict, we need to reclaim all elements.
250 targetClients = std::move(clients);
251 } else {
Girish6c16adb2023-11-23 10:16:47 +0000252 // Select a client among those have the needed resources.
Girish0ac5c212023-11-23 09:14:03 +0000253 getClientForResource_l(reclaimRequestInfo, clients, targetClients);
254 }
255 return !targetClients.empty();
256}
257
258void ResourceManagerServiceNew::getClientForResource_l(
259 const ReclaimRequestInfo& reclaimRequestInfo,
260 const std::vector<ClientInfo>& clients,
261 std::vector<ClientInfo>& targetClients) {
262 int callingPid = reclaimRequestInfo.mCallingPid;
263
264 // Before looking into other processes, check if we have clients marked for
265 // pending removal in the same process.
266 ClientInfo targetClient;
267 for (const MediaResourceParcel& resource : reclaimRequestInfo.mResources) {
268 if (mResourceTracker->getBiggestClientPendingRemoval(callingPid, resource.type,
269 resource.subType, targetClient)) {
270 targetClients.emplace_back(targetClient);
271 return;
272 }
273 }
274
Girish6c16adb2023-11-23 10:16:47 +0000275 // Run through all the reclaim policies until a client to reclaim from is identified.
276 for (std::unique_ptr<IReclaimPolicy>& reclaimPolicy : mReclaimPolicies) {
277 if (reclaimPolicy->getClients(reclaimRequestInfo, clients, targetClients)) {
Girish0ac5c212023-11-23 09:14:03 +0000278 return;
279 }
280 }
281}
282
Girish0ac5c212023-11-23 09:14:03 +0000283bool ResourceManagerServiceNew::getLowestPriorityBiggestClient_l(
284 const ResourceRequestInfo& resourceRequestInfo,
285 ClientInfo& clientInfo) {
286 //NOTE: This function is used only by the test: ResourceManagerServiceTest
287 if (resourceRequestInfo.mResource == nullptr) {
288 return false;
289 }
Girish6c16adb2023-11-23 10:16:47 +0000290
291 // Use the DefaultResourceModel to get all the clients with the resources requested.
Girish0ac5c212023-11-23 09:14:03 +0000292 std::vector<MediaResourceParcel> resources{*resourceRequestInfo.mResource};
293 ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid, resources};
294 std::vector<ClientInfo> clients;
295 mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients);
Girish6c16adb2023-11-23 10:16:47 +0000296
297 // Use the ProcessPriorityReclaimPolicy to select a client to reclaim from.
298 std::unique_ptr<IReclaimPolicy> reclaimPolicy
299 = std::make_unique<ProcessPriorityReclaimPolicy>(mResourceTracker);
300 std::vector<ClientInfo> targetClients;
301 if (reclaimPolicy->getClients(reclaimRequestInfo, clients, targetClients)) {
302 if (!targetClients.empty()) {
303 clientInfo = targetClients[0];
304 return true;
305 }
306 }
307
308 return false;
Girish0ac5c212023-11-23 09:14:03 +0000309}
310
Girish6a6044d2023-11-22 21:23:14 +0000311bool ResourceManagerServiceNew::getPriority_l(int pid, int* priority) const {
312 return mResourceTracker->getPriority(pid, priority);
313}
314
315bool ResourceManagerServiceNew::getLowestPriorityPid_l(
316 MediaResource::Type type, MediaResource::SubType subType,
317 int* lowestPriorityPid, int* lowestPriority) {
Girish0ac5c212023-11-23 09:14:03 +0000318 //NOTE: This function is used only by the test: ResourceManagerServiceTest
Girish6a6044d2023-11-22 21:23:14 +0000319 return mResourceTracker->getLowestPriorityPid(type, subType,
320 *lowestPriorityPid,
321 *lowestPriority);
322}
323
Girish6a6044d2023-11-22 21:23:14 +0000324bool ResourceManagerServiceNew::getAllClients_l(
325 const ResourceRequestInfo& resourceRequestInfo,
326 std::vector<ClientInfo>& clientsInfo) {
Girish0ac5c212023-11-23 09:14:03 +0000327 //NOTE: This function is used only by the test: ResourceManagerServiceTest
Girish6a6044d2023-11-22 21:23:14 +0000328 MediaResource::Type type = resourceRequestInfo.mResource->type;
Girish0ac5c212023-11-23 09:14:03 +0000329 // Get the list of all clients that has requested resources.
Girish6a6044d2023-11-22 21:23:14 +0000330 std::vector<ClientInfo> clients;
331 mResourceTracker->getAllClients(resourceRequestInfo, clients);
332
333 // Check is there any high priority process holding up the resources already.
334 for (const ClientInfo& info : clients) {
335 if (!isCallingPriorityHigher_l(resourceRequestInfo.mCallingPid, info.mPid)) {
336 // some higher/equal priority process owns the resource,
337 // this request can't be fulfilled.
338 ALOGE("%s: can't reclaim resource %s from pid %d", __func__, asString(type), info.mPid);
339 return false;
340 }
341 clientsInfo.emplace_back(info);
342 }
343 if (clientsInfo.size() == 0) {
344 ALOGV("%s: didn't find any resource %s", __func__, asString(type));
345 }
346 return true;
347}
348
349std::shared_ptr<IResourceManagerClient> ResourceManagerServiceNew::getClient(
350 int pid, const int64_t& clientId) const {
351 return mResourceTracker->getClient(pid, clientId);
352}
353
354bool ResourceManagerServiceNew::removeClient(int pid, const int64_t& clientId) {
355 return mResourceTracker->removeClient(pid, clientId);
356}
357
358const std::map<int, ResourceInfos>& ResourceManagerServiceNew::getResourceMap() const {
359 return mResourceTracker->getResourceMap();
360}
361
Girish1484e5d2023-11-20 06:00:44 +0000362} // namespace android