summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2015-05-13 21:42:57 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-05-13 21:43:00 +0000
commit4ee67bc7a7bb84da1c92dc08427f9737ff8252d6 (patch)
tree1cde9191650b0264f6f4e831a563bcadbecc848c
parentae8fcaf4c320dbf68db7dc032269692806150d99 (diff)
parentdfa5e0705ff82f15e228ba076bc192893bcbe118 (diff)
downloadframeworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.zip
frameworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.tar.gz
frameworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.tar.bz2
Merge "AAPT2: Fix issue where @null was wrongly encoded" into mnc-dev
-rw-r--r--tools/aapt2/BinaryResourceParser.cpp3
-rw-r--r--tools/aapt2/ResourceParser.cpp14
-rw-r--r--tools/aapt2/ResourceParser_test.cpp26
3 files changed, 34 insertions, 9 deletions
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp
index 620f0fe..3559f43 100644
--- a/tools/aapt2/BinaryResourceParser.cpp
+++ b/tools/aapt2/BinaryResourceParser.cpp
@@ -697,8 +697,7 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na
// This is not an unresolved symbol, so it must be the magic @null reference.
Res_value nullType = {};
- nullType.dataType = Res_value::TYPE_NULL;
- nullType.data = Res_value::DATA_NULL_UNDEFINED;
+ nullType.dataType = Res_value::TYPE_REFERENCE;
return util::make_unique<BinaryPrimitive>(nullType);
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 59915a2..13f916b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -193,18 +193,18 @@ std::unique_ptr<Reference> ResourceParser::tryParseReference(const StringPiece16
std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseNullOrEmpty(const StringPiece16& str) {
StringPiece16 trimmedStr(util::trimWhitespace(str));
- uint32_t data = 0;
+ android::Res_value value = {};
if (trimmedStr == u"@null") {
- data = android::Res_value::DATA_NULL_UNDEFINED;
+ // TYPE_NULL with data set to 0 is interpreted by the runtime as an error.
+ // Instead we set the data type to TYPE_REFERENCE with a value of 0.
+ value.dataType = android::Res_value::TYPE_REFERENCE;
} else if (trimmedStr == u"@empty") {
- data = android::Res_value::DATA_NULL_EMPTY;
+ // TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime.
+ value.dataType = android::Res_value::TYPE_NULL;
+ value.data = android::Res_value::DATA_NULL_EMPTY;
} else {
return {};
}
-
- android::Res_value value = {};
- value.dataType = android::Res_value::TYPE_NULL;
- value.data = data;
return util::make_unique<BinaryPrimitive>(value);
}
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 3d8a2f0..a93d0ff 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -191,6 +191,32 @@ TEST_F(ResourceParserTest, ParseEscapedString) {
EXPECT_EQ(std::u16string(u"?123"), *str->value);
}
+TEST_F(ResourceParserTest, ParseNull) {
+ std::string input = "<integer name=\"foo\">@null</integer>";
+ ASSERT_TRUE(testParse(input));
+
+ // The Android runtime treats a value of android::Res_value::TYPE_NULL as
+ // a non-existing value, and this causes problems in styles when trying to resolve
+ // an attribute. Null values must be encoded as android::Res_value::TYPE_REFERENCE
+ // with a data value of 0.
+ const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
+ u"android", ResourceType::kInteger, u"foo" });
+ ASSERT_NE(nullptr, integer);
+ EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType);
+ EXPECT_EQ(0u, integer->value.data);
+}
+
+TEST_F(ResourceParserTest, ParseEmpty) {
+ std::string input = "<integer name=\"foo\">@empty</integer>";
+ ASSERT_TRUE(testParse(input));
+
+ const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
+ u"android", ResourceType::kInteger, u"foo" });
+ ASSERT_NE(nullptr, integer);
+ EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType);
+ EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data);
+}
+
TEST_F(ResourceParserTest, ParseAttr) {
std::string input = "<attr name=\"foo\" format=\"string\"/>\n"
"<attr name=\"bar\"/>";