• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2023, 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 #ifndef ANDROID_MEDIA_RESOURCETRACKER_H_
19 #define ANDROID_MEDIA_RESOURCETRACKER_H_
20 
21 #include <map>
22 #include <memory>
23 #include <string>
24 #include <vector>
25 #include <media/MediaResource.h>
26 #include <aidl/android/media/ClientInfoParcel.h>
27 #include <aidl/android/media/IResourceManagerClient.h>
28 #include <aidl/android/media/MediaResourceParcel.h>
29 
30 #include "ResourceManagerServiceUtils.h"
31 
32 namespace android {
33 
34 class DeathNotifier;
35 class ResourceManagerServiceNew;
36 class ResourceObserverService;
37 struct ProcessInfoInterface;
38 struct ResourceRequestInfo;
39 struct ClientInfo;
40 
41 /*
42  * ResourceTracker abstracts the resources managed by the ResourceManager.
43  * It keeps track of the resource used by the clients (clientid) and by the process (pid)
44  */
45 class ResourceTracker {
46 public:
47     ResourceTracker(const std::shared_ptr<ResourceManagerServiceNew>& service,
48                     const sp<ProcessInfoInterface>& processInfo);
49     ~ResourceTracker();
50 
51     /**
52      * Add or update resources for |clientInfo|.
53      *
54      * If |clientInfo| is not tracked yet, it records its associated |client| and adds
55      * |resources| to the tracked resources. If |clientInfo| is already tracked,
56      * it updates the tracked resources by adding |resources| to them (|client| in
57      * this case is unused and unchecked).
58      *
59      * @param clientInfo Info of the calling client.
60      * @param client Interface for the client.
61      * @param resources An array of resources to be added.
62      *
63      * @return true upon successfully adding/updating the resources, false
64      * otherwise.
65      */
66     bool addResource(const aidl::android::media::ClientInfoParcel& clientInfo,
67                      const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
68                      const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
69 
70     // Update the importance of the client.
71     bool updateClientImportance(const aidl::android::media::ClientInfoParcel& clientInfo);
72 
73     // Update the resource info for given list of resources.
74     bool updateResource(const aidl::android::media::ClientInfoParcel& clientInfo,
75                         const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
76 
77     // Remove a set of resources from the given client.
78     // returns true on success, false otherwise.
79     bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo,
80                         const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
81 
82     /**
83      * Remove all resources tracked for |clientInfo|.
84      *
85      * If |validateCallingPid| is true, the (pid of the) calling process is validated that it
86      * is from a trusted process.
87      * Returns true on success (|clientInfo| was tracked and optionally the caller
88      * was a validated trusted process), false otherwise (|clientInfo| was not tracked,
89      * or the caller was not a trusted process)
90      */
91     bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo,
92                         bool validateCallingPid);
93 
94     // Mark the client for pending removal.
95     // Such clients are primary candidate for reclaim.
96     // returns true on success, false otherwise.
97     bool markClientForPendingRemoval(const aidl::android::media::ClientInfoParcel& clientInfo);
98 
99     // Get a list of clients that belong to process with given pid and are maked to be
100     // pending removal by markClientForPendingRemoval.
101     // returns true on success, false otherwise.
102     bool getClientsMarkedPendingRemoval(int32_t pid, std::vector<ClientInfo>& targetClients);
103 
104     // Override the pid of originalPid with newPid
105     // To remove the pid entry from the override list, set newPid as -1
106     // returns true on successful override, false otherwise.
107     bool overridePid(int originalPid, int newPid);
108 
109     // Override the process info {state, oom score} of the process with pid.
110     // returns true on success, false otherwise.
111     bool overrideProcessInfo(
112             const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
113             int pid, int procState, int oomScore);
114 
115     // Remove the overridden process info.
116     void removeProcessInfoOverride(int pid);
117 
118     // Find all clients that have given resources.
119     // If applicable, match the primary type too.
120     // The |clients| (list) isn't cleared by this function to allow calling this
121     // function multiple times for different resources.
122     // returns true upon finding at lease one client with the given resource request info,
123     // false otherwise (no clients)
124     bool getAllClients(
125             const ResourceRequestInfo& resourceRequestInfo,
126             std::vector<ClientInfo>& clients,
127             MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType);
128 
129     // Look for the lowest priority process with the given resources.
130     // Upon success lowestPriorityPid and lowestPriority are
131     // set accordingly and it returns true.
132     // If there isn't a lower priority process with the given resources, it will return false
133     // with out updating lowestPriorityPid and lowerPriority.
134     bool getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType,
135                               int& lowestPriorityPid, int& lowestPriority);
136 
137     // Look for the lowest priority process with the given resources
138     // among the given client list.
139     // If applicable, match the primary type too.
140     // returns true on success, false otherwise.
141     bool getLowestPriorityPid(
142             MediaResource::Type type, MediaResource::SubType subType,
143             MediaResource::SubType primarySubType,
144             const std::vector<ClientInfo>& clients,
145             int& lowestPriorityPid, int& lowestPriority);
146 
147     // Find the biggest client of the given process with given resources,
148     // that is marked as pending to be removed.
149     // returns true on success, false otherwise.
150     bool getBiggestClientPendingRemoval(
151             int pid, MediaResource::Type type,
152             MediaResource::SubType subType,
153             ClientInfo& clientInfo);
154 
155     // Find the biggest client from the process pid, selecting them from the list of clients.
156     // If applicable, match the primary type too.
157     // Returns true when a client is found and clientInfo is updated accordingly.
158     // Upon failure to find a client, it will return false without updating
159     // clientInfo.
160     // Upon failure to find a client, it will return false.
161     bool getBiggestClient(
162             int targetPid,
163             MediaResource::Type type,
164             MediaResource::SubType subType,
165             const std::vector<ClientInfo>& clients,
166             ClientInfo& clientInfo,
167             MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType);
168 
169     // Find the biggest client from the process pid, that has the least importance
170     // (than given importance) among the given list of clients.
171     // If applicable, match the primary type too.
172     // returns true on success, false otherwise.
173     bool getLeastImportantBiggestClient(int targetPid, int32_t importance,
174                                         MediaResource::Type type,
175                                         MediaResource::SubType subType,
176                                         MediaResource::SubType primarySubType,
177                                         const std::vector<ClientInfo>& clients,
178                                         ClientInfo& clientInfo);
179 
180     // Find the client that belongs to given process(pid) and with the given clientId.
181     // A nullptr is returned upon failure to find the client.
182     std::shared_ptr<::aidl::android::media::IResourceManagerClient> getClient(
183             int pid, const int64_t& clientId) const;
184 
185     // Removes the client from the given process(pid) with the given clientId.
186     // returns true on success, false otherwise.
187     bool removeClient(int pid, const int64_t& clientId);
188 
189     // Set the resource observer service, to which to notify when the resources
190     // are added and removed.
191     void setResourceObserverService(
192             const std::shared_ptr<ResourceObserverService>& observerService);
193 
194     // Dump all the resource allocations for all the processes into a given string
195     void dump(std::string& resourceLogs);
196 
197     // get the priority of the process.
198     // If we can't get the priority of the process (with given pid), it will
199     // return false.
200     bool getPriority(int pid, int* priority);
201 
202     // Check if the given resource request has conflicting clients.
203     // The resource conflict is defined by the ResourceModel (such as
204     // co-existence of secure codec with another secure or non-secure codec).
205     // But here, the ResourceTracker only looks for resources from lower
206     // priority processes.
207     // If is/are only higher or same priority process/es with the given resource,
208     // it will return false.
209     // Otherwise, adds all the clients to the list of clients and return true.
210     bool getNonConflictingClients(const ResourceRequestInfo& resourceRequestInfo,
211                                   std::vector<ClientInfo>& clients);
212 
213     // Returns unmodifiable reference to the resource map.
getResourceMap()214     const std::map<int, ResourceInfos>& getResourceMap() const {
215         return mMap;
216     }
217 
218     // For each MediaResourceType, get amount of resource being used at the moment.
219     void getMediaResourceUsageReport(std::vector<MediaResourceParcel>* resources) const;
220 
221 private:
222     // Get ResourceInfos associated with the given process.
223     // If none exists, this method will create and associate an empty object and return it.
224     ResourceInfos& getResourceInfosForEdit(int pid);
225 
226     // A helper function that returns true if the callingPid has higher priority than pid.
227     // Returns false otherwise.
228     bool isCallingPriorityHigher(int callingPid, int pid);
229 
230     // Locate the resource info corresponding to the process pid and
231     // the client clientId.
232     const ResourceInfo* getResourceInfo(int pid, const int64_t& clientId) const;
233 
234     // Notify when a resource is added for the first time.
235     void onFirstAdded(const MediaResourceParcel& resource, uid_t uid);
236     // Notify when a resource is removed for the last time.
237     void onLastRemoved(const MediaResourceParcel& resource, uid_t uid);
238 
239 private:
240     // Structure that defines process info that needs to be overridden.
241     struct ProcessInfoOverride {
242         std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
243         std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
244     };
245 
246     // Map of Resource information indexed through the process id.
247     std::map<int, ResourceInfos> mMap;
248     // A weak reference (to avoid cyclic dependency) to the ResourceManagerService.
249     // ResourceTracker uses this to communicate back with the ResourceManagerService.
250     std::weak_ptr<ResourceManagerServiceNew> mService;
251     // To notify the ResourceObserverService abour resources are added or removed.
252     std::shared_ptr<ResourceObserverService> mObserverService;
253     // Map of pid and their overrided id.
254     std::map<int, int> mOverridePidMap;
255     // Map of pid and their overridden process info.
256     std::map<pid_t, ProcessInfoOverride> mProcessInfoOverrideMap;
257     // Interface that gets process specific information.
258     sp<ProcessInfoInterface> mProcessInfo;
259 };
260 
261 } // namespace android
262 
263 #endif // ANDROID_MEDIA_RESOURCETRACKER_H_
264