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