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