/* ** ** Copyright 2023, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #ifndef ANDROID_MEDIA_RESOURCETRACKER_H_ #define ANDROID_MEDIA_RESOURCETRACKER_H_ #include #include #include #include #include #include #include #include #include "ResourceManagerServiceUtils.h" namespace android { class DeathNotifier; class ResourceManagerServiceNew; class ResourceObserverService; struct ProcessInfoInterface; struct ResourceRequestInfo; struct ClientInfo; /* * ResourceTracker abstracts the resources managed by the ResourceManager. * It keeps track of the resource used by the clients (clientid) and by the process (pid) */ class ResourceTracker { public: ResourceTracker(const std::shared_ptr& service, const sp& processInfo); ~ResourceTracker(); /** * Add or update resources for |clientInfo|. * * If |clientInfo| is not tracked yet, it records its associated |client| and adds * |resources| to the tracked resources. If |clientInfo| is already tracked, * it updates the tracked resources by adding |resources| to them (|client| in * this case is unused and unchecked). * * @param clientInfo Info of the calling client. * @param client Interface for the client. * @param resources An array of resources to be added. * * @return true upon successfully adding/updating the resources, false * otherwise. */ bool addResource(const aidl::android::media::ClientInfoParcel& clientInfo, const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client, const std::vector<::aidl::android::media::MediaResourceParcel>& resources); // Update the resource info, if there is any changes. bool updateResource(const aidl::android::media::ClientInfoParcel& clientInfo); // Remove a set of resources from the given client. // returns true on success, false otherwise. bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo, const std::vector<::aidl::android::media::MediaResourceParcel>& resources); /** * Remove all resources tracked for |clientInfo|. * * If |validateCallingPid| is true, the (pid of the) calling process is validated that it * is from a trusted process. * Returns true on success (|clientInfo| was tracked and optionally the caller * was a validated trusted process), false otherwise (|clientInfo| was not tracked, * or the caller was not a trusted process) */ bool removeResource(const aidl::android::media::ClientInfoParcel& clientInfo, bool validateCallingPid); // Mark the client for pending removal. // Such clients are primary candidate for reclaim. // returns true on success, false otherwise. bool markClientForPendingRemoval(const aidl::android::media::ClientInfoParcel& clientInfo); // Get a list of clients that belong to process with given pid and are maked to be // pending removal by markClientForPendingRemoval. // returns true on success, false otherwise. bool getClientsMarkedPendingRemoval(int32_t pid, std::vector& targetClients); // Override the pid of originalPid with newPid // To remove the pid entry from the override list, set newPid as -1 // returns true on successful override, false otherwise. bool overridePid(int originalPid, int newPid); // Override the process info {state, oom score} of the process with pid. // returns true on success, false otherwise. bool overrideProcessInfo( const std::shared_ptr& client, int pid, int procState, int oomScore); // Remove the overridden process info. void removeProcessInfoOverride(int pid); // Find all clients that have given resources. // If applicable, match the primary type too. // The |clients| (list) isn't cleared by this function to allow calling this // function multiple times for different resources. // returns true upon finding at lease one client with the given resource request info, // false otherwise (no clients) bool getAllClients( const ResourceRequestInfo& resourceRequestInfo, std::vector& clients, MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType); // Look for the lowest priority process with the given resources. // Upon success lowestPriorityPid and lowestPriority are // set accordingly and it returns true. // If there isn't a lower priority process with the given resources, it will return false // with out updating lowestPriorityPid and lowerPriority. bool getLowestPriorityPid(MediaResource::Type type, MediaResource::SubType subType, int& lowestPriorityPid, int& lowestPriority); // Look for the lowest priority process with the given resources // among the given client list. // If applicable, match the primary type too. // returns true on success, false otherwise. bool getLowestPriorityPid( MediaResource::Type type, MediaResource::SubType subType, MediaResource::SubType primarySubType, const std::vector& clients, int& lowestPriorityPid, int& lowestPriority); // Find the biggest client of the given process with given resources, // that is marked as pending to be removed. // returns true on success, false otherwise. bool getBiggestClientPendingRemoval( int pid, MediaResource::Type type, MediaResource::SubType subType, ClientInfo& clientInfo); // Find the biggest client from the process pid, selecting them from the list of clients. // If applicable, match the primary type too. // Returns true when a client is found and clientInfo is updated accordingly. // Upon failure to find a client, it will return false without updating // clientInfo. // Upon failure to find a client, it will return false. bool getBiggestClient( int targetPid, MediaResource::Type type, MediaResource::SubType subType, const std::vector& clients, ClientInfo& clientInfo, MediaResource::SubType primarySubType = MediaResource::SubType::kUnspecifiedSubType); // Find the biggest client from the process pid, that has the least importance // (than given importance) among the given list of clients. // If applicable, match the primary type too. // returns true on success, false otherwise. bool getLeastImportantBiggestClient(int targetPid, int32_t importance, MediaResource::Type type, MediaResource::SubType subType, MediaResource::SubType primarySubType, const std::vector& clients, ClientInfo& clientInfo); // Find the client that belongs to given process(pid) and with the given clientId. // A nullptr is returned upon failure to find the client. std::shared_ptr<::aidl::android::media::IResourceManagerClient> getClient( int pid, const int64_t& clientId) const; // Removes the client from the given process(pid) with the given clientId. // returns true on success, false otherwise. bool removeClient(int pid, const int64_t& clientId); // Set the resource observer service, to which to notify when the resources // are added and removed. void setResourceObserverService( const std::shared_ptr& observerService); // Dump all the resource allocations for all the processes into a given string void dump(std::string& resourceLogs); // get the priority of the process. // If we can't get the priority of the process (with given pid), it will // return false. bool getPriority(int pid, int* priority); // Check if the given resource request has conflicting clients. // The resource conflict is defined by the ResourceModel (such as // co-existence of secure codec with another secure or non-secure codec). // But here, the ResourceTracker only looks for resources from lower // priority processes. // If is/are only higher or same priority process/es with the given resource, // it will return false. // Otherwise, adds all the clients to the list of clients and return true. bool getNonConflictingClients(const ResourceRequestInfo& resourceRequestInfo, std::vector& clients); // Returns unmodifiable reference to the resource map. const std::map& getResourceMap() const { return mMap; } private: // Get ResourceInfos associated with the given process. // If none exists, this method will create and associate an empty object and return it. ResourceInfos& getResourceInfosForEdit(int pid); // A helper function that returns true if the callingPid has higher priority than pid. // Returns false otherwise. bool isCallingPriorityHigher(int callingPid, int pid); // Locate the resource info corresponding to the process pid and // the client clientId. const ResourceInfo* getResourceInfo(int pid, const int64_t& clientId) const; // Notify when a resource is added for the first time. void onFirstAdded(const MediaResourceParcel& resource, uid_t uid); // Notify when a resource is removed for the last time. void onLastRemoved(const MediaResourceParcel& resource, uid_t uid); private: // Structure that defines process info that needs to be overridden. struct ProcessInfoOverride { std::shared_ptr deathNotifier = nullptr; std::shared_ptr<::aidl::android::media::IResourceManagerClient> client; }; // Map of Resource information indexed through the process id. std::map mMap; // A weak reference (to avoid cyclic dependency) to the ResourceManagerService. // ResourceTracker uses this to communicate back with the ResourceManagerService. std::weak_ptr mService; // To notify the ResourceObserverService abour resources are added or removed. std::shared_ptr mObserverService; // Map of pid and their overrided id. std::map mOverridePidMap; // Map of pid and their overridden process info. std::map mProcessInfoOverrideMap; // Interface that gets process specific information. sp mProcessInfo; }; } // namespace android #endif // ANDROID_MEDIA_RESOURCETRACKER_H_