blob: f94446f14ca2443d0fe3031a2b9ade9b9924fb25 [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 =
366 AServiceManager_addService(service->asBinder().get(), getServiceName());
367 if (status != STATUS_OK) {
368 return;
369 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700370
371 std::shared_ptr<ResourceObserverService> observerService =
372 ResourceObserverService::instantiate();
373
374 if (observerService != nullptr) {
375 service->setObserverService(observerService);
376 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800377 // TODO: mediaserver main() is already starting the thread pool,
378 // move this to mediaserver main() when other services in mediaserver
379 // are converted to ndk-platform aidl.
380 //ABinderProcess_startThreadPool();
381}
382
Ronghua Wu231c3d12015-03-11 15:10:32 -0700383ResourceManagerService::~ResourceManagerService() {}
384
Chong Zhanga9d45c72020-09-09 12:41:17 -0700385void ResourceManagerService::setObserverService(
386 const std::shared_ptr<ResourceObserverService>& observerService) {
387 mObserverService = observerService;
388}
389
Chong Zhang181e6952019-10-09 13:23:39 -0700390Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700391 String8 log = String8::format("config(%s)", getString(policies).string());
392 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700393
394 Mutex::Autolock lock(mLock);
395 for (size_t i = 0; i < policies.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700396 const std::string &type = policies[i].type;
397 const std::string &value = policies[i].value;
398 if (type == MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700399 mSupportsMultipleSecureCodecs = (value == "true");
Chong Zhang181e6952019-10-09 13:23:39 -0700400 } else if (type == MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700401 mSupportsSecureWithNonSecureCodec = (value == "true");
Ronghua Wu231c3d12015-03-11 15:10:32 -0700402 }
403 }
Chong Zhang181e6952019-10-09 13:23:39 -0700404 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700405}
406
Brian Lindahl64ee9452022-01-14 13:31:16 +0100407void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource,
408 const ResourceInfo& clientInfo) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700409 // first time added
Chong Zhang181e6952019-10-09 13:23:39 -0700410 if (resource.type == MediaResource::Type::kCpuBoost
411 && resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700412 // Request it on every new instance of kCpuBoost, as the media.codec
413 // could have died, if we only do it the first time subsequent instances
414 // never gets the boost.
Chong Zhangfdd512a2019-11-22 11:03:14 -0800415 if (mSystemCB->requestCpusetBoost(true) != OK) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700416 ALOGW("couldn't request cpuset boost");
417 }
418 mCpuBoostCount++;
Chong Zhang181e6952019-10-09 13:23:39 -0700419 } else if (resource.type == MediaResource::Type::kBattery
420 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700421 mSystemCB->noteStartVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700422 }
423}
424
Brian Lindahl64ee9452022-01-14 13:31:16 +0100425void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource,
426 const ResourceInfo& clientInfo) {
Chong Zhang181e6952019-10-09 13:23:39 -0700427 if (resource.type == MediaResource::Type::kCpuBoost
428 && resource.subType == MediaResource::SubType::kUnspecifiedSubType
Chong Zhangfb092d32019-08-12 09:45:44 -0700429 && mCpuBoostCount > 0) {
430 if (--mCpuBoostCount == 0) {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800431 mSystemCB->requestCpusetBoost(false);
Chong Zhangfb092d32019-08-12 09:45:44 -0700432 }
Chong Zhang181e6952019-10-09 13:23:39 -0700433 } else if (resource.type == MediaResource::Type::kBattery
434 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700435 mSystemCB->noteStopVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700436 }
437}
438
Brian Lindahl64ee9452022-01-14 13:31:16 +0100439void ResourceManagerService::mergeResources(MediaResourceParcel& r1,
440 const MediaResourceParcel& r2) {
Chong Zhang181e6952019-10-09 13:23:39 -0700441 // The resource entry on record is maintained to be in [0,INT64_MAX].
442 // Clamp if merging in the new resource value causes it to go out of bound.
443 // Note that the new resource value could be negative, eg.DrmSession, the
444 // value goes lower when the session is used more often. During reclaim
445 // the session with the highest value (lowest usage) would be closed.
446 if (r2.value < INT64_MAX - r1.value) {
447 r1.value += r2.value;
448 if (r1.value < 0) {
449 r1.value = 0;
450 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700451 } else {
Chong Zhang181e6952019-10-09 13:23:39 -0700452 r1.value = INT64_MAX;
Robert Shihc3af31b2019-09-20 21:45:01 -0700453 }
454}
455
Girish9128e242022-11-23 20:52:29 +0000456Status ResourceManagerService::addResource(const ClientInfoParcel& clientInfo,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800457 const std::shared_ptr<IResourceManagerClient>& client,
Chong Zhang181e6952019-10-09 13:23:39 -0700458 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000459 int32_t pid = clientInfo.pid;
460 int32_t uid = clientInfo.uid;
461 int64_t clientId = clientInfo.id;
462 const std::string& name = clientInfo.name;
463 String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
464 pid, uid, (long long) clientId, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700465 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700466
467 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100468 if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800469 pid_t callingPid = IPCThreadState::self()->getCallingPid();
470 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100471 ALOGW("%s called with untrusted pid %d or uid %d, using calling pid %d, uid %d",
472 __FUNCTION__, pid, uid, callingPid, callingUid);
Chong Zhangc7303e82020-12-02 16:38:52 -0800473 pid = callingPid;
474 uid = callingUid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800475 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700476 ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
Girish9128e242022-11-23 20:52:29 +0000477 ResourceInfo& info = getResourceInfoForEdit(uid, clientId, name, client, infos);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700478 ResourceList resourceAdded;
Chong Zhang79d2b282018-04-17 14:14:31 -0700479
480 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700481 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700482 const auto resType = std::tuple(res.type, res.subType, res.id);
483
484 if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
485 ALOGW("Ignoring request to remove negative value of non-drm resource");
486 continue;
487 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700488 if (info.resources.find(resType) == info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700489 if (res.value <= 0) {
490 // We can't init a new entry with negative value, although it's allowed
491 // to merge in negative values after the initial add.
492 ALOGW("Ignoring request to add new resource entry with value <= 0");
493 continue;
494 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700495 onFirstAdded(res, info);
496 info.resources[resType] = res;
Chong Zhangfb092d32019-08-12 09:45:44 -0700497 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700498 mergeResources(info.resources[resType], res);
Chong Zhang79d2b282018-04-17 14:14:31 -0700499 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700500 // Add it to the list of added resources for observers.
501 auto it = resourceAdded.find(resType);
502 if (it == resourceAdded.end()) {
503 resourceAdded[resType] = res;
504 } else {
505 mergeResources(it->second, res);
506 }
Chong Zhang79d2b282018-04-17 14:14:31 -0700507 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700508 if (info.cookie == 0 && client != nullptr) {
Arun Johnsond1f59732022-03-25 17:10:29 +0000509 info.cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700510 new DeathNotifier(ref<ResourceManagerService>(), pid, clientId));
Wonsik Kim3e378962017-01-05 17:00:02 +0900511 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700512 if (mObserverService != nullptr && !resourceAdded.empty()) {
513 mObserverService->onResourceAdded(uid, pid, resourceAdded);
514 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900515 notifyResourceGranted(pid, resources);
Girish9128e242022-11-23 20:52:29 +0000516
517 // Increase the instance count of the resource associated with this client.
518 increaseResourceInstanceCount(clientId, name);
519
Chong Zhang181e6952019-10-09 13:23:39 -0700520 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700521}
522
Girish9128e242022-11-23 20:52:29 +0000523void ResourceManagerService::increaseResourceInstanceCount(int64_t clientId,
524 const std::string& name) {
525 // Check whether this client has been looked into already.
526 if (mClientIdSet.find(clientId) == mClientIdSet.end()) {
527 mClientIdSet.insert(clientId);
528 // Update the resource instance count.
529 auto found = mConcurrentResourceCountMap.find(name);
530 if (found == mConcurrentResourceCountMap.end()) {
531 mConcurrentResourceCountMap[name] = 1;
532 } else {
533 found->second++;
534 }
535 }
536}
537
538void ResourceManagerService::decreaseResourceInstanceCount(int64_t clientId,
539 const std::string& name) {
540 // Since this client has been removed, remove it from mClientIdSet
541 mClientIdSet.erase(clientId);
542 // Update the resource instance count also.
543 auto found = mConcurrentResourceCountMap.find(name);
544 if (found != mConcurrentResourceCountMap.end()) {
545 if (found->second == 1) {
546 mConcurrentResourceCountMap.erase(found);
547 } else {
548 found->second--;
549 }
550 }
551}
552
553Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo,
Chong Zhang181e6952019-10-09 13:23:39 -0700554 const std::vector<MediaResourceParcel>& resources) {
Girish9128e242022-11-23 20:52:29 +0000555 int32_t pid = clientInfo.pid;
556 int32_t uid = clientInfo.uid;
557 int64_t clientId = clientInfo.id;
558 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
559 pid, uid, (long long) clientId, getString(resources).string());
Chong Zhangfb092d32019-08-12 09:45:44 -0700560 mServiceLog->add(log);
561
562 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100563 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800564 pid_t callingPid = IPCThreadState::self()->getCallingPid();
565 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
566 pid, callingPid);
567 pid = callingPid;
Chong Zhangfb092d32019-08-12 09:45:44 -0700568 }
569 ssize_t index = mMap.indexOfKey(pid);
570 if (index < 0) {
571 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700572 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700573 }
574 ResourceInfos &infos = mMap.editValueAt(index);
575
576 index = infos.indexOfKey(clientId);
577 if (index < 0) {
578 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700579 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700580 }
581
582 ResourceInfo &info = infos.editValueAt(index);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700583 ResourceList resourceRemoved;
Chong Zhangfb092d32019-08-12 09:45:44 -0700584 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700585 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700586 const auto resType = std::tuple(res.type, res.subType, res.id);
587
588 if (res.value < 0) {
589 ALOGW("Ignoring request to remove negative value of resource");
590 continue;
591 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700592 // ignore if we don't have it
593 if (info.resources.find(resType) != info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700594 MediaResourceParcel &resource = info.resources[resType];
Chong Zhanga9d45c72020-09-09 12:41:17 -0700595 MediaResourceParcel actualRemoved = res;
Chong Zhang181e6952019-10-09 13:23:39 -0700596 if (resource.value > res.value) {
597 resource.value -= res.value;
Chong Zhangfb092d32019-08-12 09:45:44 -0700598 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700599 onLastRemoved(res, info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700600 actualRemoved.value = resource.value;
Chong Zhang102b3e32020-11-02 12:21:50 -0800601 info.resources.erase(resType);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700602 }
603
604 // Add it to the list of removed resources for observers.
605 auto it = resourceRemoved.find(resType);
606 if (it == resourceRemoved.end()) {
607 resourceRemoved[resType] = actualRemoved;
608 } else {
609 mergeResources(it->second, actualRemoved);
Chong Zhangfb092d32019-08-12 09:45:44 -0700610 }
611 }
612 }
Chong Zhanga9d45c72020-09-09 12:41:17 -0700613 if (mObserverService != nullptr && !resourceRemoved.empty()) {
614 mObserverService->onResourceRemoved(info.uid, pid, resourceRemoved);
615 }
Chong Zhang181e6952019-10-09 13:23:39 -0700616 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700617}
618
Girish9128e242022-11-23 20:52:29 +0000619Status ResourceManagerService::removeClient(const ClientInfoParcel& clientInfo) {
620 removeResource(clientInfo, true /*checkValid*/);
Chong Zhang181e6952019-10-09 13:23:39 -0700621 return Status::ok();
Wonsik Kim3e378962017-01-05 17:00:02 +0900622}
623
Girish9128e242022-11-23 20:52:29 +0000624Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo, bool checkValid) {
625 int32_t pid = clientInfo.pid;
626 int32_t uid = clientInfo.uid;
627 int64_t clientId = clientInfo.id;
628 String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
629 pid, uid, (long long) clientId);
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700630 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700631
632 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100633 if (checkValid && !mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800634 pid_t callingPid = IPCThreadState::self()->getCallingPid();
635 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
636 pid, callingPid);
637 pid = callingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800638 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700639 ssize_t index = mMap.indexOfKey(pid);
640 if (index < 0) {
641 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700642 return Status::ok();
Ronghua Wu37c89242015-07-15 12:23:48 -0700643 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700644 ResourceInfos &infos = mMap.editValueAt(index);
Chong Zhangfb092d32019-08-12 09:45:44 -0700645
646 index = infos.indexOfKey(clientId);
647 if (index < 0) {
648 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700649 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700650 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700651
652 const ResourceInfo &info = infos[index];
653 for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
654 onLastRemoved(it->second, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700655 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700656
Girish9128e242022-11-23 20:52:29 +0000657 // Since this client has been removed, decrease the corresponding
658 // resources instance count.
659 decreaseResourceInstanceCount(clientId, info.name);
660
Arun Johnsond1f59732022-03-25 17:10:29 +0000661 removeCookieAndUnlink_l(info.client, info.cookie);
Chong Zhangfb092d32019-08-12 09:45:44 -0700662
Chong Zhanga9d45c72020-09-09 12:41:17 -0700663 if (mObserverService != nullptr && !info.resources.empty()) {
664 mObserverService->onResourceRemoved(info.uid, pid, info.resources);
665 }
666
Chong Zhangfb092d32019-08-12 09:45:44 -0700667 infos.removeItemsAt(index);
Chong Zhang181e6952019-10-09 13:23:39 -0700668 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700669}
670
Girish9128e242022-11-23 20:52:29 +0000671void ResourceManagerService::getClientForResource_l(int callingPid,
672 const MediaResourceParcel *res,
673 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800674 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700675 if (res == NULL) {
676 return;
677 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800678 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +0000679 if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, idVector, &client)) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700680 clients->push_back(client);
681 }
682}
683
Girish9128e242022-11-23 20:52:29 +0000684Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
Brian Lindahl64ee9452022-01-14 13:31:16 +0100685 const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
Girish9128e242022-11-23 20:52:29 +0000686 int32_t callingPid = clientInfo.pid;
687 std::string clientName = clientInfo.name;
688 String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
689 callingPid, clientInfo.uid, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700690 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700691 *_aidl_return = false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700692
Chong Zhangfdd512a2019-11-22 11:03:14 -0800693 Vector<std::shared_ptr<IResourceManagerClient>> clients;
Girish9128e242022-11-23 20:52:29 +0000694 PidUidVector idVector;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700695 {
696 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +0100697 if (!mProcessInfo->isPidTrusted(callingPid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -0800698 pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
699 ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
700 callingPid, actualCallingPid);
701 callingPid = actualCallingPid;
Ronghua Wud11c43a2016-01-27 16:26:12 -0800702 }
Chong Zhang181e6952019-10-09 13:23:39 -0700703 const MediaResourceParcel *secureCodec = NULL;
704 const MediaResourceParcel *nonSecureCodec = NULL;
705 const MediaResourceParcel *graphicMemory = NULL;
706 const MediaResourceParcel *drmSession = NULL;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700707 for (size_t i = 0; i < resources.size(); ++i) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100708 switch (resources[i].type) {
709 case MediaResource::Type::kSecureCodec:
710 secureCodec = &resources[i];
711 break;
712 case MediaResource::Type::kNonSecureCodec:
713 nonSecureCodec = &resources[i];
714 break;
715 case MediaResource::Type::kGraphicMemory:
716 graphicMemory = &resources[i];
717 break;
718 case MediaResource::Type::kDrmSession:
719 drmSession = &resources[i];
720 break;
721 default:
722 break;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700723 }
724 }
725
726 // first pass to handle secure/non-secure codec conflict
727 if (secureCodec != NULL) {
728 if (!mSupportsMultipleSecureCodecs) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100729 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000730 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700731 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700732 }
733 }
734 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100735 if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000736 secureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700737 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700738 }
739 }
740 }
741 if (nonSecureCodec != NULL) {
742 if (!mSupportsSecureWithNonSecureCodec) {
Brian Lindahl64ee9452022-01-14 13:31:16 +0100743 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
Girish9128e242022-11-23 20:52:29 +0000744 nonSecureCodec->subType, &idVector, &clients)) {
Chong Zhang181e6952019-10-09 13:23:39 -0700745 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700746 }
747 }
748 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700749 if (drmSession != NULL) {
Girish9128e242022-11-23 20:52:29 +0000750 getClientForResource_l(callingPid, drmSession, &idVector, &clients);
Robert Shihc3af31b2019-09-20 21:45:01 -0700751 if (clients.size() == 0) {
Chong Zhang181e6952019-10-09 13:23:39 -0700752 return Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700753 }
754 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700755
756 if (clients.size() == 0) {
757 // if no secure/non-secure codec conflict, run second pass to handle other resources.
Girish9128e242022-11-23 20:52:29 +0000758 getClientForResource_l(callingPid, graphicMemory, &idVector, &clients);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700759 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700760
761 if (clients.size() == 0) {
762 // if we are here, run the third pass to free one codec with the same type.
Girish9128e242022-11-23 20:52:29 +0000763 getClientForResource_l(callingPid, secureCodec, &idVector, &clients);
764 getClientForResource_l(callingPid, nonSecureCodec, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700765 }
766
767 if (clients.size() == 0) {
768 // if we are here, run the fourth pass to free one codec with the different type.
769 if (secureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700770 MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000771 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700772 }
773 if (nonSecureCodec != NULL) {
Wonsik Kimb3639012022-03-16 13:57:41 -0700774 MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
Girish9128e242022-11-23 20:52:29 +0000775 getClientForResource_l(callingPid, &temp, &idVector, &clients);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700776 }
777 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700778 }
779
Brian Lindahl64ee9452022-01-14 13:31:16 +0100780 *_aidl_return = reclaimUnconditionallyFrom(clients);
Girish9128e242022-11-23 20:52:29 +0000781
782 // Log Reclaim Pushed Atom to statsd
783 pushReclaimAtom(clientInfo, clients, idVector, *_aidl_return);
784
Wonsik Kim271429d2020-10-01 10:12:56 -0700785 return Status::ok();
786}
787
Girish9128e242022-11-23 20:52:29 +0000788void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
789 const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
790 const PidUidVector& idVector, bool reclaimed) {
791 // Construct the metrics for codec reclaim as a pushed atom.
792 // 1. Information about the requester.
793 // - UID and the priority (oom score)
794 int32_t callingPid = clientInfo.pid;
795 int32_t requesterUid = clientInfo.uid;
796 std::string clientName = clientInfo.name;
797 int requesterPriority = -1;
798 getPriority_l(callingPid, &requesterPriority);
799
800 // 2. Information about the codec.
801 // - Name of the codec requested
802 // - Number of concurrent codecs running.
803 int32_t noOfConcurrentCodecs = 0;
804 auto found = mConcurrentResourceCountMap.find(clientName);
805 if (found != mConcurrentResourceCountMap.end()) {
806 noOfConcurrentCodecs = found->second;
807 }
808
809 // 3. Information about the Reclaim:
810 // - Status of reclaim request
811 // - How many codecs are reclaimed
812 // - For each codecs reclaimed, information of the process that it belonged to:
813 // - UID and the Priority (oom score)
814 int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
815 if (!reclaimed) {
816 if (clients.size() == 0) {
817 // No clients to reclaim from
818 reclaimStatus =
819 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
820 } else {
821 // Couldn't reclaim resources from the clients
822 reclaimStatus =
823 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
824 }
825 }
826 int32_t noOfCodecsReclaimed = clients.size();
827 int32_t targetIndex = 1;
828 for (const auto& id : idVector) {
829 int32_t targetUid = id.second;
830 int targetPriority = -1;
831 getPriority_l(id.first, &targetPriority);
832 // Post the pushed atom
833 int result = stats_write(
834 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
835 requesterUid,
836 requesterPriority,
837 clientName.c_str(),
838 noOfConcurrentCodecs,
839 reclaimStatus,
840 noOfCodecsReclaimed,
841 targetIndex,
842 targetUid,
843 targetPriority);
844 ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
845 "Requester[pid(%d): uid(%d): priority(%d)] "
846 "Codec: [%s] "
847 "No of concurrent codecs: %d "
848 "Reclaim Status: %d "
849 "No of codecs reclaimed: %d "
850 "Target[%d][pid(%d): uid(%d): priority(%d)] "
851 "Atom Size: %d",
852 __func__, callingPid, requesterUid, requesterPriority,
853 clientName.c_str(), noOfConcurrentCodecs,
854 reclaimStatus, noOfCodecsReclaimed,
855 targetIndex, id.first, targetUid, targetPriority, result);
856 targetIndex++;
857 }
858}
859
Brian Lindahl64ee9452022-01-14 13:31:16 +0100860bool ResourceManagerService::reclaimUnconditionallyFrom(
Wonsik Kim271429d2020-10-01 10:12:56 -0700861 const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700862 if (clients.size() == 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700863 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700864 }
865
Chong Zhangfdd512a2019-11-22 11:03:14 -0800866 std::shared_ptr<IResourceManagerClient> failedClient;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700867 for (size_t i = 0; i < clients.size(); ++i) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700868 String8 log = String8::format("reclaimResource from client %p", clients[i].get());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700869 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700870 bool success;
871 Status status = clients[i]->reclaimResource(&success);
872 if (!status.isOk() || !success) {
Ronghua Wu67e7f542015-03-13 10:47:08 -0700873 failedClient = clients[i];
874 break;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700875 }
876 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700877
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700878 if (failedClient == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -0700879 return true;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700880 }
881
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200882 int failedClientPid = -1;
Ronghua Wu67e7f542015-03-13 10:47:08 -0700883 {
884 Mutex::Autolock lock(mLock);
885 bool found = false;
886 for (size_t i = 0; i < mMap.size(); ++i) {
887 ResourceInfos &infos = mMap.editValueAt(i);
888 for (size_t j = 0; j < infos.size();) {
889 if (infos[j].client == failedClient) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700890 j = infos.removeItemsAt(j);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700891 found = true;
892 } else {
893 ++j;
894 }
895 }
896 if (found) {
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200897 failedClientPid = mMap.keyAt(i);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700898 break;
899 }
900 }
Brian Lindahl9f626cf2022-04-25 13:29:59 +0200901 if (found) {
902 ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
903 } else {
904 ALOGW("Failed to reclaim resources from unlocateable client");
Ronghua Wu67e7f542015-03-13 10:47:08 -0700905 }
906 }
907
Wonsik Kim271429d2020-10-01 10:12:56 -0700908 return false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700909}
910
Brian Lindahl64ee9452022-01-14 13:31:16 +0100911Status ResourceManagerService::overridePid(int originalPid, int newPid) {
Henry Fang32762922020-01-28 18:40:39 -0800912 String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
913 originalPid, newPid);
914 mServiceLog->add(log);
915
916 // allow if this is called from the same process or the process has
917 // permission.
918 if ((AIBinder_getCallingPid() != getpid()) &&
919 (checkCallingPermission(String16(
920 "android.permission.MEDIA_RESOURCE_OVERRIDE_PID")) == false)) {
921 ALOGE(
922 "Permission Denial: can't access overridePid method from pid=%d, "
923 "self pid=%d\n",
924 AIBinder_getCallingPid(), getpid());
925 return Status::fromServiceSpecificError(PERMISSION_DENIED);
926 }
927
928 {
929 Mutex::Autolock lock(mLock);
930 mOverridePidMap.erase(originalPid);
931 if (newPid != -1) {
932 mOverridePidMap.emplace(originalPid, newPid);
933 }
934 }
935
936 return Status::ok();
937}
938
Chong Zhang97d367b2020-09-16 12:53:14 -0700939Status ResourceManagerService::overrideProcessInfo(
Brian Lindahl64ee9452022-01-14 13:31:16 +0100940 const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState,
Chong Zhang97d367b2020-09-16 12:53:14 -0700941 int oomScore) {
942 String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)",
943 pid, procState, oomScore);
944 mServiceLog->add(log);
945
946 // Only allow the override if the caller already can access process state and oom scores.
947 int callingPid = AIBinder_getCallingPid();
948 if (callingPid != getpid() && (callingPid != pid || !checkCallingPermission(String16(
949 "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE")))) {
950 ALOGE("Permission Denial: overrideProcessInfo method from pid=%d", callingPid);
951 return Status::fromServiceSpecificError(PERMISSION_DENIED);
952 }
953
954 if (client == nullptr) {
955 return Status::fromServiceSpecificError(BAD_VALUE);
956 }
957
958 Mutex::Autolock lock(mLock);
959 removeProcessInfoOverride_l(pid);
960
961 if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
962 // Override value is rejected by ProcessInfo.
963 return Status::fromServiceSpecificError(BAD_VALUE);
964 }
965
Arun Johnsond1f59732022-03-25 17:10:29 +0000966 uintptr_t cookie = addCookieAndLink_l(client,
Chong Zhang97d367b2020-09-16 12:53:14 -0700967 new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), pid));
968
969 mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{cookie, client});
970
971 return Status::ok();
972}
973
Arun Johnsond1f59732022-03-25 17:10:29 +0000974uintptr_t ResourceManagerService::addCookieAndLink_l(
975 const std::shared_ptr<IResourceManagerClient>& client, const sp<DeathNotifier>& notifier) {
976 if (client == nullptr) {
977 return 0;
978 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700979 std::scoped_lock lock{sCookieLock};
980
981 uintptr_t cookie;
982 // Need to skip cookie 0 (if it wraps around). ResourceInfo has cookie initialized to 0
983 // indicating the death notifier is not created yet.
984 while ((cookie = ++sCookieCounter) == 0);
Arun Johnsond1f59732022-03-25 17:10:29 +0000985 AIBinder_linkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -0700986 sCookieToDeathNotifierMap.emplace(cookie, notifier);
987
988 return cookie;
989}
990
Arun Johnsond1f59732022-03-25 17:10:29 +0000991void ResourceManagerService::removeCookieAndUnlink_l(
992 const std::shared_ptr<IResourceManagerClient>& client, uintptr_t cookie) {
Chong Zhang97d367b2020-09-16 12:53:14 -0700993 std::scoped_lock lock{sCookieLock};
Arun Johnsond1f59732022-03-25 17:10:29 +0000994 if (client != nullptr) {
995 AIBinder_unlinkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
996 }
Chong Zhang97d367b2020-09-16 12:53:14 -0700997 sCookieToDeathNotifierMap.erase(cookie);
998}
999
1000void ResourceManagerService::removeProcessInfoOverride(int pid) {
1001 Mutex::Autolock lock(mLock);
1002
1003 removeProcessInfoOverride_l(pid);
1004}
1005
1006void ResourceManagerService::removeProcessInfoOverride_l(int pid) {
1007 auto it = mProcessInfoOverrideMap.find(pid);
1008 if (it == mProcessInfoOverrideMap.end()) {
1009 return;
1010 }
1011
1012 mProcessInfo->removeProcessInfoOverride(pid);
1013
Arun Johnsond1f59732022-03-25 17:10:29 +00001014 removeCookieAndUnlink_l(it->second.client, it->second.cookie);
Chong Zhang97d367b2020-09-16 12:53:14 -07001015
1016 mProcessInfoOverrideMap.erase(pid);
1017}
1018
Girish9128e242022-11-23 20:52:29 +00001019Status ResourceManagerService::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
1020 int32_t pid = clientInfo.pid;
1021 int64_t clientId = clientInfo.id;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001022 String8 log = String8::format(
1023 "markClientForPendingRemoval(pid %d, clientId %lld)",
1024 pid, (long long) clientId);
1025 mServiceLog->add(log);
1026
1027 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001028 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001029 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1030 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1031 pid, callingPid);
1032 pid = callingPid;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001033 }
1034 ssize_t index = mMap.indexOfKey(pid);
1035 if (index < 0) {
1036 ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
1037 pid, (long long)clientId);
1038 return Status::ok();
1039 }
1040 ResourceInfos &infos = mMap.editValueAt(index);
1041
1042 index = infos.indexOfKey(clientId);
1043 if (index < 0) {
1044 ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
1045 return Status::ok();
1046 }
1047
1048 ResourceInfo &info = infos.editValueAt(index);
1049 info.pendingRemoval = true;
1050 return Status::ok();
1051}
1052
Wonsik Kim271429d2020-10-01 10:12:56 -07001053Status ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(int32_t pid) {
1054 String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
1055 mServiceLog->add(log);
1056
1057 Vector<std::shared_ptr<IResourceManagerClient>> clients;
1058 {
1059 Mutex::Autolock lock(mLock);
Brian Lindahlcf3bafb2022-01-27 14:21:38 +01001060 if (!mProcessInfo->isPidTrusted(pid)) {
Chong Zhangc7303e82020-12-02 16:38:52 -08001061 pid_t callingPid = IPCThreadState::self()->getCallingPid();
1062 ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
1063 pid, callingPid);
1064 pid = callingPid;
Wonsik Kim271429d2020-10-01 10:12:56 -07001065 }
1066
1067 for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
1068 MediaResource::Type::kNonSecureCodec,
1069 MediaResource::Type::kGraphicMemory,
1070 MediaResource::Type::kDrmSession}) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001071 switch (type) {
1072 // Codec resources are segregated by audio, video and image domains.
1073 case MediaResource::Type::kSecureCodec:
1074 case MediaResource::Type::kNonSecureCodec:
1075 for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec,
1076 MediaResource::SubType::kVideoCodec,
1077 MediaResource::SubType::kImageCodec}) {
1078 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001079 uid_t uid = 0;
1080 if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001081 clients.add(client);
1082 continue;
1083 }
1084 }
1085 break;
1086 // Non-codec resources are shared by audio, video and image codecs (no subtype).
1087 default:
1088 std::shared_ptr<IResourceManagerClient> client;
Girish9128e242022-11-23 20:52:29 +00001089 uid_t uid = 0;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001090 if (getBiggestClientPendingRemoval_l(pid, type,
Girish9128e242022-11-23 20:52:29 +00001091 MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001092 clients.add(client);
1093 }
1094 break;
Wonsik Kim271429d2020-10-01 10:12:56 -07001095 }
1096 }
1097 }
1098
1099 if (!clients.empty()) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001100 reclaimUnconditionallyFrom(clients);
Wonsik Kim271429d2020-10-01 10:12:56 -07001101 }
1102 return Status::ok();
1103}
1104
Henry Fang32762922020-01-28 18:40:39 -08001105bool ResourceManagerService::getPriority_l(int pid, int* priority) {
1106 int newPid = pid;
1107
1108 if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
1109 newPid = mOverridePidMap[pid];
1110 ALOGD("getPriority_l: use override pid %d instead original pid %d",
1111 newPid, pid);
1112 }
1113
1114 return mProcessInfo->getPriority(newPid, priority);
1115}
1116
Brian Lindahl64ee9452022-01-14 13:31:16 +01001117bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001118 MediaResource::SubType subType,
1119 PidUidVector* idVector,
1120 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Chong Zhangfdd512a2019-11-22 11:03:14 -08001121 Vector<std::shared_ptr<IResourceManagerClient>> temp;
Girish9128e242022-11-23 20:52:29 +00001122 PidUidVector tempIdList;
1123
Ronghua Wu231c3d12015-03-11 15:10:32 -07001124 for (size_t i = 0; i < mMap.size(); ++i) {
1125 ResourceInfos &infos = mMap.editValueAt(i);
1126 for (size_t j = 0; j < infos.size(); ++j) {
Brian Lindahl64ee9452022-01-14 13:31:16 +01001127 if (hasResourceType(type, subType, infos[j].resources)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001128 if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
1129 // some higher/equal priority process owns the resource,
1130 // this request can't be fulfilled.
1131 ALOGE("getAllClients_l: can't reclaim resource %s from pid %d",
Ronghua Wuea15fd22016-03-03 13:35:05 -08001132 asString(type), mMap.keyAt(i));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001133 return false;
1134 }
1135 temp.push_back(infos[j].client);
Girish9128e242022-11-23 20:52:29 +00001136 tempIdList.emplace_back(mMap.keyAt(i), infos[j].uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001137 }
1138 }
1139 }
1140 if (temp.size() == 0) {
Ronghua Wuea15fd22016-03-03 13:35:05 -08001141 ALOGV("getAllClients_l: didn't find any resource %s", asString(type));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001142 return true;
1143 }
1144 clients->appendVector(temp);
Girish9128e242022-11-23 20:52:29 +00001145 idVector->insert(std::end(*idVector), std::begin(tempIdList), std::end(tempIdList));
Ronghua Wu231c3d12015-03-11 15:10:32 -07001146 return true;
1147}
1148
Brian Lindahl64ee9452022-01-14 13:31:16 +01001149bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid,
Girish9128e242022-11-23 20:52:29 +00001150 MediaResource::Type type,
1151 MediaResource::SubType subType,
1152 PidUidVector* idVector,
Chong Zhangfdd512a2019-11-22 11:03:14 -08001153 std::shared_ptr<IResourceManagerClient> *client) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001154 int lowestPriorityPid;
1155 int lowestPriority;
1156 int callingPriority;
Girish9128e242022-11-23 20:52:29 +00001157 uid_t uid = 0;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001158
1159 // Before looking into other processes, check if we have clients marked for
1160 // pending removal in the same process.
Girish9128e242022-11-23 20:52:29 +00001161 if (getBiggestClientPendingRemoval_l(callingPid, type, subType, uid, client)) {
1162 idVector->emplace_back(callingPid, uid);
Wonsik Kimd20e9362020-04-28 10:42:57 -07001163 return true;
1164 }
Henry Fang32762922020-01-28 18:40:39 -08001165 if (!getPriority_l(callingPid, &callingPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001166 ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
1167 callingPid);
1168 return false;
1169 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001170 if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001171 return false;
1172 }
1173 if (lowestPriority <= callingPriority) {
1174 ALOGE("getLowestPriorityBiggestClient_l: lowest priority %d vs caller priority %d",
1175 lowestPriority, callingPriority);
1176 return false;
1177 }
1178
Girish9128e242022-11-23 20:52:29 +00001179 if (!getBiggestClient_l(lowestPriorityPid, type, subType, uid, client)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001180 return false;
1181 }
Girish9128e242022-11-23 20:52:29 +00001182
1183 idVector->emplace_back(lowestPriorityPid, uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001184 return true;
1185}
1186
Brian Lindahl64ee9452022-01-14 13:31:16 +01001187bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type,
1188 MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001189 int pid = -1;
1190 int priority = -1;
1191 for (size_t i = 0; i < mMap.size(); ++i) {
1192 if (mMap.valueAt(i).size() == 0) {
1193 // no client on this process.
1194 continue;
1195 }
Brian Lindahl64ee9452022-01-14 13:31:16 +01001196 if (!hasResourceType(type, subType, mMap.valueAt(i))) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001197 // doesn't have the requested resource type
1198 continue;
1199 }
1200 int tempPid = mMap.keyAt(i);
1201 int tempPriority;
Henry Fang32762922020-01-28 18:40:39 -08001202 if (!getPriority_l(tempPid, &tempPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001203 ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
1204 // TODO: remove this pid from mMap?
1205 continue;
1206 }
1207 if (pid == -1 || tempPriority > priority) {
1208 // initial the value
1209 pid = tempPid;
1210 priority = tempPriority;
1211 }
1212 }
1213 if (pid != -1) {
1214 *lowestPriorityPid = pid;
1215 *lowestPriority = priority;
1216 }
1217 return (pid != -1);
1218}
1219
1220bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) {
1221 int callingPidPriority;
Henry Fang32762922020-01-28 18:40:39 -08001222 if (!getPriority_l(callingPid, &callingPidPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001223 return false;
1224 }
1225
1226 int priority;
Henry Fang32762922020-01-28 18:40:39 -08001227 if (!getPriority_l(pid, &priority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001228 return false;
1229 }
1230
1231 return (callingPidPriority < priority);
1232}
1233
Brian Lindahl64ee9452022-01-14 13:31:16 +01001234bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001235 MediaResource::SubType subType, uid_t& uid,
1236 std::shared_ptr<IResourceManagerClient> *client) {
1237 return getBiggestClient_l(pid, type, subType, uid, client, true /* pendingRemovalOnly */);
Brian Lindahl64ee9452022-01-14 13:31:16 +01001238}
1239
1240bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
Girish9128e242022-11-23 20:52:29 +00001241 MediaResource::SubType subType, uid_t& uid,
1242 std::shared_ptr<IResourceManagerClient> *client,
Wonsik Kimd20e9362020-04-28 10:42:57 -07001243 bool pendingRemovalOnly) {
Ronghua Wu231c3d12015-03-11 15:10:32 -07001244 ssize_t index = mMap.indexOfKey(pid);
1245 if (index < 0) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001246 ALOGE_IF(!pendingRemovalOnly,
1247 "getBiggestClient_l: can't find resource info for pid %d", pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001248 return false;
1249 }
1250
Chong Zhangfdd512a2019-11-22 11:03:14 -08001251 std::shared_ptr<IResourceManagerClient> clientTemp;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001252 uint64_t largestValue = 0;
1253 const ResourceInfos &infos = mMap.valueAt(index);
1254 for (size_t i = 0; i < infos.size(); ++i) {
Chong Zhangfb092d32019-08-12 09:45:44 -07001255 const ResourceList &resources = infos[i].resources;
Wonsik Kimd20e9362020-04-28 10:42:57 -07001256 if (pendingRemovalOnly && !infos[i].pendingRemoval) {
1257 continue;
1258 }
Chong Zhangfb092d32019-08-12 09:45:44 -07001259 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -07001260 const MediaResourceParcel &resource = it->second;
Brian Lindahl64ee9452022-01-14 13:31:16 +01001261 if (hasResourceType(type, subType, resource)) {
Chong Zhang181e6952019-10-09 13:23:39 -07001262 if (resource.value > largestValue) {
1263 largestValue = resource.value;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001264 clientTemp = infos[i].client;
Girish9128e242022-11-23 20:52:29 +00001265 uid = infos[i].uid;
Ronghua Wu231c3d12015-03-11 15:10:32 -07001266 }
1267 }
1268 }
1269 }
1270
1271 if (clientTemp == NULL) {
Wonsik Kim271429d2020-10-01 10:12:56 -07001272 ALOGE_IF(!pendingRemovalOnly,
Brian Lindahl64ee9452022-01-14 13:31:16 +01001273 "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d",
1274 asString(type), asString(subType), pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -07001275 return false;
1276 }
1277
1278 *client = clientTemp;
1279 return true;
1280}
1281
Ronghua Wu231c3d12015-03-11 15:10:32 -07001282} // namespace android