blob: 20c904d95b6fc01746b11585071d3e69b2c65930 [file] [log] [blame]
/*
**
** 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_