11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/* 21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License. 61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at 71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software 111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and 141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License. 151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 174670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski#include "format/binary/XmlFlattener.h" 18ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 19ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h" 20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "link/Linkers.h" 22d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include "test/Test.h" 23467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "util/BigBuffer.h" 24467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "util/Util.h" 251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 26fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::aapt::test::StrEq; 27fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::android::StringPiece16; 28fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::testing::Eq; 29fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::testing::Ge; 30fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::testing::IsNull; 31fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::testing::Ne; 32fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinskiusing ::testing::NotNull; 33d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt { 351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass XmlFlattenerTest : public ::testing::Test { 37cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 38cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski void SetUp() override { 39f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski context_ = test::ContextBuilder() 40f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .SetCompilationPackage("com.app.test") 41f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) 42f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .AddSymbolSource( 43f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski test::StaticSymbolSourceBuilder() 444ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski .AddPublicSymbol("android:attr/id", ResourceId(0x010100d0), 454ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski test::AttributeBuilder().Build()) 46f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .AddSymbol("com.app.test:id/id", ResourceId(0x7f020000)) 47f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .AddPublicSymbol("android:attr/paddingStart", ResourceId(0x010103b3), 48f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski test::AttributeBuilder().Build()) 49f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .AddPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435), 50f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski test::AttributeBuilder().Build()) 514ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski .AddSymbol("com.app.test.feature:id/foo", ResourceId(0x80020000)) 524ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski .AddSymbol("com.app.test.feature:attr/foo", ResourceId(0x80010000), 534ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski test::AttributeBuilder().Build()) 54f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .Build()) 55f34b6f4f2b969b47a3f371eb9549e92ef1680d91Adam Lesinski .Build(); 56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 584670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski ::testing::AssertionResult Flatten(xml::XmlResource* doc, android::ResXMLTree* out_tree, 59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const XmlFlattenerOptions& options = {}) { 60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski using namespace android; // For NO_ERROR on windows because it is a macro. 61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BigBuffer buffer(1024); 63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski XmlFlattener flattener(&buffer, options); 64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!flattener.Consume(context_.get(), doc)) { 65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return ::testing::AssertionFailure() << "failed to flatten XML Tree"; 661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<uint8_t[]> data = util::Copy(buffer); 69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (out_tree->setTo(data.get(), buffer.size(), true) != NO_ERROR) { 70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return ::testing::AssertionFailure() << "flattened XML is corrupt"; 711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return ::testing::AssertionSuccess(); 73cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 741ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski protected: 764ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski std::unique_ptr<test::Context> context_; 771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 791ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { 80fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"( 81fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski <View xmlns:test="http://com.test" attr="hey"> 82fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski <Layout test:hello="hi" /> 83fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski <Layout>Some text\\</Layout> 84fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski </View>)"); 851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski android::ResXMLTree tree; 87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 88fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE)); 891ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size_t len; 91fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test")); 92fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test")); 931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 94fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 95fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 96fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementName(&len), StrEq(u"View")); 971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 98fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 99fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeNamespace(0, &len), IsNull()); 100fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"attr")); 1011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 102fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski const StringPiece16 kAttr(u"attr"); 103fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kAttr.data(), kAttr.size()), Eq(0)); 1041ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 105fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 106fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 107fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout")); 1081ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 109fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 110fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeNamespace(0, &len), StrEq(u"http://com.test")); 111fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"hello")); 1121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 113fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 114fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 1151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 116fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 117fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout")); 118fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(0u)); 1191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 120fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 121fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getText(&len), StrEq(u"Some text\\")); 1221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 123fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 124fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 125fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout")); 1261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 127fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 128fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 129fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getElementName(&len), StrEq(u"View")); 1301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 131fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_NAMESPACE)); 132fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test")); 133fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test")); 1341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 135fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT)); 1361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} 1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 138a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria CornwallTEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) { 139fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"( 140fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski <View xmlns:tools="http://schemas.android.com/tools" 141fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski xmlns:foo="http://schemas.android.com/foo" 142fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski foo:bar="Foo" 143fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski tools:ignore="MissingTranslation"/>)"); 144a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria Cornwall 145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski android::ResXMLTree tree; 146ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 147fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE)); 148a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria Cornwall 149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size_t len; 150fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"foo")); 151fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://schemas.android.com/foo")); 152fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 153a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria Cornwall 154fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"), 155fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski Eq(android::NAME_NOT_FOUND)); 156fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), Ge(0)); 157a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria Cornwall} 158a9ff14098b9d938aec86cf58abbdd3c4dc0779ccAlexandria Cornwall 1591ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) { 160fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"( 161fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski <View xmlns:android="http://schemas.android.com/apk/res/android" 162fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski android:id="@id/id" 163fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski class="str" 164fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski style="@id/id"/>)"); 1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski android::ResXMLTree tree; 167ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 170fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 171fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 172cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 174fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfClass(), Eq(0)); 175fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfStyle(), Eq(1)); 1761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} 1771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1784ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski// The device ResXMLParser in libandroidfw differentiates between empty namespace and null 1794ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski// namespace. 1801ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) { 181fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package="android"/>)"); 1821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 183cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski android::ResXMLTree tree; 184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 1851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 186cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 187fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 188fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 189cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1901ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 191cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const StringPiece16 kPackage = u"package"; 192fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), Ge(0)); 1931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} 1941ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 195e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam LesinskiTEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) { 196fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package=""/>)"); 197e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski 198cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski android::ResXMLTree tree; 199ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 200e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski 201cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 202fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 203fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 204cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 205e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski 206cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const StringPiece16 kPackage = u"package"; 207c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski ssize_t idx = tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()); 208fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 209e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski 210cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size_t len; 211fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(idx, &len), NotNull()); 212e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski} 213e1fda9aec4337deb93ae7675e7c4a96d3172464dAdam Lesinski 2144ca56978a9aea3f021a54ed9265de10811984d94Adam LesinskiTEST_F(XmlFlattenerTest, FlattenNonStandardPackageId) { 2154ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski context_->SetCompilationPackage("com.app.test.feature"); 2164ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski context_->SetPackageId(0x80); 2174ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski context_->SetNameManglerPolicy({"com.app.test.feature"}); 2184ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 219fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"( 2204ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski <View xmlns:android="http://schemas.android.com/apk/res/android" 2214ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski xmlns:app="http://schemas.android.com/apk/res-auto" 2224ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski android:id="@id/foo" 223fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski app:foo="@id/foo" />)"); 2244ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2254ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski XmlReferenceLinker linker; 2264ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); 2274ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2284ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski // The tree needs a custom DynamicRefTable since it is not using a standard app ID (0x7f). 2294ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski android::DynamicRefTable dynamic_ref_table; 2304ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski dynamic_ref_table.addMapping(0x80, 0x80); 2314ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2324ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski android::ResXMLTree tree(&dynamic_ref_table); 2334ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 2344ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2354ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 236fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 237fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 2384ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski } 2394ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2404ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski ssize_t idx; 2414ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2424ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski idx = tree.indexOfAttribute(xml::kSchemaAndroid, "id"); 243fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 244fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.indexOfID(), Eq(idx)); 245fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x010100d0u)); 2464ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 2474ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski idx = tree.indexOfAttribute(xml::kSchemaAuto, "foo"); 248fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 249fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x80010000u)); 250fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(idx), Eq(android::Res_value::TYPE_REFERENCE)); 251fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeData(idx), Eq(int32_t(0x80020000))); 2524ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski} 2534ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski 25448448e8a310e72eb2846ad0f86672ce4f0b47e47Adam LesinskiTEST_F(XmlFlattenerTest, ProcessEscapedStrings) { 25548448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom( 256fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski R"(<element value="\?hello" pattern="\\d{5}" other=""">\\d{5}</element>)"); 25748448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 25848448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski android::ResXMLTree tree; 25948448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree)); 26048448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 26148448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 262fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 263fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 26448448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski } 26548448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 26648448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski const StringPiece16 kValue = u"value"; 26748448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski const StringPiece16 kPattern = u"pattern"; 268fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski const StringPiece16 kOther = u"other"; 26948448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 27048448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski size_t len; 27148448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski ssize_t idx; 27248448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 27348448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski idx = tree.indexOfAttribute(nullptr, 0, kValue.data(), kValue.size()); 274fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 275fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"?hello")); 27648448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 27748448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski idx = tree.indexOfAttribute(nullptr, 0, kPattern.data(), kPattern.size()); 278fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 279fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\\d{5}")); 280fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski 281fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski idx = tree.indexOfAttribute(nullptr, 0, kOther.data(), kOther.size()); 282fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(idx, Ge(0)); 283fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\"")); 284fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski 285fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 286fba0cf2950a91726e475fb180090cc25bcb11a7aAdam Lesinski EXPECT_THAT(tree.getText(&len), StrEq(u"\\d{5}")); 28748448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski} 28848448e8a310e72eb2846ad0f86672ce4f0b47e47Adam Lesinski 2890dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan MitchellTEST_F(XmlFlattenerTest, ProcessQuotes) { 2900dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom( 2910dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell R"(<root> 2920dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>Regular text</item> 2930dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>"Text in double quotes"</item> 2940dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>'Text in single quotes'</item> 2950dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>Text containing "double quotes"</item> 2960dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>Text containing 'single quotes'</item> 2970dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell </root>)"); 2980dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 2990dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell size_t len; 3000dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell android::ResXMLTree tree; 3010dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3020dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell XmlFlattenerOptions options; 3030dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 3040dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3050dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3060dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3070dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3080dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3090dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"Regular text")); 3100dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3110dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3120dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3130dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3140dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3150dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"\"Text in double quotes\"")); 3160dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3170dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3180dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3190dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementNamespace(&len), IsNull()); 3200dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3210dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3220dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"'Text in single quotes'")); 3230dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3240dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3250dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3260dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3270dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3280dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"Text containing \"double quotes\"")); 3290dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3300dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3310dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3320dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3330dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3340dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"Text containing 'single quotes'")); 3350dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3360dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3370dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3380dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT)); 3390dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell} 3400dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3410dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan MitchellTEST_F(XmlFlattenerTest, ProcessWhitepspace) { 3420dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom( 3430dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell R"(<root> 3440dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> Compact Spaces </item> 3450dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> 3460dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell A 3470dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell </item> 3480dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>B </item> 3490dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item>C </item> 3500dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> D </item> 3510dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> E</item> 3520dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> F</item> 3530dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> G </item> 3540dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> H </item> 3550dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell<item> 3560dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan MitchellI 3570dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell</item> 3580dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell<item> 3590dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3600dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell J 3610dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3620dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell</item> 3630dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell <item> 3640dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell </item> 3650dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell </root>)"); 3660dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3670dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell size_t len; 3680dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell android::ResXMLTree tree; 3690dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3700dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell XmlFlattenerOptions options; 3710dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 3720dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3730dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3740dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3750dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3760dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3770dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" Compact Spaces ")); 3780dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3790dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3800dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3810dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3820dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3830dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" A ")); 3840dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3850dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3860dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3870dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3880dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3890dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"B ")); 3900dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3910dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3920dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3930dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 3940dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 3950dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u"C ")); 3960dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 3970dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 3980dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 3990dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4000dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4010dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" D ")); 4020dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4030dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4040dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4050dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4060dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4070dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" E")); 4080dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4090dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4100dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4110dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4120dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4130dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" F")); 4140dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4150dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4160dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4170dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4180dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4190dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" G ")); 4200dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4210dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4220dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4230dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4240dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4250dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" H ")); 4260dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4270dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4280dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4290dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4300dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4310dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" I ")); 4320dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4330dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4340dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4350dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4360dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT)); 4370dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getText(&len), StrEq(u" J ")); 4380dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4390dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4400dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG)); 4410dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell EXPECT_THAT(tree.getElementName(&len), StrEq(u"item")); 4420dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4430dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG)); 4440dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 4450dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT)); 4460dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell} 4470dcb20c72742a1de30b4984c4b8996d76cb7a428Ryan Mitchell 448e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenRawValueOnlyMakesCompiledValueToo) { 449e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)"); 450e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 451e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski // Raw values are kept when encoding an attribute with no compiled value, regardless of option. 452e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 453e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 454e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 455e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 456e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 457e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 458e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 459e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 460e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 461e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 462e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 463e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 464e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 465e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING)); 466e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0))); 467e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 468e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 469e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledStringValuePreservesRawValue) { 470e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)"); 471e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = 472e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski util::make_unique<String>(doc->string_pool.MakeRef("bar")); 473e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 474e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski // Raw values are kept when encoding a string anyways. 475e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 476e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 477e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 478e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 479e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 480e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 481e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 482e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 483e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 484e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 485e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 486e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 487e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 488e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING)); 489e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0))); 490e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 491e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 492e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionFalse) { 493e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)"); 494e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true); 495e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 496e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 497e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 498e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 499e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 500e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 501e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 502e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 503e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 504e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 505e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 506e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 507e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 508e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1)); 509e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN)); 510e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 511e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 512e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionTrue) { 513e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)"); 514e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true); 515e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 516e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 517e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = true; 518e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 519e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 520e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 521e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 522e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 523e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 524e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 525e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 526e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 527e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 528e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 529e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 530e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski size_t len; 531e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(0, &len), StrEq(u"true")); 532e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 533e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN)); 534e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 535e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 536cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 537