blob: 3d36f8ea934dfa59b67991a787b1b404dfc5dfd9 [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>
Dongwon Kangfe508d32015-12-15 14:22:05 +090024#include <binder/IMediaResourceMonitor.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>
37
38#include "ResourceManagerService.h"
Ronghua Wua8ec8fc2015-05-07 13:58:22 -070039#include "ServiceLog.h"
Chong Zhangee33d642019-08-08 14:26:43 -070040
Ronghua Wu231c3d12015-03-11 15:10:32 -070041namespace android {
42
Chong Zhangfdd512a2019-11-22 11:03:14 -080043DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
44 int pid, int64_t clientId)
45 : mService(service), mPid(pid), mClientId(clientId) {}
Wonsik Kim3e378962017-01-05 17:00:02 +090046
Chong Zhangfdd512a2019-11-22 11:03:14 -080047//static
48void DeathNotifier::BinderDiedCallback(void* cookie) {
49 auto thiz = static_cast<DeathNotifier*>(cookie);
50 thiz->binderDied();
51}
Wonsik Kim3e378962017-01-05 17:00:02 +090052
Chong Zhangfdd512a2019-11-22 11:03:14 -080053void DeathNotifier::binderDied() {
54 // Don't check for pid validity since we know it's already dead.
55 std::shared_ptr<ResourceManagerService> service = mService.lock();
56 if (service == nullptr) {
57 ALOGW("ResourceManagerService is dead as well.");
58 return;
Wonsik Kim3e378962017-01-05 17:00:02 +090059 }
Henry Fang32762922020-01-28 18:40:39 -080060
61 service->overridePid(mPid, -1);
Henry Fangb35141c2020-06-29 13:11:39 -070062 // thiz is freed in the call below, so it must be last call referring thiz
63 service->removeResource(mPid, mClientId, false);
64
Chong Zhangfdd512a2019-11-22 11:03:14 -080065}
Wonsik Kim3e378962017-01-05 17:00:02 +090066
Ronghua Wu231c3d12015-03-11 15:10:32 -070067template <typename T>
Chong Zhang181e6952019-10-09 13:23:39 -070068static String8 getString(const std::vector<T> &items) {
Ronghua Wu231c3d12015-03-11 15:10:32 -070069 String8 itemsStr;
70 for (size_t i = 0; i < items.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -070071 itemsStr.appendFormat("%s ", toString(items[i]).string());
Ronghua Wu231c3d12015-03-11 15:10:32 -070072 }
73 return itemsStr;
74}
75
Chong Zhangfb092d32019-08-12 09:45:44 -070076static bool hasResourceType(MediaResource::Type type, const ResourceList& resources) {
77 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -070078 if (it->second.type == type) {
Ronghua Wu231c3d12015-03-11 15:10:32 -070079 return true;
80 }
81 }
82 return false;
83}
84
Chih-Hung Hsieh51873d82016-08-09 14:18:51 -070085static bool hasResourceType(MediaResource::Type type, const ResourceInfos& infos) {
Ronghua Wu231c3d12015-03-11 15:10:32 -070086 for (size_t i = 0; i < infos.size(); ++i) {
87 if (hasResourceType(type, infos[i].resources)) {
88 return true;
89 }
90 }
91 return false;
92}
93
94static ResourceInfos& getResourceInfosForEdit(
95 int pid,
96 PidResourceInfosMap& map) {
97 ssize_t index = map.indexOfKey(pid);
98 if (index < 0) {
99 // new pid
100 ResourceInfos infosForPid;
101 map.add(pid, infosForPid);
102 }
103
104 return map.editValueFor(pid);
105}
106
107static ResourceInfo& getResourceInfoForEdit(
Chong Zhangee33d642019-08-08 14:26:43 -0700108 uid_t uid,
Ronghua Wu231c3d12015-03-11 15:10:32 -0700109 int64_t clientId,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800110 const std::shared_ptr<IResourceManagerClient>& client,
Ronghua Wu231c3d12015-03-11 15:10:32 -0700111 ResourceInfos& infos) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700112 ssize_t index = infos.indexOfKey(clientId);
113
114 if (index < 0) {
115 ResourceInfo info;
116 info.uid = uid;
117 info.clientId = clientId;
118 info.client = client;
Wonsik Kimd20e9362020-04-28 10:42:57 -0700119 info.pendingRemoval = false;
Chong Zhangfb092d32019-08-12 09:45:44 -0700120
121 index = infos.add(clientId, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700122 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700123
124 return infos.editValueAt(index);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700125}
126
Chong Zhang181e6952019-10-09 13:23:39 -0700127static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel> &resources) {
Dongwon Kangfe508d32015-12-15 14:22:05 +0900128 static const char* const kServiceName = "media_resource_monitor";
Dongwon Kang2642c842016-03-23 18:07:29 -0700129 sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
Dongwon Kangfe508d32015-12-15 14:22:05 +0900130 if (binder != NULL) {
131 sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
132 for (size_t i = 0; i < resources.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700133 if (resources[i].subType == MediaResource::SubType::kAudioCodec) {
Dongwon Kang69c23dd2016-03-22 15:22:45 -0700134 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
Chong Zhang181e6952019-10-09 13:23:39 -0700135 } else if (resources[i].subType == MediaResource::SubType::kVideoCodec) {
Dongwon Kang69c23dd2016-03-22 15:22:45 -0700136 service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
137 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900138 }
139 }
140}
141
Chong Zhangfdd512a2019-11-22 11:03:14 -0800142binder_status_t ResourceManagerService::dump(
143 int fd, const char** /*args*/, uint32_t /*numArgs*/) {
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700144 String8 result;
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700145
dcashman014e91e2015-09-11 09:33:01 -0700146 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
147 result.format("Permission Denial: "
148 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
Chong Zhangfdd512a2019-11-22 11:03:14 -0800149 AIBinder_getCallingPid(),
150 AIBinder_getCallingUid());
dcashman014e91e2015-09-11 09:33:01 -0700151 write(fd, result.string(), result.size());
152 return PERMISSION_DENIED;
153 }
154
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700155 PidResourceInfosMap mapCopy;
156 bool supportsMultipleSecureCodecs;
157 bool supportsSecureWithNonSecureCodec;
Henry Fang32762922020-01-28 18:40:39 -0800158 std::map<int, int> overridePidMapCopy;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700159 String8 serviceLog;
160 {
161 Mutex::Autolock lock(mLock);
162 mapCopy = mMap; // Shadow copy, real copy will happen on write.
163 supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
164 supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
165 serviceLog = mServiceLog->toString(" " /* linePrefix */);
Henry Fang32762922020-01-28 18:40:39 -0800166 overridePidMapCopy = mOverridePidMap;
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700167 }
168
169 const size_t SIZE = 256;
170 char buffer[SIZE];
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700171 snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
172 result.append(buffer);
173 result.append(" Policies:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700174 snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", supportsMultipleSecureCodecs);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700175 result.append(buffer);
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700176 snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n",
177 supportsSecureWithNonSecureCodec);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700178 result.append(buffer);
179
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700180 result.append(" Processes:\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700181 for (size_t i = 0; i < mapCopy.size(); ++i) {
182 snprintf(buffer, SIZE, " Pid: %d\n", mapCopy.keyAt(i));
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700183 result.append(buffer);
184
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700185 const ResourceInfos &infos = mapCopy.valueAt(i);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700186 for (size_t j = 0; j < infos.size(); ++j) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700187 result.append(" Client:\n");
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700188 snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
189 result.append(buffer);
190
Chong Zhang181e6952019-10-09 13:23:39 -0700191 std::string clientName;
192 Status status = infos[j].client->getName(&clientName);
193 if (!status.isOk()) {
194 clientName = "<unknown client>";
195 }
196 snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700197 result.append(buffer);
198
Chong Zhangfb092d32019-08-12 09:45:44 -0700199 const ResourceList &resources = infos[j].resources;
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700200 result.append(" Resources:\n");
Chong Zhangfb092d32019-08-12 09:45:44 -0700201 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -0700202 snprintf(buffer, SIZE, " %s\n", toString(it->second).string());
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700203 result.append(buffer);
204 }
205 }
206 }
Henry Fang32762922020-01-28 18:40:39 -0800207 result.append(" Process Pid override:\n");
208 for (auto it = overridePidMapCopy.begin(); it != overridePidMapCopy.end(); ++it) {
209 snprintf(buffer, SIZE, " Original Pid: %d, Override Pid: %d\n",
210 it->first, it->second);
211 result.append(buffer);
212 }
Ronghua Wu022ed722015-05-11 15:15:09 -0700213 result.append(" Events logs (most recent at top):\n");
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700214 result.append(serviceLog);
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700215
216 write(fd, result.string(), result.size());
217 return OK;
218}
219
Chong Zhangdd726802019-08-21 17:24:13 -0700220struct SystemCallbackImpl :
221 public ResourceManagerService::SystemCallbackInterface {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800222 SystemCallbackImpl() : mClientToken(new BBinder()) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700223
Chong Zhangdd726802019-08-21 17:24:13 -0700224 virtual void noteStartVideo(int uid) override {
225 BatteryNotifier::getInstance().noteStartVideo(uid);
226 }
227 virtual void noteStopVideo(int uid) override {
228 BatteryNotifier::getInstance().noteStopVideo(uid);
229 }
230 virtual void noteResetVideo() override {
231 BatteryNotifier::getInstance().noteResetVideo();
232 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800233 virtual bool requestCpusetBoost(bool enable) override {
234 return android::requestCpusetBoost(enable, mClientToken);
Chong Zhangdd726802019-08-21 17:24:13 -0700235 }
236
237protected:
238 virtual ~SystemCallbackImpl() {}
239
240private:
241 DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl);
Chong Zhangfdd512a2019-11-22 11:03:14 -0800242 sp<IBinder> mClientToken;
Chong Zhangdd726802019-08-21 17:24:13 -0700243};
244
245ResourceManagerService::ResourceManagerService()
246 : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {}
247
248ResourceManagerService::ResourceManagerService(
249 const sp<ProcessInfoInterface> &processInfo,
250 const sp<SystemCallbackInterface> &systemResource)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700251 : mProcessInfo(processInfo),
Chong Zhangdd726802019-08-21 17:24:13 -0700252 mSystemCB(systemResource),
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700253 mServiceLog(new ServiceLog()),
Ronghua Wu231c3d12015-03-11 15:10:32 -0700254 mSupportsMultipleSecureCodecs(true),
Chong Zhang79d2b282018-04-17 14:14:31 -0700255 mSupportsSecureWithNonSecureCodec(true),
Chong Zhangfdd512a2019-11-22 11:03:14 -0800256 mCpuBoostCount(0),
257 mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
Chong Zhangdd726802019-08-21 17:24:13 -0700258 mSystemCB->noteResetVideo();
Chong Zhangee33d642019-08-08 14:26:43 -0700259}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700260
Chong Zhangfdd512a2019-11-22 11:03:14 -0800261//static
262void ResourceManagerService::instantiate() {
263 std::shared_ptr<ResourceManagerService> service =
264 ::ndk::SharedRefBase::make<ResourceManagerService>();
265 binder_status_t status =
266 AServiceManager_addService(service->asBinder().get(), getServiceName());
267 if (status != STATUS_OK) {
268 return;
269 }
270 // TODO: mediaserver main() is already starting the thread pool,
271 // move this to mediaserver main() when other services in mediaserver
272 // are converted to ndk-platform aidl.
273 //ABinderProcess_startThreadPool();
274}
275
Ronghua Wu231c3d12015-03-11 15:10:32 -0700276ResourceManagerService::~ResourceManagerService() {}
277
Chong Zhang181e6952019-10-09 13:23:39 -0700278Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700279 String8 log = String8::format("config(%s)", getString(policies).string());
280 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700281
282 Mutex::Autolock lock(mLock);
283 for (size_t i = 0; i < policies.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700284 const std::string &type = policies[i].type;
285 const std::string &value = policies[i].value;
286 if (type == MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700287 mSupportsMultipleSecureCodecs = (value == "true");
Chong Zhang181e6952019-10-09 13:23:39 -0700288 } else if (type == MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec()) {
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700289 mSupportsSecureWithNonSecureCodec = (value == "true");
Ronghua Wu231c3d12015-03-11 15:10:32 -0700290 }
291 }
Chong Zhang181e6952019-10-09 13:23:39 -0700292 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700293}
294
Chong Zhangfb092d32019-08-12 09:45:44 -0700295void ResourceManagerService::onFirstAdded(
Chong Zhang181e6952019-10-09 13:23:39 -0700296 const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700297 // first time added
Chong Zhang181e6952019-10-09 13:23:39 -0700298 if (resource.type == MediaResource::Type::kCpuBoost
299 && resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700300 // Request it on every new instance of kCpuBoost, as the media.codec
301 // could have died, if we only do it the first time subsequent instances
302 // never gets the boost.
Chong Zhangfdd512a2019-11-22 11:03:14 -0800303 if (mSystemCB->requestCpusetBoost(true) != OK) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700304 ALOGW("couldn't request cpuset boost");
305 }
306 mCpuBoostCount++;
Chong Zhang181e6952019-10-09 13:23:39 -0700307 } else if (resource.type == MediaResource::Type::kBattery
308 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700309 mSystemCB->noteStartVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700310 }
311}
312
313void ResourceManagerService::onLastRemoved(
Chong Zhang181e6952019-10-09 13:23:39 -0700314 const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
315 if (resource.type == MediaResource::Type::kCpuBoost
316 && resource.subType == MediaResource::SubType::kUnspecifiedSubType
Chong Zhangfb092d32019-08-12 09:45:44 -0700317 && mCpuBoostCount > 0) {
318 if (--mCpuBoostCount == 0) {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800319 mSystemCB->requestCpusetBoost(false);
Chong Zhangfb092d32019-08-12 09:45:44 -0700320 }
Chong Zhang181e6952019-10-09 13:23:39 -0700321 } else if (resource.type == MediaResource::Type::kBattery
322 && resource.subType == MediaResource::SubType::kVideoCodec) {
Chong Zhangdd726802019-08-21 17:24:13 -0700323 mSystemCB->noteStopVideo(clientInfo.uid);
Chong Zhangfb092d32019-08-12 09:45:44 -0700324 }
325}
326
Robert Shihc3af31b2019-09-20 21:45:01 -0700327void ResourceManagerService::mergeResources(
Chong Zhang181e6952019-10-09 13:23:39 -0700328 MediaResourceParcel& r1, const MediaResourceParcel& r2) {
329 // The resource entry on record is maintained to be in [0,INT64_MAX].
330 // Clamp if merging in the new resource value causes it to go out of bound.
331 // Note that the new resource value could be negative, eg.DrmSession, the
332 // value goes lower when the session is used more often. During reclaim
333 // the session with the highest value (lowest usage) would be closed.
334 if (r2.value < INT64_MAX - r1.value) {
335 r1.value += r2.value;
336 if (r1.value < 0) {
337 r1.value = 0;
338 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700339 } else {
Chong Zhang181e6952019-10-09 13:23:39 -0700340 r1.value = INT64_MAX;
Robert Shihc3af31b2019-09-20 21:45:01 -0700341 }
342}
343
Chong Zhang181e6952019-10-09 13:23:39 -0700344Status ResourceManagerService::addResource(
345 int32_t pid,
346 int32_t uid,
Ronghua Wu231c3d12015-03-11 15:10:32 -0700347 int64_t clientId,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800348 const std::shared_ptr<IResourceManagerClient>& client,
Chong Zhang181e6952019-10-09 13:23:39 -0700349 const std::vector<MediaResourceParcel>& resources) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700350 String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)",
Ronghua Wu231c3d12015-03-11 15:10:32 -0700351 pid, (long long) clientId, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700352 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700353
354 Mutex::Autolock lock(mLock);
Ronghua Wud11c43a2016-01-27 16:26:12 -0800355 if (!mProcessInfo->isValidPid(pid)) {
356 ALOGE("Rejected addResource call with invalid pid.");
Chong Zhang181e6952019-10-09 13:23:39 -0700357 return Status::fromServiceSpecificError(BAD_VALUE);
Ronghua Wud11c43a2016-01-27 16:26:12 -0800358 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700359 ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
Chong Zhangee33d642019-08-08 14:26:43 -0700360 ResourceInfo& info = getResourceInfoForEdit(uid, clientId, client, infos);
Chong Zhang79d2b282018-04-17 14:14:31 -0700361
362 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700363 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700364 const auto resType = std::tuple(res.type, res.subType, res.id);
365
366 if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
367 ALOGW("Ignoring request to remove negative value of non-drm resource");
368 continue;
369 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700370 if (info.resources.find(resType) == info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700371 if (res.value <= 0) {
372 // We can't init a new entry with negative value, although it's allowed
373 // to merge in negative values after the initial add.
374 ALOGW("Ignoring request to add new resource entry with value <= 0");
375 continue;
376 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700377 onFirstAdded(res, info);
378 info.resources[resType] = res;
Chong Zhangfb092d32019-08-12 09:45:44 -0700379 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700380 mergeResources(info.resources[resType], res);
Chong Zhang79d2b282018-04-17 14:14:31 -0700381 }
382 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700383 if (info.deathNotifier == nullptr && client != nullptr) {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800384 info.deathNotifier = new DeathNotifier(ref<ResourceManagerService>(), pid, clientId);
385 AIBinder_linkToDeath(client->asBinder().get(),
386 mDeathRecipient.get(), info.deathNotifier.get());
Wonsik Kim3e378962017-01-05 17:00:02 +0900387 }
Dongwon Kangfe508d32015-12-15 14:22:05 +0900388 notifyResourceGranted(pid, resources);
Chong Zhang181e6952019-10-09 13:23:39 -0700389 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700390}
391
Chong Zhang181e6952019-10-09 13:23:39 -0700392Status ResourceManagerService::removeResource(
393 int32_t pid, int64_t clientId,
394 const std::vector<MediaResourceParcel>& resources) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700395 String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)",
396 pid, (long long) clientId, getString(resources).string());
397 mServiceLog->add(log);
398
399 Mutex::Autolock lock(mLock);
400 if (!mProcessInfo->isValidPid(pid)) {
401 ALOGE("Rejected removeResource call with invalid pid.");
Chong Zhang181e6952019-10-09 13:23:39 -0700402 return Status::fromServiceSpecificError(BAD_VALUE);
Chong Zhangfb092d32019-08-12 09:45:44 -0700403 }
404 ssize_t index = mMap.indexOfKey(pid);
405 if (index < 0) {
406 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700407 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700408 }
409 ResourceInfos &infos = mMap.editValueAt(index);
410
411 index = infos.indexOfKey(clientId);
412 if (index < 0) {
413 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700414 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700415 }
416
417 ResourceInfo &info = infos.editValueAt(index);
418
419 for (size_t i = 0; i < resources.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700420 const auto &res = resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700421 const auto resType = std::tuple(res.type, res.subType, res.id);
422
423 if (res.value < 0) {
424 ALOGW("Ignoring request to remove negative value of resource");
425 continue;
426 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700427 // ignore if we don't have it
428 if (info.resources.find(resType) != info.resources.end()) {
Chong Zhang181e6952019-10-09 13:23:39 -0700429 MediaResourceParcel &resource = info.resources[resType];
430 if (resource.value > res.value) {
431 resource.value -= res.value;
Chong Zhangfb092d32019-08-12 09:45:44 -0700432 } else {
Robert Shihc3af31b2019-09-20 21:45:01 -0700433 onLastRemoved(res, info);
Chong Zhangfb092d32019-08-12 09:45:44 -0700434 info.resources.erase(resType);
435 }
436 }
437 }
Chong Zhang181e6952019-10-09 13:23:39 -0700438 return Status::ok();
Chong Zhangfb092d32019-08-12 09:45:44 -0700439}
440
Chong Zhang181e6952019-10-09 13:23:39 -0700441Status ResourceManagerService::removeClient(int32_t pid, int64_t clientId) {
Wonsik Kim3e378962017-01-05 17:00:02 +0900442 removeResource(pid, clientId, true);
Chong Zhang181e6952019-10-09 13:23:39 -0700443 return Status::ok();
Wonsik Kim3e378962017-01-05 17:00:02 +0900444}
445
Chong Zhang181e6952019-10-09 13:23:39 -0700446Status ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) {
Ronghua Wu37c89242015-07-15 12:23:48 -0700447 String8 log = String8::format(
448 "removeResource(pid %d, clientId %lld)",
449 pid, (long long) clientId);
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700450 mServiceLog->add(log);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700451
452 Mutex::Autolock lock(mLock);
Wonsik Kim3e378962017-01-05 17:00:02 +0900453 if (checkValid && !mProcessInfo->isValidPid(pid)) {
Ronghua Wud11c43a2016-01-27 16:26:12 -0800454 ALOGE("Rejected removeResource call with invalid pid.");
Chong Zhang181e6952019-10-09 13:23:39 -0700455 return Status::fromServiceSpecificError(BAD_VALUE);
Ronghua Wud11c43a2016-01-27 16:26:12 -0800456 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700457 ssize_t index = mMap.indexOfKey(pid);
458 if (index < 0) {
459 ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700460 return Status::ok();
Ronghua Wu37c89242015-07-15 12:23:48 -0700461 }
Ronghua Wu37c89242015-07-15 12:23:48 -0700462 ResourceInfos &infos = mMap.editValueAt(index);
Chong Zhangfb092d32019-08-12 09:45:44 -0700463
464 index = infos.indexOfKey(clientId);
465 if (index < 0) {
466 ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
Chong Zhang181e6952019-10-09 13:23:39 -0700467 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700468 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700469
470 const ResourceInfo &info = infos[index];
471 for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
472 onLastRemoved(it->second, info);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700473 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700474
Chong Zhangfdd512a2019-11-22 11:03:14 -0800475 AIBinder_unlinkToDeath(info.client->asBinder().get(),
476 mDeathRecipient.get(), info.deathNotifier.get());
Chong Zhangfb092d32019-08-12 09:45:44 -0700477
478 infos.removeItemsAt(index);
Chong Zhang181e6952019-10-09 13:23:39 -0700479 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700480}
481
Ronghua Wu05d89f12015-07-07 16:47:42 -0700482void ResourceManagerService::getClientForResource_l(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800483 int callingPid, const MediaResourceParcel *res,
484 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700485 if (res == NULL) {
486 return;
487 }
Chong Zhangfdd512a2019-11-22 11:03:14 -0800488 std::shared_ptr<IResourceManagerClient> client;
Chong Zhang181e6952019-10-09 13:23:39 -0700489 if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700490 clients->push_back(client);
491 }
492}
493
Chong Zhang181e6952019-10-09 13:23:39 -0700494Status ResourceManagerService::reclaimResource(
495 int32_t callingPid,
496 const std::vector<MediaResourceParcel>& resources,
497 bool* _aidl_return) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700498 String8 log = String8::format("reclaimResource(callingPid %d, resources %s)",
Ronghua Wu231c3d12015-03-11 15:10:32 -0700499 callingPid, getString(resources).string());
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700500 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700501 *_aidl_return = false;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700502
Chong Zhangfdd512a2019-11-22 11:03:14 -0800503 Vector<std::shared_ptr<IResourceManagerClient>> clients;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700504 {
505 Mutex::Autolock lock(mLock);
Ronghua Wud11c43a2016-01-27 16:26:12 -0800506 if (!mProcessInfo->isValidPid(callingPid)) {
507 ALOGE("Rejected reclaimResource call with invalid callingPid.");
Chong Zhang181e6952019-10-09 13:23:39 -0700508 return Status::fromServiceSpecificError(BAD_VALUE);
Ronghua Wud11c43a2016-01-27 16:26:12 -0800509 }
Chong Zhang181e6952019-10-09 13:23:39 -0700510 const MediaResourceParcel *secureCodec = NULL;
511 const MediaResourceParcel *nonSecureCodec = NULL;
512 const MediaResourceParcel *graphicMemory = NULL;
513 const MediaResourceParcel *drmSession = NULL;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700514 for (size_t i = 0; i < resources.size(); ++i) {
Chong Zhang181e6952019-10-09 13:23:39 -0700515 MediaResource::Type type = resources[i].type;
516 if (resources[i].type == MediaResource::Type::kSecureCodec) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700517 secureCodec = &resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700518 } else if (type == MediaResource::Type::kNonSecureCodec) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700519 nonSecureCodec = &resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700520 } else if (type == MediaResource::Type::kGraphicMemory) {
Ronghua Wu05d89f12015-07-07 16:47:42 -0700521 graphicMemory = &resources[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700522 } else if (type == MediaResource::Type::kDrmSession) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700523 drmSession = &resources[i];
Ronghua Wu05d89f12015-07-07 16:47:42 -0700524 }
525 }
526
527 // first pass to handle secure/non-secure codec conflict
528 if (secureCodec != NULL) {
529 if (!mSupportsMultipleSecureCodecs) {
Chong Zhang181e6952019-10-09 13:23:39 -0700530 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
531 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700532 }
533 }
534 if (!mSupportsSecureWithNonSecureCodec) {
Chong Zhang181e6952019-10-09 13:23:39 -0700535 if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, &clients)) {
536 return Status::ok();
Ronghua Wu05d89f12015-07-07 16:47:42 -0700537 }
538 }
539 }
540 if (nonSecureCodec != NULL) {
541 if (!mSupportsSecureWithNonSecureCodec) {
Chong Zhang181e6952019-10-09 13:23:39 -0700542 if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
543 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700544 }
545 }
546 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700547 if (drmSession != NULL) {
548 getClientForResource_l(callingPid, drmSession, &clients);
549 if (clients.size() == 0) {
Chong Zhang181e6952019-10-09 13:23:39 -0700550 return Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700551 }
552 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700553
554 if (clients.size() == 0) {
555 // if no secure/non-secure codec conflict, run second pass to handle other resources.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700556 getClientForResource_l(callingPid, graphicMemory, &clients);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700557 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700558
559 if (clients.size() == 0) {
560 // if we are here, run the third pass to free one codec with the same type.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700561 getClientForResource_l(callingPid, secureCodec, &clients);
562 getClientForResource_l(callingPid, nonSecureCodec, &clients);
563 }
564
565 if (clients.size() == 0) {
566 // if we are here, run the fourth pass to free one codec with the different type.
567 if (secureCodec != NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700568 MediaResource temp(MediaResource::Type::kNonSecureCodec, 1);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700569 getClientForResource_l(callingPid, &temp, &clients);
570 }
571 if (nonSecureCodec != NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700572 MediaResource temp(MediaResource::Type::kSecureCodec, 1);
Ronghua Wu05d89f12015-07-07 16:47:42 -0700573 getClientForResource_l(callingPid, &temp, &clients);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700574 }
575 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700576 }
577
578 if (clients.size() == 0) {
Chong Zhang181e6952019-10-09 13:23:39 -0700579 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700580 }
581
Chong Zhangfdd512a2019-11-22 11:03:14 -0800582 std::shared_ptr<IResourceManagerClient> failedClient;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700583 for (size_t i = 0; i < clients.size(); ++i) {
Ronghua Wua8ec8fc2015-05-07 13:58:22 -0700584 log = String8::format("reclaimResource from client %p", clients[i].get());
585 mServiceLog->add(log);
Chong Zhang181e6952019-10-09 13:23:39 -0700586 bool success;
587 Status status = clients[i]->reclaimResource(&success);
588 if (!status.isOk() || !success) {
Ronghua Wu67e7f542015-03-13 10:47:08 -0700589 failedClient = clients[i];
590 break;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700591 }
592 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700593
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700594 if (failedClient == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700595 *_aidl_return = true;
596 return Status::ok();
Ronghua Wu76d4c7f2015-10-23 15:01:53 -0700597 }
598
Ronghua Wu67e7f542015-03-13 10:47:08 -0700599 {
600 Mutex::Autolock lock(mLock);
601 bool found = false;
602 for (size_t i = 0; i < mMap.size(); ++i) {
603 ResourceInfos &infos = mMap.editValueAt(i);
604 for (size_t j = 0; j < infos.size();) {
605 if (infos[j].client == failedClient) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700606 j = infos.removeItemsAt(j);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700607 found = true;
608 } else {
609 ++j;
610 }
611 }
612 if (found) {
613 break;
614 }
615 }
616 if (!found) {
617 ALOGV("didn't find failed client");
618 }
619 }
620
Chong Zhang181e6952019-10-09 13:23:39 -0700621 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700622}
623
Henry Fang32762922020-01-28 18:40:39 -0800624Status ResourceManagerService::overridePid(
625 int originalPid,
626 int newPid) {
627 String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
628 originalPid, newPid);
629 mServiceLog->add(log);
630
631 // allow if this is called from the same process or the process has
632 // permission.
633 if ((AIBinder_getCallingPid() != getpid()) &&
634 (checkCallingPermission(String16(
635 "android.permission.MEDIA_RESOURCE_OVERRIDE_PID")) == false)) {
636 ALOGE(
637 "Permission Denial: can't access overridePid method from pid=%d, "
638 "self pid=%d\n",
639 AIBinder_getCallingPid(), getpid());
640 return Status::fromServiceSpecificError(PERMISSION_DENIED);
641 }
642
643 {
644 Mutex::Autolock lock(mLock);
645 mOverridePidMap.erase(originalPid);
646 if (newPid != -1) {
647 mOverridePidMap.emplace(originalPid, newPid);
648 }
649 }
650
651 return Status::ok();
652}
653
Wonsik Kimd20e9362020-04-28 10:42:57 -0700654Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) {
655 String8 log = String8::format(
656 "markClientForPendingRemoval(pid %d, clientId %lld)",
657 pid, (long long) clientId);
658 mServiceLog->add(log);
659
660 Mutex::Autolock lock(mLock);
661 if (!mProcessInfo->isValidPid(pid)) {
662 ALOGE("Rejected markClientForPendingRemoval call with invalid pid.");
663 return Status::fromServiceSpecificError(BAD_VALUE);
664 }
665 ssize_t index = mMap.indexOfKey(pid);
666 if (index < 0) {
667 ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
668 pid, (long long)clientId);
669 return Status::ok();
670 }
671 ResourceInfos &infos = mMap.editValueAt(index);
672
673 index = infos.indexOfKey(clientId);
674 if (index < 0) {
675 ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
676 return Status::ok();
677 }
678
679 ResourceInfo &info = infos.editValueAt(index);
680 info.pendingRemoval = true;
681 return Status::ok();
682}
683
Henry Fang32762922020-01-28 18:40:39 -0800684bool ResourceManagerService::getPriority_l(int pid, int* priority) {
685 int newPid = pid;
686
687 if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
688 newPid = mOverridePidMap[pid];
689 ALOGD("getPriority_l: use override pid %d instead original pid %d",
690 newPid, pid);
691 }
692
693 return mProcessInfo->getPriority(newPid, priority);
694}
695
Ronghua Wu231c3d12015-03-11 15:10:32 -0700696bool ResourceManagerService::getAllClients_l(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800697 int callingPid, MediaResource::Type type,
698 Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
699 Vector<std::shared_ptr<IResourceManagerClient>> temp;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700700 for (size_t i = 0; i < mMap.size(); ++i) {
701 ResourceInfos &infos = mMap.editValueAt(i);
702 for (size_t j = 0; j < infos.size(); ++j) {
703 if (hasResourceType(type, infos[j].resources)) {
704 if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
705 // some higher/equal priority process owns the resource,
706 // this request can't be fulfilled.
707 ALOGE("getAllClients_l: can't reclaim resource %s from pid %d",
Ronghua Wuea15fd22016-03-03 13:35:05 -0800708 asString(type), mMap.keyAt(i));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700709 return false;
710 }
711 temp.push_back(infos[j].client);
712 }
713 }
714 }
715 if (temp.size() == 0) {
Ronghua Wuea15fd22016-03-03 13:35:05 -0800716 ALOGV("getAllClients_l: didn't find any resource %s", asString(type));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700717 return true;
718 }
719 clients->appendVector(temp);
720 return true;
721}
722
723bool ResourceManagerService::getLowestPriorityBiggestClient_l(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800724 int callingPid, MediaResource::Type type,
725 std::shared_ptr<IResourceManagerClient> *client) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700726 int lowestPriorityPid;
727 int lowestPriority;
728 int callingPriority;
Wonsik Kimd20e9362020-04-28 10:42:57 -0700729
730 // Before looking into other processes, check if we have clients marked for
731 // pending removal in the same process.
732 if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) {
733 return true;
734 }
Henry Fang32762922020-01-28 18:40:39 -0800735 if (!getPriority_l(callingPid, &callingPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700736 ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d",
737 callingPid);
738 return false;
739 }
740 if (!getLowestPriorityPid_l(type, &lowestPriorityPid, &lowestPriority)) {
741 return false;
742 }
743 if (lowestPriority <= callingPriority) {
744 ALOGE("getLowestPriorityBiggestClient_l: lowest priority %d vs caller priority %d",
745 lowestPriority, callingPriority);
746 return false;
747 }
748
749 if (!getBiggestClient_l(lowestPriorityPid, type, client)) {
750 return false;
751 }
752 return true;
753}
754
755bool ResourceManagerService::getLowestPriorityPid_l(
Ronghua Wuea15fd22016-03-03 13:35:05 -0800756 MediaResource::Type type, int *lowestPriorityPid, int *lowestPriority) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700757 int pid = -1;
758 int priority = -1;
759 for (size_t i = 0; i < mMap.size(); ++i) {
760 if (mMap.valueAt(i).size() == 0) {
761 // no client on this process.
762 continue;
763 }
764 if (!hasResourceType(type, mMap.valueAt(i))) {
765 // doesn't have the requested resource type
766 continue;
767 }
768 int tempPid = mMap.keyAt(i);
769 int tempPriority;
Henry Fang32762922020-01-28 18:40:39 -0800770 if (!getPriority_l(tempPid, &tempPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700771 ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
772 // TODO: remove this pid from mMap?
773 continue;
774 }
775 if (pid == -1 || tempPriority > priority) {
776 // initial the value
777 pid = tempPid;
778 priority = tempPriority;
779 }
780 }
781 if (pid != -1) {
782 *lowestPriorityPid = pid;
783 *lowestPriority = priority;
784 }
785 return (pid != -1);
786}
787
788bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) {
789 int callingPidPriority;
Henry Fang32762922020-01-28 18:40:39 -0800790 if (!getPriority_l(callingPid, &callingPidPriority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700791 return false;
792 }
793
794 int priority;
Henry Fang32762922020-01-28 18:40:39 -0800795 if (!getPriority_l(pid, &priority)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700796 return false;
797 }
798
799 return (callingPidPriority < priority);
800}
801
802bool ResourceManagerService::getBiggestClient_l(
Wonsik Kimd20e9362020-04-28 10:42:57 -0700803 int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client,
804 bool pendingRemovalOnly) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700805 ssize_t index = mMap.indexOfKey(pid);
806 if (index < 0) {
807 ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid);
808 return false;
809 }
810
Chong Zhangfdd512a2019-11-22 11:03:14 -0800811 std::shared_ptr<IResourceManagerClient> clientTemp;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700812 uint64_t largestValue = 0;
813 const ResourceInfos &infos = mMap.valueAt(index);
814 for (size_t i = 0; i < infos.size(); ++i) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700815 const ResourceList &resources = infos[i].resources;
Wonsik Kimd20e9362020-04-28 10:42:57 -0700816 if (pendingRemovalOnly && !infos[i].pendingRemoval) {
817 continue;
818 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700819 for (auto it = resources.begin(); it != resources.end(); it++) {
Chong Zhang181e6952019-10-09 13:23:39 -0700820 const MediaResourceParcel &resource = it->second;
821 if (resource.type == type) {
822 if (resource.value > largestValue) {
823 largestValue = resource.value;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700824 clientTemp = infos[i].client;
825 }
826 }
827 }
828 }
829
830 if (clientTemp == NULL) {
Ronghua Wuea15fd22016-03-03 13:35:05 -0800831 ALOGE("getBiggestClient_l: can't find resource type %s for pid %d", asString(type), pid);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700832 return false;
833 }
834
835 *client = clientTemp;
836 return true;
837}
838
Ronghua Wu231c3d12015-03-11 15:10:32 -0700839} // namespace android