aboutsummaryrefslogtreecommitdiff
path: root/cpp/watchdog
diff options
context:
space:
mode:
authorLakshman Annadorai <lakshmana@google.com>2021-07-09 14:39:23 -0700
committerLakshman Annadorai <lakshmana@google.com>2021-07-14 15:44:29 -0700
commitc31fc6b04878dbd9e26359a6fc5285a11f914d7c (patch)
treeea6300703a28c3c4d35142a12f98bfcfeff855d6 /cpp/watchdog
parent8305437442df424ecea8830e5cb1afc776826025 (diff)
downloadCar-c31fc6b04878dbd9e26359a6fc5285a11f914d7c.tar.gz
Handle shared UID in watchdog daemon.
- Daemon should mark a shared UID as safe-to-kill when at least one package is marked as safe-to-kill in the config. - Shared package names contain the "shared:" prefix and the package specific thresholds and safe-to-kill checking are done with the prefix. - When app cateogry is not mapped by the shared package name, fallback to fetching app category mapped to any package under the shared UID. Test: atest libwatchdog_test Bug: 191892687 Change-Id: If3a0f3887eeac9475b984441b1e1965d72f7720c
Diffstat (limited to 'cpp/watchdog')
-rw-r--r--cpp/watchdog/server/src/IoOveruseConfigs.cpp33
-rw-r--r--cpp/watchdog/server/src/PackageInfoResolver.cpp20
-rw-r--r--cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp138
-rw-r--r--cpp/watchdog/server/tests/PackageInfoResolverTest.cpp25
4 files changed, 204 insertions, 12 deletions
diff --git a/cpp/watchdog/server/src/IoOveruseConfigs.cpp b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
index 6fb663397d..96dd6b3c6c 100644
--- a/cpp/watchdog/server/src/IoOveruseConfigs.cpp
+++ b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
@@ -238,6 +238,16 @@ Result<void> isValidResourceOveruseConfigs(
return {};
}
+bool isSafeToKillAnyPackage(const std::vector<std::string>& packages,
+ const std::unordered_set<std::string>& safeToKillPackages) {
+ for (const auto& packageName : packages) {
+ if (safeToKillPackages.find(packageName) != safeToKillPackages.end()) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
IoOveruseConfigs::ParseXmlFileFunction IoOveruseConfigs::sParseXmlFile =
@@ -724,11 +734,26 @@ bool IoOveruseConfigs::isSafeToKill(const PackageInfo& packageInfo) const {
}
switch (packageInfo.componentType) {
case ComponentType::SYSTEM:
- return mSystemConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
- mSystemConfig.mSafeToKillPackages.end();
+ if (mSystemConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
+ mSystemConfig.mSafeToKillPackages.end()) {
+ return true;
+ }
+ return isSafeToKillAnyPackage(packageInfo.sharedUidPackages,
+ mSystemConfig.mSafeToKillPackages);
case ComponentType::VENDOR:
- return mVendorConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
- mVendorConfig.mSafeToKillPackages.end();
+ if (mVendorConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
+ mVendorConfig.mSafeToKillPackages.end()) {
+ return true;
+ }
+ /*
+ * Packages under the vendor shared UID may contain system packages because when
+ * CarWatchdogService derives the shared component type it attributes system packages
+ * as vendor packages when there is at least one vendor package.
+ */
+ return isSafeToKillAnyPackage(packageInfo.sharedUidPackages,
+ mSystemConfig.mSafeToKillPackages) ||
+ isSafeToKillAnyPackage(packageInfo.sharedUidPackages,
+ mVendorConfig.mSafeToKillPackages);
default:
return true;
}
diff --git a/cpp/watchdog/server/src/PackageInfoResolver.cpp b/cpp/watchdog/server/src/PackageInfoResolver.cpp
index 2b30600e7a..84d7c670e7 100644
--- a/cpp/watchdog/server/src/PackageInfoResolver.cpp
+++ b/cpp/watchdog/server/src/PackageInfoResolver.cpp
@@ -179,9 +179,23 @@ void PackageInfoResolver::updatePackageInfos(const std::vector<uid_t>& uids) {
if (id.name.empty()) {
continue;
}
- if (const auto it = mPackagesToAppCategories.find(id.name);
- packageInfo.uidType == UidType::APPLICATION && it != mPackagesToAppCategories.end()) {
- packageInfo.appCategoryType = it->second;
+ if (packageInfo.uidType == UidType::APPLICATION) {
+ if (const auto it = mPackagesToAppCategories.find(id.name);
+ it != mPackagesToAppCategories.end()) {
+ packageInfo.appCategoryType = it->second;
+ } else if (!packageInfo.sharedUidPackages.empty()) {
+ /* The recommendation for the OEMs is to define the application category mapping
+ * by the shared package names. However, this a fallback to catch if any mapping is
+ * defined by the individual package name.
+ */
+ for (const auto& packageName : packageInfo.sharedUidPackages) {
+ if (const auto it = mPackagesToAppCategories.find(packageName);
+ it != mPackagesToAppCategories.end()) {
+ packageInfo.appCategoryType = it->second;
+ break;
+ }
+ }
+ }
}
mUidToPackageInfoMapping[id.uid] = packageInfo;
}
diff --git a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
index 79b32fcc46..c03ad85eab 100644
--- a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
@@ -75,12 +75,14 @@ std::unordered_map<std::string, ApplicationCategoryType> toPackageToAppCategoryM
PackageInfo constructPackageInfo(
const char* packageName, const ComponentType componentType,
- const ApplicationCategoryType appCategoryType = ApplicationCategoryType::OTHERS) {
+ const ApplicationCategoryType appCategoryType = ApplicationCategoryType::OTHERS,
+ const std::vector<std::string>& sharedUidPackages = std::vector<std::string>()) {
PackageInfo packageInfo;
packageInfo.packageIdentifier.name = packageName;
packageInfo.uidType = UidType::APPLICATION;
packageInfo.componentType = componentType;
packageInfo.appCategoryType = appCategoryType;
+ packageInfo.sharedUidPackages = sharedUidPackages;
return packageInfo;
}
@@ -832,6 +834,28 @@ TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSystemPackages) {
EXPECT_THAT(actual, MEDIA_THRESHOLDS);
}
+TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSharedSystemPackages) {
+ const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+ auto sampleSystemConfig = sampleUpdateSystemConfig();
+ auto& ioConfig = sampleSystemConfig.resourceSpecificConfigurations[0]
+ .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+ ioConfig.packageSpecificThresholds.push_back(
+ toPerStateIoOveruseThreshold("shared:systemSharedPackage",
+ toPerStateBytes(100, 200, 300)));
+
+ ioOveruseConfigs->update({sampleSystemConfig});
+
+ auto actual = ioOveruseConfigs->fetchThreshold(
+ constructPackageInfo("shared:systemSharedPackage", ComponentType::SYSTEM));
+
+ EXPECT_THAT(actual, toPerStateBytes(100, 200, 300));
+
+ actual = ioOveruseConfigs->fetchThreshold(
+ constructPackageInfo("systemSharedPackage", ComponentType::SYSTEM));
+
+ EXPECT_THAT(actual, SYSTEM_COMPONENT_LEVEL_THRESHOLDS);
+}
+
TEST_F(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
@@ -853,6 +877,28 @@ TEST_F(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
EXPECT_THAT(actual, MAPS_THRESHOLDS);
}
+TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSharedVendorPackages) {
+ const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+ auto sampleVendorConfig = sampleUpdateVendorConfig();
+ auto& ioConfig = sampleVendorConfig.resourceSpecificConfigurations[0]
+ .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+ ioConfig.packageSpecificThresholds.push_back(
+ toPerStateIoOveruseThreshold("shared:vendorSharedPackage",
+ toPerStateBytes(100, 200, 300)));
+
+ ioOveruseConfigs->update({sampleVendorConfig});
+
+ auto actual = ioOveruseConfigs->fetchThreshold(
+ constructPackageInfo("shared:vendorSharedPackage", ComponentType::VENDOR));
+
+ EXPECT_THAT(actual, toPerStateBytes(100, 200, 300));
+
+ actual = ioOveruseConfigs->fetchThreshold(
+ constructPackageInfo("vendorSharedPackage", ComponentType::VENDOR));
+
+ EXPECT_THAT(actual, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
+}
+
TEST_F(IoOveruseConfigsTest, TestFetchThresholdForThirdPartyPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
@@ -883,6 +929,36 @@ TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSystemPackages) {
constructPackageInfo("systemPackageA", ComponentType::SYSTEM)));
}
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSharedSystemPackages) {
+ auto sampleSystemConfig = sampleUpdateSystemConfig();
+ sampleSystemConfig.safeToKillPackages.push_back("sharedUidSystemPackageC");
+ sampleSystemConfig.safeToKillPackages.push_back("shared:systemSharedPackageD");
+ sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
+
+ EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleSystemConfig}));
+
+ PackageInfo packageInfo =
+ constructPackageInfo("systemSharedPackage", ComponentType::SYSTEM,
+ ApplicationCategoryType::OTHERS,
+ {"sharedUidSystemPackageA", "sharedUidSystemPackageB",
+ "sharedUidSystemPackageC"});
+
+ EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Should be safe-to-kill when at least one package under shared UID is safe-to-kill";
+
+ packageInfo =
+ constructPackageInfo("shared:systemSharedPackageD", ComponentType::SYSTEM,
+ ApplicationCategoryType::OTHERS, {"sharedUidSystemPackageA"});
+ EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Should be safe-to-kill when shared package is safe-to-kill";
+
+ packageInfo =
+ constructPackageInfo("systemSharedPackageD", ComponentType::SYSTEM,
+ ApplicationCategoryType::OTHERS, {"sharedUidSystemPackageA"});
+ EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Shouldn't be safe-to-kill when the 'shared:' prefix is missing";
+}
+
TEST_F(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
@@ -892,6 +968,40 @@ TEST_F(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
constructPackageInfo("vendorPackageA", ComponentType::VENDOR)));
}
+TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSharedVendorPackages) {
+ auto sampleVendorConfig = sampleUpdateVendorConfig();
+ sampleVendorConfig.safeToKillPackages.push_back("sharedUidVendorPackageC");
+ sampleVendorConfig.safeToKillPackages.push_back("shared:vendorSharedPackageD");
+
+ auto sampleSystemConfig = sampleUpdateSystemConfig();
+ sampleSystemConfig.safeToKillPackages.push_back("sharedUidSystemPackageC");
+
+ sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
+
+ EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleSystemConfig, sampleVendorConfig}));
+
+ PackageInfo packageInfo =
+ constructPackageInfo("vendorSharedPackage", ComponentType::VENDOR,
+ ApplicationCategoryType::OTHERS,
+ {"sharedUidVendorPackageA", "sharedUidVendorPackageB",
+ "sharedUidVendorPackageC"});
+
+ EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Should be safe-to-kill when at least one package under shared UID is safe-to-kill";
+
+ packageInfo =
+ constructPackageInfo("shared:vendorSharedPackageD", ComponentType::VENDOR,
+ ApplicationCategoryType::OTHERS, {"sharedUidVendorPackageA"});
+ EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Should be safe-to-kill when shared package is safe-to-kill";
+
+ packageInfo =
+ constructPackageInfo("shared:vendorSharedPackageE", ComponentType::VENDOR,
+ ApplicationCategoryType::OTHERS, {"sharedUidVendorPackageA"});
+ EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo))
+ << "Shouldn't be safe-to-kill when the 'shared:' prefix is missing";
+}
+
TEST_F(IoOveruseConfigsTest, TestIsSafeToKillThirdPartyPackages) {
const auto ioOveruseConfigs = sampleIoOveruseConfigs();
EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
@@ -931,6 +1041,32 @@ TEST_F(IoOveruseConfigsTest, TestVendorPackagePrefixes) {
UnorderedElementsAre("vendorPackage", "vendorPkgB"));
}
+TEST_F(IoOveruseConfigsTest, TestVendorPackagePrefixesWithSharedPackages) {
+ auto sampleVendorConfig = sampleUpdateVendorConfig();
+ sampleVendorConfig.vendorPackagePrefixes.push_back("shared:vendorSharedPackage");
+ sampleVendorConfig.safeToKillPackages.push_back("sharedUidVendorPackageD");
+ sampleVendorConfig.safeToKillPackages.push_back("shared:vendorSharedPackageE");
+ sampleVendorConfig.safeToKillPackages.push_back("shared:vndrSharedPkgF");
+
+ auto& ioConfig = sampleVendorConfig.resourceSpecificConfigurations[0]
+ .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+
+ ioConfig.packageSpecificThresholds.push_back(
+ toPerStateIoOveruseThreshold("shared:vendorSharedPackageG",
+ VENDOR_PACKAGE_A_THRESHOLDS));
+ ioConfig.packageSpecificThresholds.push_back(
+ toPerStateIoOveruseThreshold("shared:vndrSharedPkgH", VENDOR_PACKAGE_A_THRESHOLDS));
+
+ sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
+
+ EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleVendorConfig}));
+
+ EXPECT_THAT(ioOveruseConfigs->vendorPackagePrefixes(),
+ UnorderedElementsAre("vendorPackage", "vendorPkgB", "shared:vendorSharedPackage",
+ "sharedUidVendorPackageD", "shared:vndrSharedPkgF",
+ "shared:vndrSharedPkgH"));
+}
+
TEST_F(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithSystemConfig) {
IoOveruseConfigs ioOveruseConfigs;
const auto resourceOveruseConfig = sampleUpdateSystemConfig();
diff --git a/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp b/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
index f2fe3a69a1..cf282be5fb 100644
--- a/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
+++ b/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
@@ -195,6 +195,8 @@ TEST(PackageInfoResolverTest, TestGetPackageInfosForUidsViaWatchdogService) {
// system.package.B is native package so this should be ignored.
{"system.package.B", ApplicationCategoryType::MAPS},
{"vendor.package.A", ApplicationCategoryType::MEDIA},
+ {"shared:vendor.package.C", ApplicationCategoryType::MEDIA},
+ {"vendor.package.shared.uid.D", ApplicationCategoryType::MAPS},
};
peer.setPackageConfigurations({"vendor.pkg"}, packagesToAppCategories);
/*
@@ -213,23 +215,38 @@ TEST(PackageInfoResolverTest, TestGetPackageInfosForUidsViaWatchdogService) {
ApplicationCategoryType::OTHERS)},
{15100,
constructPackageInfo("vendor.package.A", 15100, UidType::APPLICATION,
- ComponentType::VENDOR, ApplicationCategoryType::MEDIA)},
+ ComponentType::VENDOR, ApplicationCategoryType::OTHERS)},
{16700,
constructPackageInfo("vendor.pkg", 16700, UidType::NATIVE, ComponentType::VENDOR,
ApplicationCategoryType::OTHERS)},
+ {18100,
+ constructPackageInfo("shared:vendor.package.C", 18100, UidType::APPLICATION,
+ ComponentType::VENDOR, ApplicationCategoryType::OTHERS)},
+ {19100,
+ constructPackageInfo("shared:vendor.package.D", 19100, UidType::APPLICATION,
+ ComponentType::VENDOR, ApplicationCategoryType::OTHERS,
+ {"vendor.package.shared.uid.D"})},
};
- std::vector<int32_t> expectedUids = {6100, 7700, 15100, 16700};
+ std::vector<int32_t> expectedUids = {6100, 7700, 15100, 16700, 18100, 19100};
std::vector<std::string> expectedPrefixes = {"vendor.pkg"};
std::vector<PackageInfo> injectPackageInfos = {expectedMappings.at(6100),
expectedMappings.at(7700),
expectedMappings.at(15100),
- expectedMappings.at(16700)};
+ expectedMappings.at(16700),
+ expectedMappings.at(18100),
+ expectedMappings.at(19100)};
+
+ expectedMappings.at(15100).appCategoryType = ApplicationCategoryType::MEDIA;
+ expectedMappings.at(18100).appCategoryType = ApplicationCategoryType::MEDIA;
+ expectedMappings.at(19100).appCategoryType = ApplicationCategoryType::MAPS;
+
EXPECT_CALL(*peer.mockWatchdogServiceHelper,
getPackageInfosForUids(expectedUids, expectedPrefixes, _))
.WillOnce(DoAll(SetArgPointee<2>(injectPackageInfos), Return(binder::Status::ok())));
- auto actualMappings = packageInfoResolver->getPackageInfosForUids({6100, 7700, 15100, 16700});
+ auto actualMappings =
+ packageInfoResolver->getPackageInfosForUids({6100, 7700, 15100, 16700, 18100, 19100});
EXPECT_THAT(actualMappings, UnorderedElementsAreArray(expectedMappings))
<< "Expected: " << toString(expectedMappings)