| /* |
| ** |
| ** 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 <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| #include <media/MediaResource.h> |
| #include <aidl/android/media/ClientInfoParcel.h> |
| #include <aidl/android/media/IResourceManagerClient.h> |
| #include <aidl/android/media/MediaResourceParcel.h> |
| |
| #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<ResourceManagerServiceNew>& service, |
| const sp<ProcessInfoInterface>& 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<ClientInfo>& 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<aidl::android::media::IResourceManagerClient>& 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<ClientInfo>& 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<ClientInfo>& 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<ClientInfo>& 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<ClientInfo>& 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<ResourceObserverService>& 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<ClientInfo>& clients); |
| |
| // Returns unmodifiable reference to the resource map. |
| const std::map<int, ResourceInfos>& 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> deathNotifier = nullptr; |
| std::shared_ptr<::aidl::android::media::IResourceManagerClient> client; |
| }; |
| |
| // Map of Resource information indexed through the process id. |
| std::map<int, ResourceInfos> mMap; |
| // A weak reference (to avoid cyclic dependency) to the ResourceManagerService. |
| // ResourceTracker uses this to communicate back with the ResourceManagerService. |
| std::weak_ptr<ResourceManagerServiceNew> mService; |
| // To notify the ResourceObserverService abour resources are added or removed. |
| std::shared_ptr<ResourceObserverService> mObserverService; |
| // Map of pid and their overrided id. |
| std::map<int, int> mOverridePidMap; |
| // Map of pid and their overridden process info. |
| std::map<pid_t, ProcessInfoOverride> mProcessInfoOverrideMap; |
| // Interface that gets process specific information. |
| sp<ProcessInfoInterface> mProcessInfo; |
| }; |
| |
| } // namespace android |
| |
| #endif // ANDROID_MEDIA_RESOURCETRACKER_H_ |