blob: 5582528b94738ff5d34ec5f3c1400f1c486f441b [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>
Ronghua Wu231c3d12015-03-11 15:10:32 -070029#include <media/stagefright/ProcessInfo.h>
Chong Zhangee33d642019-08-08 14:26:43 -070030#include <mediautils/BatteryNotifier.h>
31#include <mediautils/SchedulingPolicyService.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070032#include <string.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/time.h>
36#include <unistd.h>
Girish9128e242022-11-23 20:52:29 +000037#include <stats_media_metrics.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070038
Steven Moreland0a0ff0b2021-04-02 00:06:01 +000039#include "IMediaResourceMonitor.h"
Ronghua Wu231c3d12015-03-11 15:10:32 -070040#include "ResourceManagerService.h"
Chong Zhanga9d45c72020-09-09 12:41:17 -070041#include "ResourceObserverService.h"
Ronghua Wua8ec8fc2015-05-07 13:58:22 -070042#include "ServiceLog.h"
Chong Zhangee33d642019-08-08 14:26:43 -070043
Ronghua Wu231c3d12015-03-11 15:10:32 -070044namespace android {
45
Girish9128e242022-11-23 20:52:29 +000046using stats::media_metrics::stats_write;
47using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED;
48using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
49using stats::media_metrics::\
50 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
51using stats::media_metrics::\
52 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
53
Chong Zhang97d367b2020-09-16 12:53:14 -070054//static
55std::mutex ResourceManagerService::sCookieLock;
56//static
57uintptr_t ResourceManagerService::sCookieCounter = 0;
58//static
59std::map<uintptr_t, sp<DeathNotifier> > ResourceManagerService::sCookieToDeathNotifierMap;
60
61class DeathNotifier : public RefBase {
62public:
Brian Lindahl64ee9452022-01-14 13:31:16 +010063 DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid,
64 int64_t clientId);
Chong Zhang97d367b2020-09-16 12:53:14 -070065
66 virtual ~DeathNotifier() {}
67
68 // Implement death recipient
69 static void BinderDiedCallback(void* cookie);
70 virtual void binderDied();
71
72protected:
73 std::weak_ptr<ResourceManagerService> mService;
74 int mPid;
75 int64_t mClientId;
76};
77
Chong Zhangfdd512a2019-11-22 11:03:14 -080078DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
79 int pid, int64_t clientId)
80 : mService(service), mPid(pid), mClientId(clientId) {}
Wonsik Kim3e378962017-01-05 17:00:02 +090081
Chong Zhangfdd512a2019-11-22 11:03:14 -080082//static
83void DeathNotifier::BinderDiedCallback(void* cookie) {
Chong Zhang97d367b2020-09-16 12:53:14 -070084 sp<DeathNotifier> notifier;
85 {
86 std::scoped_lock lock{ResourceManagerService::sCookieLock};
87 auto it = ResourceManagerService::sCookieToDeathNotifierMap.find(
88 reinterpret_cast<uintptr_t>(cookie));
89 if (it == ResourceManagerService::sCookieToDeathNotifierMap.end()) {
90 return;
91 }
92 notifier = it->second;
93 }
94 if (notifier.get() != nullptr) {
95 notifier->binderDied();
96 }
Chong Zhangfdd512a2019-11-22 11:03:14 -080097}
Wonsik Kim3e378962017-01-05 17:00:02 +090098
Chong Zhangfdd512a2019-11-22 11:03:14 -080099void DeathNotifier::binderDied() {
100 // Don't check for pid validity since we know it's already dead.
101 std::shared_ptr<ResourceManagerService> service = mService.lock();
102 if (service == nullptr) {
103 ALOGW("ResourceManagerService is dead as well.");
104 return;
Wonsik Kim3e378962017-01-05 17:00:02 +0900105 }
Henry Fang32762922020-01-28 18:40:39 -0800106
107 service->overridePid(mPid, -1);
Henry Fangb35141c2020-06-29 13:11:39 -0700108 // thiz is freed in the call below, so it must be last call referring thiz
Girish9128e242022-11-23 20:52:29 +0000109 ClientInfoParcel clientInfo{.pid = mPid, .id = mClientId};
110 service->removeResource(clientInfo, false /*checkValid*/);
Chong Zhang97d367b2020-09-16 12:53:14 -0700111}
Henry Fangb35141c2020-06-29 13:11:39 -0700112
Chong Zhang97d367b2020-09-16 12:53:14 -0700113class OverrideProcessInfoDeathNotifier : public DeathNotifier {
114public:
115 OverrideProcessInfoDeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
116 int pid) : DeathNotifier(service, pid, 0) {}
117
118 virtual ~OverrideProcessInfoDeathNotifier() {}
119
120 virtual void binderDied();
121};
122
123void OverrideProcessInfoDeathNotifier::binderDied() {
124 // Don't check for pid validity since we know it's already dead.
125 std::shared_ptr<ResourceManagerService> service = mService.lock();
126 if (service == nullptr) {
127 ALOGW("ResourceManagerService is dead as well.");
128 return;
129 }
130
131 service->removeProcessInfoOverride(mPid);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800132}
Wonsik Kim3e378962017-01-05 17:00:02 +0900133
Ronghua Wu231c3d12015-03-11 15:10:32 -0700134template <typename T>
Chong Zhang181e6952019-10-09 13:23:39 -0700135static String8 getString(const std::vector<T> &items) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700136 String8 itemsStr;
137 for (size_t i = 0; i < items.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700138 itemsStr.appendFormat("%s ", toString(items[i]).string());
Ronghua Wu231c3d12015-03-11 15:10:32 -0700139 }
140 return itemsStr;
141}
142
Brian Lindahl64ee9452022-01-14 13:31:16 +0100143static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
144 MediaResourceParcel resource) {
145 if (type != resource.type) {
146 return false;
147 }
148 switch (type) {
149 // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so
150 // compare the subtypes as well.
151 case MediaResource::Type::kSecureCodec:
152 case MediaResource::Type::kNonSecureCodec:
153 if (resource.subType == subType) {
154 return true;
155 }
156 break;
157 // Non-codec resources are not segregated by the subtype (e.g. video vs. audio).
158 default:
159 return true;
160 }
161 return false;
162}
163
164static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
165 const ResourceList& resources) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700166 for (auto it = resources.begin(); it != resources.end(); it++) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100167 if (hasResourceType(type, subType, it->second)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700168 return true;
169 }
170 }
171 return false;
172}
173
Brian Lindahl64ee9452022-01-14 13:31:16 +0100174static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
175 const ResourceInfos& infos) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700176 for (size_t i = 0; i < infos.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100177 if (hasResourceType(type, subType, infos[i].resources)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700178 return true;
179 }
180 }
181 return false;
182}
183
Brian Lindahl64ee9452022-01-14 13:31:16 +0100184static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700185 ssize_t index = map.indexOfKey(pid);
186 if (index < 0) {
187 // new pid
188 ResourceInfos infosForPid;
189 map.add(pid, infosForPid);
190 }
191
192 return map.editValueFor(pid);
193}
194
Brian Lindahl64ee9452022-01-14 13:31:16 +0100195static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
Girish9128e242022-11-23 20:52:29 +0000196 const std::string& name,
Brian Lindahl64ee9452022-01-14 13:31:16 +0100197 const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700198 ssize_t index = infos.indexOfKey(clientId);
199
200 if (index < 0) {
201 ResourceInfo info;
202 info.uid = uid;
203 info.clientId = clientId;
Girish9128e242022-11-23 20:52:29 +0000204 info.name = name;
Chong Zhangfb092d32019-08-12 09:45:44 -0700205 info.client = client;
Chong Zhang97d367b2020-09-16 12:53:14 -0700206 info.cookie = 0;
Wonsik Kimd20e9362020-04-28 10:42:57 -0700207 info.pendingRemoval = false;
Chong Zhangfb092d32019-08-12 09:45:44 -0700208
209 index = infos.add(clientId, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700210 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700211
212 return infos.editValueAt(index);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700213}
214
Chong Zhang181e6952019-10-09 13:23:39 -0700215static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel> &resources) {
Dongwon Kangfe508d32015-12-15 14:22:05 +0900216 static const char* const kServiceName = "media_resource_monitor";
Dongwon Kang2642c842016-03-23 18:07:29 -0700217 sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
Dongwon Kangfe508d32015-12-15 14:22:05 +0900218 if (binder != NULL) {
219 sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
220 for (size_t i = 0; i < resources.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100221 switch (resources[i].subType) {
222 case MediaResource::SubType::kAudioCodec:
223 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
224 break;
225 case MediaResource::SubType::kVideoCodec:
226 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
227 break;
228 case MediaResource::SubType::kImageCodec:
229 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC);
230 break;
231 case MediaResource::SubType::kUnspecifiedSubType:
232 break;
Dongwon Kang69c23dd2016-03-22 15:22:45 -0700233 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900234 }
235 }
236}
237
Brian Lindahl64ee9452022-01-14 13:31:16 +0100238binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700239 String8 result;
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700240
dcashman014e91e2015-09-11 09:33:01 -0700241 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
242 result.format("Permission Denial: "
243 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
Chong Zhangfdd512a2019-11-22 11:03:14 -0800244 AIBinder_getCallingPid(),
245 AIBinder_getCallingUid());
dcashman014e91e2015-09-11 09:33:01 -0700246 write(fd, result.string(), result.size());
247 return PERMISSION_DENIED;
248 }
249
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700250 PidResourceInfosMap mapCopy;
251 bool supportsMultipleSecureCodecs;
252 bool supportsSecureWithNonSecureCodec;
Henry Fang32762922020-01-28 18:40:39 -0800253 std::map<int, int> overridePidMapCopy;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700254 String8 serviceLog;
255 {
256 Mutex::Autolock lock(mLock);
257 mapCopy = mMap; // Shadow copy, real copy will happen on write.
258 supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
259 supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
260 serviceLog = mServiceLog->toString(" " /* linePrefix */);
Henry Fang32762922020-01-28 18:40:39 -0800261 overridePidMapCopy = mOverridePidMap;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700262 }
263
264 const size_t SIZE = 256;
265 char buffer[SIZE];
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700266 snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
267 result.append(buffer);
268 result.append(" Policies:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700269 snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", supportsMultipleSecureCodecs);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700270 result.append(buffer);
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700271 snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n",
272 supportsSecureWithNonSecureCodec);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700273 result.append(buffer);
274
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700275 result.append(" Processes:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700276 for (size_t i = 0; i < mapCopy.size(); ++i) {
Girish9128e242022-11-23 20:52:29 +0000277 int pid = mapCopy.keyAt(i);
278 snprintf(buffer, SIZE, " Pid: %d\n", pid);
279 result.append(buffer);
280 int priority = 0;
281 if (getPriority_l(pid, &priority)) {
282 snprintf(buffer, SIZE, " Priority: %d\n", priority);
283 } else {
284 snprintf(buffer, SIZE, " Priority: <unknown>\n");
285 }
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700286 result.append(buffer);
287
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700288 const ResourceInfos &infos = mapCopy.valueAt(i);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700289 for (size_t j = 0; j < infos.size(); ++j) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700290 result.append(" Client:\n");
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700291 snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
292 result.append(buffer);
293
Arun Johnsonaabe0142022-07-18 19:16:04 +0000294 std::string clientName = "<unknown client>";
295 if (infos[j].client != nullptr) {
Girish9128e242022-11-23 20:52:29 +0000296 clientName = infos[j].name;
Chong Zhang181e6952019-10-09 13:23:39 -0700297 }
298 snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700299 result.append(buffer);
300
Chong Zhangfb092d32019-08-12 09:45:44 -0700301 const ResourceList &resources = infos[j].resources;
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700302 result.append(" Resources:\n");
Chong Zhangfb092d32019-08-12 09:45:44 -0700303 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -0700304 snprintf(buffer, SIZE, " %s\n", toString(it->second).string());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700305 result.append(buffer);
306 }
307 }
308 }
Henry Fang32762922020-01-28 18:40:39 -0800309 result.append(" Process Pid override:\n");
310 for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
311 snprintf(buffer, SIZE, " Original Pid: %d, Override Pid: %d\n",
312 it->first, it->second);
313 result.append(buffer);
314 }
Ronghua Wu022ed722015-05-11 15:15:09 -0700315 result.append(" Events logs (most recent at top):\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700316 result.append(serviceLog);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700317
318 write(fd, result.string(), result.size());
319 return OK;
320}
321
Brian Lindahl64ee9452022-01-14 13:31:16 +0100322struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800323 SystemCallbackImpl() : mClientToken(new BBinder()) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700324
Chong Zhangdd726802019-08-21 17:24:13 -0700325 virtual void noteStartVideo(int uid) override {
326 BatteryNotifier::getInstance().noteStartVideo(uid);
327 }
328 virtual void noteStopVideo(int uid) override {
329 BatteryNotifier::getInstance().noteStopVideo(uid);
330 }
331 virtual void noteResetVideo() override {
332 BatteryNotifier::getInstance().noteResetVideo();
333 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800334 virtual bool requestCpusetBoost(bool enable) override {
335 return android::requestCpusetBoost(enable, mClientToken);
Chong Zhangdd726802019-08-21 17:24:13 -0700336 }
337
338protected:
339 virtual ~SystemCallbackImpl() {}
340
341private:
342 DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800343 sp<IBinder> mClientToken;
Chong Zhangdd726802019-08-21 17:24:13 -0700344};
345
346ResourceManagerService::ResourceManagerService()
347 : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {}
348
Brian Lindahl64ee9452022-01-14 13:31:16 +0100349ResourceManagerService::ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
Chong Zhangdd726802019-08-21 17:24:13 -0700350 const sp<SystemCallbackInterface> &systemResource)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700351 : mProcessInfo(processInfo),
Chong Zhangdd726802019-08-21 17:24:13 -0700352 mSystemCB(systemResource),
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700353 mServiceLog(new ServiceLog()),
Ronghua Wu231c3d12015-03-11 15:10:32 -0700354 mSupportsMultipleSecureCodecs(true),
Chong Zhang79d2b282018-04-17 14:14:31 -0700355 mSupportsSecureWithNonSecureCodec(true),
Chong Zhangfdd512a2019-11-22 11:03:14 -0800356 mCpuBoostCount(0),
357 mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
Chong Zhangdd726802019-08-21 17:24:13 -0700358 mSystemCB->noteResetVideo();
Chong Zhangee33d642019-08-08 14:26:43 -0700359}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700360
Chong Zhangfdd512a2019-11-22 11:03:14 -0800361//static
362void ResourceManagerService::instantiate() {
363 std::shared_ptr<ResourceManagerService> service =
364 ::ndk::SharedRefBase::make<ResourceManagerService>();
365 binder_status_t status =
Charles Chene55549f2023-03-15 01:21:22 +0000366 AServiceManager_addServiceWithFlags(
367 service->asBinder().get(), getServiceName(),
368 AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800369 if (status != STATUS_OK) {
370 return;
371 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700372
373 std::shared_ptr<ResourceObserverService> observerService =
374 ResourceObserverService::instantiate();
375
376 if (observerService != nullptr) {
377 service->setObserverService(observerService);
378 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800379 // TODO: mediaserver main() is already starting the thread pool,
380 // move this to mediaserver main() when other services in mediaserver
381 // are converted to ndk-platform aidl.
382 //ABinderProcess_startThreadPool();
383}
384
Ronghua Wu231c3d12015-03-11 15:10:32 -0700385ResourceManagerService::~ResourceManagerService() {}
386
Chong Zhanga9d45c72020-09-09 12:41:17 -0700387void ResourceManagerService::setObserverService(
388 const std::shared_ptr<ResourceObserverService>& observerService) {
389 mObserverService = observerService;
390}
391
Chong Zhang181e6952019-10-09 13:23:39 -0700392Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700393 String8 log = String8::format("config(%s)", getString(policies).string());
394 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700395
396 Mutex::Autolock lock(mLock);
397 for (size_t i = 0; i < policies.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700398 const std::string &type = policies[i].type;
399 const std::string &value = policies[i].value;
400 if (type == MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700401 mSupportsMultipleSecureCodecs = (value == "true");
Chong Zhang181e6952019-10-09 13:23:39 -0700402 } else if (type == MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700403 mSupportsSecureWithNonSecureCodec = (value == "true");
Ronghua Wu231c3d12015-03-11 15:10:32 -0700404 }
405 }
Chong Zhang181e6952019-10-09 13:23:39 -0700406 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700407}
408
Brian Lindahl64ee9452022-01-14 13:31:16 +0100409void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource,
410 const ResourceInfo& clientInfo) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700411 // first time added
Chong Zhang181e6952019-10-09 13:23:39 -0700412 if (resource.type == MediaResource::Type::kCpuBoost
413 && resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700414 // Request it on every new instance of kCpuBoost, as the media.codec
415 // could have died, if we only do it the first time subsequent instances
416 // never gets the boost.
Chong Zhangfdd512a2019-11-22 11:03:14 -0800417 if (mSystemCB->requestCpusetBoost(true) != OK) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700418 ALOGW("couldn't request cpuset boost");
419 }
420 mCpuBoostCount++;
Chong Zhang181e6952019-10-09 13:23:39 -0700421 } else if (resource.type == MediaResource::Type::kBattery
422 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700423 mSystemCB->noteStartVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700424 }
425}
426
Brian Lindahl64ee9452022-01-14 13:31:16 +0100427void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource,
428 const ResourceInfo& clientInfo) {
Chong Zhang181e6952019-10-09 13:23:39 -0700429 if (resource.type == MediaResource::Type::kCpuBoost
430 && resource.subType == MediaResource::SubType::kUnspecifiedSubType
Chong Zhangfb092d32019-08-12 09:45:44 -0700431 && mCpuBoostCount > 0) {
432 if (--mCpuBoostCount == 0) {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800433 mSystemCB->requestCpusetBoost(false);
Chong Zhangfb092d32019-08-12 09:45:44 -0700434 }
Chong Zhang181e6952019-10-09 13:23:39 -0700435 } else if (resource.type == MediaResource::Type::kBattery
436 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700437 mSystemCB->noteStopVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700438 }
439}
440
Brian Lindahl64ee9452022-01-14 13:31:16 +0100441void ResourceManagerService::mergeResources(MediaResourceParcel& r1,
442 const MediaResourceParcel& r2) {
Chong Zhang181e6952019-10-09 13:23:39 -0700443 // The resource entry on record is maintained to be in [0,INT64_MAX].
444 // Clamp if merging in the new resource value causes it to go out of bound.
445 // Note that the new resource value could be negative, eg.DrmSession, the
446 // value goes lower when the session is used more often. During reclaim
447 // the session with the highest value (lowest usage) would be closed.
448 if (r2.value < INT64_MAX - r1.value) {
449 r1.value += r2.value;
450 if (r1.value < 0) {
451 r1.value = 0;
452 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700453 } else {
Chong Zhang181e6952019-10-09 13:23:39 -0700454 r1.value = INT64_MAX;
Robert Shihc3af31b2019-09-20 21:45:01 -0700455 }
456}
457
Girish9128e242022-11-23 20:52:29 +0000458Status ResourceManagerService::addResource(const ClientInfoParcel& clientInfo,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800459 const std::shared_ptr<IResourceManagerClient>& client,
Chong Zhang181e6952019-10-09 13:23:39 -0700460 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000461 int32_t pid = clientInfo.pid;
462 int32_t uid = clientInfo.uid;
463 int64_t clientId = clientInfo.id;
464 const std::string& name = clientInfo.name;
465 String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
466 pid, uid, (long long) clientId, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700467 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700468
469 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100470 if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800471 pid_t callingPid = IPCThreadState::self()->getCallingPid();
472 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100473 ALOGW("%s called with untrusted pid %d or uid %d, using calling pid %d, uid %d",
474 __FUNCTION__, pid, uid, callingPid, callingUid);
Chong Zhangc7303e82020-12-02 16:38:52 -0800475 pid = callingPid;
476 uid = callingUid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800477 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700478 ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
Girish9128e242022-11-23 20:52:29 +0000479 ResourceInfo& info = getResourceInfoForEdit(uid, clientId, name, client, infos);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700480 ResourceList resourceAdded;
Chong Zhang79d2b282018-04-17 14:14:31 -0700481
482 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700483 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700484 const auto resType = std::tuple(res.type, res.subType, res.id);
485
486 if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
487 ALOGW("Ignoring request to remove negative value of non-drm resource");
488 continue;
489 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700490 if (info.resources.find(resType) == info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700491 if (res.value <= 0) {
492 // We can't init a new entry with negative value, although it's allowed
493 // to merge in negative values after the initial add.
494 ALOGW("Ignoring request to add new resource entry with value <= 0");
495 continue;
496 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700497 onFirstAdded(res, info);
498 info.resources[resType] = res;
Chong Zhangfb092d32019-08-12 09:45:44 -0700499 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700500 mergeResources(info.resources[resType], res);
Chong Zhang79d2b282018-04-17 14:14:31 -0700501 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700502 // Add it to the list of added resources for observers.
503 auto it = resourceAdded.find(resType);
504 if (it == resourceAdded.end()) {
505 resourceAdded[resType] = res;
506 } else {
507 mergeResources(it->second, res);
508 }
Chong Zhang79d2b282018-04-17 14:14:31 -0700509 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700510 if (info.cookie == 0 && client != nullptr) {
Arun Johnsond1f59732022-03-25 17:10:29 +0000511 info.cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700512 new DeathNotifier(ref<ResourceManagerService>(), pid, clientId));
Wonsik Kim3e378962017-01-05 17:00:02 +0900513 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700514 if (mObserverService != nullptr && !resourceAdded.empty()) {
515 mObserverService->onResourceAdded(uid, pid, resourceAdded);
516 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900517 notifyResourceGranted(pid, resources);
Girish9128e242022-11-23 20:52:29 +0000518
519 // Increase the instance count of the resource associated with this client.
520 increaseResourceInstanceCount(clientId, name);
521
Chong Zhang181e6952019-10-09 13:23:39 -0700522 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700523}
524
Girish9128e242022-11-23 20:52:29 +0000525void ResourceManagerService::increaseResourceInstanceCount(int64_t clientId,
526 const std::string& name) {
527 // Check whether this client has been looked into already.
528 if (mClientIdSet.find(clientId) == mClientIdSet.end()) {
529 mClientIdSet.insert(clientId);
530 // Update the resource instance count.
531 auto found = mConcurrentResourceCountMap.find(name);
532 if (found == mConcurrentResourceCountMap.end()) {
533 mConcurrentResourceCountMap[name] = 1;
534 } else {
535 found->second++;
536 }
537 }
538}
539
540void ResourceManagerService::decreaseResourceInstanceCount(int64_t clientId,
541 const std::string& name) {
542 // Since this client has been removed, remove it from mClientIdSet
543 mClientIdSet.erase(clientId);
544 // Update the resource instance count also.
545 auto found = mConcurrentResourceCountMap.find(name);
546 if (found != mConcurrentResourceCountMap.end()) {
547 if (found->second == 1) {
548 mConcurrentResourceCountMap.erase(found);
549 } else {
550 found->second--;
551 }
552 }
553}
554
555Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo,
Chong Zhang181e6952019-10-09 13:23:39 -0700556 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000557 int32_t pid = clientInfo.pid;
558 int32_t uid = clientInfo.uid;
559 int64_t clientId = clientInfo.id;
560 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
561 pid, uid, (long long) clientId, getString(resources).string());
Chong Zhangfb092d32019-08-12 09:45:44 -0700562 mServiceLog->add(log);
563
564 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100565 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800566 pid_t callingPid = IPCThreadState::self()->getCallingPid();
567 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
568 pid, callingPid);
569 pid = callingPid;
Chong Zhangfb092d32019-08-12 09:45:44 -0700570 }
571 ssize_t index = mMap.indexOfKey(pid);
572 if (index < 0) {
573 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700574 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700575 }
576 ResourceInfos &infos = mMap.editValueAt(index);
577
578 index = infos.indexOfKey(clientId);
579 if (index < 0) {
580 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700581 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700582 }
583
584 ResourceInfo &info = infos.editValueAt(index);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700585 ResourceList resourceRemoved;
Chong Zhangfb092d32019-08-12 09:45:44 -0700586 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700587 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700588 const auto resType = std::tuple(res.type, res.subType, res.id);
589
590 if (res.value < 0) {
591 ALOGW("Ignoring request to remove negative value of resource");
592 continue;
593 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700594 // ignore if we don't have it
595 if (info.resources.find(resType) != info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700596 MediaResourceParcel &resource = info.resources[resType];
Chong Zhanga9d45c72020-09-09 12:41:17 -0700597 MediaResourceParcel actualRemoved = res;
Chong Zhang181e6952019-10-09 13:23:39 -0700598 if (resource.value > res.value) {
599 resource.value -= res.value;
Chong Zhangfb092d32019-08-12 09:45:44 -0700600 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700601 onLastRemoved(res, info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700602 actualRemoved.value = resource.value;
Chong Zhang102b3e32020-11-02 12:21:50 -0800603 info.resources.erase(resType);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700604 }
605
606 // Add it to the list of removed resources for observers.
607 auto it = resourceRemoved.find(resType);
608 if (it == resourceRemoved.end()) {
609 resourceRemoved[resType] = actualRemoved;
610 } else {
611 mergeResources(it->second, actualRemoved);
Chong Zhangfb092d32019-08-12 09:45:44 -0700612 }
613 }
614 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700615 if (mObserverService != nullptr && !resourceRemoved.empty()) {
616 mObserverService->onResourceRemoved(info.uid, pid, resourceRemoved);
617 }
Chong Zhang181e6952019-10-09 13:23:39 -0700618 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700619}
620
Girish9128e242022-11-23 20:52:29 +0000621Status ResourceManagerService::removeClient(const ClientInfoParcel& clientInfo) {
622 removeResource(clientInfo, true /*checkValid*/);
Chong Zhang181e6952019-10-09 13:23:39 -0700623 return Status::ok();
Wonsik Kim3e378962017-01-05 17:00:02 +0900624}
625
Girish9128e242022-11-23 20:52:29 +0000626Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo, bool checkValid) {
627 int32_t pid = clientInfo.pid;
628 int32_t uid = clientInfo.uid;
629 int64_t clientId = clientInfo.id;
630 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
631 pid, uid, (long long) clientId);
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700632 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700633
634 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100635 if (checkValid && !mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800636 pid_t callingPid = IPCThreadState::self()->getCallingPid();
637 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
638 pid, callingPid);
639 pid = callingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800640 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700641 ssize_t index = mMap.indexOfKey(pid);
642 if (index < 0) {
643 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700644 return Status::ok();
Ronghua Wu37c89242015-07-15 12:23:48 -0700645 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700646 ResourceInfos &infos = mMap.editValueAt(index);
Chong Zhangfb092d32019-08-12 09:45:44 -0700647
648 index = infos.indexOfKey(clientId);
649 if (index < 0) {
650 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700651 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700652 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700653
654 const ResourceInfo &info = infos[index];
655 for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
656 onLastRemoved(it->second, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700657 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700658
Girish9128e242022-11-23 20:52:29 +0000659 // Since this client has been removed, decrease the corresponding
660 // resources instance count.
661 decreaseResourceInstanceCount(clientId, info.name);
662
Arun Johnsond1f59732022-03-25 17:10:29 +0000663 removeCookieAndUnlink_l(info.client, info.cookie);
Chong Zhangfb092d32019-08-12 09:45:44 -0700664
Chong Zhanga9d45c72020-09-09 12:41:17 -0700665 if (mObserverService != nullptr && !info.resources.empty()) {
666 mObserverService->onResourceRemoved(info.uid, pid, info.resources);
667 }
668
Chong Zhangfb092d32019-08-12 09:45:44 -0700669 infos.removeItemsAt(index);
Chong Zhang181e6952019-10-09 13:23:39 -0700670 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700671}
672
Girish9128e242022-11-23 20:52:29 +0000673void ResourceManagerService::getClientForResource_l(int callingPid,
674 const MediaResourceParcel *res,
675 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800676 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700677 if (res == NULL) {
678 return;
679 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800680 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +0000681 if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, idVector, &client)) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700682 clients->push_back(client);
683 }
684}
685
Girish9128e242022-11-23 20:52:29 +0000686Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
Brian Lindahl64ee9452022-01-14 13:31:16 +0100687 const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
Girish9128e242022-11-23 20:52:29 +0000688 int32_t callingPid = clientInfo.pid;
689 std::string clientName = clientInfo.name;
690 String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
691 callingPid, clientInfo.uid, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700692 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700693 *_aidl_return = false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700694
Chong Zhangfdd512a2019-11-22 11:03:14 -0800695 Vector<std::shared_ptr<IResourceManagerClient>> clients;
Girish9128e242022-11-23 20:52:29 +0000696 PidUidVector idVector;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700697 {
698 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100699 if (!mProcessInfo->isPidTrusted(callingPid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800700 pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
701 ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
702 callingPid, actualCallingPid);
703 callingPid = actualCallingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800704 }
Chong Zhang181e6952019-10-09 13:23:39 -0700705 const MediaResourceParcel *secureCodec = NULL;
706 const MediaResourceParcel *nonSecureCodec = NULL;
707 const MediaResourceParcel *graphicMemory = NULL;
708 const MediaResourceParcel *drmSession = NULL;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700709 for (size_t i = 0; i < resources.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100710 switch (resources[i].type) {
711 case MediaResource::Type::kSecureCodec:
712 secureCodec = &resources[i];
713 break;
714 case MediaResource::Type::kNonSecureCodec:
715 nonSecureCodec = &resources[i];
716 break;
717 case MediaResource::Type::kGraphicMemory:
718 graphicMemory = &resources[i];
719 break;
720 case MediaResource::Type::kDrmSession:
721 drmSession = &resources[i];
722 break;
723 default:
724 break;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700725 }
726 }
727
728 // first pass to handle secure/non-secure codec conflict
729 if (secureCodec != NULL) {
730 if (!mSupportsMultipleSecureCodecs) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100731 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000732 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700733 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700734 }
735 }
736 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100737 if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000738 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700739 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700740 }
741 }
742 }
743 if (nonSecureCodec != NULL) {
744 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100745 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000746 nonSecureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700747 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700748 }
749 }
750 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700751 if (drmSession != NULL) {
Girish9128e242022-11-23 20:52:29 +0000752 getClientForResource_l(callingPid, drmSession, &idVector, &clients);
Robert Shihc3af31b2019-09-20 21:45:01 -0700753 if (clients.size() == 0) {
Chong Zhang181e6952019-10-09 13:23:39 -0700754 return Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700755 }
756 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700757
758 if (clients.size() == 0) {
759 // if no secure/non-secure codec conflict, run second pass to handle other resources.
Girish9128e242022-11-23 20:52:29 +0000760 getClientForResource_l(callingPid, graphicMemory, &idVector, &clients);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700761 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700762
763 if (clients.size() == 0) {
764 // if we are here, run the third pass to free one codec with the same type.
Girish9128e242022-11-23 20:52:29 +0000765 getClientForResource_l(callingPid, secureCodec, &idVector, &clients);
766 getClientForResource_l(callingPid, nonSecureCodec, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700767 }
768
769 if (clients.size() == 0) {
770 // if we are here, run the fourth pass to free one codec with the different type.
771 if (secureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700772 MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000773 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700774 }
775 if (nonSecureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700776 MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000777 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700778 }
779 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700780 }
781
Brian Lindahl64ee9452022-01-14 13:31:16 +0100782 *_aidl_return = reclaimUnconditionallyFrom(clients);
Girish9128e242022-11-23 20:52:29 +0000783
784 // Log Reclaim Pushed Atom to statsd
785 pushReclaimAtom(clientInfo, clients, idVector, *_aidl_return);
786
Wonsik Kim271429d2020-10-01 10:12:56 -0700787 return Status::ok();
788}
789
Girish9128e242022-11-23 20:52:29 +0000790void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
791 const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
792 const PidUidVector& idVector, bool reclaimed) {
793 // Construct the metrics for codec reclaim as a pushed atom.
794 // 1. Information about the requester.
795 // - UID and the priority (oom score)
796 int32_t callingPid = clientInfo.pid;
797 int32_t requesterUid = clientInfo.uid;
798 std::string clientName = clientInfo.name;
799 int requesterPriority = -1;
800 getPriority_l(callingPid, &requesterPriority);
801
802 // 2. Information about the codec.
803 // - Name of the codec requested
804 // - Number of concurrent codecs running.
805 int32_t noOfConcurrentCodecs = 0;
806 auto found = mConcurrentResourceCountMap.find(clientName);
807 if (found != mConcurrentResourceCountMap.end()) {
808 noOfConcurrentCodecs = found->second;
809 }
810
811 // 3. Information about the Reclaim:
812 // - Status of reclaim request
813 // - How many codecs are reclaimed
814 // - For each codecs reclaimed, information of the process that it belonged to:
815 // - UID and the Priority (oom score)
816 int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
817 if (!reclaimed) {
818 if (clients.size() == 0) {
819 // No clients to reclaim from
820 reclaimStatus =
821 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
822 } else {
823 // Couldn't reclaim resources from the clients
824 reclaimStatus =
825 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
826 }
827 }
828 int32_t noOfCodecsReclaimed = clients.size();
829 int32_t targetIndex = 1;
830 for (const auto& id : idVector) {
831 int32_t targetUid = id.second;
832 int targetPriority = -1;
833 getPriority_l(id.first, &targetPriority);
834 // Post the pushed atom
835 int result = stats_write(
836 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
837 requesterUid,
838 requesterPriority,
839 clientName.c_str(),
840 noOfConcurrentCodecs,
841 reclaimStatus,
842 noOfCodecsReclaimed,
843 targetIndex,
844 targetUid,
845 targetPriority);
846 ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
847 "Requester[pid(%d): uid(%d): priority(%d)] "
848 "Codec: [%s] "
849 "No of concurrent codecs: %d "
850 "Reclaim Status: %d "
851 "No of codecs reclaimed: %d "
852 "Target[%d][pid(%d): uid(%d): priority(%d)] "
853 "Atom Size: %d",
854 __func__, callingPid, requesterUid, requesterPriority,
855 clientName.c_str(), noOfConcurrentCodecs,
856 reclaimStatus, noOfCodecsReclaimed,
857 targetIndex, id.first, targetUid, targetPriority, result);
858 targetIndex++;
859 }
860}
861
Brian Lindahl64ee9452022-01-14 13:31:16 +0100862bool ResourceManagerService::reclaimUnconditionallyFrom(
Wonsik Kim271429d2020-10-01 10:12:56 -0700863 const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700864 if (clients.size() == 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700865 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700866 }
867
Chong Zhangfdd512a2019-11-22 11:03:14 -0800868 std::shared_ptr<IResourceManagerClient> failedClient;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700869 for (size_t i = 0; i < clients.size(); ++i) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700870 String8 log = String8::format("reclaimResource from client %p", clients[i].get());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700871 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700872 bool success;
873 Status status = clients[i]->reclaimResource(&success);
874 if (!status.isOk() || !success) {
Ronghua Wu67e7f542015-03-13 10:47:08 -0700875 failedClient = clients[i];
876 break;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700877 }
878 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700879
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700880 if (failedClient == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700881 return true;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700882 }
883
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200884 int failedClientPid = -1;
Ronghua Wu67e7f542015-03-13 10:47:08 -0700885 {
886 Mutex::Autolock lock(mLock);
887 bool found = false;
888 for (size_t i = 0; i < mMap.size(); ++i) {
889 ResourceInfos &infos = mMap.editValueAt(i);
890 for (size_t j = 0; j < infos.size();) {
891 if (infos[j].client == failedClient) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700892 j = infos.removeItemsAt(j);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700893 found = true;
894 } else {
895 ++j;
896 }
897 }
898 if (found) {
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200899 failedClientPid = mMap.keyAt(i);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700900 break;
901 }
902 }
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200903 if (found) {
904 ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
905 } else {
906 ALOGW("Failed to reclaim resources from unlocateable client");
Ronghua Wu67e7f542015-03-13 10:47:08 -0700907 }
908 }
909
Wonsik Kim271429d2020-10-01 10:12:56 -0700910 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700911}
912
Brian Lindahl64ee9452022-01-14 13:31:16 +0100913Status ResourceManagerService::overridePid(int originalPid, int newPid) {
Henry Fang32762922020-01-28 18:40:39 -0800914 String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
915 originalPid, newPid);
916 mServiceLog->add(log);
917
918 // allow if this is called from the same process or the process has
919 // permission.
920 if ((AIBinder_getCallingPid() != getpid()) &&
921 (checkCallingPermission(String16(
922 "android.permission.MEDIA_RESOURCE_OVERRIDE_PID")) == false)) {
923 ALOGE(
924 "Permission Denial: can't access overridePid method from pid=%d, "
925 "self pid=%d\n",
926 AIBinder_getCallingPid(), getpid());
927 return Status::fromServiceSpecificError(PERMISSION_DENIED);
928 }
929
930 {
931 Mutex::Autolock lock(mLock);
932 mOverridePidMap.erase(originalPid);
933 if (newPid != -1) {
934 mOverridePidMap.emplace(originalPid, newPid);
935 }
936 }
937
938 return Status::ok();
939}
940
Chong Zhang97d367b2020-09-16 12:53:14 -0700941Status ResourceManagerService::overrideProcessInfo(
Brian Lindahl64ee9452022-01-14 13:31:16 +0100942 const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState,
Chong Zhang97d367b2020-09-16 12:53:14 -0700943 int oomScore) {
944 String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)",
945 pid, procState, oomScore);
946 mServiceLog->add(log);
947
948 // Only allow the override if the caller already can access process state and oom scores.
949 int callingPid = AIBinder_getCallingPid();
950 if (callingPid != getpid() && (callingPid != pid || !checkCallingPermission(String16(
951 "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE")))) {
952 ALOGE("Permission Denial: overrideProcessInfo method from pid=%d", callingPid);
953 return Status::fromServiceSpecificError(PERMISSION_DENIED);
954 }
955
956 if (client == nullptr) {
957 return Status::fromServiceSpecificError(BAD_VALUE);
958 }
959
960 Mutex::Autolock lock(mLock);
961 removeProcessInfoOverride_l(pid);
962
963 if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
964 // Override value is rejected by ProcessInfo.
965 return Status::fromServiceSpecificError(BAD_VALUE);
966 }
967
Arun Johnsond1f59732022-03-25 17:10:29 +0000968 uintptr_t cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700969 new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), pid));
970
971 mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{cookie, client});
972
973 return Status::ok();
974}
975
Arun Johnsond1f59732022-03-25 17:10:29 +0000976uintptr_t ResourceManagerService::addCookieAndLink_l(
977 const std::shared_ptr<IResourceManagerClient>& client, const sp<DeathNotifier>& notifier) {
978 if (client == nullptr) {
979 return 0;
980 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700981 std::scoped_lock lock{sCookieLock};
982
983 uintptr_t cookie;
984 // Need to skip cookie 0 (if it wraps around). ResourceInfo has cookie initialized to 0
985 // indicating the death notifier is not created yet.
986 while ((cookie = ++sCookieCounter) == 0);
Arun Johnsond1f59732022-03-25 17:10:29 +0000987 AIBinder_linkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -0700988 sCookieToDeathNotifierMap.emplace(cookie, notifier);
989
990 return cookie;
991}
992
Arun Johnsond1f59732022-03-25 17:10:29 +0000993void ResourceManagerService::removeCookieAndUnlink_l(
994 const std::shared_ptr<IResourceManagerClient>& client, uintptr_t cookie) {
Chong Zhang97d367b2020-09-16 12:53:14 -0700995 std::scoped_lock lock{sCookieLock};
Arun Johnsond1f59732022-03-25 17:10:29 +0000996 if (client != nullptr) {
997 AIBinder_unlinkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
998 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700999 sCookieToDeathNotifierMap.erase(cookie);
1000}
1001
1002void ResourceManagerService::removeProcessInfoOverride(int pid) {
1003 Mutex::Autolock lock(mLock);
1004
1005 removeProcessInfoOverride_l(pid);
1006}
1007
1008void ResourceManagerService::removeProcessInfoOverride_l(int pid) {
1009 auto it = mProcessInfoOverrideMap.find(pid);
1010 if (it == mProcessInfoOverrideMap.end()) {
1011 return;
1012 }
1013
1014 mProcessInfo->removeProcessInfoOverride(pid);
1015
Arun Johnsond1f59732022-03-25 17:10:29 +00001016 removeCookieAndUnlink_l(it->second.client, it->second.cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -07001017
1018 mProcessInfoOverrideMap.erase(pid);
1019}
1020
Girish9128e242022-11-23 20:52:29 +00001021Status ResourceManagerService::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
1022 int32_t pid = clientInfo.pid;
1023 int64_t clientId = clientInfo.id;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001024 String8 log = String8::format(
1025 "markClientForPendingRemoval(pid %d, clientId %lld)",
1026 pid, (long long) clientId);
1027 mServiceLog->add(log);
1028
1029 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001030 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001031 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1032 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1033 pid, callingPid);
1034 pid = callingPid;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001035 }
1036 ssize_t index = mMap.indexOfKey(pid);
1037 if (index < 0) {
1038 ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
1039 pid, (long long)clientId);
1040 return Status::ok();
1041 }
1042 ResourceInfos &infos = mMap.editValueAt(index);
1043
1044 index = infos.indexOfKey(clientId);
1045 if (index < 0) {
1046 ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
1047 return Status::ok();
1048 }
1049
1050 ResourceInfo &info = infos.editValueAt(index);
1051 info.pendingRemoval = true;
1052 return Status::ok();
1053}
1054
Wonsik Kim271429d2020-10-01 10:12:56 -07001055Status ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(int32_t pid) {
1056 String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
1057 mServiceLog->add(log);
1058
1059 Vector<std::shared_ptr<IResourceManagerClient>> clients;
1060 {
1061 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001062 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001063 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1064 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1065 pid, callingPid);
1066 pid = callingPid;
Wonsik Kim271429d2020-10-01 10:12:56 -07001067 }
1068
1069 for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
1070 MediaResource::Type::kNonSecureCodec,
1071 MediaResource::Type::kGraphicMemory,
1072 MediaResource::Type::kDrmSession}) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001073 switch (type) {
1074 // Codec resources are segregated by audio, video and image domains.
1075 case MediaResource::Type::kSecureCodec:
1076 case MediaResource::Type::kNonSecureCodec:
1077 for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec,
1078 MediaResource::SubType::kVideoCodec,
1079 MediaResource::SubType::kImageCodec}) {
1080 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001081 uid_t uid = 0;
1082 if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001083 clients.add(client);
1084 continue;
1085 }
1086 }
1087 break;
1088 // Non-codec resources are shared by audio, video and image codecs (no subtype).
1089 default:
1090 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001091 uid_t uid = 0;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001092 if (getBiggestClientPendingRemoval_l(pid, type,
Girish9128e242022-11-23 20:52:29 +00001093 MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001094 clients.add(client);
1095 }
1096 break;
Wonsik Kim271429d2020-10-01 10:12:56 -07001097 }
1098 }
1099 }
1100
1101 if (!clients.empty()) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001102 reclaimUnconditionallyFrom(clients);
Wonsik Kim271429d2020-10-01 10:12:56 -07001103 }
1104 return Status::ok();
1105}
1106
Henry Fang32762922020-01-28 18:40:39 -08001107bool ResourceManagerService::getPriority_l(int pid, int* priority) {
1108 int newPid = pid;
1109
1110 if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
1111 newPid = mOverridePidMap[pid];
1112 ALOGD("getPriority_l: use override pid %d instead original pid %d",
1113 newPid, pid);
1114 }
1115
1116 return mProcessInfo->getPriority(newPid, priority);
1117}
1118
Brian Lindahl64ee9452022-01-14 13:31:16 +01001119bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001120 MediaResource::SubType subType,
1121 PidUidVector* idVector,
1122 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Chong Zhangfdd512a2019-11-22 11:03:14 -08001123 Vector<std::shared_ptr<IResourceManagerClient>> temp;
Girish9128e242022-11-23 20:52:29 +00001124 PidUidVector tempIdList;
1125
Ronghua Wu231c3d12015-03-11 15:10:32 -07001126 for (size_t i = 0; i < mMap.size(); ++i) {
1127 ResourceInfos &infos = mMap.editValueAt(i);
1128 for (size_t j = 0; j < infos.size(); ++j) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001129 if (hasResourceType(type, subType, infos[j].resources)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001130 if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
1131 // some higher/equal priority process owns the resource,
1132 // this request can't be fulfilled.
1133 ALOGE("getAllClients_l: can't reclaim resource %s from pid %d",
Ronghua Wuea15fd22016-03-03 13:35:05 -08001134 asString(type), mMap.keyAt(i));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001135 return false;
1136 }
1137 temp.push_back(infos[j].client);
Girish9128e242022-11-23 20:52:29 +00001138 tempIdList.emplace_back(mMap.keyAt(i), infos[j].uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001139 }
1140 }
1141 }
1142 if (temp.size() == 0) {
Ronghua Wuea15fd22016-03-03 13:35:05 -08001143 ALOGV("getAllClients_l: didn't find any resource %s", asString(type));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001144 return true;
1145 }
1146 clients->appendVector(temp);
Girish9128e242022-11-23 20:52:29 +00001147 idVector->insert(std::end(*idVector), std::begin(tempIdList), std::end(tempIdList));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001148 return true;
1149}
1150
Brian Lindahl64ee9452022-01-14 13:31:16 +01001151bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid,
Girish9128e242022-11-23 20:52:29 +00001152 MediaResource::Type type,
1153 MediaResource::SubType subType,
1154 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -08001155 std::shared_ptr<IResourceManagerClient> *client) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001156 int lowestPriorityPid;
1157 int lowestPriority;
1158 int callingPriority;
Girish9128e242022-11-23 20:52:29 +00001159 uid_t uid = 0;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001160
1161 // Before looking into other processes, check if we have clients marked for
1162 // pending removal in the same process.
Girish9128e242022-11-23 20:52:29 +00001163 if (getBiggestClientPendingRemoval_l(callingPid, type, subType, uid, client)) {
1164 idVector->emplace_back(callingPid, uid);
Wonsik Kimd20e9362020-04-28 10:42:57 -07001165 return true;
1166 }
Henry Fang32762922020-01-28 18:40:39 -08001167 if (!getPriority_l(callingPid, &callingPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001168 ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
1169 callingPid);
1170 return false;
1171 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001172 if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001173 return false;
1174 }
1175 if (lowestPriority <= callingPriority) {
1176 ALOGE("getLowestPriorityBiggestClient_l: lowest priority %d vs caller priority %d",
1177 lowestPriority, callingPriority);
1178 return false;
1179 }
1180
Girish9128e242022-11-23 20:52:29 +00001181 if (!getBiggestClient_l(lowestPriorityPid, type, subType, uid, client)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001182 return false;
1183 }
Girish9128e242022-11-23 20:52:29 +00001184
1185 idVector->emplace_back(lowestPriorityPid, uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001186 return true;
1187}
1188
Brian Lindahl64ee9452022-01-14 13:31:16 +01001189bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type,
1190 MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001191 int pid = -1;
1192 int priority = -1;
1193 for (size_t i = 0; i < mMap.size(); ++i) {
1194 if (mMap.valueAt(i).size() == 0) {
1195 // no client on this process.
1196 continue;
1197 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001198 if (!hasResourceType(type, subType, mMap.valueAt(i))) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001199 // doesn't have the requested resource type
1200 continue;
1201 }
1202 int tempPid = mMap.keyAt(i);
1203 int tempPriority;
Henry Fang32762922020-01-28 18:40:39 -08001204 if (!getPriority_l(tempPid, &tempPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001205 ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
1206 // TODO: remove this pid from mMap?
1207 continue;
1208 }
1209 if (pid == -1 || tempPriority > priority) {
1210 // initial the value
1211 pid = tempPid;
1212 priority = tempPriority;
1213 }
1214 }
1215 if (pid != -1) {
1216 *lowestPriorityPid = pid;
1217 *lowestPriority = priority;
1218 }
1219 return (pid != -1);
1220}
1221
1222bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) {
1223 int callingPidPriority;
Henry Fang32762922020-01-28 18:40:39 -08001224 if (!getPriority_l(callingPid, &callingPidPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001225 return false;
1226 }
1227
1228 int priority;
Henry Fang32762922020-01-28 18:40:39 -08001229 if (!getPriority_l(pid, &priority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001230 return false;
1231 }
1232
1233 return (callingPidPriority < priority);
1234}
1235
Brian Lindahl64ee9452022-01-14 13:31:16 +01001236bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001237 MediaResource::SubType subType, uid_t& uid,
1238 std::shared_ptr<IResourceManagerClient> *client) {
1239 return getBiggestClient_l(pid, type, subType, uid, client, true /* pendingRemovalOnly */);
Brian Lindahl64ee9452022-01-14 13:31:16 +01001240}
1241
1242bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001243 MediaResource::SubType subType, uid_t& uid,
1244 std::shared_ptr<IResourceManagerClient> *client,
Wonsik Kimd20e9362020-04-28 10:42:57 -07001245 bool pendingRemovalOnly) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001246 ssize_t index = mMap.indexOfKey(pid);
1247 if (index < 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001248 ALOGE_IF(!pendingRemovalOnly,
1249 "getBiggestClient_l: can't find resource info for pid %d", pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001250 return false;
1251 }
1252
Chong Zhangfdd512a2019-11-22 11:03:14 -08001253 std::shared_ptr<IResourceManagerClient> clientTemp;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001254 uint64_t largestValue = 0;
1255 const ResourceInfos &infos = mMap.valueAt(index);
1256 for (size_t i = 0; i < infos.size(); ++i) {
Chong Zhangfb092d32019-08-12 09:45:44 -07001257 const ResourceList &resources = infos[i].resources;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001258 if (pendingRemovalOnly && !infos[i].pendingRemoval) {
1259 continue;
1260 }
Chong Zhangfb092d32019-08-12 09:45:44 -07001261 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -07001262 const MediaResourceParcel &resource = it->second;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001263 if (hasResourceType(type, subType, resource)) {
Chong Zhang181e6952019-10-09 13:23:39 -07001264 if (resource.value > largestValue) {
1265 largestValue = resource.value;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001266 clientTemp = infos[i].client;
Girish9128e242022-11-23 20:52:29 +00001267 uid = infos[i].uid;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001268 }
1269 }
1270 }
1271 }
1272
1273 if (clientTemp == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001274 ALOGE_IF(!pendingRemovalOnly,
Brian Lindahl64ee9452022-01-14 13:31:16 +01001275 "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d",
1276 asString(type), asString(subType), pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001277 return false;
1278 }
1279
1280 *client = clientTemp;
1281 return true;
1282}
1283
Ronghua Wu231c3d12015-03-11 15:10:32 -07001284} // namespace android