1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2023, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ResourceTracker"
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/ProcessInfo.h>
24*ec779b8eSAndroid Build Coastguard Worker #include "ResourceTracker.h"
25*ec779b8eSAndroid Build Coastguard Worker #include "ResourceManagerServiceNew.h"
26*ec779b8eSAndroid Build Coastguard Worker #include "ResourceObserverService.h"
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker namespace android {
29*ec779b8eSAndroid Build Coastguard Worker
isHwCodec(MediaResource::SubType subType)30*ec779b8eSAndroid Build Coastguard Worker inline bool isHwCodec(MediaResource::SubType subType) {
31*ec779b8eSAndroid Build Coastguard Worker return subType == MediaResource::SubType::kHwImageCodec ||
32*ec779b8eSAndroid Build Coastguard Worker subType == MediaResource::SubType::kHwVideoCodec;
33*ec779b8eSAndroid Build Coastguard Worker }
34*ec779b8eSAndroid Build Coastguard Worker
35*ec779b8eSAndroid Build Coastguard Worker // Check whether a given resource (of type and subtype) is found in given resource list
36*ec779b8eSAndroid Build Coastguard Worker // that also has the given Primary SubType.
hasResourceType(MediaResource::Type type,MediaResource::SubType subType,const ResourceList & resources,MediaResource::SubType primarySubType)37*ec779b8eSAndroid Build Coastguard Worker static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
38*ec779b8eSAndroid Build Coastguard Worker const ResourceList& resources, MediaResource::SubType primarySubType) {
39*ec779b8eSAndroid Build Coastguard Worker bool foundResource = false;
40*ec779b8eSAndroid Build Coastguard Worker bool matchedPrimary =
41*ec779b8eSAndroid Build Coastguard Worker (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ? true : false;
42*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& res : resources.getResources()) {
43*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, res)) {
44*ec779b8eSAndroid Build Coastguard Worker foundResource = true;
45*ec779b8eSAndroid Build Coastguard Worker } else if (res.subType == primarySubType) {
46*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
47*ec779b8eSAndroid Build Coastguard Worker } else if (isHwCodec(res.subType) == isHwCodec(primarySubType)) {
48*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
49*ec779b8eSAndroid Build Coastguard Worker }
50*ec779b8eSAndroid Build Coastguard Worker if (matchedPrimary && foundResource) {
51*ec779b8eSAndroid Build Coastguard Worker return true;
52*ec779b8eSAndroid Build Coastguard Worker }
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker return false;
55*ec779b8eSAndroid Build Coastguard Worker }
56*ec779b8eSAndroid Build Coastguard Worker
57*ec779b8eSAndroid Build Coastguard Worker // See if the given client is already in the list of clients.
contains(const std::vector<ClientInfo> & clients,const int64_t & clientId)58*ec779b8eSAndroid Build Coastguard Worker inline bool contains(const std::vector<ClientInfo>& clients, const int64_t& clientId) {
59*ec779b8eSAndroid Build Coastguard Worker std::vector<ClientInfo>::const_iterator found =
60*ec779b8eSAndroid Build Coastguard Worker std::find_if(clients.begin(), clients.end(),
61*ec779b8eSAndroid Build Coastguard Worker [clientId](const ClientInfo& client) -> bool {
62*ec779b8eSAndroid Build Coastguard Worker return client.mClientId == clientId;
63*ec779b8eSAndroid Build Coastguard Worker });
64*ec779b8eSAndroid Build Coastguard Worker
65*ec779b8eSAndroid Build Coastguard Worker return found != clients.end();
66*ec779b8eSAndroid Build Coastguard Worker }
67*ec779b8eSAndroid Build Coastguard Worker
68*ec779b8eSAndroid Build Coastguard Worker
ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew> & service,const sp<ProcessInfoInterface> & processInfo)69*ec779b8eSAndroid Build Coastguard Worker ResourceTracker::ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew>& service,
70*ec779b8eSAndroid Build Coastguard Worker const sp<ProcessInfoInterface>& processInfo) :
71*ec779b8eSAndroid Build Coastguard Worker mService(service),
72*ec779b8eSAndroid Build Coastguard Worker mProcessInfo(processInfo) {
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker
~ResourceTracker()75*ec779b8eSAndroid Build Coastguard Worker ResourceTracker::~ResourceTracker() {
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker
setResourceObserverService(const std::shared_ptr<ResourceObserverService> & observerService)78*ec779b8eSAndroid Build Coastguard Worker void ResourceTracker::setResourceObserverService(
79*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<ResourceObserverService>& observerService) {
80*ec779b8eSAndroid Build Coastguard Worker mObserverService = observerService;
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
getResourceInfosForEdit(int pid)83*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& ResourceTracker::getResourceInfosForEdit(int pid) {
84*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
85*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
86*ec779b8eSAndroid Build Coastguard Worker // new pid
87*ec779b8eSAndroid Build Coastguard Worker ResourceInfos infosForPid;
88*ec779b8eSAndroid Build Coastguard Worker auto [it, inserted] = mMap.emplace(pid, infosForPid);
89*ec779b8eSAndroid Build Coastguard Worker found = it;
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker
92*ec779b8eSAndroid Build Coastguard Worker return found->second;
93*ec779b8eSAndroid Build Coastguard Worker }
94*ec779b8eSAndroid Build Coastguard Worker
addResource(const ClientInfoParcel & clientInfo,const std::shared_ptr<IResourceManagerClient> & client,const std::vector<MediaResourceParcel> & resources)95*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::addResource(const ClientInfoParcel& clientInfo,
96*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<IResourceManagerClient>& client,
97*ec779b8eSAndroid Build Coastguard Worker const std::vector<MediaResourceParcel>& resources) {
98*ec779b8eSAndroid Build Coastguard Worker int32_t pid = clientInfo.pid;
99*ec779b8eSAndroid Build Coastguard Worker int32_t uid = clientInfo.uid;
100*ec779b8eSAndroid Build Coastguard Worker
101*ec779b8eSAndroid Build Coastguard Worker if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
102*ec779b8eSAndroid Build Coastguard Worker pid_t callingPid = IPCThreadState::self()->getCallingPid();
103*ec779b8eSAndroid Build Coastguard Worker uid_t callingUid = IPCThreadState::self()->getCallingUid();
104*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s called with untrusted pid %d or uid %d, using calling pid %d, uid %d",
105*ec779b8eSAndroid Build Coastguard Worker __func__, pid, uid, callingPid, callingUid);
106*ec779b8eSAndroid Build Coastguard Worker pid = callingPid;
107*ec779b8eSAndroid Build Coastguard Worker uid = callingUid;
108*ec779b8eSAndroid Build Coastguard Worker }
109*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = getResourceInfosForEdit(pid);
110*ec779b8eSAndroid Build Coastguard Worker ResourceInfo& info = getResourceInfoForEdit(clientInfo, client, infos);
111*ec779b8eSAndroid Build Coastguard Worker ResourceList resourceAdded;
112*ec779b8eSAndroid Build Coastguard Worker
113*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& res : resources) {
114*ec779b8eSAndroid Build Coastguard Worker if (res.value < 0 && res.type != MediaResource::Type::kDrmSession) {
115*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Ignoring request to remove negative value of non-drm resource", __func__);
116*ec779b8eSAndroid Build Coastguard Worker continue;
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker bool isNewEntry = false;
119*ec779b8eSAndroid Build Coastguard Worker if (!info.resources.add(res, &isNewEntry)) {
120*ec779b8eSAndroid Build Coastguard Worker continue;
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker if (isNewEntry) {
123*ec779b8eSAndroid Build Coastguard Worker onFirstAdded(res, info.uid);
124*ec779b8eSAndroid Build Coastguard Worker }
125*ec779b8eSAndroid Build Coastguard Worker
126*ec779b8eSAndroid Build Coastguard Worker // Add it to the list of added resources for observers.
127*ec779b8eSAndroid Build Coastguard Worker resourceAdded.add(res);
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker if (info.deathNotifier == nullptr && client != nullptr) {
130*ec779b8eSAndroid Build Coastguard Worker info.deathNotifier = DeathNotifier::Create(client, mService, clientInfo);
131*ec779b8eSAndroid Build Coastguard Worker }
132*ec779b8eSAndroid Build Coastguard Worker if (mObserverService != nullptr && !resourceAdded.empty()) {
133*ec779b8eSAndroid Build Coastguard Worker mObserverService->onResourceAdded(uid, pid, resourceAdded);
134*ec779b8eSAndroid Build Coastguard Worker }
135*ec779b8eSAndroid Build Coastguard Worker
136*ec779b8eSAndroid Build Coastguard Worker return !resourceAdded.empty();
137*ec779b8eSAndroid Build Coastguard Worker }
138*ec779b8eSAndroid Build Coastguard Worker
updateResource(const aidl::android::media::ClientInfoParcel & clientInfo)139*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::updateResource(const aidl::android::media::ClientInfoParcel& clientInfo) {
140*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = getResourceInfosForEdit(clientInfo.pid);
141*ec779b8eSAndroid Build Coastguard Worker
142*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::iterator found = infos.find(clientInfo.id);
143*ec779b8eSAndroid Build Coastguard Worker if (found == infos.end()) {
144*ec779b8eSAndroid Build Coastguard Worker return false;
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker // Update the client importance.
147*ec779b8eSAndroid Build Coastguard Worker found->second.importance = std::max(0, clientInfo.importance);
148*ec779b8eSAndroid Build Coastguard Worker return true;
149*ec779b8eSAndroid Build Coastguard Worker }
150*ec779b8eSAndroid Build Coastguard Worker
removeResource(const ClientInfoParcel & clientInfo,const std::vector<MediaResourceParcel> & resources)151*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::removeResource(const ClientInfoParcel& clientInfo,
152*ec779b8eSAndroid Build Coastguard Worker const std::vector<MediaResourceParcel>& resources) {
153*ec779b8eSAndroid Build Coastguard Worker int32_t pid = clientInfo.pid;
154*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = clientInfo.id;
155*ec779b8eSAndroid Build Coastguard Worker
156*ec779b8eSAndroid Build Coastguard Worker if (!mProcessInfo->isPidTrusted(pid)) {
157*ec779b8eSAndroid Build Coastguard Worker pid_t callingPid = IPCThreadState::self()->getCallingPid();
158*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
159*ec779b8eSAndroid Build Coastguard Worker pid, callingPid);
160*ec779b8eSAndroid Build Coastguard Worker pid = callingPid;
161*ec779b8eSAndroid Build Coastguard Worker }
162*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
163*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
164*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
165*ec779b8eSAndroid Build Coastguard Worker return false;
166*ec779b8eSAndroid Build Coastguard Worker }
167*ec779b8eSAndroid Build Coastguard Worker
168*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = found->second;
169*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::iterator foundClient = infos.find(clientId);
170*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
171*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
172*ec779b8eSAndroid Build Coastguard Worker return false;
173*ec779b8eSAndroid Build Coastguard Worker }
174*ec779b8eSAndroid Build Coastguard Worker
175*ec779b8eSAndroid Build Coastguard Worker ResourceInfo& info = foundClient->second;
176*ec779b8eSAndroid Build Coastguard Worker ResourceList resourceRemoved;
177*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& res : resources) {
178*ec779b8eSAndroid Build Coastguard Worker if (res.value < 0) {
179*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Ignoring request to remove negative value of resource", __func__);
180*ec779b8eSAndroid Build Coastguard Worker continue;
181*ec779b8eSAndroid Build Coastguard Worker }
182*ec779b8eSAndroid Build Coastguard Worker
183*ec779b8eSAndroid Build Coastguard Worker long removedEntryValue = -1;
184*ec779b8eSAndroid Build Coastguard Worker if (info.resources.remove(res, &removedEntryValue)) {
185*ec779b8eSAndroid Build Coastguard Worker MediaResourceParcel actualRemoved = res;
186*ec779b8eSAndroid Build Coastguard Worker if (removedEntryValue != -1) {
187*ec779b8eSAndroid Build Coastguard Worker onLastRemoved(res, info.uid);
188*ec779b8eSAndroid Build Coastguard Worker actualRemoved.value = removedEntryValue;
189*ec779b8eSAndroid Build Coastguard Worker }
190*ec779b8eSAndroid Build Coastguard Worker
191*ec779b8eSAndroid Build Coastguard Worker // Add it to the list of removed resources for observers.
192*ec779b8eSAndroid Build Coastguard Worker resourceRemoved.add(actualRemoved);
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker }
195*ec779b8eSAndroid Build Coastguard Worker if (mObserverService != nullptr && !resourceRemoved.empty()) {
196*ec779b8eSAndroid Build Coastguard Worker mObserverService->onResourceRemoved(info.uid, pid, resourceRemoved);
197*ec779b8eSAndroid Build Coastguard Worker }
198*ec779b8eSAndroid Build Coastguard Worker return true;
199*ec779b8eSAndroid Build Coastguard Worker }
200*ec779b8eSAndroid Build Coastguard Worker
removeResource(const ClientInfoParcel & clientInfo,bool validateCallingPid)201*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::removeResource(const ClientInfoParcel& clientInfo, bool validateCallingPid) {
202*ec779b8eSAndroid Build Coastguard Worker int32_t pid = clientInfo.pid;
203*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = clientInfo.id;
204*ec779b8eSAndroid Build Coastguard Worker
205*ec779b8eSAndroid Build Coastguard Worker if (validateCallingPid && !mProcessInfo->isPidTrusted(pid)) {
206*ec779b8eSAndroid Build Coastguard Worker pid_t callingPid = IPCThreadState::self()->getCallingPid();
207*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
208*ec779b8eSAndroid Build Coastguard Worker pid, callingPid);
209*ec779b8eSAndroid Build Coastguard Worker pid = callingPid;
210*ec779b8eSAndroid Build Coastguard Worker }
211*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
212*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
213*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
214*ec779b8eSAndroid Build Coastguard Worker return false;
215*ec779b8eSAndroid Build Coastguard Worker }
216*ec779b8eSAndroid Build Coastguard Worker
217*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = found->second;
218*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::iterator foundClient = infos.find(clientId);
219*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
220*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
221*ec779b8eSAndroid Build Coastguard Worker return false;
222*ec779b8eSAndroid Build Coastguard Worker }
223*ec779b8eSAndroid Build Coastguard Worker
224*ec779b8eSAndroid Build Coastguard Worker const ResourceInfo& info = foundClient->second;
225*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& res : info.resources.getResources()) {
226*ec779b8eSAndroid Build Coastguard Worker onLastRemoved(res, info.uid);
227*ec779b8eSAndroid Build Coastguard Worker }
228*ec779b8eSAndroid Build Coastguard Worker
229*ec779b8eSAndroid Build Coastguard Worker if (mObserverService != nullptr && !info.resources.empty()) {
230*ec779b8eSAndroid Build Coastguard Worker mObserverService->onResourceRemoved(info.uid, pid, info.resources);
231*ec779b8eSAndroid Build Coastguard Worker }
232*ec779b8eSAndroid Build Coastguard Worker
233*ec779b8eSAndroid Build Coastguard Worker infos.erase(foundClient);
234*ec779b8eSAndroid Build Coastguard Worker return true;
235*ec779b8eSAndroid Build Coastguard Worker }
236*ec779b8eSAndroid Build Coastguard Worker
getClient(int pid,const int64_t & clientId) const237*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<IResourceManagerClient> ResourceTracker::getClient(
238*ec779b8eSAndroid Build Coastguard Worker int pid, const int64_t& clientId) const {
239*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::const_iterator found = mMap.find(pid);
240*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
241*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
242*ec779b8eSAndroid Build Coastguard Worker return nullptr;
243*ec779b8eSAndroid Build Coastguard Worker }
244*ec779b8eSAndroid Build Coastguard Worker
245*ec779b8eSAndroid Build Coastguard Worker const ResourceInfos& infos = found->second;
246*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::const_iterator foundClient = infos.find(clientId);
247*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
248*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
249*ec779b8eSAndroid Build Coastguard Worker return nullptr;
250*ec779b8eSAndroid Build Coastguard Worker }
251*ec779b8eSAndroid Build Coastguard Worker
252*ec779b8eSAndroid Build Coastguard Worker return foundClient->second.client;
253*ec779b8eSAndroid Build Coastguard Worker }
254*ec779b8eSAndroid Build Coastguard Worker
removeClient(int pid,const int64_t & clientId)255*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::removeClient(int pid, const int64_t& clientId) {
256*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
257*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
258*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
259*ec779b8eSAndroid Build Coastguard Worker return false;
260*ec779b8eSAndroid Build Coastguard Worker }
261*ec779b8eSAndroid Build Coastguard Worker
262*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = found->second;
263*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::iterator foundClient = infos.find(clientId);
264*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
265*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
266*ec779b8eSAndroid Build Coastguard Worker return false;
267*ec779b8eSAndroid Build Coastguard Worker }
268*ec779b8eSAndroid Build Coastguard Worker
269*ec779b8eSAndroid Build Coastguard Worker infos.erase(foundClient);
270*ec779b8eSAndroid Build Coastguard Worker return true;
271*ec779b8eSAndroid Build Coastguard Worker }
272*ec779b8eSAndroid Build Coastguard Worker
markClientForPendingRemoval(const ClientInfoParcel & clientInfo)273*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
274*ec779b8eSAndroid Build Coastguard Worker int32_t pid = clientInfo.pid;
275*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = clientInfo.id;
276*ec779b8eSAndroid Build Coastguard Worker
277*ec779b8eSAndroid Build Coastguard Worker if (!mProcessInfo->isPidTrusted(pid)) {
278*ec779b8eSAndroid Build Coastguard Worker pid_t callingPid = IPCThreadState::self()->getCallingPid();
279*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__,
280*ec779b8eSAndroid Build Coastguard Worker pid, callingPid);
281*ec779b8eSAndroid Build Coastguard Worker pid = callingPid;
282*ec779b8eSAndroid Build Coastguard Worker }
283*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
284*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
285*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long)clientId);
286*ec779b8eSAndroid Build Coastguard Worker return false;
287*ec779b8eSAndroid Build Coastguard Worker }
288*ec779b8eSAndroid Build Coastguard Worker
289*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& infos = found->second;
290*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::iterator foundClient = infos.find(clientId);
291*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
292*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
293*ec779b8eSAndroid Build Coastguard Worker return false;
294*ec779b8eSAndroid Build Coastguard Worker }
295*ec779b8eSAndroid Build Coastguard Worker
296*ec779b8eSAndroid Build Coastguard Worker ResourceInfo& info = foundClient->second;
297*ec779b8eSAndroid Build Coastguard Worker info.pendingRemoval = true;
298*ec779b8eSAndroid Build Coastguard Worker return true;
299*ec779b8eSAndroid Build Coastguard Worker }
300*ec779b8eSAndroid Build Coastguard Worker
getClientsMarkedPendingRemoval(int32_t pid,std::vector<ClientInfo> & targetClients)301*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getClientsMarkedPendingRemoval(int32_t pid,
302*ec779b8eSAndroid Build Coastguard Worker std::vector<ClientInfo>& targetClients) {
303*ec779b8eSAndroid Build Coastguard Worker if (!mProcessInfo->isPidTrusted(pid)) {
304*ec779b8eSAndroid Build Coastguard Worker pid_t callingPid = IPCThreadState::self()->getCallingPid();
305*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s called with untrusted pid %d, using calling pid %d", __func__, pid, callingPid);
306*ec779b8eSAndroid Build Coastguard Worker pid = callingPid;
307*ec779b8eSAndroid Build Coastguard Worker }
308*ec779b8eSAndroid Build Coastguard Worker
309*ec779b8eSAndroid Build Coastguard Worker // Go through all the MediaResource types (and corresponding subtypes for
310*ec779b8eSAndroid Build Coastguard Worker // each, if applicable) and see if the process (with given pid) holds any
311*ec779b8eSAndroid Build Coastguard Worker // such resources that are marked as pending removal.
312*ec779b8eSAndroid Build Coastguard Worker // Since the use-case of this function is to get all such resources (pending
313*ec779b8eSAndroid Build Coastguard Worker // removal) and reclaim them all - the order in which we look for the
314*ec779b8eSAndroid Build Coastguard Worker // resource type doesn't matter.
315*ec779b8eSAndroid Build Coastguard Worker for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
316*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type::kNonSecureCodec,
317*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type::kGraphicMemory,
318*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type::kDrmSession}) {
319*ec779b8eSAndroid Build Coastguard Worker switch (type) {
320*ec779b8eSAndroid Build Coastguard Worker // Codec resources are segregated by audio, video and image domains.
321*ec779b8eSAndroid Build Coastguard Worker case MediaResource::Type::kSecureCodec:
322*ec779b8eSAndroid Build Coastguard Worker case MediaResource::Type::kNonSecureCodec:
323*ec779b8eSAndroid Build Coastguard Worker for (MediaResource::SubType subType : {MediaResource::SubType::kHwAudioCodec,
324*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType::kSwAudioCodec,
325*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType::kHwVideoCodec,
326*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType::kSwVideoCodec,
327*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType::kHwImageCodec,
328*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType::kSwImageCodec}) {
329*ec779b8eSAndroid Build Coastguard Worker ClientInfo clientInfo;
330*ec779b8eSAndroid Build Coastguard Worker if (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
331*ec779b8eSAndroid Build Coastguard Worker if (!contains(targetClients, clientInfo.mClientId)) {
332*ec779b8eSAndroid Build Coastguard Worker targetClients.emplace_back(clientInfo);
333*ec779b8eSAndroid Build Coastguard Worker }
334*ec779b8eSAndroid Build Coastguard Worker continue;
335*ec779b8eSAndroid Build Coastguard Worker }
336*ec779b8eSAndroid Build Coastguard Worker }
337*ec779b8eSAndroid Build Coastguard Worker break;
338*ec779b8eSAndroid Build Coastguard Worker // Non-codec resources are shared by audio, video and image codecs (no subtype).
339*ec779b8eSAndroid Build Coastguard Worker default:
340*ec779b8eSAndroid Build Coastguard Worker ClientInfo clientInfo;
341*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
342*ec779b8eSAndroid Build Coastguard Worker if (getBiggestClientPendingRemoval(pid, type, subType, clientInfo)) {
343*ec779b8eSAndroid Build Coastguard Worker if (!contains(targetClients, clientInfo.mClientId)) {
344*ec779b8eSAndroid Build Coastguard Worker targetClients.emplace_back(clientInfo);
345*ec779b8eSAndroid Build Coastguard Worker }
346*ec779b8eSAndroid Build Coastguard Worker }
347*ec779b8eSAndroid Build Coastguard Worker break;
348*ec779b8eSAndroid Build Coastguard Worker }
349*ec779b8eSAndroid Build Coastguard Worker }
350*ec779b8eSAndroid Build Coastguard Worker
351*ec779b8eSAndroid Build Coastguard Worker return true;
352*ec779b8eSAndroid Build Coastguard Worker }
353*ec779b8eSAndroid Build Coastguard Worker
overridePid(int originalPid,int newPid)354*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::overridePid(int originalPid, int newPid) {
355*ec779b8eSAndroid Build Coastguard Worker mOverridePidMap.erase(originalPid);
356*ec779b8eSAndroid Build Coastguard Worker if (newPid != -1) {
357*ec779b8eSAndroid Build Coastguard Worker mOverridePidMap.emplace(originalPid, newPid);
358*ec779b8eSAndroid Build Coastguard Worker return true;
359*ec779b8eSAndroid Build Coastguard Worker }
360*ec779b8eSAndroid Build Coastguard Worker return false;
361*ec779b8eSAndroid Build Coastguard Worker }
362*ec779b8eSAndroid Build Coastguard Worker
overrideProcessInfo(const std::shared_ptr<IResourceManagerClient> & client,int pid,int procState,int oomScore)363*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client,
364*ec779b8eSAndroid Build Coastguard Worker int pid, int procState, int oomScore) {
365*ec779b8eSAndroid Build Coastguard Worker removeProcessInfoOverride(pid);
366*ec779b8eSAndroid Build Coastguard Worker
367*ec779b8eSAndroid Build Coastguard Worker if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
368*ec779b8eSAndroid Build Coastguard Worker // Override value is rejected by ProcessInfo.
369*ec779b8eSAndroid Build Coastguard Worker return false;
370*ec779b8eSAndroid Build Coastguard Worker }
371*ec779b8eSAndroid Build Coastguard Worker
372*ec779b8eSAndroid Build Coastguard Worker ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
373*ec779b8eSAndroid Build Coastguard Worker .uid = 0,
374*ec779b8eSAndroid Build Coastguard Worker .id = 0,
375*ec779b8eSAndroid Build Coastguard Worker .name = "<unknown client>"};
376*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<DeathNotifier> deathNotifier =
377*ec779b8eSAndroid Build Coastguard Worker DeathNotifier::Create(client, mService, clientInfo, true);
378*ec779b8eSAndroid Build Coastguard Worker
379*ec779b8eSAndroid Build Coastguard Worker mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{deathNotifier, client});
380*ec779b8eSAndroid Build Coastguard Worker
381*ec779b8eSAndroid Build Coastguard Worker return true;
382*ec779b8eSAndroid Build Coastguard Worker }
383*ec779b8eSAndroid Build Coastguard Worker
removeProcessInfoOverride(int pid)384*ec779b8eSAndroid Build Coastguard Worker void ResourceTracker::removeProcessInfoOverride(int pid) {
385*ec779b8eSAndroid Build Coastguard Worker auto it = mProcessInfoOverrideMap.find(pid);
386*ec779b8eSAndroid Build Coastguard Worker if (it == mProcessInfoOverrideMap.end()) {
387*ec779b8eSAndroid Build Coastguard Worker return;
388*ec779b8eSAndroid Build Coastguard Worker }
389*ec779b8eSAndroid Build Coastguard Worker
390*ec779b8eSAndroid Build Coastguard Worker mProcessInfo->removeProcessInfoOverride(pid);
391*ec779b8eSAndroid Build Coastguard Worker mProcessInfoOverrideMap.erase(pid);
392*ec779b8eSAndroid Build Coastguard Worker }
393*ec779b8eSAndroid Build Coastguard Worker
getAllClients(const ResourceRequestInfo & resourceRequestInfo,std::vector<ClientInfo> & clients,MediaResource::SubType primarySubType)394*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getAllClients(const ResourceRequestInfo& resourceRequestInfo,
395*ec779b8eSAndroid Build Coastguard Worker std::vector<ClientInfo>& clients,
396*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType primarySubType) {
397*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type type = resourceRequestInfo.mResource->type;
398*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
399*ec779b8eSAndroid Build Coastguard Worker bool foundClient = false;
400*ec779b8eSAndroid Build Coastguard Worker
401*ec779b8eSAndroid Build Coastguard Worker for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
402*ec779b8eSAndroid Build Coastguard Worker for (auto& [id, /* ResourceInfo */ info] : infos) {
403*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, info.resources, primarySubType)) {
404*ec779b8eSAndroid Build Coastguard Worker if (!contains(clients, info.clientId)) {
405*ec779b8eSAndroid Build Coastguard Worker clients.emplace_back(info.pid, info.uid, info.clientId);
406*ec779b8eSAndroid Build Coastguard Worker foundClient = true;
407*ec779b8eSAndroid Build Coastguard Worker }
408*ec779b8eSAndroid Build Coastguard Worker }
409*ec779b8eSAndroid Build Coastguard Worker }
410*ec779b8eSAndroid Build Coastguard Worker }
411*ec779b8eSAndroid Build Coastguard Worker
412*ec779b8eSAndroid Build Coastguard Worker return foundClient;
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker
getLowestPriorityPid(MediaResource::Type type,MediaResource::SubType subType,int & lowestPriorityPid,int & lowestPriority)415*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
416*ec779b8eSAndroid Build Coastguard Worker int& lowestPriorityPid, int& lowestPriority) {
417*ec779b8eSAndroid Build Coastguard Worker int pid = -1;
418*ec779b8eSAndroid Build Coastguard Worker int priority = -1;
419*ec779b8eSAndroid Build Coastguard Worker for (auto& [tempPid, /* ResourceInfos */ infos] : mMap) {
420*ec779b8eSAndroid Build Coastguard Worker if (infos.size() == 0) {
421*ec779b8eSAndroid Build Coastguard Worker // no client on this process.
422*ec779b8eSAndroid Build Coastguard Worker continue;
423*ec779b8eSAndroid Build Coastguard Worker }
424*ec779b8eSAndroid Build Coastguard Worker if (!hasResourceType(type, subType, infos)) {
425*ec779b8eSAndroid Build Coastguard Worker // doesn't have the requested resource type
426*ec779b8eSAndroid Build Coastguard Worker continue;
427*ec779b8eSAndroid Build Coastguard Worker }
428*ec779b8eSAndroid Build Coastguard Worker int tempPriority = -1;
429*ec779b8eSAndroid Build Coastguard Worker if (!getPriority(tempPid, &tempPriority)) {
430*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: can't get priority of pid %d, skipped", __func__, tempPid);
431*ec779b8eSAndroid Build Coastguard Worker // TODO: remove this pid from mMap?
432*ec779b8eSAndroid Build Coastguard Worker continue;
433*ec779b8eSAndroid Build Coastguard Worker }
434*ec779b8eSAndroid Build Coastguard Worker if (pid == -1 || tempPriority > priority) {
435*ec779b8eSAndroid Build Coastguard Worker // initial the value
436*ec779b8eSAndroid Build Coastguard Worker pid = tempPid;
437*ec779b8eSAndroid Build Coastguard Worker priority = tempPriority;
438*ec779b8eSAndroid Build Coastguard Worker }
439*ec779b8eSAndroid Build Coastguard Worker }
440*ec779b8eSAndroid Build Coastguard Worker
441*ec779b8eSAndroid Build Coastguard Worker bool success = (pid != -1);
442*ec779b8eSAndroid Build Coastguard Worker
443*ec779b8eSAndroid Build Coastguard Worker if (success) {
444*ec779b8eSAndroid Build Coastguard Worker lowestPriorityPid = pid;
445*ec779b8eSAndroid Build Coastguard Worker lowestPriority = priority;
446*ec779b8eSAndroid Build Coastguard Worker }
447*ec779b8eSAndroid Build Coastguard Worker return success;
448*ec779b8eSAndroid Build Coastguard Worker }
449*ec779b8eSAndroid Build Coastguard Worker
getLowestPriorityPid(MediaResource::Type type,MediaResource::SubType subType,MediaResource::SubType primarySubType,const std::vector<ClientInfo> & clients,int & lowestPriorityPid,int & lowestPriority)450*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
451*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType primarySubType,
452*ec779b8eSAndroid Build Coastguard Worker const std::vector<ClientInfo>& clients,
453*ec779b8eSAndroid Build Coastguard Worker int& lowestPriorityPid, int& lowestPriority) {
454*ec779b8eSAndroid Build Coastguard Worker int pid = -1;
455*ec779b8eSAndroid Build Coastguard Worker int priority = -1;
456*ec779b8eSAndroid Build Coastguard Worker for (const ClientInfo& client : clients) {
457*ec779b8eSAndroid Build Coastguard Worker const ResourceInfo* info = getResourceInfo(client.mPid, client.mClientId);
458*ec779b8eSAndroid Build Coastguard Worker if (info == nullptr) {
459*ec779b8eSAndroid Build Coastguard Worker continue;
460*ec779b8eSAndroid Build Coastguard Worker }
461*ec779b8eSAndroid Build Coastguard Worker if (!hasResourceType(type, subType, info->resources, primarySubType)) {
462*ec779b8eSAndroid Build Coastguard Worker // doesn't have the requested resource type
463*ec779b8eSAndroid Build Coastguard Worker continue;
464*ec779b8eSAndroid Build Coastguard Worker }
465*ec779b8eSAndroid Build Coastguard Worker int tempPriority = -1;
466*ec779b8eSAndroid Build Coastguard Worker if (!getPriority(client.mPid, &tempPriority)) {
467*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: can't get priority of pid %d, skipped", __func__, client.mPid);
468*ec779b8eSAndroid Build Coastguard Worker // TODO: remove this pid from mMap?
469*ec779b8eSAndroid Build Coastguard Worker continue;
470*ec779b8eSAndroid Build Coastguard Worker }
471*ec779b8eSAndroid Build Coastguard Worker if (pid == -1 || tempPriority > priority) {
472*ec779b8eSAndroid Build Coastguard Worker // initial the value
473*ec779b8eSAndroid Build Coastguard Worker pid = client.mPid;
474*ec779b8eSAndroid Build Coastguard Worker priority = tempPriority;
475*ec779b8eSAndroid Build Coastguard Worker }
476*ec779b8eSAndroid Build Coastguard Worker }
477*ec779b8eSAndroid Build Coastguard Worker
478*ec779b8eSAndroid Build Coastguard Worker bool success = (pid != -1);
479*ec779b8eSAndroid Build Coastguard Worker
480*ec779b8eSAndroid Build Coastguard Worker if (success) {
481*ec779b8eSAndroid Build Coastguard Worker lowestPriorityPid = pid;
482*ec779b8eSAndroid Build Coastguard Worker lowestPriority = priority;
483*ec779b8eSAndroid Build Coastguard Worker }
484*ec779b8eSAndroid Build Coastguard Worker return success;
485*ec779b8eSAndroid Build Coastguard Worker }
486*ec779b8eSAndroid Build Coastguard Worker
getBiggestClientPendingRemoval(int pid,MediaResource::Type type,MediaResource::SubType subType,ClientInfo & clientInfo)487*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getBiggestClientPendingRemoval(int pid, MediaResource::Type type,
488*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType subType,
489*ec779b8eSAndroid Build Coastguard Worker ClientInfo& clientInfo) {
490*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
491*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
492*ec779b8eSAndroid Build Coastguard Worker return false;
493*ec779b8eSAndroid Build Coastguard Worker }
494*ec779b8eSAndroid Build Coastguard Worker
495*ec779b8eSAndroid Build Coastguard Worker uid_t uid = -1;
496*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = -1;
497*ec779b8eSAndroid Build Coastguard Worker uint64_t largestValue = 0;
498*ec779b8eSAndroid Build Coastguard Worker const ResourceInfos& infos = found->second;
499*ec779b8eSAndroid Build Coastguard Worker for (const auto& [id, /* ResourceInfo */ info] : infos) {
500*ec779b8eSAndroid Build Coastguard Worker const ResourceList& resources = info.resources;
501*ec779b8eSAndroid Build Coastguard Worker // Skip if the client is not marked pending removal.
502*ec779b8eSAndroid Build Coastguard Worker if (!info.pendingRemoval) {
503*ec779b8eSAndroid Build Coastguard Worker continue;
504*ec779b8eSAndroid Build Coastguard Worker }
505*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& resource : resources.getResources()) {
506*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, resource)) {
507*ec779b8eSAndroid Build Coastguard Worker if (resource.value > largestValue) {
508*ec779b8eSAndroid Build Coastguard Worker largestValue = resource.value;
509*ec779b8eSAndroid Build Coastguard Worker clientId = info.clientId;
510*ec779b8eSAndroid Build Coastguard Worker uid = info.uid;
511*ec779b8eSAndroid Build Coastguard Worker }
512*ec779b8eSAndroid Build Coastguard Worker }
513*ec779b8eSAndroid Build Coastguard Worker }
514*ec779b8eSAndroid Build Coastguard Worker }
515*ec779b8eSAndroid Build Coastguard Worker
516*ec779b8eSAndroid Build Coastguard Worker if (clientId == -1) {
517*ec779b8eSAndroid Build Coastguard Worker return false;
518*ec779b8eSAndroid Build Coastguard Worker }
519*ec779b8eSAndroid Build Coastguard Worker
520*ec779b8eSAndroid Build Coastguard Worker clientInfo.mPid = pid;
521*ec779b8eSAndroid Build Coastguard Worker clientInfo.mUid = uid;
522*ec779b8eSAndroid Build Coastguard Worker clientInfo.mClientId = clientId;
523*ec779b8eSAndroid Build Coastguard Worker return true;
524*ec779b8eSAndroid Build Coastguard Worker }
525*ec779b8eSAndroid Build Coastguard Worker
getBiggestClient(int targetPid,MediaResource::Type type,MediaResource::SubType subType,const std::vector<ClientInfo> & clients,ClientInfo & clientInfo,MediaResource::SubType primarySubType)526*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getBiggestClient(int targetPid,
527*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type type, MediaResource::SubType subType,
528*ec779b8eSAndroid Build Coastguard Worker const std::vector<ClientInfo>& clients,
529*ec779b8eSAndroid Build Coastguard Worker ClientInfo& clientInfo,
530*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType primarySubType) {
531*ec779b8eSAndroid Build Coastguard Worker uid_t uid = -1;
532*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = -1;
533*ec779b8eSAndroid Build Coastguard Worker uint64_t largestValue = 0;
534*ec779b8eSAndroid Build Coastguard Worker
535*ec779b8eSAndroid Build Coastguard Worker for (const ClientInfo& client : clients) {
536*ec779b8eSAndroid Build Coastguard Worker // Skip the clients that doesn't belong go the targetPid
537*ec779b8eSAndroid Build Coastguard Worker if (client.mPid != targetPid) {
538*ec779b8eSAndroid Build Coastguard Worker continue;
539*ec779b8eSAndroid Build Coastguard Worker }
540*ec779b8eSAndroid Build Coastguard Worker const ResourceInfo* info = getResourceInfo(client.mPid, client.mClientId);
541*ec779b8eSAndroid Build Coastguard Worker if (info == nullptr) {
542*ec779b8eSAndroid Build Coastguard Worker continue;
543*ec779b8eSAndroid Build Coastguard Worker }
544*ec779b8eSAndroid Build Coastguard Worker
545*ec779b8eSAndroid Build Coastguard Worker const ResourceList& resources = info->resources;
546*ec779b8eSAndroid Build Coastguard Worker bool matchedPrimary =
547*ec779b8eSAndroid Build Coastguard Worker (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ? true : false;
548*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& resource : resources.getResources()) {
549*ec779b8eSAndroid Build Coastguard Worker if (resource.subType == primarySubType) {
550*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
551*ec779b8eSAndroid Build Coastguard Worker break;
552*ec779b8eSAndroid Build Coastguard Worker } else if (isHwCodec(resource.subType) == isHwCodec(primarySubType)) {
553*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
554*ec779b8eSAndroid Build Coastguard Worker break;
555*ec779b8eSAndroid Build Coastguard Worker }
556*ec779b8eSAndroid Build Coastguard Worker }
557*ec779b8eSAndroid Build Coastguard Worker // Primary type doesn't match, skip the client
558*ec779b8eSAndroid Build Coastguard Worker if (!matchedPrimary) {
559*ec779b8eSAndroid Build Coastguard Worker continue;
560*ec779b8eSAndroid Build Coastguard Worker }
561*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& resource : resources.getResources()) {
562*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, resource)) {
563*ec779b8eSAndroid Build Coastguard Worker if (resource.value > largestValue) {
564*ec779b8eSAndroid Build Coastguard Worker largestValue = resource.value;
565*ec779b8eSAndroid Build Coastguard Worker clientId = info->clientId;
566*ec779b8eSAndroid Build Coastguard Worker uid = info->uid;
567*ec779b8eSAndroid Build Coastguard Worker }
568*ec779b8eSAndroid Build Coastguard Worker }
569*ec779b8eSAndroid Build Coastguard Worker }
570*ec779b8eSAndroid Build Coastguard Worker }
571*ec779b8eSAndroid Build Coastguard Worker
572*ec779b8eSAndroid Build Coastguard Worker if (clientId == -1) {
573*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: can't find resource type %s and subtype %s for pid %d",
574*ec779b8eSAndroid Build Coastguard Worker __func__, asString(type), asString(subType), targetPid);
575*ec779b8eSAndroid Build Coastguard Worker return false;
576*ec779b8eSAndroid Build Coastguard Worker }
577*ec779b8eSAndroid Build Coastguard Worker
578*ec779b8eSAndroid Build Coastguard Worker clientInfo.mPid = targetPid;
579*ec779b8eSAndroid Build Coastguard Worker clientInfo.mUid = uid;
580*ec779b8eSAndroid Build Coastguard Worker clientInfo.mClientId = clientId;
581*ec779b8eSAndroid Build Coastguard Worker return true;
582*ec779b8eSAndroid Build Coastguard Worker }
583*ec779b8eSAndroid Build Coastguard Worker
getLeastImportantBiggestClient(int targetPid,int32_t importance,MediaResource::Type type,MediaResource::SubType subType,MediaResource::SubType primarySubType,const std::vector<ClientInfo> & clients,ClientInfo & clientInfo)584*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getLeastImportantBiggestClient(int targetPid, int32_t importance,
585*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type type,
586*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType subType,
587*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType primarySubType,
588*ec779b8eSAndroid Build Coastguard Worker const std::vector<ClientInfo>& clients,
589*ec779b8eSAndroid Build Coastguard Worker ClientInfo& clientInfo) {
590*ec779b8eSAndroid Build Coastguard Worker uid_t uid = -1;
591*ec779b8eSAndroid Build Coastguard Worker int64_t clientId = -1;
592*ec779b8eSAndroid Build Coastguard Worker uint64_t largestValue = 0;
593*ec779b8eSAndroid Build Coastguard Worker
594*ec779b8eSAndroid Build Coastguard Worker for (const ClientInfo& client : clients) {
595*ec779b8eSAndroid Build Coastguard Worker // Skip the clients that doesn't belong go the targetPid
596*ec779b8eSAndroid Build Coastguard Worker if (client.mPid != targetPid) {
597*ec779b8eSAndroid Build Coastguard Worker continue;
598*ec779b8eSAndroid Build Coastguard Worker }
599*ec779b8eSAndroid Build Coastguard Worker const ResourceInfo* info = getResourceInfo(client.mPid, client.mClientId);
600*ec779b8eSAndroid Build Coastguard Worker if (info == nullptr) {
601*ec779b8eSAndroid Build Coastguard Worker continue;
602*ec779b8eSAndroid Build Coastguard Worker }
603*ec779b8eSAndroid Build Coastguard Worker
604*ec779b8eSAndroid Build Coastguard Worker // Make sure the importance is lower.
605*ec779b8eSAndroid Build Coastguard Worker if (info->importance <= importance) {
606*ec779b8eSAndroid Build Coastguard Worker continue;
607*ec779b8eSAndroid Build Coastguard Worker }
608*ec779b8eSAndroid Build Coastguard Worker const ResourceList& resources = info->resources;
609*ec779b8eSAndroid Build Coastguard Worker bool matchedPrimary =
610*ec779b8eSAndroid Build Coastguard Worker (primarySubType == MediaResource::SubType::kUnspecifiedSubType) ? true : false;
611*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& resource : resources.getResources()) {
612*ec779b8eSAndroid Build Coastguard Worker if (resource.subType == primarySubType) {
613*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
614*ec779b8eSAndroid Build Coastguard Worker } else if (isHwCodec(resource.subType) == isHwCodec(primarySubType)) {
615*ec779b8eSAndroid Build Coastguard Worker matchedPrimary = true;
616*ec779b8eSAndroid Build Coastguard Worker }
617*ec779b8eSAndroid Build Coastguard Worker }
618*ec779b8eSAndroid Build Coastguard Worker // Primary type doesn't match, skip the client
619*ec779b8eSAndroid Build Coastguard Worker if (!matchedPrimary) {
620*ec779b8eSAndroid Build Coastguard Worker continue;
621*ec779b8eSAndroid Build Coastguard Worker }
622*ec779b8eSAndroid Build Coastguard Worker for (const MediaResourceParcel& resource : resources.getResources()) {
623*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, resource)) {
624*ec779b8eSAndroid Build Coastguard Worker if (resource.value > largestValue) {
625*ec779b8eSAndroid Build Coastguard Worker largestValue = resource.value;
626*ec779b8eSAndroid Build Coastguard Worker clientId = info->clientId;
627*ec779b8eSAndroid Build Coastguard Worker uid = info->uid;
628*ec779b8eSAndroid Build Coastguard Worker }
629*ec779b8eSAndroid Build Coastguard Worker }
630*ec779b8eSAndroid Build Coastguard Worker }
631*ec779b8eSAndroid Build Coastguard Worker }
632*ec779b8eSAndroid Build Coastguard Worker
633*ec779b8eSAndroid Build Coastguard Worker if (clientId == -1) {
634*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: can't find resource type %s and subtype %s for pid %d",
635*ec779b8eSAndroid Build Coastguard Worker __func__, asString(type), asString(subType), targetPid);
636*ec779b8eSAndroid Build Coastguard Worker return false;
637*ec779b8eSAndroid Build Coastguard Worker }
638*ec779b8eSAndroid Build Coastguard Worker
639*ec779b8eSAndroid Build Coastguard Worker clientInfo.mPid = targetPid;
640*ec779b8eSAndroid Build Coastguard Worker clientInfo.mUid = uid;
641*ec779b8eSAndroid Build Coastguard Worker clientInfo.mClientId = clientId;
642*ec779b8eSAndroid Build Coastguard Worker return true;
643*ec779b8eSAndroid Build Coastguard Worker }
644*ec779b8eSAndroid Build Coastguard Worker
dump(std::string & resourceLogs)645*ec779b8eSAndroid Build Coastguard Worker void ResourceTracker::dump(std::string& resourceLogs) {
646*ec779b8eSAndroid Build Coastguard Worker const size_t SIZE = 256;
647*ec779b8eSAndroid Build Coastguard Worker char buffer[SIZE];
648*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(" Processes:\n");
649*ec779b8eSAndroid Build Coastguard Worker for (const auto& [pid, /* ResourceInfos */ infos] : mMap) {
650*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Pid: %d\n", pid);
651*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(buffer);
652*ec779b8eSAndroid Build Coastguard Worker int priority = 0;
653*ec779b8eSAndroid Build Coastguard Worker if (getPriority(pid, &priority)) {
654*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Priority: %d\n", priority);
655*ec779b8eSAndroid Build Coastguard Worker } else {
656*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Priority: <unknown>\n");
657*ec779b8eSAndroid Build Coastguard Worker }
658*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(buffer);
659*ec779b8eSAndroid Build Coastguard Worker
660*ec779b8eSAndroid Build Coastguard Worker for (const auto& [infoKey, /* ResourceInfo */ info] : infos) {
661*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(" Client:\n");
662*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Id: %lld\n", (long long)info.clientId);
663*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(buffer);
664*ec779b8eSAndroid Build Coastguard Worker
665*ec779b8eSAndroid Build Coastguard Worker std::string clientName = info.name;
666*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
667*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(buffer);
668*ec779b8eSAndroid Build Coastguard Worker
669*ec779b8eSAndroid Build Coastguard Worker const ResourceList& resources = info.resources;
670*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(" Resources:\n");
671*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(resources.toString());
672*ec779b8eSAndroid Build Coastguard Worker }
673*ec779b8eSAndroid Build Coastguard Worker }
674*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(" Process Pid override:\n");
675*ec779b8eSAndroid Build Coastguard Worker for (const auto& [oldPid, newPid] : mOverridePidMap) {
676*ec779b8eSAndroid Build Coastguard Worker snprintf(buffer, SIZE, " Original Pid: %d, Override Pid: %d\n", oldPid, newPid);
677*ec779b8eSAndroid Build Coastguard Worker resourceLogs.append(buffer);
678*ec779b8eSAndroid Build Coastguard Worker }
679*ec779b8eSAndroid Build Coastguard Worker }
680*ec779b8eSAndroid Build Coastguard Worker
onFirstAdded(const MediaResourceParcel & resource,uid_t uid)681*ec779b8eSAndroid Build Coastguard Worker void ResourceTracker::onFirstAdded(const MediaResourceParcel& resource, uid_t uid) {
682*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<ResourceManagerServiceNew> service = mService.lock();
683*ec779b8eSAndroid Build Coastguard Worker if (service == nullptr) {
684*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: ResourceManagerService is invalid!", __func__);
685*ec779b8eSAndroid Build Coastguard Worker return;
686*ec779b8eSAndroid Build Coastguard Worker }
687*ec779b8eSAndroid Build Coastguard Worker
688*ec779b8eSAndroid Build Coastguard Worker service->onFirstAdded(resource, uid);
689*ec779b8eSAndroid Build Coastguard Worker }
690*ec779b8eSAndroid Build Coastguard Worker
onLastRemoved(const MediaResourceParcel & resource,uid_t uid)691*ec779b8eSAndroid Build Coastguard Worker void ResourceTracker::onLastRemoved(const MediaResourceParcel& resource, uid_t uid) {
692*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<ResourceManagerServiceNew> service = mService.lock();
693*ec779b8eSAndroid Build Coastguard Worker if (service == nullptr) {
694*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: ResourceManagerService is invalid!", __func__);
695*ec779b8eSAndroid Build Coastguard Worker return;
696*ec779b8eSAndroid Build Coastguard Worker }
697*ec779b8eSAndroid Build Coastguard Worker
698*ec779b8eSAndroid Build Coastguard Worker service->onLastRemoved(resource, uid);
699*ec779b8eSAndroid Build Coastguard Worker }
700*ec779b8eSAndroid Build Coastguard Worker
getPriority(int pid,int * priority)701*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getPriority(int pid, int* priority) {
702*ec779b8eSAndroid Build Coastguard Worker int newPid = pid;
703*ec779b8eSAndroid Build Coastguard Worker
704*ec779b8eSAndroid Build Coastguard Worker if (mOverridePidMap.find(pid) != mOverridePidMap.end()) {
705*ec779b8eSAndroid Build Coastguard Worker newPid = mOverridePidMap[pid];
706*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: use override pid %d instead original pid %d", __func__, newPid, pid);
707*ec779b8eSAndroid Build Coastguard Worker }
708*ec779b8eSAndroid Build Coastguard Worker
709*ec779b8eSAndroid Build Coastguard Worker return mProcessInfo->getPriority(newPid, priority);
710*ec779b8eSAndroid Build Coastguard Worker }
711*ec779b8eSAndroid Build Coastguard Worker
getNonConflictingClients(const ResourceRequestInfo & resourceRequestInfo,std::vector<ClientInfo> & clients)712*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::getNonConflictingClients(const ResourceRequestInfo& resourceRequestInfo,
713*ec779b8eSAndroid Build Coastguard Worker std::vector<ClientInfo>& clients) {
714*ec779b8eSAndroid Build Coastguard Worker MediaResource::Type type = resourceRequestInfo.mResource->type;
715*ec779b8eSAndroid Build Coastguard Worker MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
716*ec779b8eSAndroid Build Coastguard Worker for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
717*ec779b8eSAndroid Build Coastguard Worker for (const auto& [id, /* ResourceInfo */ info] : infos) {
718*ec779b8eSAndroid Build Coastguard Worker if (pid == resourceRequestInfo.mCallingPid && id == resourceRequestInfo.mClientId) {
719*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Skip the client[%jd] for which the resource request is made",
720*ec779b8eSAndroid Build Coastguard Worker __func__, id);
721*ec779b8eSAndroid Build Coastguard Worker continue;
722*ec779b8eSAndroid Build Coastguard Worker }
723*ec779b8eSAndroid Build Coastguard Worker if (hasResourceType(type, subType, info.resources)) {
724*ec779b8eSAndroid Build Coastguard Worker if (!isCallingPriorityHigher(resourceRequestInfo.mCallingPid, pid)) {
725*ec779b8eSAndroid Build Coastguard Worker // some higher/equal priority process owns the resource,
726*ec779b8eSAndroid Build Coastguard Worker // this is a conflict.
727*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: The resource (%s) request from pid %d is conflicting",
728*ec779b8eSAndroid Build Coastguard Worker __func__, asString(type), pid);
729*ec779b8eSAndroid Build Coastguard Worker clients.clear();
730*ec779b8eSAndroid Build Coastguard Worker return false;
731*ec779b8eSAndroid Build Coastguard Worker } else {
732*ec779b8eSAndroid Build Coastguard Worker if (!contains(clients, info.clientId)) {
733*ec779b8eSAndroid Build Coastguard Worker clients.emplace_back(info.pid, info.uid, info.clientId);
734*ec779b8eSAndroid Build Coastguard Worker }
735*ec779b8eSAndroid Build Coastguard Worker }
736*ec779b8eSAndroid Build Coastguard Worker }
737*ec779b8eSAndroid Build Coastguard Worker }
738*ec779b8eSAndroid Build Coastguard Worker }
739*ec779b8eSAndroid Build Coastguard Worker
740*ec779b8eSAndroid Build Coastguard Worker return true;
741*ec779b8eSAndroid Build Coastguard Worker }
742*ec779b8eSAndroid Build Coastguard Worker
getResourceInfo(int pid,const int64_t & clientId) const743*ec779b8eSAndroid Build Coastguard Worker const ResourceInfo* ResourceTracker::getResourceInfo(int pid, const int64_t& clientId) const {
744*ec779b8eSAndroid Build Coastguard Worker std::map<int, ResourceInfos>::const_iterator found = mMap.find(pid);
745*ec779b8eSAndroid Build Coastguard Worker if (found == mMap.end()) {
746*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
747*ec779b8eSAndroid Build Coastguard Worker return nullptr;
748*ec779b8eSAndroid Build Coastguard Worker }
749*ec779b8eSAndroid Build Coastguard Worker
750*ec779b8eSAndroid Build Coastguard Worker const ResourceInfos& infos = found->second;
751*ec779b8eSAndroid Build Coastguard Worker ResourceInfos::const_iterator foundClient = infos.find(clientId);
752*ec779b8eSAndroid Build Coastguard Worker if (foundClient == infos.end()) {
753*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
754*ec779b8eSAndroid Build Coastguard Worker return nullptr;
755*ec779b8eSAndroid Build Coastguard Worker }
756*ec779b8eSAndroid Build Coastguard Worker
757*ec779b8eSAndroid Build Coastguard Worker return &foundClient->second;
758*ec779b8eSAndroid Build Coastguard Worker }
759*ec779b8eSAndroid Build Coastguard Worker
isCallingPriorityHigher(int callingPid,int pid)760*ec779b8eSAndroid Build Coastguard Worker bool ResourceTracker::isCallingPriorityHigher(int callingPid, int pid) {
761*ec779b8eSAndroid Build Coastguard Worker int callingPidPriority;
762*ec779b8eSAndroid Build Coastguard Worker if (!getPriority(callingPid, &callingPidPriority)) {
763*ec779b8eSAndroid Build Coastguard Worker return false;
764*ec779b8eSAndroid Build Coastguard Worker }
765*ec779b8eSAndroid Build Coastguard Worker
766*ec779b8eSAndroid Build Coastguard Worker int priority;
767*ec779b8eSAndroid Build Coastguard Worker if (!getPriority(pid, &priority)) {
768*ec779b8eSAndroid Build Coastguard Worker return false;
769*ec779b8eSAndroid Build Coastguard Worker }
770*ec779b8eSAndroid Build Coastguard Worker
771*ec779b8eSAndroid Build Coastguard Worker return (callingPidPriority < priority);
772*ec779b8eSAndroid Build Coastguard Worker }
773*ec779b8eSAndroid Build Coastguard Worker
774*ec779b8eSAndroid Build Coastguard Worker } // namespace android
775