Add namespace handling in attribute values
Previously, you could only reference namespace prefixes in attribute names:
<View xmlns:appcompat="http://schemas.android.com/apk/res/android.support.v7.appcompat"
appcompat:name="hey"
...
Now you can also reference them in resource names within an attribute value:
...
android:text="@appcompat:string/confirm"
...
Which will be treated as "@android.support.v7.appcompat:string/confirm".
Change-Id: Ib076e867a990c80cf877a704eb77cd1ef0b23b52
diff --git a/tools/aapt2/ManifestValidator.cpp b/tools/aapt2/ManifestValidator.cpp
index 7ec0bc7..123b9fa 100644
--- a/tools/aapt2/ManifestValidator.cpp
+++ b/tools/aapt2/ManifestValidator.cpp
@@ -190,18 +190,26 @@
bool error = false;
SourceLogger logger(source);
- const size_t attrCount = parser->getAttributeCount();
- for (size_t i = 0; i < attrCount; i++) {
- size_t len = 0;
- StringPiece16 attrNamespace(parser->getAttributeNamespace(i, &len), len);
- StringPiece16 attrName(parser->getAttributeName(i, &len), len);
- if (attrNamespace.empty() && attrName == u"package") {
- error |= !validateInlineAttribute(parser, i, logger, kPackageIdentSet);
- } else if (attrNamespace == u"android") {
- if (attrName == u"sharedUserId") {
- error |= !validateInlineAttribute(parser, i, logger, kPackageIdentSet);
- }
- }
+ const StringPiece16 kAndroid = u"android";
+ const StringPiece16 kPackage = u"package";
+ const StringPiece16 kSharedUserId = u"sharedUserId";
+
+ ssize_t idx;
+
+ idx = parser->indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size());
+ if (idx < 0) {
+ logger.error(parser->getLineNumber())
+ << "missing package attribute."
+ << std::endl;
+ error = true;
+ } else {
+ error |= !validateInlineAttribute(parser, idx, logger, kPackageIdentSet);
+ }
+
+ idx = parser->indexOfAttribute(kAndroid.data(), kAndroid.size(),
+ kSharedUserId.data(), kSharedUserId.size());
+ if (idx >= 0) {
+ error |= !validateInlineAttribute(parser, idx, logger, kPackageIdentSet);
}
return !error;
}