Merge changes I94e08d61,I431fe6b7 into sc-dev
* changes:
Read the on-device XML configurations on initialization.
Convert per state thresholds read from XML configs.
diff --git a/cpp/watchdog/server/Android.bp b/cpp/watchdog/server/Android.bp
index 9b5b973..8ce4c04 100644
--- a/cpp/watchdog/server/Android.bp
+++ b/cpp/watchdog/server/Android.bp
@@ -200,4 +200,20 @@
"libwatchdog_package_info_resolver",
],
vintf_fragments: ["carwatchdogd.xml"],
+ required: [
+ "system_resource_overuse_configuration.xml",
+ "third_party_resource_overuse_configuration.xml",
+ ],
+}
+
+prebuilt_etc {
+ name: "system_resource_overuse_configuration.xml",
+ src: "data/system_resource_overuse_configuration.xml",
+ sub_dir: "automotive/watchdog/",
+}
+
+prebuilt_etc {
+ name: "third_party_resource_overuse_configuration.xml",
+ src: "data/third_party_resource_overuse_configuration.xml",
+ sub_dir: "automotive/watchdog/",
}
diff --git a/cpp/watchdog/server/data/system_resource_overuse_configuration.xml b/cpp/watchdog/server/data/system_resource_overuse_configuration.xml
new file mode 100644
index 0000000..e04e17f
--- /dev/null
+++ b/cpp/watchdog/server/data/system_resource_overuse_configuration.xml
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<resourceOveruseConfiguration version="1.0">
+ <componentType> SYSTEM </componentType>
+ <!-- List of safe to kill system packages. -->
+ <safeToKillPackages>
+ <package> shared:com.google.android.car.uid.kitchensink </package>
+ </safeToKillPackages>
+
+ <ioOveruseConfiguration>
+ <!-- Default thresholds in MiB for all system packages that don’t have package specific
+ thresholds or app category specific thresholds. -->
+ <componentLevelThresholds>
+ <state id="foreground_mode"> 3072 </state>
+ <state id="background_mode"> 2048 </state>
+ <state id="garage_mode"> 4096 </state>
+ </componentLevelThresholds>
+
+ <!-- Package specific thresholds. -->
+ <!-- Kitchensink app tests package warning/killing on overuse and requires less threshold so it
+ can test the implementation with less amount of writes. However, it shouldn't be killed
+ often when running other tests.-->
+ <packageSpecificThresholds id="shared:com.google.android.car.uid.kitchensink">
+ <state id="foreground_mode"> 512 </state>
+ <state id="background_mode"> 512 </state>
+ <state id="garage_mode"> 512 </state>
+ </packageSpecificThresholds>
+
+ <!-- List of system-wide disk I/O overuse alert thresholds. -->
+ <systemWideThresholds>
+ <!-- 1GiB written in 30 seconds -->
+ <param id="duration_seconds"> 30 </param>
+ <param id="written_bytes_per_second"> 35791394 </param>
+ </systemWideThresholds>
+ <systemWideThresholds>
+ <!-- 500MiB written in 10 seconds -->
+ <param id="duration_seconds"> 10 </param>
+ <param id="written_bytes_per_second"> 52428800 </param>
+ </systemWideThresholds>
+ </ioOveruseConfiguration>
+</resourceOveruseConfiguration>
diff --git a/cpp/watchdog/server/data/third_party_resource_overuse_configuration.xml b/cpp/watchdog/server/data/third_party_resource_overuse_configuration.xml
new file mode 100644
index 0000000..ee17b60
--- /dev/null
+++ b/cpp/watchdog/server/data/third_party_resource_overuse_configuration.xml
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<resourceOveruseConfiguration version="1.0">
+ <componentType> THIRD_PARTY </componentType>
+ <ioOveruseConfiguration>
+ <!-- Default thresholds in MiB for all third-party packages that don't have app category
+ specific thresholds. -->
+ <componentLevelThresholds>
+ <state id="foreground_mode"> 3072 </state>
+ <state id="background_mode"> 2048 </state>
+ <state id="garage_mode"> 4096 </state>
+ </componentLevelThresholds>
+ </ioOveruseConfiguration>
+</resourceOveruseConfiguration>
diff --git a/cpp/watchdog/server/src/IoOveruseConfigs.cpp b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
index 90a73df..ca49c1b 100644
--- a/cpp/watchdog/server/src/IoOveruseConfigs.cpp
+++ b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,12 +18,15 @@
#include "IoOveruseConfigs.h"
+#include "OveruseConfigurationXmlHelper.h"
#include "PackageInfoResolver.h"
#include <android-base/strings.h>
+#include <log/log.h>
#include <inttypes.h>
+#include <filesystem>
#include <limits>
namespace android {
@@ -180,7 +183,46 @@
}
}
-Result<void> isValidConfigs(
+Result<void> isValidResourceOveruseConfig(
+ const ResourceOveruseConfiguration& resourceOveruseConfig) {
+ const auto filter = getComponentFilter(resourceOveruseConfig.componentType);
+ if (!filter.ok()) {
+ return Error() << filter.error();
+ }
+ std::unordered_map<std::string, ApplicationCategoryType> seenCategoryMappings;
+ for (const auto& meta : resourceOveruseConfig.packageMetadata) {
+ if (const auto it = seenCategoryMappings.find(meta.packageName);
+ it != seenCategoryMappings.end() && it->second != meta.appCategoryType) {
+ return Error()
+ << "Must provide exactly one application category mapping for the package "
+ << meta.packageName << ": Provided mappings " << toString(meta.appCategoryType)
+ << " and " << toString(it->second);
+ }
+ seenCategoryMappings[meta.packageName] = meta.appCategoryType;
+ }
+ if (resourceOveruseConfig.resourceSpecificConfigurations.size() != 1) {
+ return Error() << "Must provide exactly one I/O overuse configuration. Received "
+ << resourceOveruseConfig.resourceSpecificConfigurations.size()
+ << " configurations";
+ }
+ for (const auto& config : resourceOveruseConfig.resourceSpecificConfigurations) {
+ if (config.getTag() != ResourceSpecificConfiguration::ioOveruseConfiguration) {
+ return Error() << "Invalid resource type: " << config.getTag();
+ }
+ const auto& ioOveruseConfig =
+ config.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+ if (auto result = isValidIoOveruseConfiguration(resourceOveruseConfig.componentType,
+ *filter, ioOveruseConfig);
+ !result.ok()) {
+ return Error() << "Invalid I/O overuse configuration for component "
+ << toString(resourceOveruseConfig.componentType).c_str() << ": "
+ << result.error();
+ }
+ }
+ return {};
+}
+
+Result<void> isValidResourceOveruseConfigs(
const std::vector<ResourceOveruseConfiguration>& resourceOveruseConfigs) {
std::unordered_set<ComponentType> seenComponentTypes;
for (const auto& resourceOveruseConfig : resourceOveruseConfigs) {
@@ -188,36 +230,19 @@
return Error() << "Cannot provide duplicate configs for the same component type "
<< toString(resourceOveruseConfig.componentType);
}
- const auto filter = getComponentFilter(resourceOveruseConfig.componentType);
- if (!filter.ok()) {
- return Error() << filter.error();
+ if (const auto result = isValidResourceOveruseConfig(resourceOveruseConfig); !result.ok()) {
+ return result;
}
seenComponentTypes.insert(resourceOveruseConfig.componentType);
- if (resourceOveruseConfig.resourceSpecificConfigurations.size() != 1) {
- return Error() << "Must provide exactly one I/O overuse configuration. Received "
- << resourceOveruseConfig.resourceSpecificConfigurations.size()
- << " configurations";
- }
- for (const auto& config : resourceOveruseConfig.resourceSpecificConfigurations) {
- if (config.getTag() != ResourceSpecificConfiguration::ioOveruseConfiguration) {
- return Error() << "Invalid resource type: " << config.getTag();
- }
- const auto& ioOveruseConfig =
- config.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
- if (auto result = isValidIoOveruseConfiguration(resourceOveruseConfig.componentType,
- *filter, ioOveruseConfig);
- !result.ok()) {
- return Error() << "Invalid config for component "
- << toString(resourceOveruseConfig.componentType).c_str()
- << result.error();
- }
- }
}
return {};
}
} // namespace
+IoOveruseConfigs::ParseXmlFileFunction IoOveruseConfigs::sParseXmlFile =
+ &OveruseConfigurationXmlHelper::parseXmlFile;
+
Result<void> ComponentSpecificConfig::updatePerPackageThresholds(
const std::vector<PerStateIoOveruseThreshold>& thresholds,
const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes) {
@@ -234,7 +259,7 @@
maybeAppendVendorPackagePrefixes(packageThreshold.name);
if (auto result = containsValidThresholds(packageThreshold); !result.ok()) {
StringAppendF(&errorMsgs,
- "\tSkipping invalid package specific thresholds for package %s: %s\n",
+ "\tSkipping invalid package specific thresholds for package '%s': %s\n",
packageThreshold.name.c_str(), result.error().message().c_str());
continue;
}
@@ -267,6 +292,54 @@
return errorMsgs.empty() ? Result<void>{} : Error() << errorMsgs;
}
+IoOveruseConfigs::IoOveruseConfigs() :
+ mSystemConfig({}),
+ mVendorConfig({}),
+ mThirdPartyConfig({}),
+ mPackagesToAppCategories({}),
+ mPackagesToAppCategoryMappingUpdateMode(OVERWRITE),
+ mPerCategoryThresholds({}),
+ mVendorPackagePrefixes({}) {
+ const auto updateFromXmlPerType = [&](const char* filename, const char* configType) -> bool {
+ if (const auto result = this->updateFromXml(filename); !result.ok()) {
+ ALOGE("Failed to parse %s resource overuse configuration from '%s': %s", configType,
+ filename, result.error().message().c_str());
+ return false;
+ }
+ ALOGI("Updated with %s resource overuse configuration from '%s'", configType, filename);
+ return true;
+ };
+ /*
+ * Package to app category mapping is common between system and vendor component configs. When
+ * the build system and vendor component configs are used, the mapping shouldn't be
+ * overwritten by either of the configs because the build configurations defined by the
+ * vendor or system components may not be aware of mappings included in other component's
+ * config. Ergo, the mapping from both the component configs should be merged together. When a
+ * latest config is used for either of the components, the latest mapping should be given higher
+ * priority.
+ */
+ bool isBuildSystemConfig = false;
+ if (!updateFromXmlPerType(kLatestSystemConfigXmlPath, "latest system")) {
+ isBuildSystemConfig = updateFromXmlPerType(kBuildSystemConfigXmlPath, "build system");
+ }
+ if (!updateFromXmlPerType(kLatestVendorConfigXmlPath, "latest vendor")) {
+ mPackagesToAppCategoryMappingUpdateMode = isBuildSystemConfig ? MERGE : NO_UPDATE;
+ if (!updateFromXmlPerType(kBuildVendorConfigXmlPath, "build vendor") &&
+ mSystemConfig.mGeneric.name != kDefaultThresholdName) {
+ mVendorConfig.mGeneric = mSystemConfig.mGeneric;
+ mVendorConfig.mGeneric.name = toString(ComponentType::VENDOR);
+ }
+ mPackagesToAppCategoryMappingUpdateMode = OVERWRITE;
+ }
+ if (!updateFromXmlPerType(kLatestThirdPartyConfigXmlPath, "latest third-party")) {
+ if (!updateFromXmlPerType(kBuildThirdPartyConfigXmlPath, "build third-party") &&
+ mSystemConfig.mGeneric.name != kDefaultThresholdName) {
+ mThirdPartyConfig.mGeneric = mSystemConfig.mGeneric;
+ mThirdPartyConfig.mGeneric.name = toString(ComponentType::THIRD_PARTY);
+ }
+ }
+}
+
size_t IoOveruseConfigs::AlertThresholdHashByDuration::operator()(
const IoOveruseAlertThreshold& threshold) const {
return std::hash<std::string>{}(std::to_string(threshold.durationInSeconds));
@@ -286,13 +359,13 @@
std::string errorMsgs;
for (const auto& categoryThreshold : thresholds) {
if (auto result = containsValidThresholds(categoryThreshold); !result.ok()) {
- StringAppendF(&errorMsgs, "\tInvalid category specific thresholds: %s\n",
+ StringAppendF(&errorMsgs, "\tInvalid category specific thresholds: '%s'\n",
result.error().message().c_str());
continue;
}
if (auto category = toApplicationCategoryType(categoryThreshold.name);
category == ApplicationCategoryType::OTHERS) {
- StringAppendF(&errorMsgs, "\tInvalid application category %s\n",
+ StringAppendF(&errorMsgs, "\tInvalid application category '%s'\n",
categoryThreshold.name.c_str());
} else {
if (const auto& it = mPerCategoryThresholds.find(category);
@@ -330,52 +403,68 @@
Result<void> IoOveruseConfigs::update(
const std::vector<ResourceOveruseConfiguration>& resourceOveruseConfigs) {
- if (auto result = isValidConfigs(resourceOveruseConfigs); !result.ok()) {
+ if (const auto result = isValidResourceOveruseConfigs(resourceOveruseConfigs); !result.ok()) {
return Error(Status::EX_ILLEGAL_ARGUMENT) << result.error();
}
-
for (const auto& resourceOveruseConfig : resourceOveruseConfigs) {
- ComponentSpecificConfig* targetComponentConfig;
- int32_t updatableConfigsFilter = 0;
- switch (resourceOveruseConfig.componentType) {
- case ComponentType::SYSTEM:
- targetComponentConfig = &mSystemConfig;
- updatableConfigsFilter = kSystemComponentUpdatableConfigs;
- break;
- case ComponentType::VENDOR:
- targetComponentConfig = &mVendorConfig;
- updatableConfigsFilter = kVendorComponentUpdatableConfigs;
- break;
- case ComponentType::THIRD_PARTY:
- targetComponentConfig = &mThirdPartyConfig;
- updatableConfigsFilter = kThirdPartyComponentUpdatableConfigs;
- break;
- default:
- // This case shouldn't execute as it is caught during validation.
- continue;
- }
-
- const std::string componentTypeStr = toString(resourceOveruseConfig.componentType);
- for (const auto& resourceSpecificConfig :
- resourceOveruseConfig.resourceSpecificConfigurations) {
- /*
- * |resourceSpecificConfig| should contain only ioOveruseConfiguration as it is verified
- * during validation.
- */
- const auto& ioOveruseConfig =
- resourceSpecificConfig
- .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
- if (auto res = update(resourceOveruseConfig, ioOveruseConfig, updatableConfigsFilter,
- targetComponentConfig);
- !res.ok()) {
- ALOGE("Invalid I/O overuse configurations received for %s component:\n%s",
- componentTypeStr.c_str(), res.error().message().c_str());
- }
- }
+ updateFromAidlConfig(resourceOveruseConfig);
}
return {};
}
+Result<void> IoOveruseConfigs::updateFromXml(const char* filename) {
+ const auto resourceOveruseConfig = sParseXmlFile(filename);
+ if (!resourceOveruseConfig.ok()) {
+ return Error() << "Failed to parse configuration: " << resourceOveruseConfig.error();
+ }
+ if (const auto result = isValidResourceOveruseConfig(*resourceOveruseConfig); !result.ok()) {
+ return result;
+ }
+ updateFromAidlConfig(*resourceOveruseConfig);
+ return {};
+}
+
+void IoOveruseConfigs::updateFromAidlConfig(
+ const ResourceOveruseConfiguration& resourceOveruseConfig) {
+ ComponentSpecificConfig* targetComponentConfig;
+ int32_t updatableConfigsFilter = 0;
+ switch (resourceOveruseConfig.componentType) {
+ case ComponentType::SYSTEM:
+ targetComponentConfig = &mSystemConfig;
+ updatableConfigsFilter = kSystemComponentUpdatableConfigs;
+ break;
+ case ComponentType::VENDOR:
+ targetComponentConfig = &mVendorConfig;
+ updatableConfigsFilter = kVendorComponentUpdatableConfigs;
+ break;
+ case ComponentType::THIRD_PARTY:
+ targetComponentConfig = &mThirdPartyConfig;
+ updatableConfigsFilter = kThirdPartyComponentUpdatableConfigs;
+ break;
+ default:
+ // This case shouldn't execute as it is caught during validation.
+ return;
+ }
+
+ const std::string componentTypeStr = toString(resourceOveruseConfig.componentType);
+ for (const auto& resourceSpecificConfig :
+ resourceOveruseConfig.resourceSpecificConfigurations) {
+ /*
+ * |resourceSpecificConfig| should contain only ioOveruseConfiguration as it is verified
+ * during validation.
+ */
+ const auto& ioOveruseConfig =
+ resourceSpecificConfig.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+ if (auto res = update(resourceOveruseConfig, ioOveruseConfig, updatableConfigsFilter,
+ targetComponentConfig);
+ !res.ok()) {
+ ALOGE("Ignorable I/O overuse configuration errors for '%s' component:\n%s",
+ componentTypeStr.c_str(), res.error().message().c_str());
+ }
+ }
+ return;
+}
+
Result<void> IoOveruseConfigs::update(
const ResourceOveruseConfiguration& resourceOveruseConfiguration,
const IoOveruseConfiguration& ioOveruseConfiguration, int32_t updatableConfigsFilter,
@@ -398,10 +487,14 @@
}
if (updatableConfigsFilter & OveruseConfigEnum::PACKAGE_APP_CATEGORY_MAPPINGS) {
- mPackagesToAppCategories.clear();
- for (const auto& meta : resourceOveruseConfiguration.packageMetadata) {
- if (!meta.packageName.empty()) {
- mPackagesToAppCategories[meta.packageName] = meta.appCategoryType;
+ if (mPackagesToAppCategoryMappingUpdateMode == OVERWRITE) {
+ mPackagesToAppCategories.clear();
+ }
+ if (mPackagesToAppCategoryMappingUpdateMode != NO_UPDATE) {
+ for (const auto& meta : resourceOveruseConfiguration.packageMetadata) {
+ if (!meta.packageName.empty()) {
+ mPackagesToAppCategories[meta.packageName] = meta.appCategoryType;
+ }
}
}
} else if (!resourceOveruseConfiguration.packageMetadata.empty()) {
@@ -430,7 +523,7 @@
.packageSpecificThresholds,
maybeAppendVendorPackagePrefixes);
!result.ok()) {
- StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
+ StringAppendF(&errorMsgs, "\t\t%s", result.error().message().c_str());
}
} else if (!ioOveruseConfiguration.packageSpecificThresholds.empty()) {
StringAppendF(&nonUpdatableConfigMsgs, "%sper-package thresholds",
@@ -443,7 +536,8 @@
.safeToKillPackages,
maybeAppendVendorPackagePrefixes);
!result.ok()) {
- StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
+ StringAppendF(&errorMsgs, "%s\t\t%s", !errorMsgs.empty() ? "\n" : "",
+ result.error().message().c_str());
}
} else if (!resourceOveruseConfiguration.safeToKillPackages.empty()) {
StringAppendF(&nonUpdatableConfigMsgs, "%ssafe-to-kill list",
@@ -454,7 +548,8 @@
if (auto result =
updatePerCategoryThresholds(ioOveruseConfiguration.categorySpecificThresholds);
!result.ok()) {
- StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
+ StringAppendF(&errorMsgs, "%s\t\t%s", !errorMsgs.empty() ? "\n" : "",
+ result.error().message().c_str());
}
} else if (!ioOveruseConfiguration.categorySpecificThresholds.empty()) {
StringAppendF(&nonUpdatableConfigMsgs, "%scategory specific thresholds",
@@ -464,7 +559,8 @@
if (updatableConfigsFilter & OveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) {
if (auto result = updateAlertThresholds(ioOveruseConfiguration.systemWideThresholds);
!result.ok()) {
- StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
+ StringAppendF(&errorMsgs, "%s\t\t%s", !errorMsgs.empty() ? "\n" : "",
+ result.error().message().c_str());
}
} else if (!ioOveruseConfiguration.systemWideThresholds.empty()) {
StringAppendF(&nonUpdatableConfigMsgs, "%ssystem-wide alert thresholds",
@@ -472,8 +568,8 @@
}
if (!nonUpdatableConfigMsgs.empty()) {
- StringAppendF(&errorMsgs, "\tReceived values for non-updatable configs: %s\n",
- nonUpdatableConfigMsgs.c_str());
+ StringAppendF(&errorMsgs, "%s\t\tReceived values for non-updatable configs: [%s]",
+ !errorMsgs.empty() ? "\n" : "", nonUpdatableConfigMsgs.c_str());
}
if (!errorMsgs.empty()) {
return Error() << errorMsgs.c_str();
diff --git a/cpp/watchdog/server/src/IoOveruseConfigs.h b/cpp/watchdog/server/src/IoOveruseConfigs.h
index e0a2435..ad7c3ac 100644
--- a/cpp/watchdog/server/src/IoOveruseConfigs.h
+++ b/cpp/watchdog/server/src/IoOveruseConfigs.h
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,11 +32,24 @@
#include <string_view>
#include <unordered_map>
#include <unordered_set>
+#include <vector>
namespace android {
namespace automotive {
namespace watchdog {
-constexpr const char* kDefaultThresholdName = "default";
+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() {
@@ -48,6 +61,13 @@
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.
*/
@@ -159,7 +179,7 @@
*/
class IoOveruseConfigs final : public IIoOveruseConfigs {
public:
- IoOveruseConfigs() {}
+ IoOveruseConfigs();
~IoOveruseConfigs() {
mPerCategoryThresholds.clear();
mVendorPackagePrefixes.clear();
@@ -168,30 +188,43 @@
android::base::Result<void>
update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
- configs);
+ configs) override;
void get(std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
- resourceOveruseConfigs);
+ resourceOveruseConfigs) override;
PerStateBytes fetchThreshold(
- const android::automotive::watchdog::internal::PackageInfo& packageInfo) const;
+ const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
bool isSafeToKill(
- const android::automotive::watchdog::internal::PackageInfo& packageInfo) const;
+ const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
- const IoOveruseAlertThresholdSet& systemWideAlertThresholds() { return mAlertThresholds; }
+ const IoOveruseAlertThresholdSet& systemWideAlertThresholds() override {
+ return mAlertThresholds;
+ }
- const std::unordered_set<std::string>& vendorPackagePrefixes() {
+ const std::unordered_set<std::string>& vendorPackagePrefixes() override {
return mVendorPackagePrefixes;
}
const std::unordered_map<std::string,
android::automotive::watchdog::internal::ApplicationCategoryType>&
- packagesToAppCategories() {
+ 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,
@@ -199,6 +232,13 @@
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);
@@ -212,6 +252,7 @@
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>
@@ -221,12 +262,12 @@
// System-wide disk I/O overuse alert thresholds.
IoOveruseAlertThresholdSet mAlertThresholds;
- 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);
+ // For unit tests.
+ using ParseXmlFileFunction = std::function<android::base::Result<
+ android::automotive::watchdog::internal::ResourceOveruseConfiguration>(const char*)>;
+ static ParseXmlFileFunction sParseXmlFile;
+
+ friend class internal::IoOveruseConfigsPeer;
};
} // namespace watchdog
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.cpp b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
index ddc606b..9790586 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.cpp
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,6 +28,7 @@
#include <binder/IPCThreadState.h>
#include <binder/Status.h>
#include <cutils/multiuser.h>
+#include <log/log.h>
#include <limits>
@@ -117,7 +118,7 @@
mIoOveruseWarnPercentage(0),
mLastUserPackageIoMonitorTime(0),
mOveruseListenersByUid({}),
- mBinderDeathRecipient(new BinderDeathRecipient(this)) {}
+ mBinderDeathRecipient(sp<BinderDeathRecipient>::make(this)) {}
Result<void> IoOveruseMonitor::init() {
std::unique_lock writeLock(mRwMutex);
@@ -134,17 +135,7 @@
}
mIoOveruseWarnPercentage = static_cast<double>(
sysprop::ioOveruseWarnPercentage().value_or(kDefaultIoOveruseWarnPercentage));
- /*
- * TODO(b/185287136): Read the latest I/O overuse config.
- * The latest I/O overuse config is read in this order:
- * 1. From /data partition as this contains the latest config and any updates received from OEM
- * and system applications.
- * 2. From /system and /vendor partitions as this contains the default configs shipped with the
- * the image.
- */
-
- mIoOveruseConfigs = new IoOveruseConfigs();
- // TODO(b/185287136): Read the vendor package prefixes from disk before the below call.
+ mIoOveruseConfigs = sp<IoOveruseConfigs>::make();
mPackageInfoResolver = PackageInfoResolver::getInstance();
mPackageInfoResolver->setPackageConfigurations(mIoOveruseConfigs->vendorPackagePrefixes(),
mIoOveruseConfigs->packagesToAppCategories());
@@ -187,10 +178,8 @@
gmtime_r(&time, &curGmt);
if (prevGmt.tm_yday != curGmt.tm_yday || prevGmt.tm_year != curGmt.tm_year) {
/*
- * Date changed so reset the daily I/O usage cache.
- *
- * TODO(b/185287136): Ping CarWatchdogService on date change so it can re-enable the daily
- * disabled packages. Also sync prev day's stats with CarWatchdogService.
+ * Date changed so reset the daily I/O usage cache. CarWatchdogService automatically handles
+ * date change on |CarWatchdogService.latestIoOveruseStats| call.
*/
mUserPackageDailyIoUsageById.clear();
}
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.h b/cpp/watchdog/server/src/IoOveruseMonitor.h
index e749eec..efac553 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.h
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.h
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.cpp b/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.cpp
index f76bcc5..f3d0f04 100644
--- a/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.cpp
+++ b/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.cpp
@@ -233,22 +233,23 @@
if (seenStates.find(state) != seenStates.end()) {
return Error() << "Duplicate threshold specified for state '" << state << "'";
}
- int64_t bytes = 0;
+ int64_t megaBytes = 0;
if (const auto text = childElement->GetText(); text == nullptr) {
return Error() << "Must specify non-empty threshold for state '" << state << "'";
- } else if (const auto bytesStr = Trim(text); !ParseInt(bytesStr.c_str(), &bytes)) {
+ } else if (const auto megaBytesStr = Trim(text);
+ !ParseInt(megaBytesStr.c_str(), &megaBytes)) {
return Error() << "Failed to parse threshold for the state '" << state
- << "': Received threshold value '" << bytesStr << "'";
+ << "': Received threshold value '" << megaBytesStr << "'";
}
if (!strcmp(state, kStateIdForegroundMode)) {
seenStates.insert(kStateIdForegroundMode);
- perStateBytes.foregroundBytes = bytes;
+ perStateBytes.foregroundBytes = megaBytes * kOneMegaByte;
} else if (!strcmp(state, kStateIdBackgroundMode)) {
seenStates.insert(kStateIdBackgroundMode);
- perStateBytes.backgroundBytes = bytes;
+ perStateBytes.backgroundBytes = megaBytes * kOneMegaByte;
} else if (!strcmp(state, kStateIdGarageMode)) {
seenStates.insert(kStateIdGarageMode);
- perStateBytes.garageModeBytes = bytes;
+ perStateBytes.garageModeBytes = megaBytes * kOneMegaByte;
} else {
return Error() << "Invalid state '" << state << "' in per-state bytes";
}
diff --git a/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.h b/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.h
index 9f501c4..382c4f5 100644
--- a/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.h
+++ b/cpp/watchdog/server/src/OveruseConfigurationXmlHelper.h
@@ -25,6 +25,8 @@
namespace automotive {
namespace watchdog {
+constexpr int64_t kOneMegaByte = 1024 * 1024;
+
class OveruseConfigurationXmlHelper : public android::RefBase {
public:
static android::base::Result<
diff --git a/cpp/watchdog/server/src/WatchdogPerfService.cpp b/cpp/watchdog/server/src/WatchdogPerfService.cpp
index 030f318..151a5ef 100644
--- a/cpp/watchdog/server/src/WatchdogPerfService.cpp
+++ b/cpp/watchdog/server/src/WatchdogPerfService.cpp
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/cpp/watchdog/server/src/WatchdogPerfService.h b/cpp/watchdog/server/src/WatchdogPerfService.h
index 0551d35..6f1230a 100644
--- a/cpp/watchdog/server/src/WatchdogPerfService.h
+++ b/cpp/watchdog/server/src/WatchdogPerfService.h
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
index 43d08d7..84f28bb 100644
--- a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
@@ -16,12 +16,15 @@
#include "IoOveruseConfigs.h"
#include "OveruseConfigurationTestUtils.h"
+#include "OveruseConfigurationXmlHelper.h"
#include <android-base/strings.h>
#include <gmock/gmock.h>
#include <inttypes.h>
+#include <unordered_map>
+
namespace android {
namespace automotive {
namespace watchdog {
@@ -36,6 +39,7 @@
using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
using ::android::automotive::watchdog::internal::ResourceSpecificConfiguration;
using ::android::automotive::watchdog::internal::UidType;
+using ::android::base::Error;
using ::android::base::StringAppendF;
using ::android::base::StringPrintf;
using ::testing::IsEmpty;
@@ -100,7 +104,53 @@
return matchers;
}
-ResourceOveruseConfiguration sampleSystemConfig() {
+ResourceOveruseConfiguration sampleBuildSystemConfig() {
+ auto systemIoConfig = constructIoOveruseConfig(
+ /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
+ toPerStateBytes(1200, 1100, 1500)),
+ /*packageSpecific=*/
+ {toPerStateIoOveruseThreshold("systemPackageA", SYSTEM_PACKAGE_A_THRESHOLDS)},
+ /*categorySpecific=*/{},
+ /*systemWide=*/ALERT_THRESHOLDS);
+ return constructResourceOveruseConfig(ComponentType::SYSTEM,
+ /*safeToKill=*/{"systemPackageA"},
+ /*vendorPrefixes=*/{},
+ /*packageMetadata*/
+ {toPackageMetadata("systemPackageA",
+ ApplicationCategoryType::MEDIA)},
+ systemIoConfig);
+}
+
+ResourceOveruseConfiguration sampleBuildVendorConfig() {
+ auto vendorIoConfig = constructIoOveruseConfig(
+ /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
+ toPerStateBytes(1100, 150, 1900)),
+ /*packageSpecific=*/
+ {toPerStateIoOveruseThreshold("vendorPackageA", VENDOR_PACKAGE_A_THRESHOLDS)},
+ /*categorySpecific=*/
+ {toPerStateIoOveruseThreshold("MEDIA", MEDIA_THRESHOLDS)},
+ /*systemWide=*/{});
+ return constructResourceOveruseConfig(ComponentType::VENDOR,
+ /*safeToKill=*/{},
+ /*vendorPrefixes=*/{"vendorPackage"},
+ /*packageMetadata=*/
+ {toPackageMetadata("vendorPackageA",
+ ApplicationCategoryType::MEDIA)},
+ vendorIoConfig);
+}
+
+ResourceOveruseConfiguration sampleBuildThirdPartyConfig() {
+ auto thirdPartyIoConfig = constructIoOveruseConfig(
+ /*componentLevel=*/
+ toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
+ toPerStateBytes(1300, 1150, 2900)),
+ /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
+ return constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
+ /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+ thirdPartyIoConfig);
+}
+
+ResourceOveruseConfiguration sampleUpdateSystemConfig() {
auto systemIoConfig = constructIoOveruseConfig(
/*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
SYSTEM_COMPONENT_LEVEL_THRESHOLDS),
@@ -119,7 +169,7 @@
systemIoConfig);
}
-ResourceOveruseConfiguration sampleVendorConfig() {
+ResourceOveruseConfiguration sampleUpdateVendorConfig() {
auto vendorIoConfig = constructIoOveruseConfig(
/*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
VENDOR_COMPONENT_LEVEL_THRESHOLDS),
@@ -141,7 +191,7 @@
vendorIoConfig);
}
-ResourceOveruseConfiguration sampleThirdPartyConfig() {
+ResourceOveruseConfiguration sampleUpdateThirdPartyConfig() {
auto thirdPartyIoConfig = constructIoOveruseConfig(
/*componentLevel=*/
toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
@@ -154,17 +204,198 @@
sp<IoOveruseConfigs> sampleIoOveruseConfigs() {
sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
- EXPECT_RESULT_OK(ioOveruseConfigs->update(
- {sampleSystemConfig(), sampleVendorConfig(), sampleThirdPartyConfig()}));
+ EXPECT_RESULT_OK(
+ ioOveruseConfigs->update({sampleUpdateSystemConfig(), sampleUpdateVendorConfig(),
+ sampleUpdateThirdPartyConfig()}));
return ioOveruseConfigs;
}
} // namespace
-TEST(IoOveruseConfigsTest, TestUpdateWithValidConfigs) {
- auto systemResourceConfig = sampleSystemConfig();
- auto vendorResourceConfig = sampleVendorConfig();
- auto thirdPartyResourceConfig = sampleThirdPartyConfig();
+namespace internal {
+
+class IoOveruseConfigsPeer : public android::RefBase {
+public:
+ IoOveruseConfigsPeer() {
+ IoOveruseConfigs::sParseXmlFile =
+ [&](const char* filepath) -> android::base::Result<ResourceOveruseConfiguration> {
+ if (const auto it = configsByFilepaths.find(filepath); it != configsByFilepaths.end()) {
+ return it->second;
+ }
+ return Error() << "No configs available for the given filepath '" << filepath << "'";
+ };
+ }
+ ~IoOveruseConfigsPeer() {
+ IoOveruseConfigs::sParseXmlFile = &OveruseConfigurationXmlHelper::parseXmlFile;
+ }
+ std::unordered_map<std::string, ResourceOveruseConfiguration> configsByFilepaths;
+};
+
+} // namespace internal
+
+class IoOveruseConfigsTest : public ::testing::Test {
+public:
+ virtual void SetUp() { mPeer = sp<internal::IoOveruseConfigsPeer>::make(); }
+ virtual void TearDown() { mPeer.clear(); }
+
+ sp<internal::IoOveruseConfigsPeer> mPeer;
+};
+
+TEST_F(IoOveruseConfigsTest, TestConstructWithBuildConfigs) {
+ auto buildSystemResourceConfig = sampleBuildSystemConfig();
+ auto buildVendorResourceConfig = sampleBuildVendorConfig();
+ const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
+
+ mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig},
+ {kBuildVendorConfigXmlPath, buildVendorResourceConfig},
+ {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig}};
+
+ IoOveruseConfigs ioOveruseConfigs;
+
+ /* Package to app category mapping should be merged from both vendor and system configs. */
+ buildVendorResourceConfig.packageMetadata
+ .insert(buildVendorResourceConfig.packageMetadata.end(),
+ buildSystemResourceConfig.packageMetadata.begin(),
+ buildSystemResourceConfig.packageMetadata.end());
+ buildSystemResourceConfig.packageMetadata = buildVendorResourceConfig.packageMetadata;
+ std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
+ buildVendorResourceConfig,
+ buildThirdPartyResourceConfig};
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
+ << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST_F(IoOveruseConfigsTest, TestConstructWithLatestConfigs) {
+ const auto latestSystemResourceConfig = sampleUpdateSystemConfig();
+ auto latestVendorResourceConfig = sampleUpdateVendorConfig();
+ const auto latestThirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
+
+ mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, sampleBuildSystemConfig()},
+ {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
+ {kBuildThirdPartyConfigXmlPath, sampleBuildThirdPartyConfig()},
+ {kLatestSystemConfigXmlPath, latestSystemResourceConfig},
+ {kLatestVendorConfigXmlPath, latestVendorResourceConfig},
+ {kLatestThirdPartyConfigXmlPath, latestThirdPartyResourceConfig}};
+
+ IoOveruseConfigs ioOveruseConfigs;
+
+ latestVendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
+ std::vector<ResourceOveruseConfiguration> expected = {latestSystemResourceConfig,
+ latestVendorResourceConfig,
+ latestThirdPartyResourceConfig};
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
+ << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST_F(IoOveruseConfigsTest, TestConstructWithOnlyBuildSystemConfig) {
+ const auto buildSystemResourceConfig = sampleBuildSystemConfig();
+
+ mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig}};
+
+ IoOveruseConfigs ioOveruseConfigs;
+
+ /*
+ * Vendor/Third-party component-level thresholds should be derived from system
+ * component-level thresholds when build configs for Vendor/Third-party components are not
+ * available.
+ */
+ const auto& defaultComponentLevelThresholds =
+ buildSystemResourceConfig.resourceSpecificConfigurations[0]
+ .get<ResourceSpecificConfiguration::ioOveruseConfiguration>()
+ .componentLevelThresholds.perStateWriteBytes;
+ const auto vendorResourceConfig = constructResourceOveruseConfig(
+ ComponentType::VENDOR, /*safeToKill=*/{}, /*vendorPrefixes=*/{},
+ /*packageMetadata=*/buildSystemResourceConfig.packageMetadata,
+ constructIoOveruseConfig(
+ /*componentLevel=*/
+ toPerStateIoOveruseThreshold(ComponentType::VENDOR,
+ defaultComponentLevelThresholds),
+ /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{}));
+ const auto thirdPartyResourceConfig =
+ constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
+ /*vendorPrefixes=*/{},
+ /*packageMetadata=*/{},
+ constructIoOveruseConfig(
+ /*componentLevel=*/toPerStateIoOveruseThreshold(
+ ComponentType::THIRD_PARTY,
+ defaultComponentLevelThresholds),
+ /*packageSpecific=*/{}, /*categorySpecific=*/{},
+ /*systemWide=*/{}));
+
+ std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
+ vendorResourceConfig,
+ thirdPartyResourceConfig};
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
+ << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST_F(IoOveruseConfigsTest, TestConstructWithBuildSystemConfigLatestVendorConfig) {
+ auto buildSystemResourceConfig = sampleBuildSystemConfig();
+ auto latestVendorResourceConfig = sampleUpdateVendorConfig();
+ const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
+
+ mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig},
+ {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
+ {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig},
+ {kLatestVendorConfigXmlPath, latestVendorResourceConfig}};
+
+ IoOveruseConfigs ioOveruseConfigs;
+
+ // Package to app category mapping from latest vendor configuration should be given priority.
+ buildSystemResourceConfig.packageMetadata = latestVendorResourceConfig.packageMetadata;
+ latestVendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
+ std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
+ latestVendorResourceConfig,
+ buildThirdPartyResourceConfig};
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
+ << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST_F(IoOveruseConfigsTest, TestConstructWithLatestSystemConfigBuildVendorConfig) {
+ const auto latestSystemResourceConfig = sampleUpdateSystemConfig();
+ auto buildVendorResourceConfig = sampleBuildVendorConfig();
+ const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
+
+ mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, sampleBuildSystemConfig()},
+ {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
+ {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig},
+ {kLatestSystemConfigXmlPath, latestSystemResourceConfig}};
+
+ IoOveruseConfigs ioOveruseConfigs;
+
+ // Package to app category mapping from latest system configuration should be given priority.
+ buildVendorResourceConfig.packageMetadata = latestSystemResourceConfig.packageMetadata;
+ std::vector<ResourceOveruseConfiguration> expected = {latestSystemResourceConfig,
+ buildVendorResourceConfig,
+ buildThirdPartyResourceConfig};
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
+ << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST_F(IoOveruseConfigsTest, TestUpdateWithValidConfigs) {
+ auto systemResourceConfig = sampleUpdateSystemConfig();
+ auto vendorResourceConfig = sampleUpdateVendorConfig();
+ auto thirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
IoOveruseConfigs ioOveruseConfigs;
ASSERT_RESULT_OK(ioOveruseConfigs.update(
@@ -248,7 +479,7 @@
<< "Expected: " << toString(expected) << "Actual:" << toString(actual);
}
-TEST(IoOveruseConfigsTest, TestDefaultConfigWithoutUpdate) {
+TEST_F(IoOveruseConfigsTest, TestDefaultConfigWithoutUpdate) {
PerStateBytes defaultPerStateBytes = defaultThreshold().perStateWriteBytes;
IoOveruseConfigs ioOveruseConfigs;
@@ -281,7 +512,7 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentName) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentName) {
IoOveruseConfiguration randomIoConfig;
randomIoConfig.componentLevelThresholds =
toPerStateIoOveruseThreshold("random name", 200, 100, 500);
@@ -308,7 +539,32 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentLevelThresholds) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnDuplicatePackageToAppCategoryMappings) {
+ IoOveruseConfiguration ioConfig;
+ ioConfig.componentLevelThresholds =
+ toPerStateIoOveruseThreshold(ComponentType::VENDOR, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
+
+ IoOveruseConfigs ioOveruseConfigs;
+ EXPECT_FALSE(
+ ioOveruseConfigs
+ .update({constructResourceOveruseConfig(
+ ComponentType::VENDOR,
+ /*safeToKill=*/{},
+ /*vendorPrefixes=*/{"vendorPackage"},
+ /*packageMetadata=*/
+ {toPackageMetadata("vendorPackageA", ApplicationCategoryType::MEDIA),
+ toPackageMetadata("vendorPackageA", ApplicationCategoryType::MAPS)},
+ ioConfig)})
+ .ok())
+ << "Should error on duplicate package to app category mapping";
+
+ std::vector<ResourceOveruseConfiguration> actual;
+ ioOveruseConfigs.get(&actual);
+
+ EXPECT_THAT(actual, IsEmpty());
+}
+
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentLevelThresholds) {
IoOveruseConfiguration ioConfig;
ioConfig.componentLevelThresholds =
toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 0, 0, 0);
@@ -326,7 +582,7 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidSystemWideAlertThresholds) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidSystemWideAlertThresholds) {
IoOveruseConfiguration ioConfig;
ioConfig.componentLevelThresholds =
toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 100, 200, 300);
@@ -345,9 +601,11 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnDuplicateConfigsForSameComponent) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnDuplicateConfigsForSameComponent) {
IoOveruseConfigs ioOveruseConfigs;
- EXPECT_FALSE(ioOveruseConfigs.update({sampleThirdPartyConfig(), sampleThirdPartyConfig()}).ok())
+ EXPECT_FALSE(ioOveruseConfigs
+ .update({sampleUpdateThirdPartyConfig(), sampleUpdateThirdPartyConfig()})
+ .ok())
<< "Should error on duplicate configs for the same component";
std::vector<ResourceOveruseConfiguration> actual;
@@ -356,7 +614,7 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnNoIoOveruseConfiguration) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnNoIoOveruseConfiguration) {
ResourceOveruseConfiguration resConfig;
resConfig.componentType = ComponentType::THIRD_PARTY;
@@ -370,7 +628,7 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnMultipleIoOveruseConfigurations) {
+TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnMultipleIoOveruseConfigurations) {
IoOveruseConfiguration ioConfig;
ioConfig.componentLevelThresholds =
toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 100, 200, 300);
@@ -392,7 +650,7 @@
EXPECT_THAT(actual, IsEmpty());
}
-TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsBySystemComponent) {
+TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsBySystemComponent) {
auto systemIoConfig = constructIoOveruseConfig(
/*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 200, 100, 500),
/*packageSpecific=*/
@@ -427,7 +685,7 @@
<< "Expected: " << toString(expected) << "Actual:" << toString(actual);
}
-TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByVendorComponent) {
+TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByVendorComponent) {
auto vendorIoConfig = constructIoOveruseConfig(
/*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 100, 50, 900),
/*packageSpecific=*/
@@ -466,7 +724,7 @@
<< "Expected: " << toString(expected) << "Actual:" << toString(actual);
}
-TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByThirdPartyComponent) {
+TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByThirdPartyComponent) {
auto thirdPartyIoConfig = constructIoOveruseConfig(
/*componentLevel=*/
toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150, 1900),
@@ -505,7 +763,7 @@
<< "Expected: " << toString(expected) << "Actual:" << toString(actual);
}
-TEST(IoOveruseConfigsTest, TestFetchThresholdForSystemPackages) {
+TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSystemPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
auto actual = ioOveruseConfigs->fetchThreshold(
@@ -533,7 +791,7 @@
EXPECT_THAT(actual, MEDIA_THRESHOLDS);
}
-TEST(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
+TEST_F(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
auto actual = ioOveruseConfigs->fetchThreshold(
@@ -554,7 +812,7 @@
EXPECT_THAT(actual, MAPS_THRESHOLDS);
}
-TEST(IoOveruseConfigsTest, TestFetchThresholdForThirdPartyPackages) {
+TEST_F(IoOveruseConfigsTest, TestFetchThresholdForThirdPartyPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
auto actual = ioOveruseConfigs->fetchThreshold(
@@ -575,7 +833,7 @@
EXPECT_THAT(actual, MEDIA_THRESHOLDS);
}
-TEST(IoOveruseConfigsTest, TestIsSafeToKillSystemPackages) {
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSystemPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
constructPackageInfo("systemPackageGeneric", ComponentType::SYSTEM)));
@@ -584,7 +842,7 @@
constructPackageInfo("systemPackageA", ComponentType::SYSTEM)));
}
-TEST(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
constructPackageInfo("vendorPackageGeneric", ComponentType::VENDOR)));
@@ -593,7 +851,7 @@
constructPackageInfo("vendorPackageA", ComponentType::VENDOR)));
}
-TEST(IoOveruseConfigsTest, TestIsSafeToKillThirdPartyPackages) {
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillThirdPartyPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
constructPackageInfo("vendorPackageGenericImpostor", ComponentType::THIRD_PARTY)));
@@ -603,7 +861,7 @@
ApplicationCategoryType::MAPS)));
}
-TEST(IoOveruseConfigsTest, TestIsSafeToKillNativePackages) {
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillNativePackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
PackageInfo packageInfo;
@@ -618,23 +876,23 @@
EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo));
}
-TEST(IoOveruseConfigsTest, TestSystemWideAlertThresholds) {
+TEST_F(IoOveruseConfigsTest, TestSystemWideAlertThresholds) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_THAT(ioOveruseConfigs->systemWideAlertThresholds(),
UnorderedElementsAreArray(ALERT_THRESHOLDS));
}
-TEST(IoOveruseConfigsTest, TestVendorPackagePrefixes) {
+TEST_F(IoOveruseConfigsTest, TestVendorPackagePrefixes) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_THAT(ioOveruseConfigs->vendorPackagePrefixes(),
UnorderedElementsAre("vendorPackage", "vendorPkgB"));
}
-TEST(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithSystemConfig) {
+TEST_F(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithSystemConfig) {
IoOveruseConfigs ioOveruseConfigs;
- const auto resourceOveruseConfig = sampleSystemConfig();
+ const auto resourceOveruseConfig = sampleUpdateSystemConfig();
ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
@@ -643,9 +901,9 @@
toPackageToAppCategoryMappings(resourceOveruseConfig.packageMetadata)));
}
-TEST(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithVendorConfig) {
+TEST_F(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithVendorConfig) {
IoOveruseConfigs ioOveruseConfigs;
- const auto resourceOveruseConfig = sampleVendorConfig();
+ const auto resourceOveruseConfig = sampleUpdateVendorConfig();
ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
diff --git a/cpp/watchdog/server/tests/OveruseConfigurationTestUtils.cpp b/cpp/watchdog/server/tests/OveruseConfigurationTestUtils.cpp
index ec5908a..1bf270d 100644
--- a/cpp/watchdog/server/tests/OveruseConfigurationTestUtils.cpp
+++ b/cpp/watchdog/server/tests/OveruseConfigurationTestUtils.cpp
@@ -67,6 +67,11 @@
}
}
+MATCHER_P(IsPackageMetadata, expected, "") {
+ return arg.packageName == expected.packageName &&
+ arg.appCategoryType == expected.appCategoryType;
+}
+
} // namespace
ResourceOveruseConfiguration constructResourceOveruseConfig(
@@ -151,9 +156,15 @@
Matcher<const ResourceOveruseConfiguration> ResourceOveruseConfigurationMatcher(
const ResourceOveruseConfiguration& config) {
- std::vector<Matcher<const ResourceSpecificConfiguration>> matchers;
+ std::vector<Matcher<const ResourceSpecificConfiguration>> resourceSpecificConfigMatchers;
for (const auto& resourceSpecificConfig : config.resourceSpecificConfigurations) {
- matchers.push_back(IsResourceSpecificConfiguration(resourceSpecificConfig));
+ resourceSpecificConfigMatchers.push_back(
+ IsResourceSpecificConfiguration(resourceSpecificConfig));
+ }
+
+ std::vector<Matcher<const PackageMetadata>> metadataMatchers;
+ for (const auto& metadata : config.packageMetadata) {
+ metadataMatchers.push_back(IsPackageMetadata(metadata));
}
return AllOf(Field(&ResourceOveruseConfiguration::componentType, config.componentType),
@@ -161,8 +172,10 @@
UnorderedElementsAreArray(config.safeToKillPackages)),
Field(&ResourceOveruseConfiguration::vendorPackagePrefixes,
UnorderedElementsAreArray(config.vendorPackagePrefixes)),
+ Field(&ResourceOveruseConfiguration::packageMetadata,
+ UnorderedElementsAreArray(metadataMatchers)),
Field(&ResourceOveruseConfiguration::resourceSpecificConfigurations,
- UnorderedElementsAreArray(matchers)));
+ UnorderedElementsAreArray(resourceSpecificConfigMatchers)));
}
} // namespace watchdog
diff --git a/cpp/watchdog/server/tests/OveruseConfigurationXmlHelperTest.cpp b/cpp/watchdog/server/tests/OveruseConfigurationXmlHelperTest.cpp
index 2595c2b..88006d7 100644
--- a/cpp/watchdog/server/tests/OveruseConfigurationXmlHelperTest.cpp
+++ b/cpp/watchdog/server/tests/OveruseConfigurationXmlHelperTest.cpp
@@ -72,10 +72,14 @@
TEST(OveruseConfigurationXmlHelperTest, TestValidSystemConfiguration) {
auto ioConfig = constructIoOveruseConfig(
- /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 300, 150, 500),
+ /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
+ 300 * kOneMegaByte, 150 * kOneMegaByte,
+ 500 * kOneMegaByte),
/*packageSpecific=*/
- {toPerStateIoOveruseThreshold("system.package.C", 400, 100, 200),
- toPerStateIoOveruseThreshold("system.package.D", 1024, 500, 2048)},
+ {toPerStateIoOveruseThreshold("system.package.C", 400 * kOneMegaByte,
+ 100 * kOneMegaByte, 200 * kOneMegaByte),
+ toPerStateIoOveruseThreshold("system.package.D", 1024 * kOneMegaByte,
+ 500 * kOneMegaByte, 2048 * kOneMegaByte)},
/*categorySpecific=*/{},
/*systemWide=*/{toIoOveruseAlertThreshold(10, 200), toIoOveruseAlertThreshold(5, 50)});
ResourceOveruseConfiguration expected =
@@ -97,13 +101,19 @@
TEST(OveruseConfigurationXmlHelperTest, TestValidVendorConfiguration) {
auto ioConfig = constructIoOveruseConfig(
- /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 1024, 512, 3072),
+ /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
+ 1024 * kOneMegaByte, 512 * kOneMegaByte,
+ 3072 * kOneMegaByte),
/*packageSpecific=*/
- {toPerStateIoOveruseThreshold("com.vendor.package.C", 400, 100, 200),
- toPerStateIoOveruseThreshold("com.vendor.package.D", 1024, 500, 2048)},
+ {toPerStateIoOveruseThreshold("com.vendor.package.C", 400 * kOneMegaByte,
+ 100 * kOneMegaByte, 200 * kOneMegaByte),
+ toPerStateIoOveruseThreshold("com.vendor.package.D", 1024 * kOneMegaByte,
+ 500 * kOneMegaByte, 2048 * kOneMegaByte)},
/*categorySpecific=*/
- {toPerStateIoOveruseThreshold("MAPS", 800, 900, 2048),
- toPerStateIoOveruseThreshold("MEDIA", 600, 700, 1024)},
+ {toPerStateIoOveruseThreshold("MAPS", 800 * kOneMegaByte, 900 * kOneMegaByte,
+ 2048 * kOneMegaByte),
+ toPerStateIoOveruseThreshold("MEDIA", 600 * kOneMegaByte, 700 * kOneMegaByte,
+ 1024 * kOneMegaByte)},
/*systemWide=*/{});
ResourceOveruseConfiguration expected =
constructResourceOveruseConfig(ComponentType::VENDOR,
@@ -129,8 +139,9 @@
TEST(OveruseConfigurationXmlHelperTest, TestValidThirdPartyConfiguration) {
auto ioConfig = constructIoOveruseConfig(
- /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150,
- 500),
+ /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
+ 300 * kOneMegaByte, 150 * kOneMegaByte,
+ 500 * kOneMegaByte),
/*packageSpecific=*/{},
/*categorySpecific=*/{},
/*systemWide=*/{});
diff --git a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
index 40d6389..47d82b7 100644
--- a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
@@ -30,7 +30,6 @@
#include <binder/IPCThreadState.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include <log/log.h>
#include <private/android_filesystem_config.h>
#include <utils/RefBase.h>
diff --git a/cpp/watchdog/server/tests/data/valid_overuse_third_party_configuration.xml b/cpp/watchdog/server/tests/data/valid_overuse_third_party_configuration.xml
index b3bacb6..f12a47c 100644
--- a/cpp/watchdog/server/tests/data/valid_overuse_third_party_configuration.xml
+++ b/cpp/watchdog/server/tests/data/valid_overuse_third_party_configuration.xml
@@ -24,4 +24,4 @@
<state id="garage_mode"> 500 </state>
</componentLevelThresholds>
</ioOveruseConfiguration>
-</resourceOveruseConfiguration>
\ No newline at end of file
+</resourceOveruseConfiguration>