blob: 1cef9d55a0c2166d5e1a4990d580da71170f1c32 [file] [log] [blame]
Ronghua Wu231c3d12015-03-11 15:10:32 -07001/*
2**
3** Copyright 2015, 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 "ResourceManagerService"
20#include <utils/Log.h>
21
Chong Zhangfdd512a2019-11-22 11:03:14 -080022#include <android/binder_manager.h>
23#include <android/binder_process.h>
Chong Zhangc7303e82020-12-02 16:38:52 -080024#include <binder/IPCThreadState.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070025#include <binder/IServiceManager.h>
Chong Zhangee33d642019-08-08 14:26:43 -070026#include <cutils/sched_policy.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070027#include <dirent.h>
Chong Zhang181e6952019-10-09 13:23:39 -070028#include <media/MediaResourcePolicy.h>
Atneya Nairf5b68512022-05-23 20:02:49 -040029#include <media/stagefright/foundation/ABase.h>
Chong Zhangee33d642019-08-08 14:26:43 -070030#include <mediautils/BatteryNotifier.h>
Atneya Nairf5b68512022-05-23 20:02:49 -040031#include <mediautils/ProcessInfo.h>
Chong Zhangee33d642019-08-08 14:26:43 -070032#include <mediautils/SchedulingPolicyService.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070033#include <string.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/time.h>
37#include <unistd.h>
Girish9128e242022-11-23 20:52:29 +000038#include <stats_media_metrics.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070039
Steven Moreland0a0ff0b2021-04-02 00:06:01 +000040#include "IMediaResourceMonitor.h"
Ronghua Wu231c3d12015-03-11 15:10:32 -070041#include "ResourceManagerService.h"
Chong Zhanga9d45c72020-09-09 12:41:17 -070042#include "ResourceObserverService.h"
Ronghua Wua8ec8fc2015-05-07 13:58:22 -070043#include "ServiceLog.h"
Chong Zhangee33d642019-08-08 14:26:43 -070044
Ronghua Wu231c3d12015-03-11 15:10:32 -070045namespace android {
46
Girish9128e242022-11-23 20:52:29 +000047using stats::media_metrics::stats_write;
48using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED;
49using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
50using stats::media_metrics::\
51 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
52using stats::media_metrics::\
53 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
54
Chong Zhang97d367b2020-09-16 12:53:14 -070055//static
56std::mutex ResourceManagerService::sCookieLock;
57//static
58uintptr_t ResourceManagerService::sCookieCounter = 0;
59//static
60std::map<uintptr_t, sp<DeathNotifier> > ResourceManagerService::sCookieToDeathNotifierMap;
61
62class DeathNotifier : public RefBase {
63public:
Brian Lindahl64ee9452022-01-14 13:31:16 +010064 DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid,
65 int64_t clientId);
Chong Zhang97d367b2020-09-16 12:53:14 -070066
67 virtual ~DeathNotifier() {}
68
69 // Implement death recipient
70 static void BinderDiedCallback(void* cookie);
71 virtual void binderDied();
72
73protected:
74 std::weak_ptr<ResourceManagerService> mService;
75 int mPid;
76 int64_t mClientId;
77};
78
Chong Zhangfdd512a2019-11-22 11:03:14 -080079DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
80 int pid, int64_t clientId)
81 : mService(service), mPid(pid), mClientId(clientId) {}
Wonsik Kim3e378962017-01-05 17:00:02 +090082
Chong Zhangfdd512a2019-11-22 11:03:14 -080083//static
84void DeathNotifier::BinderDiedCallback(void* cookie) {
Chong Zhang97d367b2020-09-16 12:53:14 -070085 sp<DeathNotifier> notifier;
86 {
87 std::scoped_lock lock{ResourceManagerService::sCookieLock};
88 auto it = ResourceManagerService::sCookieToDeathNotifierMap.find(
89 reinterpret_cast<uintptr_t>(cookie));
90 if (it == ResourceManagerService::sCookieToDeathNotifierMap.end()) {
91 return;
92 }
93 notifier = it->second;
94 }
95 if (notifier.get() != nullptr) {
96 notifier->binderDied();
97 }
Chong Zhangfdd512a2019-11-22 11:03:14 -080098}
Wonsik Kim3e378962017-01-05 17:00:02 +090099
Chong Zhangfdd512a2019-11-22 11:03:14 -0800100void DeathNotifier::binderDied() {
101 // Don't check for pid validity since we know it's already dead.
102 std::shared_ptr<ResourceManagerService> service = mService.lock();
103 if (service == nullptr) {
104 ALOGW("ResourceManagerService is dead as well.");
105 return;
Wonsik Kim3e378962017-01-05 17:00:02 +0900106 }
Henry Fang32762922020-01-28 18:40:39 -0800107
108 service->overridePid(mPid, -1);
Henry Fangb35141c2020-06-29 13:11:39 -0700109 // thiz is freed in the call below, so it must be last call referring thiz
Girish9128e242022-11-23 20:52:29 +0000110 ClientInfoParcel clientInfo{.pid = mPid, .id = mClientId};
111 service->removeResource(clientInfo, false /*checkValid*/);
Chong Zhang97d367b2020-09-16 12:53:14 -0700112}
Henry Fangb35141c2020-06-29 13:11:39 -0700113
Chong Zhang97d367b2020-09-16 12:53:14 -0700114class OverrideProcessInfoDeathNotifier : public DeathNotifier {
115public:
116 OverrideProcessInfoDeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
117 int pid) : DeathNotifier(service, pid, 0) {}
118
119 virtual ~OverrideProcessInfoDeathNotifier() {}
120
121 virtual void binderDied();
122};
123
124void OverrideProcessInfoDeathNotifier::binderDied() {
125 // Don't check for pid validity since we know it's already dead.
126 std::shared_ptr<ResourceManagerService> service = mService.lock();
127 if (service == nullptr) {
128 ALOGW("ResourceManagerService is dead as well.");
129 return;
130 }
131
132 service->removeProcessInfoOverride(mPid);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800133}
Wonsik Kim3e378962017-01-05 17:00:02 +0900134
Ronghua Wu231c3d12015-03-11 15:10:32 -0700135template <typename T>
Chong Zhang181e6952019-10-09 13:23:39 -0700136static String8 getString(const std::vector<T> &items) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700137 String8 itemsStr;
138 for (size_t i = 0; i < items.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700139 itemsStr.appendFormat("%s ", toString(items[i]).string());
Ronghua Wu231c3d12015-03-11 15:10:32 -0700140 }
141 return itemsStr;
142}
143
Brian Lindahl64ee9452022-01-14 13:31:16 +0100144static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
145 MediaResourceParcel resource) {
146 if (type != resource.type) {
147 return false;
148 }
149 switch (type) {
150 // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so
151 // compare the subtypes as well.
152 case MediaResource::Type::kSecureCodec:
153 case MediaResource::Type::kNonSecureCodec:
154 if (resource.subType == subType) {
155 return true;
156 }
157 break;
158 // Non-codec resources are not segregated by the subtype (e.g. video vs. audio).
159 default:
160 return true;
161 }
162 return false;
163}
164
165static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
166 const ResourceList& resources) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700167 for (auto it = resources.begin(); it != resources.end(); it++) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100168 if (hasResourceType(type, subType, it->second)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700169 return true;
170 }
171 }
172 return false;
173}
174
Brian Lindahl64ee9452022-01-14 13:31:16 +0100175static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
176 const ResourceInfos& infos) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700177 for (size_t i = 0; i < infos.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100178 if (hasResourceType(type, subType, infos[i].resources)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700179 return true;
180 }
181 }
182 return false;
183}
184
Brian Lindahl64ee9452022-01-14 13:31:16 +0100185static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700186 ssize_t index = map.indexOfKey(pid);
187 if (index < 0) {
188 // new pid
189 ResourceInfos infosForPid;
190 map.add(pid, infosForPid);
191 }
192
193 return map.editValueFor(pid);
194}
195
Brian Lindahl64ee9452022-01-14 13:31:16 +0100196static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
Girish9128e242022-11-23 20:52:29 +0000197 const std::string& name,
Brian Lindahl64ee9452022-01-14 13:31:16 +0100198 const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700199 ssize_t index = infos.indexOfKey(clientId);
200
201 if (index < 0) {
202 ResourceInfo info;
203 info.uid = uid;
204 info.clientId = clientId;
Girish9128e242022-11-23 20:52:29 +0000205 info.name = name;
Chong Zhangfb092d32019-08-12 09:45:44 -0700206 info.client = client;
Chong Zhang97d367b2020-09-16 12:53:14 -0700207 info.cookie = 0;
Wonsik Kimd20e9362020-04-28 10:42:57 -0700208 info.pendingRemoval = false;
Chong Zhangfb092d32019-08-12 09:45:44 -0700209
210 index = infos.add(clientId, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700211 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700212
213 return infos.editValueAt(index);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700214}
215
Chong Zhang181e6952019-10-09 13:23:39 -0700216static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel> &resources) {
Dongwon Kangfe508d32015-12-15 14:22:05 +0900217 static const char* const kServiceName = "media_resource_monitor";
Dongwon Kang2642c842016-03-23 18:07:29 -0700218 sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
Dongwon Kangfe508d32015-12-15 14:22:05 +0900219 if (binder != NULL) {
220 sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
221 for (size_t i = 0; i < resources.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100222 switch (resources[i].subType) {
223 case MediaResource::SubType::kAudioCodec:
224 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
225 break;
226 case MediaResource::SubType::kVideoCodec:
227 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
228 break;
229 case MediaResource::SubType::kImageCodec:
230 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC);
231 break;
232 case MediaResource::SubType::kUnspecifiedSubType:
233 break;
Dongwon Kang69c23dd2016-03-22 15:22:45 -0700234 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900235 }
236 }
237}
238
Brian Lindahl64ee9452022-01-14 13:31:16 +0100239binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700240 String8 result;
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700241
dcashman014e91e2015-09-11 09:33:01 -0700242 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
243 result.format("Permission Denial: "
244 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
Chong Zhangfdd512a2019-11-22 11:03:14 -0800245 AIBinder_getCallingPid(),
246 AIBinder_getCallingUid());
dcashman014e91e2015-09-11 09:33:01 -0700247 write(fd, result.string(), result.size());
248 return PERMISSION_DENIED;
249 }
250
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700251 PidResourceInfosMap mapCopy;
252 bool supportsMultipleSecureCodecs;
253 bool supportsSecureWithNonSecureCodec;
Henry Fang32762922020-01-28 18:40:39 -0800254 std::map<int, int> overridePidMapCopy;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700255 String8 serviceLog;
256 {
257 Mutex::Autolock lock(mLock);
258 mapCopy = mMap; // Shadow copy, real copy will happen on write.
259 supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
260 supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
261 serviceLog = mServiceLog->toString(" " /* linePrefix */);
Henry Fang32762922020-01-28 18:40:39 -0800262 overridePidMapCopy = mOverridePidMap;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700263 }
264
265 const size_t SIZE = 256;
266 char buffer[SIZE];
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700267 snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
268 result.append(buffer);
269 result.append(" Policies:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700270 snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", supportsMultipleSecureCodecs);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700271 result.append(buffer);
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700272 snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n",
273 supportsSecureWithNonSecureCodec);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700274 result.append(buffer);
275
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700276 result.append(" Processes:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700277 for (size_t i = 0; i < mapCopy.size(); ++i) {
Girish9128e242022-11-23 20:52:29 +0000278 int pid = mapCopy.keyAt(i);
279 snprintf(buffer, SIZE, " Pid: %d\n", pid);
280 result.append(buffer);
281 int priority = 0;
282 if (getPriority_l(pid, &priority)) {
283 snprintf(buffer, SIZE, " Priority: %d\n", priority);
284 } else {
285 snprintf(buffer, SIZE, " Priority: <unknown>\n");
286 }
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700287 result.append(buffer);
288
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700289 const ResourceInfos &infos = mapCopy.valueAt(i);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700290 for (size_t j = 0; j < infos.size(); ++j) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700291 result.append(" Client:\n");
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700292 snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
293 result.append(buffer);
294
Arun Johnsonaabe0142022-07-18 19:16:04 +0000295 std::string clientName = "<unknown client>";
296 if (infos[j].client != nullptr) {
Girish9128e242022-11-23 20:52:29 +0000297 clientName = infos[j].name;
Chong Zhang181e6952019-10-09 13:23:39 -0700298 }
299 snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700300 result.append(buffer);
301
Chong Zhangfb092d32019-08-12 09:45:44 -0700302 const ResourceList &resources = infos[j].resources;
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700303 result.append(" Resources:\n");
Chong Zhangfb092d32019-08-12 09:45:44 -0700304 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -0700305 snprintf(buffer, SIZE, " %s\n", toString(it->second).string());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700306 result.append(buffer);
307 }
308 }
309 }
Henry Fang32762922020-01-28 18:40:39 -0800310 result.append(" Process Pid override:\n");
311 for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
312 snprintf(buffer, SIZE, " Original Pid: %d, Override Pid: %d\n",
313 it->first, it->second);
314 result.append(buffer);
315 }
Ronghua Wu022ed722015-05-11 15:15:09 -0700316 result.append(" Events logs (most recent at top):\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700317 result.append(serviceLog);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700318
319 write(fd, result.string(), result.size());
320 return OK;
321}
322
Brian Lindahl64ee9452022-01-14 13:31:16 +0100323struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800324 SystemCallbackImpl() : mClientToken(new BBinder()) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700325
Chong Zhangdd726802019-08-21 17:24:13 -0700326 virtual void noteStartVideo(int uid) override {
327 BatteryNotifier::getInstance().noteStartVideo(uid);
328 }
329 virtual void noteStopVideo(int uid) override {
330 BatteryNotifier::getInstance().noteStopVideo(uid);
331 }
332 virtual void noteResetVideo() override {
333 BatteryNotifier::getInstance().noteResetVideo();
334 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800335 virtual bool requestCpusetBoost(bool enable) override {
336 return android::requestCpusetBoost(enable, mClientToken);
Chong Zhangdd726802019-08-21 17:24:13 -0700337 }
338
339protected:
340 virtual ~SystemCallbackImpl() {}
341
342private:
343 DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800344 sp<IBinder> mClientToken;
Chong Zhangdd726802019-08-21 17:24:13 -0700345};
346
347ResourceManagerService::ResourceManagerService()
348 : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {}
349
Brian Lindahl64ee9452022-01-14 13:31:16 +0100350ResourceManagerService::ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
Chong Zhangdd726802019-08-21 17:24:13 -0700351 const sp<SystemCallbackInterface> &systemResource)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700352 : mProcessInfo(processInfo),
Chong Zhangdd726802019-08-21 17:24:13 -0700353 mSystemCB(systemResource),
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700354 mServiceLog(new ServiceLog()),
Ronghua Wu231c3d12015-03-11 15:10:32 -0700355 mSupportsMultipleSecureCodecs(true),
Chong Zhang79d2b282018-04-17 14:14:31 -0700356 mSupportsSecureWithNonSecureCodec(true),
Chong Zhangfdd512a2019-11-22 11:03:14 -0800357 mCpuBoostCount(0),
358 mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
Chong Zhangdd726802019-08-21 17:24:13 -0700359 mSystemCB->noteResetVideo();
Chong Zhangee33d642019-08-08 14:26:43 -0700360}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700361
Chong Zhangfdd512a2019-11-22 11:03:14 -0800362//static
363void ResourceManagerService::instantiate() {
364 std::shared_ptr<ResourceManagerService> service =
365 ::ndk::SharedRefBase::make<ResourceManagerService>();
366 binder_status_t status =
Charles Chen5b097ef2023-03-15 01:21:22 +0000367 AServiceManager_addServiceWithFlags(
Charles Chend2fb31f2023-02-16 00:11:56 +0000368 service->asBinder().get(), getServiceName(),
369 AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800370 if (status != STATUS_OK) {
371 return;
372 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700373
374 std::shared_ptr<ResourceObserverService> observerService =
375 ResourceObserverService::instantiate();
376
377 if (observerService != nullptr) {
378 service->setObserverService(observerService);
379 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800380 // TODO: mediaserver main() is already starting the thread pool,
381 // move this to mediaserver main() when other services in mediaserver
382 // are converted to ndk-platform aidl.
383 //ABinderProcess_startThreadPool();
384}
385
Ronghua Wu231c3d12015-03-11 15:10:32 -0700386ResourceManagerService::~ResourceManagerService() {}
387
Chong Zhanga9d45c72020-09-09 12:41:17 -0700388void ResourceManagerService::setObserverService(
389 const std::shared_ptr<ResourceObserverService>& observerService) {
390 mObserverService = observerService;
391}
392
Chong Zhang181e6952019-10-09 13:23:39 -0700393Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700394 String8 log = String8::format("config(%s)", getString(policies).string());
395 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700396
397 Mutex::Autolock lock(mLock);
398 for (size_t i = 0; i < policies.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700399 const std::string &type = policies[i].type;
400 const std::string &value = policies[i].value;
401 if (type == MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700402 mSupportsMultipleSecureCodecs = (value == "true");
Chong Zhang181e6952019-10-09 13:23:39 -0700403 } else if (type == MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700404 mSupportsSecureWithNonSecureCodec = (value == "true");
Ronghua Wu231c3d12015-03-11 15:10:32 -0700405 }
406 }
Chong Zhang181e6952019-10-09 13:23:39 -0700407 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700408}
409
Brian Lindahl64ee9452022-01-14 13:31:16 +0100410void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource,
411 const ResourceInfo& clientInfo) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700412 // first time added
Chong Zhang181e6952019-10-09 13:23:39 -0700413 if (resource.type == MediaResource::Type::kCpuBoost
414 && resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700415 // Request it on every new instance of kCpuBoost, as the media.codec
416 // could have died, if we only do it the first time subsequent instances
417 // never gets the boost.
Chong Zhangfdd512a2019-11-22 11:03:14 -0800418 if (mSystemCB->requestCpusetBoost(true) != OK) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700419 ALOGW("couldn't request cpuset boost");
420 }
421 mCpuBoostCount++;
Chong Zhang181e6952019-10-09 13:23:39 -0700422 } else if (resource.type == MediaResource::Type::kBattery
423 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700424 mSystemCB->noteStartVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700425 }
426}
427
Brian Lindahl64ee9452022-01-14 13:31:16 +0100428void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource,
429 const ResourceInfo& clientInfo) {
Chong Zhang181e6952019-10-09 13:23:39 -0700430 if (resource.type == MediaResource::Type::kCpuBoost
431 && resource.subType == MediaResource::SubType::kUnspecifiedSubType
Chong Zhangfb092d32019-08-12 09:45:44 -0700432 && mCpuBoostCount > 0) {
433 if (--mCpuBoostCount == 0) {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800434 mSystemCB->requestCpusetBoost(false);
Chong Zhangfb092d32019-08-12 09:45:44 -0700435 }
Chong Zhang181e6952019-10-09 13:23:39 -0700436 } else if (resource.type == MediaResource::Type::kBattery
437 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700438 mSystemCB->noteStopVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700439 }
440}
441
Brian Lindahl64ee9452022-01-14 13:31:16 +0100442void ResourceManagerService::mergeResources(MediaResourceParcel& r1,
443 const MediaResourceParcel& r2) {
Chong Zhang181e6952019-10-09 13:23:39 -0700444 // The resource entry on record is maintained to be in [0,INT64_MAX].
445 // Clamp if merging in the new resource value causes it to go out of bound.
446 // Note that the new resource value could be negative, eg.DrmSession, the
447 // value goes lower when the session is used more often. During reclaim
448 // the session with the highest value (lowest usage) would be closed.
449 if (r2.value < INT64_MAX - r1.value) {
450 r1.value += r2.value;
451 if (r1.value < 0) {
452 r1.value = 0;
453 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700454 } else {
Chong Zhang181e6952019-10-09 13:23:39 -0700455 r1.value = INT64_MAX;
Robert Shihc3af31b2019-09-20 21:45:01 -0700456 }
457}
458
Girish9128e242022-11-23 20:52:29 +0000459Status ResourceManagerService::addResource(const ClientInfoParcel& clientInfo,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800460 const std::shared_ptr<IResourceManagerClient>& client,
Chong Zhang181e6952019-10-09 13:23:39 -0700461 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000462 int32_t pid = clientInfo.pid;
463 int32_t uid = clientInfo.uid;
464 int64_t clientId = clientInfo.id;
465 const std::string& name = clientInfo.name;
466 String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
467 pid, uid, (long long) clientId, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700468 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700469
470 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100471 if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800472 pid_t callingPid = IPCThreadState::self()->getCallingPid();
473 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100474 ALOGW("%s called with untrusted pid %d or uid %d, using calling pid %d, uid %d",
475 __FUNCTION__, pid, uid, callingPid, callingUid);
Chong Zhangc7303e82020-12-02 16:38:52 -0800476 pid = callingPid;
477 uid = callingUid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800478 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700479 ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
Girish9128e242022-11-23 20:52:29 +0000480 ResourceInfo& info = getResourceInfoForEdit(uid, clientId, name, client, infos);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700481 ResourceList resourceAdded;
Chong Zhang79d2b282018-04-17 14:14:31 -0700482
483 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700484 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700485 const auto resType = std::tuple(res.type, res.subType, res.id);
486
487 if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
488 ALOGW("Ignoring request to remove negative value of non-drm resource");
489 continue;
490 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700491 if (info.resources.find(resType) == info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700492 if (res.value <= 0) {
493 // We can't init a new entry with negative value, although it's allowed
494 // to merge in negative values after the initial add.
495 ALOGW("Ignoring request to add new resource entry with value <= 0");
496 continue;
497 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700498 onFirstAdded(res, info);
499 info.resources[resType] = res;
Chong Zhangfb092d32019-08-12 09:45:44 -0700500 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700501 mergeResources(info.resources[resType], res);
Chong Zhang79d2b282018-04-17 14:14:31 -0700502 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700503 // Add it to the list of added resources for observers.
504 auto it = resourceAdded.find(resType);
505 if (it == resourceAdded.end()) {
506 resourceAdded[resType] = res;
507 } else {
508 mergeResources(it->second, res);
509 }
Chong Zhang79d2b282018-04-17 14:14:31 -0700510 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700511 if (info.cookie == 0 && client != nullptr) {
Arun Johnsond1f59732022-03-25 17:10:29 +0000512 info.cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700513 new DeathNotifier(ref<ResourceManagerService>(), pid, clientId));
Wonsik Kim3e378962017-01-05 17:00:02 +0900514 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700515 if (mObserverService != nullptr && !resourceAdded.empty()) {
516 mObserverService->onResourceAdded(uid, pid, resourceAdded);
517 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900518 notifyResourceGranted(pid, resources);
Girish9128e242022-11-23 20:52:29 +0000519
520 // Increase the instance count of the resource associated with this client.
521 increaseResourceInstanceCount(clientId, name);
522
Chong Zhang181e6952019-10-09 13:23:39 -0700523 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700524}
525
Girish9128e242022-11-23 20:52:29 +0000526void ResourceManagerService::increaseResourceInstanceCount(int64_t clientId,
527 const std::string& name) {
528 // Check whether this client has been looked into already.
529 if (mClientIdSet.find(clientId) == mClientIdSet.end()) {
530 mClientIdSet.insert(clientId);
531 // Update the resource instance count.
532 auto found = mConcurrentResourceCountMap.find(name);
533 if (found == mConcurrentResourceCountMap.end()) {
534 mConcurrentResourceCountMap[name] = 1;
535 } else {
536 found->second++;
537 }
538 }
539}
540
541void ResourceManagerService::decreaseResourceInstanceCount(int64_t clientId,
542 const std::string& name) {
543 // Since this client has been removed, remove it from mClientIdSet
544 mClientIdSet.erase(clientId);
545 // Update the resource instance count also.
546 auto found = mConcurrentResourceCountMap.find(name);
547 if (found != mConcurrentResourceCountMap.end()) {
548 if (found->second == 1) {
549 mConcurrentResourceCountMap.erase(found);
550 } else {
551 found->second--;
552 }
553 }
554}
555
556Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo,
Chong Zhang181e6952019-10-09 13:23:39 -0700557 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000558 int32_t pid = clientInfo.pid;
559 int32_t uid = clientInfo.uid;
560 int64_t clientId = clientInfo.id;
561 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
562 pid, uid, (long long) clientId, getString(resources).string());
Chong Zhangfb092d32019-08-12 09:45:44 -0700563 mServiceLog->add(log);
564
565 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100566 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800567 pid_t callingPid = IPCThreadState::self()->getCallingPid();
568 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
569 pid, callingPid);
570 pid = callingPid;
Chong Zhangfb092d32019-08-12 09:45:44 -0700571 }
572 ssize_t index = mMap.indexOfKey(pid);
573 if (index < 0) {
574 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700575 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700576 }
577 ResourceInfos &infos = mMap.editValueAt(index);
578
579 index = infos.indexOfKey(clientId);
580 if (index < 0) {
581 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700582 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700583 }
584
585 ResourceInfo &info = infos.editValueAt(index);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700586 ResourceList resourceRemoved;
Chong Zhangfb092d32019-08-12 09:45:44 -0700587 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700588 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700589 const auto resType = std::tuple(res.type, res.subType, res.id);
590
591 if (res.value < 0) {
592 ALOGW("Ignoring request to remove negative value of resource");
593 continue;
594 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700595 // ignore if we don't have it
596 if (info.resources.find(resType) != info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700597 MediaResourceParcel &resource = info.resources[resType];
Chong Zhanga9d45c72020-09-09 12:41:17 -0700598 MediaResourceParcel actualRemoved = res;
Chong Zhang181e6952019-10-09 13:23:39 -0700599 if (resource.value > res.value) {
600 resource.value -= res.value;
Chong Zhangfb092d32019-08-12 09:45:44 -0700601 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700602 onLastRemoved(res, info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700603 actualRemoved.value = resource.value;
Chong Zhang102b3e32020-11-02 12:21:50 -0800604 info.resources.erase(resType);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700605 }
606
607 // Add it to the list of removed resources for observers.
608 auto it = resourceRemoved.find(resType);
609 if (it == resourceRemoved.end()) {
610 resourceRemoved[resType] = actualRemoved;
611 } else {
612 mergeResources(it->second, actualRemoved);
Chong Zhangfb092d32019-08-12 09:45:44 -0700613 }
614 }
615 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700616 if (mObserverService != nullptr && !resourceRemoved.empty()) {
617 mObserverService->onResourceRemoved(info.uid, pid, resourceRemoved);
618 }
Chong Zhang181e6952019-10-09 13:23:39 -0700619 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700620}
621
Girish9128e242022-11-23 20:52:29 +0000622Status ResourceManagerService::removeClient(const ClientInfoParcel& clientInfo) {
623 removeResource(clientInfo, true /*checkValid*/);
Chong Zhang181e6952019-10-09 13:23:39 -0700624 return Status::ok();
Wonsik Kim3e378962017-01-05 17:00:02 +0900625}
626
Girish9128e242022-11-23 20:52:29 +0000627Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo, bool checkValid) {
628 int32_t pid = clientInfo.pid;
629 int32_t uid = clientInfo.uid;
630 int64_t clientId = clientInfo.id;
631 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
632 pid, uid, (long long) clientId);
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700633 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700634
635 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100636 if (checkValid && !mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800637 pid_t callingPid = IPCThreadState::self()->getCallingPid();
638 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
639 pid, callingPid);
640 pid = callingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800641 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700642 ssize_t index = mMap.indexOfKey(pid);
643 if (index < 0) {
644 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700645 return Status::ok();
Ronghua Wu37c89242015-07-15 12:23:48 -0700646 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700647 ResourceInfos &infos = mMap.editValueAt(index);
Chong Zhangfb092d32019-08-12 09:45:44 -0700648
649 index = infos.indexOfKey(clientId);
650 if (index < 0) {
651 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700652 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700653 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700654
655 const ResourceInfo &info = infos[index];
656 for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
657 onLastRemoved(it->second, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700658 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700659
Girish9128e242022-11-23 20:52:29 +0000660 // Since this client has been removed, decrease the corresponding
661 // resources instance count.
662 decreaseResourceInstanceCount(clientId, info.name);
663
Arun Johnsond1f59732022-03-25 17:10:29 +0000664 removeCookieAndUnlink_l(info.client, info.cookie);
Chong Zhangfb092d32019-08-12 09:45:44 -0700665
Chong Zhanga9d45c72020-09-09 12:41:17 -0700666 if (mObserverService != nullptr && !info.resources.empty()) {
667 mObserverService->onResourceRemoved(info.uid, pid, info.resources);
668 }
669
Chong Zhangfb092d32019-08-12 09:45:44 -0700670 infos.removeItemsAt(index);
Chong Zhang181e6952019-10-09 13:23:39 -0700671 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700672}
673
Girish9128e242022-11-23 20:52:29 +0000674void ResourceManagerService::getClientForResource_l(int callingPid,
675 const MediaResourceParcel *res,
676 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800677 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700678 if (res == NULL) {
679 return;
680 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800681 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +0000682 if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, idVector, &client)) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700683 clients->push_back(client);
684 }
685}
686
Girish9128e242022-11-23 20:52:29 +0000687Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
Brian Lindahl64ee9452022-01-14 13:31:16 +0100688 const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
Girish9128e242022-11-23 20:52:29 +0000689 int32_t callingPid = clientInfo.pid;
690 std::string clientName = clientInfo.name;
691 String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
692 callingPid, clientInfo.uid, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700693 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700694 *_aidl_return = false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700695
Chong Zhangfdd512a2019-11-22 11:03:14 -0800696 Vector<std::shared_ptr<IResourceManagerClient>> clients;
Girish9128e242022-11-23 20:52:29 +0000697 PidUidVector idVector;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700698 {
699 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100700 if (!mProcessInfo->isPidTrusted(callingPid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800701 pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
702 ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
703 callingPid, actualCallingPid);
704 callingPid = actualCallingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800705 }
Chong Zhang181e6952019-10-09 13:23:39 -0700706 const MediaResourceParcel *secureCodec = NULL;
707 const MediaResourceParcel *nonSecureCodec = NULL;
708 const MediaResourceParcel *graphicMemory = NULL;
709 const MediaResourceParcel *drmSession = NULL;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700710 for (size_t i = 0; i < resources.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100711 switch (resources[i].type) {
712 case MediaResource::Type::kSecureCodec:
713 secureCodec = &resources[i];
714 break;
715 case MediaResource::Type::kNonSecureCodec:
716 nonSecureCodec = &resources[i];
717 break;
718 case MediaResource::Type::kGraphicMemory:
719 graphicMemory = &resources[i];
720 break;
721 case MediaResource::Type::kDrmSession:
722 drmSession = &resources[i];
723 break;
724 default:
725 break;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700726 }
727 }
728
729 // first pass to handle secure/non-secure codec conflict
730 if (secureCodec != NULL) {
731 if (!mSupportsMultipleSecureCodecs) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100732 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000733 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700734 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700735 }
736 }
737 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100738 if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000739 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700740 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700741 }
742 }
743 }
744 if (nonSecureCodec != NULL) {
745 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100746 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000747 nonSecureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700748 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700749 }
750 }
751 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700752 if (drmSession != NULL) {
Girish9128e242022-11-23 20:52:29 +0000753 getClientForResource_l(callingPid, drmSession, &idVector, &clients);
Robert Shihc3af31b2019-09-20 21:45:01 -0700754 if (clients.size() == 0) {
Chong Zhang181e6952019-10-09 13:23:39 -0700755 return Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700756 }
757 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700758
759 if (clients.size() == 0) {
760 // if no secure/non-secure codec conflict, run second pass to handle other resources.
Girish9128e242022-11-23 20:52:29 +0000761 getClientForResource_l(callingPid, graphicMemory, &idVector, &clients);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700762 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700763
764 if (clients.size() == 0) {
765 // if we are here, run the third pass to free one codec with the same type.
Girish9128e242022-11-23 20:52:29 +0000766 getClientForResource_l(callingPid, secureCodec, &idVector, &clients);
767 getClientForResource_l(callingPid, nonSecureCodec, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700768 }
769
770 if (clients.size() == 0) {
771 // if we are here, run the fourth pass to free one codec with the different type.
772 if (secureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700773 MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000774 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700775 }
776 if (nonSecureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700777 MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000778 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700779 }
780 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700781 }
782
Brian Lindahl64ee9452022-01-14 13:31:16 +0100783 *_aidl_return = reclaimUnconditionallyFrom(clients);
Girish9128e242022-11-23 20:52:29 +0000784
785 // Log Reclaim Pushed Atom to statsd
786 pushReclaimAtom(clientInfo, clients, idVector, *_aidl_return);
787
Wonsik Kim271429d2020-10-01 10:12:56 -0700788 return Status::ok();
789}
790
Girish9128e242022-11-23 20:52:29 +0000791void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
792 const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
793 const PidUidVector& idVector, bool reclaimed) {
794 // Construct the metrics for codec reclaim as a pushed atom.
795 // 1. Information about the requester.
796 // - UID and the priority (oom score)
797 int32_t callingPid = clientInfo.pid;
798 int32_t requesterUid = clientInfo.uid;
799 std::string clientName = clientInfo.name;
800 int requesterPriority = -1;
801 getPriority_l(callingPid, &requesterPriority);
802
803 // 2. Information about the codec.
804 // - Name of the codec requested
805 // - Number of concurrent codecs running.
806 int32_t noOfConcurrentCodecs = 0;
807 auto found = mConcurrentResourceCountMap.find(clientName);
808 if (found != mConcurrentResourceCountMap.end()) {
809 noOfConcurrentCodecs = found->second;
810 }
811
812 // 3. Information about the Reclaim:
813 // - Status of reclaim request
814 // - How many codecs are reclaimed
815 // - For each codecs reclaimed, information of the process that it belonged to:
816 // - UID and the Priority (oom score)
817 int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
818 if (!reclaimed) {
819 if (clients.size() == 0) {
820 // No clients to reclaim from
821 reclaimStatus =
822 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
823 } else {
824 // Couldn't reclaim resources from the clients
825 reclaimStatus =
826 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
827 }
828 }
829 int32_t noOfCodecsReclaimed = clients.size();
830 int32_t targetIndex = 1;
831 for (const auto& id : idVector) {
832 int32_t targetUid = id.second;
833 int targetPriority = -1;
834 getPriority_l(id.first, &targetPriority);
835 // Post the pushed atom
836 int result = stats_write(
837 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
838 requesterUid,
839 requesterPriority,
840 clientName.c_str(),
841 noOfConcurrentCodecs,
842 reclaimStatus,
843 noOfCodecsReclaimed,
844 targetIndex,
845 targetUid,
846 targetPriority);
847 ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
848 "Requester[pid(%d): uid(%d): priority(%d)] "
849 "Codec: [%s] "
850 "No of concurrent codecs: %d "
851 "Reclaim Status: %d "
852 "No of codecs reclaimed: %d "
853 "Target[%d][pid(%d): uid(%d): priority(%d)] "
854 "Atom Size: %d",
855 __func__, callingPid, requesterUid, requesterPriority,
856 clientName.c_str(), noOfConcurrentCodecs,
857 reclaimStatus, noOfCodecsReclaimed,
858 targetIndex, id.first, targetUid, targetPriority, result);
859 targetIndex++;
860 }
861}
862
Brian Lindahl64ee9452022-01-14 13:31:16 +0100863bool ResourceManagerService::reclaimUnconditionallyFrom(
Wonsik Kim271429d2020-10-01 10:12:56 -0700864 const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700865 if (clients.size() == 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700866 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700867 }
868
Chong Zhangfdd512a2019-11-22 11:03:14 -0800869 std::shared_ptr<IResourceManagerClient> failedClient;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700870 for (size_t i = 0; i < clients.size(); ++i) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700871 String8 log = String8::format("reclaimResource from client %p", clients[i].get());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700872 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700873 bool success;
874 Status status = clients[i]->reclaimResource(&success);
875 if (!status.isOk() || !success) {
Ronghua Wu67e7f542015-03-13 10:47:08 -0700876 failedClient = clients[i];
877 break;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700878 }
879 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700880
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700881 if (failedClient == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700882 return true;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700883 }
884
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200885 int failedClientPid = -1;
Ronghua Wu67e7f542015-03-13 10:47:08 -0700886 {
887 Mutex::Autolock lock(mLock);
888 bool found = false;
889 for (size_t i = 0; i < mMap.size(); ++i) {
890 ResourceInfos &infos = mMap.editValueAt(i);
891 for (size_t j = 0; j < infos.size();) {
892 if (infos[j].client == failedClient) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700893 j = infos.removeItemsAt(j);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700894 found = true;
895 } else {
896 ++j;
897 }
898 }
899 if (found) {
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200900 failedClientPid = mMap.keyAt(i);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700901 break;
902 }
903 }
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200904 if (found) {
905 ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
906 } else {
907 ALOGW("Failed to reclaim resources from unlocateable client");
Ronghua Wu67e7f542015-03-13 10:47:08 -0700908 }
909 }
910
Wonsik Kim271429d2020-10-01 10:12:56 -0700911 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700912}
913
Brian Lindahl64ee9452022-01-14 13:31:16 +0100914Status ResourceManagerService::overridePid(int originalPid, int newPid) {
Henry Fang32762922020-01-28 18:40:39 -0800915 String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
916 originalPid, newPid);
917 mServiceLog->add(log);
918
919 // allow if this is called from the same process or the process has
920 // permission.
921 if ((AIBinder_getCallingPid() != getpid()) &&
922 (checkCallingPermission(String16(
923 "android.permission.MEDIA_RESOURCE_OVERRIDE_PID")) == false)) {
924 ALOGE(
925 "Permission Denial: can't access overridePid method from pid=%d, "
926 "self pid=%d\n",
927 AIBinder_getCallingPid(), getpid());
928 return Status::fromServiceSpecificError(PERMISSION_DENIED);
929 }
930
931 {
932 Mutex::Autolock lock(mLock);
933 mOverridePidMap.erase(originalPid);
934 if (newPid != -1) {
935 mOverridePidMap.emplace(originalPid, newPid);
936 }
937 }
938
939 return Status::ok();
940}
941
Chong Zhang97d367b2020-09-16 12:53:14 -0700942Status ResourceManagerService::overrideProcessInfo(
Brian Lindahl64ee9452022-01-14 13:31:16 +0100943 const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState,
Chong Zhang97d367b2020-09-16 12:53:14 -0700944 int oomScore) {
945 String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)",
946 pid, procState, oomScore);
947 mServiceLog->add(log);
948
949 // Only allow the override if the caller already can access process state and oom scores.
950 int callingPid = AIBinder_getCallingPid();
951 if (callingPid != getpid() && (callingPid != pid || !checkCallingPermission(String16(
952 "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE")))) {
953 ALOGE("Permission Denial: overrideProcessInfo method from pid=%d", callingPid);
954 return Status::fromServiceSpecificError(PERMISSION_DENIED);
955 }
956
957 if (client == nullptr) {
958 return Status::fromServiceSpecificError(BAD_VALUE);
959 }
960
961 Mutex::Autolock lock(mLock);
962 removeProcessInfoOverride_l(pid);
963
964 if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
965 // Override value is rejected by ProcessInfo.
966 return Status::fromServiceSpecificError(BAD_VALUE);
967 }
968
Arun Johnsond1f59732022-03-25 17:10:29 +0000969 uintptr_t cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700970 new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), pid));
971
972 mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{cookie, client});
973
974 return Status::ok();
975}
976
Arun Johnsond1f59732022-03-25 17:10:29 +0000977uintptr_t ResourceManagerService::addCookieAndLink_l(
978 const std::shared_ptr<IResourceManagerClient>& client, const sp<DeathNotifier>& notifier) {
979 if (client == nullptr) {
980 return 0;
981 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700982 std::scoped_lock lock{sCookieLock};
983
984 uintptr_t cookie;
985 // Need to skip cookie 0 (if it wraps around). ResourceInfo has cookie initialized to 0
986 // indicating the death notifier is not created yet.
987 while ((cookie = ++sCookieCounter) == 0);
Arun Johnsond1f59732022-03-25 17:10:29 +0000988 AIBinder_linkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -0700989 sCookieToDeathNotifierMap.emplace(cookie, notifier);
990
991 return cookie;
992}
993
Arun Johnsond1f59732022-03-25 17:10:29 +0000994void ResourceManagerService::removeCookieAndUnlink_l(
995 const std::shared_ptr<IResourceManagerClient>& client, uintptr_t cookie) {
Chong Zhang97d367b2020-09-16 12:53:14 -0700996 std::scoped_lock lock{sCookieLock};
Arun Johnsond1f59732022-03-25 17:10:29 +0000997 if (client != nullptr) {
998 AIBinder_unlinkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
999 }
Chong Zhang97d367b2020-09-16 12:53:14 -07001000 sCookieToDeathNotifierMap.erase(cookie);
1001}
1002
1003void ResourceManagerService::removeProcessInfoOverride(int pid) {
1004 Mutex::Autolock lock(mLock);
1005
1006 removeProcessInfoOverride_l(pid);
1007}
1008
1009void ResourceManagerService::removeProcessInfoOverride_l(int pid) {
1010 auto it = mProcessInfoOverrideMap.find(pid);
1011 if (it == mProcessInfoOverrideMap.end()) {
1012 return;
1013 }
1014
1015 mProcessInfo->removeProcessInfoOverride(pid);
1016
Arun Johnsond1f59732022-03-25 17:10:29 +00001017 removeCookieAndUnlink_l(it->second.client, it->second.cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -07001018
1019 mProcessInfoOverrideMap.erase(pid);
1020}
1021
Girish9128e242022-11-23 20:52:29 +00001022Status ResourceManagerService::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
1023 int32_t pid = clientInfo.pid;
1024 int64_t clientId = clientInfo.id;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001025 String8 log = String8::format(
1026 "markClientForPendingRemoval(pid %d, clientId %lld)",
1027 pid, (long long) clientId);
1028 mServiceLog->add(log);
1029
1030 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001031 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001032 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1033 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1034 pid, callingPid);
1035 pid = callingPid;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001036 }
1037 ssize_t index = mMap.indexOfKey(pid);
1038 if (index < 0) {
1039 ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
1040 pid, (long long)clientId);
1041 return Status::ok();
1042 }
1043 ResourceInfos &infos = mMap.editValueAt(index);
1044
1045 index = infos.indexOfKey(clientId);
1046 if (index < 0) {
1047 ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
1048 return Status::ok();
1049 }
1050
1051 ResourceInfo &info = infos.editValueAt(index);
1052 info.pendingRemoval = true;
1053 return Status::ok();
1054}
1055
Wonsik Kim271429d2020-10-01 10:12:56 -07001056Status ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(int32_t pid) {
1057 String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
1058 mServiceLog->add(log);
1059
1060 Vector<std::shared_ptr<IResourceManagerClient>> clients;
1061 {
1062 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001063 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001064 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1065 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1066 pid, callingPid);
1067 pid = callingPid;
Wonsik Kim271429d2020-10-01 10:12:56 -07001068 }
1069
1070 for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
1071 MediaResource::Type::kNonSecureCodec,
1072 MediaResource::Type::kGraphicMemory,
1073 MediaResource::Type::kDrmSession}) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001074 switch (type) {
1075 // Codec resources are segregated by audio, video and image domains.
1076 case MediaResource::Type::kSecureCodec:
1077 case MediaResource::Type::kNonSecureCodec:
1078 for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec,
1079 MediaResource::SubType::kVideoCodec,
1080 MediaResource::SubType::kImageCodec}) {
1081 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001082 uid_t uid = 0;
1083 if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001084 clients.add(client);
1085 continue;
1086 }
1087 }
1088 break;
1089 // Non-codec resources are shared by audio, video and image codecs (no subtype).
1090 default:
1091 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001092 uid_t uid = 0;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001093 if (getBiggestClientPendingRemoval_l(pid, type,
Girish9128e242022-11-23 20:52:29 +00001094 MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001095 clients.add(client);
1096 }
1097 break;
Wonsik Kim271429d2020-10-01 10:12:56 -07001098 }
1099 }
1100 }
1101
1102 if (!clients.empty()) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001103 reclaimUnconditionallyFrom(clients);
Wonsik Kim271429d2020-10-01 10:12:56 -07001104 }
1105 return Status::ok();
1106}
1107
Henry Fang32762922020-01-28 18:40:39 -08001108bool ResourceManagerService::getPriority_l(int pid, int* priority) {
1109 int newPid = pid;
1110
1111 if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
1112 newPid = mOverridePidMap[pid];
1113 ALOGD("getPriority_l: use override pid %d instead original pid %d",
1114 newPid, pid);
1115 }
1116
1117 return mProcessInfo->getPriority(newPid, priority);
1118}
1119
Brian Lindahl64ee9452022-01-14 13:31:16 +01001120bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001121 MediaResource::SubType subType,
1122 PidUidVector* idVector,
1123 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Chong Zhangfdd512a2019-11-22 11:03:14 -08001124 Vector<std::shared_ptr<IResourceManagerClient>> temp;
Girish9128e242022-11-23 20:52:29 +00001125 PidUidVector tempIdList;
1126
Ronghua Wu231c3d12015-03-11 15:10:32 -07001127 for (size_t i = 0; i < mMap.size(); ++i) {
1128 ResourceInfos &infos = mMap.editValueAt(i);
1129 for (size_t j = 0; j < infos.size(); ++j) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001130 if (hasResourceType(type, subType, infos[j].resources)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001131 if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
1132 // some higher/equal priority process owns the resource,
1133 // this request can't be fulfilled.
1134 ALOGE("getAllClients_l: can't reclaim resource %s from pid %d",
Ronghua Wuea15fd22016-03-03 13:35:05 -08001135 asString(type), mMap.keyAt(i));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001136 return false;
1137 }
1138 temp.push_back(infos[j].client);
Girish9128e242022-11-23 20:52:29 +00001139 tempIdList.emplace_back(mMap.keyAt(i), infos[j].uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001140 }
1141 }
1142 }
1143 if (temp.size() == 0) {
Ronghua Wuea15fd22016-03-03 13:35:05 -08001144 ALOGV("getAllClients_l: didn't find any resource %s", asString(type));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001145 return true;
1146 }
1147 clients->appendVector(temp);
Girish9128e242022-11-23 20:52:29 +00001148 idVector->insert(std::end(*idVector), std::begin(tempIdList), std::end(tempIdList));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001149 return true;
1150}
1151
Brian Lindahl64ee9452022-01-14 13:31:16 +01001152bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid,
Girish9128e242022-11-23 20:52:29 +00001153 MediaResource::Type type,
1154 MediaResource::SubType subType,
1155 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -08001156 std::shared_ptr<IResourceManagerClient> *client) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001157 int lowestPriorityPid;
1158 int lowestPriority;
1159 int callingPriority;
Girish9128e242022-11-23 20:52:29 +00001160 uid_t uid = 0;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001161
1162 // Before looking into other processes, check if we have clients marked for
1163 // pending removal in the same process.
Girish9128e242022-11-23 20:52:29 +00001164 if (getBiggestClientPendingRemoval_l(callingPid, type, subType, uid, client)) {
1165 idVector->emplace_back(callingPid, uid);
Wonsik Kimd20e9362020-04-28 10:42:57 -07001166 return true;
1167 }
Henry Fang32762922020-01-28 18:40:39 -08001168 if (!getPriority_l(callingPid, &callingPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001169 ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
1170 callingPid);
1171 return false;
1172 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001173 if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001174 return false;
1175 }
1176 if (lowestPriority <= callingPriority) {
1177 ALOGE("getLowestPriorityBiggestClient_l: lowest priority %d vs caller priority %d",
1178 lowestPriority, callingPriority);
1179 return false;
1180 }
1181
Girish9128e242022-11-23 20:52:29 +00001182 if (!getBiggestClient_l(lowestPriorityPid, type, subType, uid, client)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001183 return false;
1184 }
Girish9128e242022-11-23 20:52:29 +00001185
1186 idVector->emplace_back(lowestPriorityPid, uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001187 return true;
1188}
1189
Brian Lindahl64ee9452022-01-14 13:31:16 +01001190bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type,
1191 MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001192 int pid = -1;
1193 int priority = -1;
1194 for (size_t i = 0; i < mMap.size(); ++i) {
1195 if (mMap.valueAt(i).size() == 0) {
1196 // no client on this process.
1197 continue;
1198 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001199 if (!hasResourceType(type, subType, mMap.valueAt(i))) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001200 // doesn't have the requested resource type
1201 continue;
1202 }
1203 int tempPid = mMap.keyAt(i);
1204 int tempPriority;
Henry Fang32762922020-01-28 18:40:39 -08001205 if (!getPriority_l(tempPid, &tempPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001206 ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
1207 // TODO: remove this pid from mMap?
1208 continue;
1209 }
1210 if (pid == -1 || tempPriority > priority) {
1211 // initial the value
1212 pid = tempPid;
1213 priority = tempPriority;
1214 }
1215 }
1216 if (pid != -1) {
1217 *lowestPriorityPid = pid;
1218 *lowestPriority = priority;
1219 }
1220 return (pid != -1);
1221}
1222
1223bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) {
1224 int callingPidPriority;
Henry Fang32762922020-01-28 18:40:39 -08001225 if (!getPriority_l(callingPid, &callingPidPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001226 return false;
1227 }
1228
1229 int priority;
Henry Fang32762922020-01-28 18:40:39 -08001230 if (!getPriority_l(pid, &priority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001231 return false;
1232 }
1233
1234 return (callingPidPriority < priority);
1235}
1236
Brian Lindahl64ee9452022-01-14 13:31:16 +01001237bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001238 MediaResource::SubType subType, uid_t& uid,
1239 std::shared_ptr<IResourceManagerClient> *client) {
1240 return getBiggestClient_l(pid, type, subType, uid, client, true /* pendingRemovalOnly */);
Brian Lindahl64ee9452022-01-14 13:31:16 +01001241}
1242
1243bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001244 MediaResource::SubType subType, uid_t& uid,
1245 std::shared_ptr<IResourceManagerClient> *client,
Wonsik Kimd20e9362020-04-28 10:42:57 -07001246 bool pendingRemovalOnly) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001247 ssize_t index = mMap.indexOfKey(pid);
1248 if (index < 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001249 ALOGE_IF(!pendingRemovalOnly,
1250 "getBiggestClient_l: can't find resource info for pid %d", pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001251 return false;
1252 }
1253
Chong Zhangfdd512a2019-11-22 11:03:14 -08001254 std::shared_ptr<IResourceManagerClient> clientTemp;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001255 uint64_t largestValue = 0;
1256 const ResourceInfos &infos = mMap.valueAt(index);
1257 for (size_t i = 0; i < infos.size(); ++i) {
Chong Zhangfb092d32019-08-12 09:45:44 -07001258 const ResourceList &resources = infos[i].resources;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001259 if (pendingRemovalOnly && !infos[i].pendingRemoval) {
1260 continue;
1261 }
Chong Zhangfb092d32019-08-12 09:45:44 -07001262 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -07001263 const MediaResourceParcel &resource = it->second;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001264 if (hasResourceType(type, subType, resource)) {
Chong Zhang181e6952019-10-09 13:23:39 -07001265 if (resource.value > largestValue) {
1266 largestValue = resource.value;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001267 clientTemp = infos[i].client;
Girish9128e242022-11-23 20:52:29 +00001268 uid = infos[i].uid;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001269 }
1270 }
1271 }
1272 }
1273
1274 if (clientTemp == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001275 ALOGE_IF(!pendingRemovalOnly,
Brian Lindahl64ee9452022-01-14 13:31:16 +01001276 "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d",
1277 asString(type), asString(subType), pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001278 return false;
1279 }
1280
1281 *client = clientTemp;
1282 return true;
1283}
1284
Ronghua Wu231c3d12015-03-11 15:10:32 -07001285} // namespace android