XmlFlattener_test.cpp revision e1094a2e232277a719025aa5c97c492502c34f5b
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 289e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenRawValueOnlyMakesCompiledValueToo) { 290e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)"); 291e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 292e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski // Raw values are kept when encoding an attribute with no compiled value, regardless of option. 293e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 294e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 295e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 296e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 297e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 298e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 299e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 300e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 301e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 302e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 303e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 304e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 305e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 306e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING)); 307e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0))); 308e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 309e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 310e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledStringValuePreservesRawValue) { 311e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)"); 312e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = 313e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski util::make_unique<String>(doc->string_pool.MakeRef("bar")); 314e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 315e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski // Raw values are kept when encoding a string anyways. 316e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 317e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 318e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 319e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 320e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 321e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 322e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 323e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 324e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 325e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 326e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 327e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 328e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 329e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING)); 330e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0))); 331e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 332e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 333e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionFalse) { 334e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)"); 335e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true); 336e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 337e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 338e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = false; 339e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 340e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 341e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 342e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 343e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 344e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 345e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 346e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 347e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 348e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 349e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1)); 350e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN)); 351e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 352e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 353e1094a2e232277a719025aa5c97c492502c34f5bAdam LesinskiTEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionTrue) { 354e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)"); 355e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true); 356e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 357e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski XmlFlattenerOptions options; 358e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski options.keep_raw_values = true; 359e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 360e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski android::ResXMLTree tree; 361e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_TRUE(Flatten(doc.get(), &tree, options)); 362e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 363e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski while (tree.next() != android::ResXMLTree::START_TAG) { 364e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT)); 365e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT)); 366e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski } 367e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 368e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski ASSERT_THAT(tree.getAttributeCount(), Eq(1u)); 369e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0)); 370e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 371e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski size_t len; 372e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeStringValue(0, &len), StrEq(u"true")); 373e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 374e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN)); 375e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski} 376e1094a2e232277a719025aa5c97c492502c34f5bAdam Lesinski 377cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 378