diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 85bf6f218ba07..5812ec44f1fb0 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -213,6 +213,27 @@ static bool VerifyUsesFeature(xml::Element* el, SourcePathDiagnostics* diag) { return true; } +static bool AddDeprecatedUsesFeatures(xml::Element* el, SourcePathDiagnostics* diag) { + if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { + if (attr->value.empty()) { + return true; + } + + // Add "android.hardware.fingerprint" when "android.hardware.biometric.fingerprint" is found, + // since the former is deprecated in Q and the latter is not present pre-Q. (see b/115639644) + if (attr->value == "android.hardware.biometrics.fingerprint") { + auto element = el->CloneElement([&](const xml::Element& el, xml::Element* out_el) { + xml::Attribute* cloned_attr = out_el->FindOrCreateAttribute(xml::kSchemaAndroid, "name"); + cloned_attr->value = "android.hardware.fingerprint"; + }); + + el->parent->AppendChild(std::move(element)); + } + } + + return true; +} + bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag) { // First verify some options. @@ -247,6 +268,7 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, // Common actions. xml::XmlNodeAction uses_feature_action; uses_feature_action.Action(VerifyUsesFeature); + uses_feature_action.Action(AddDeprecatedUsesFeatures); // Common component actions. xml::XmlNodeAction component_action; diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index adea6273bc8b6..fcc9f559a73f2 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -832,4 +832,36 @@ TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) { EXPECT_THAT(Verify(input), NotNull()); } +TEST_F(ManifestFixerTest, UsesFeatureAddDeprecated) { + std::string input = R"( + + + + + + )"; + + std::unique_ptr manifest = Verify(input); + ASSERT_THAT(manifest, NotNull()); + EXPECT_THAT(manifest->root->FindChildWithAttribute("", "uses-feature", + xml::kSchemaAndroid, "name", + "android.hardware.biometrics.fingerprint"), + Ne(nullptr)); + EXPECT_THAT(manifest->root->FindChildWithAttribute("", "uses-feature", + xml::kSchemaAndroid, "name", + "android.hardware.fingerprint"), + Ne(nullptr)); + + xml::Element* feature_group = manifest->root->FindChild("", "feature-group"); + ASSERT_THAT(feature_group, Ne(nullptr)); + + EXPECT_THAT(feature_group->FindChildWithAttribute("", "uses-feature", xml::kSchemaAndroid, "name", + "android.hardware.biometrics.fingerprint"), + Ne(nullptr)); + EXPECT_THAT(feature_group->FindChildWithAttribute("", "uses-feature", xml::kSchemaAndroid, "name", + "android.hardware.fingerprint"), + Ne(nullptr)); +} + } // namespace aapt