AAPT2: Parse coreApp in <manifest> as boolean
Bug:30751662
Change-Id: I283be5725426ee084944c1921df40d1bd6188028
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 1203db7..e7edcc5 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -81,6 +81,22 @@
return true;
}
+/**
+ * The coreApp attribute in <manifest> is not a regular AAPT attribute, so type checking on it
+ * is manual.
+ */
+static bool fixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) {
+ if (xml::Attribute* attr = el->findAttribute("", "coreApp")) {
+ std::unique_ptr<BinaryPrimitive> result = ResourceUtils::tryParseBool(attr->value);
+ if (!result) {
+ diag->error(DiagMessage(el->lineNumber) << "attribute coreApp must be a boolean");
+ return false;
+ }
+ attr->compiledValue = std::move(result);
+ }
+ return true;
+}
+
bool ManifestFixer::buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag) {
// First verify some options.
if (mOptions.renameManifestPackage) {
@@ -111,6 +127,7 @@
// Manifest actions.
xml::XmlNodeAction& manifestAction = (*executor)["manifest"];
manifestAction.action(verifyManifest);
+ manifestAction.action(fixCoreAppAttribute);
manifestAction.action([&](xml::Element* el) -> bool {
if (mOptions.versionNameDefault) {
if (el->findAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 1c69a8c..16ab9ab 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -253,4 +253,24 @@
EXPECT_EQ(std::string("0x10000000"), attr->value);
}
+TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
+ EXPECT_EQ(nullptr, verify("<manifest package=\"android\" coreApp=\"hello\" />"));
+ EXPECT_EQ(nullptr, verify("<manifest package=\"android\" coreApp=\"1dp\" />"));
+
+ std::unique_ptr<xml::XmlResource> doc =
+ verify("<manifest package=\"android\" coreApp=\"true\" />");
+ ASSERT_NE(nullptr, doc);
+
+ xml::Element* el = xml::findRootElement(doc.get());
+ ASSERT_NE(nullptr, el);
+
+ EXPECT_EQ("manifest", el->name);
+
+ xml::Attribute* attr = el->findAttribute("", "coreApp");
+ ASSERT_NE(nullptr, attr);
+
+ EXPECT_NE(nullptr, attr->compiledValue);
+ EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(attr->compiledValue.get()));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index 02af5e3..a29d8dc 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -126,8 +126,9 @@
mError = true;
}
- } else {
- // We still encode references.
+ } else if (!attr.compiledValue) {
+ // We still encode references, but only if we haven't manually set this to
+ // another compiled value.
attr.compiledValue = ResourceUtils::tryParseReference(attr.value);
}