blob: 7ae758b05c98df40b043590056a5c46a64fbb29f [file] [log] [blame]
/*
* Copyright (c) 2020, 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 CPP_WATCHDOG_SERVER_SRC_IOOVERUSECONFIGS_H_
#define CPP_WATCHDOG_SERVER_SRC_IOOVERUSECONFIGS_H_
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android/automotive/watchdog/PerStateBytes.h>
#include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
#include <android/automotive/watchdog/internal/ComponentType.h>
#include <android/automotive/watchdog/internal/IoOveruseAlertThreshold.h>
#include <android/automotive/watchdog/internal/PackageInfo.h>
#include <android/automotive/watchdog/internal/PerStateIoOveruseThreshold.h>
#include <android/automotive/watchdog/internal/ResourceOveruseConfiguration.h>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace android {
namespace automotive {
namespace watchdog {
constexpr const char kBuildSystemConfigXmlPath[] =
"/system/etc/automotive/watchdog/system_resource_overuse_configuration.xml";
constexpr const char kBuildThirdPartyConfigXmlPath[] =
"/system/etc/automotive/watchdog/third_party_resource_overuse_configuration.xml";
constexpr const char kBuildVendorConfigXmlPath[] =
"/vendor/etc/automotive/watchdog/resource_overuse_configuration.xml";
constexpr const char kLatestSystemConfigXmlPath[] =
"/data/system/car/watchdog/system_resource_overuse_configuration.xml";
constexpr const char kLatestVendorConfigXmlPath[] =
"/data/system/car/watchdog/vendor_resource_overuse_configuration.xml";
constexpr const char kLatestThirdPartyConfigXmlPath[] =
"/data/system/car/watchdog/third_party_resource_overuse_configuration.xml";
constexpr const char kDefaultThresholdName[] = "default";
inline const android::automotive::watchdog::internal::PerStateIoOveruseThreshold
defaultThreshold() {
android::automotive::watchdog::internal::PerStateIoOveruseThreshold threshold;
threshold.name = kDefaultThresholdName;
threshold.perStateWriteBytes.foregroundBytes = std::numeric_limits<int64_t>::max();
threshold.perStateWriteBytes.backgroundBytes = std::numeric_limits<int64_t>::max();
threshold.perStateWriteBytes.garageModeBytes = std::numeric_limits<int64_t>::max();
return threshold;
}
// Forward declaration for testing use only.
namespace internal {
class IoOveruseConfigsPeer;
} // namespace internal
/**
* Defines the methods that the I/O overuse configs module should implement.
*/
class IIoOveruseConfigs : public android::RefBase {
public:
// Overwrites the existing configurations.
virtual android::base::Result<void>
update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
configs) = 0;
// Returns the existing configurations.
virtual void get(
std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
resourceOveruseConfigs) const = 0;
// Writes the cached configs to disk.
virtual android::base::Result<void> writeToDisk() = 0;
/**
* Returns the list of vendor package prefixes. Any pre-installed package matching one of these
* prefixes should be classified as a vendor package.
*/
virtual const std::unordered_set<std::string>& vendorPackagePrefixes() = 0;
/**
* Returns the package names to application category mappings.
*/
virtual const std::unordered_map<
std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
packagesToAppCategories() = 0;
// Fetches the I/O overuse thresholds for the given package.
virtual PerStateBytes fetchThreshold(
const android::automotive::watchdog::internal::PackageInfo& packageInfo) const = 0;
// Returns whether or not the package is safe to kill on I/O overuse.
virtual bool isSafeToKill(
const android::automotive::watchdog::internal::PackageInfo& packageInfo) const = 0;
struct AlertThresholdHashByDuration {
public:
size_t operator()(const android::automotive::watchdog::internal::IoOveruseAlertThreshold&
threshold) const;
};
struct AlertThresholdEqualByDuration {
public:
bool operator()(
const android::automotive::watchdog::internal::IoOveruseAlertThreshold& l,
const android::automotive::watchdog::internal::IoOveruseAlertThreshold& r) const;
};
using IoOveruseAlertThresholdSet =
::std::unordered_set<android::automotive::watchdog::internal::IoOveruseAlertThreshold,
AlertThresholdHashByDuration, AlertThresholdEqualByDuration>;
// Returns system-wide disk I/O overuse thresholds.
virtual const IoOveruseAlertThresholdSet& systemWideAlertThresholds() = 0;
};
class IoOveruseConfigs;
/**
* ComponentSpecificConfig represents the I/O overuse config defined per component.
*/
class ComponentSpecificConfig final {
protected:
ComponentSpecificConfig() : mGeneric(defaultThreshold()) {}
~ComponentSpecificConfig() {
mPerPackageThresholds.clear();
mSafeToKillPackages.clear();
}
/**
* Updates |mPerPackageThresholds|.
*/
android::base::Result<void> updatePerPackageThresholds(
const std::vector<android::automotive::watchdog::internal::PerStateIoOveruseThreshold>&
thresholds,
const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes);
/**
* Updates |mSafeToKillPackages|.
*/
android::base::Result<void> updateSafeToKillPackages(
const std::vector<std::string>& packages,
const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes);
/**
* I/O overuse configurations for all packages under the component that are not covered by
* |mPerPackageThresholds| or |IoOveruseConfigs.mPerCategoryThresholds|.
*/
android::automotive::watchdog::internal::PerStateIoOveruseThreshold mGeneric;
/**
* I/O overuse configurations for specific packages under the component.
*/
std::unordered_map<std::string,
android::automotive::watchdog::internal::PerStateIoOveruseThreshold>
mPerPackageThresholds;
/**
* List of safe to kill packages under the component in the event of I/O overuse.
*/
std::unordered_set<std::string> mSafeToKillPackages;
private:
friend class IoOveruseConfigs;
};
/**
* IoOveruseConfigs represents the I/O overuse configuration defined by system and vendor
* applications. This class is not thread safe for performance purposes. The caller is responsible
* for calling the methods in a thread safe manner.
*/
class IoOveruseConfigs final : public IIoOveruseConfigs {
public:
IoOveruseConfigs();
~IoOveruseConfigs() {
mPerCategoryThresholds.clear();
mVendorPackagePrefixes.clear();
mAlertThresholds.clear();
}
android::base::Result<void>
update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
configs) override;
void get(std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
resourceOveruseConfigs) const override;
android::base::Result<void> writeToDisk();
PerStateBytes fetchThreshold(
const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
bool isSafeToKill(
const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
const IoOveruseAlertThresholdSet& systemWideAlertThresholds() override {
return mAlertThresholds;
}
const std::unordered_set<std::string>& vendorPackagePrefixes() override {
return mVendorPackagePrefixes;
}
const std::unordered_map<std::string,
android::automotive::watchdog::internal::ApplicationCategoryType>&
packagesToAppCategories() override {
return mPackagesToAppCategories;
}
private:
enum ConfigUpdateMode {
OVERWRITE = 0,
MERGE,
NO_UPDATE,
};
android::base::Result<void> updateFromXml(const char* filename);
void updateFromAidlConfig(
const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
resourceOveruseConfig);
android::base::Result<void> update(
const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
resourceOveruseConfiguration,
const android::automotive::watchdog::internal::IoOveruseConfiguration&
ioOveruseConfiguration,
int32_t updatableConfigsFilter, ComponentSpecificConfig* targetComponentConfig);
android::base::Result<void> updatePerCategoryThresholds(
const std::vector<android::automotive::watchdog::internal::PerStateIoOveruseThreshold>&
thresholds);
android::base::Result<void> updateAlertThresholds(
const std::vector<android::automotive::watchdog::internal::IoOveruseAlertThreshold>&
thresholds);
std::optional<android::automotive::watchdog::internal::ResourceOveruseConfiguration> get(
const ComponentSpecificConfig& componentSpecificConfig,
const int32_t componentFilter) const;
// System component specific configuration.
ComponentSpecificConfig mSystemConfig;
// Vendor component specific configuration.
ComponentSpecificConfig mVendorConfig;
// Third-party component specific configuration.
ComponentSpecificConfig mThirdPartyConfig;
// Package name to application category mappings.
std::unordered_map<std::string,
android::automotive::watchdog::internal::ApplicationCategoryType>
mPackagesToAppCategories;
ConfigUpdateMode mPackagesToAppCategoryMappingUpdateMode;
// I/O overuse thresholds per category.
std::unordered_map<android::automotive::watchdog::internal::ApplicationCategoryType,
android::automotive::watchdog::internal::PerStateIoOveruseThreshold>
mPerCategoryThresholds;
// List of vendor package prefixes.
std::unordered_set<std::string> mVendorPackagePrefixes;
// System-wide disk I/O overuse alert thresholds.
IoOveruseAlertThresholdSet mAlertThresholds;
// For unit tests.
using ParseXmlFileFunction = std::function<android::base::Result<
android::automotive::watchdog::internal::ResourceOveruseConfiguration>(const char*)>;
using WriteXmlFileFunction = std::function<android::base::Result<
void>(const android::automotive::watchdog::internal::ResourceOveruseConfiguration&,
const char*)>;
static ParseXmlFileFunction sParseXmlFile;
static WriteXmlFileFunction sWriteXmlFile;
friend class internal::IoOveruseConfigsPeer;
};
} // namespace watchdog
} // namespace automotive
} // namespace android
#endif // CPP_WATCHDOG_SERVER_SRC_IOOVERUSECONFIGS_H_