Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include "flatten/XmlFlattener.h" |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 18 | |
| 19 | #include "androidfw/ResourceTypes.h" |
| 20 | |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 21 | #include "link/Linkers.h" |
Adam Lesinski | d0f116b | 2016-07-08 15:00:32 -0700 | [diff] [blame] | 22 | #include "test/Test.h" |
Adam Lesinski | 467f171 | 2015-11-16 17:35:44 -0800 | [diff] [blame] | 23 | #include "util/BigBuffer.h" |
| 24 | #include "util/Util.h" |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 25 | |
Adam Lesinski | d5083f6 | 2017-01-16 15:07:21 -0800 | [diff] [blame] | 26 | using android::StringPiece16; |
| 27 | |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 28 | namespace aapt { |
| 29 | |
| 30 | class XmlFlattenerTest : public ::testing::Test { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 31 | public: |
| 32 | void SetUp() override { |
Adam Lesinski | f34b6f4 | 2017-03-03 16:33:26 -0800 | [diff] [blame] | 33 | context_ = test::ContextBuilder() |
| 34 | .SetCompilationPackage("com.app.test") |
| 35 | .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) |
| 36 | .AddSymbolSource( |
| 37 | test::StaticSymbolSourceBuilder() |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 38 | .AddPublicSymbol("android:attr/id", ResourceId(0x010100d0), |
| 39 | test::AttributeBuilder().Build()) |
Adam Lesinski | f34b6f4 | 2017-03-03 16:33:26 -0800 | [diff] [blame] | 40 | .AddSymbol("com.app.test:id/id", ResourceId(0x7f020000)) |
| 41 | .AddPublicSymbol("android:attr/paddingStart", ResourceId(0x010103b3), |
| 42 | test::AttributeBuilder().Build()) |
| 43 | .AddPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435), |
| 44 | test::AttributeBuilder().Build()) |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 45 | .AddSymbol("com.app.test.feature:id/foo", ResourceId(0x80020000)) |
| 46 | .AddSymbol("com.app.test.feature:attr/foo", ResourceId(0x80010000), |
| 47 | test::AttributeBuilder().Build()) |
Adam Lesinski | f34b6f4 | 2017-03-03 16:33:26 -0800 | [diff] [blame] | 48 | .Build()) |
| 49 | .Build(); |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 50 | } |
| 51 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 52 | ::testing::AssertionResult Flatten(xml::XmlResource* doc, |
| 53 | android::ResXMLTree* out_tree, |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 54 | const XmlFlattenerOptions& options = {}) { |
| 55 | using namespace android; // For NO_ERROR on windows because it is a macro. |
| 56 | |
| 57 | BigBuffer buffer(1024); |
| 58 | XmlFlattener flattener(&buffer, options); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 59 | if (!flattener.Consume(context_.get(), doc)) { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 60 | return ::testing::AssertionFailure() << "failed to flatten XML Tree"; |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 61 | } |
| 62 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 63 | std::unique_ptr<uint8_t[]> data = util::Copy(buffer); |
| 64 | if (out_tree->setTo(data.get(), buffer.size(), true) != NO_ERROR) { |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 65 | return ::testing::AssertionFailure() << "flattened XML is corrupt"; |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 66 | } |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 67 | return ::testing::AssertionSuccess(); |
| 68 | } |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 69 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 70 | protected: |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 71 | std::unique_ptr<test::Context> context_; |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 72 | }; |
| 73 | |
| 74 | TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 75 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 76 | <View xmlns:test="http://com.test" |
| 77 | attr="hey"> |
| 78 | <Layout test:hello="hi" /> |
Adam Lesinski | ac6edc5 | 2017-03-02 19:31:28 -0800 | [diff] [blame] | 79 | <Layout>Some text\\</Layout> |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 80 | </View>)EOF"); |
| 81 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 82 | android::ResXMLTree tree; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 83 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 84 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 85 | ASSERT_EQ(android::ResXMLTree::START_NAMESPACE, tree.next()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 86 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 87 | size_t len; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 88 | const char16_t* namespace_prefix = tree.getNamespacePrefix(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 89 | EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 90 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 91 | const char16_t* namespace_uri = tree.getNamespaceUri(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 92 | ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 93 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 94 | ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 95 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 96 | ASSERT_EQ(nullptr, tree.getElementNamespace(&len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 97 | const char16_t* tag_name = tree.getElementName(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 98 | EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 99 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 100 | ASSERT_EQ(1u, tree.getAttributeCount()); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 101 | ASSERT_EQ(nullptr, tree.getAttributeNamespace(0, &len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 102 | const char16_t* attr_name = tree.getAttributeName(0, &len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 103 | EXPECT_EQ(StringPiece16(u"attr"), StringPiece16(attr_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 104 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 105 | EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr", StringPiece16(u"attr").size())); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 106 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 107 | ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 108 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 109 | ASSERT_EQ(nullptr, tree.getElementNamespace(&len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 110 | tag_name = tree.getElementName(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 111 | EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 112 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 113 | ASSERT_EQ(1u, tree.getAttributeCount()); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 114 | const char16_t* attr_namespace = tree.getAttributeNamespace(0, &len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 115 | EXPECT_EQ(StringPiece16(u"http://com.test"), StringPiece16(attr_namespace, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 116 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 117 | attr_name = tree.getAttributeName(0, &len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 118 | EXPECT_EQ(StringPiece16(u"hello"), StringPiece16(attr_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 119 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 120 | ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next()); |
| 121 | ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 122 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 123 | ASSERT_EQ(nullptr, tree.getElementNamespace(&len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 124 | tag_name = tree.getElementName(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 125 | EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len)); |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 126 | ASSERT_EQ(0u, tree.getAttributeCount()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 127 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 128 | ASSERT_EQ(android::ResXMLTree::TEXT, tree.next()); |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 129 | const char16_t* text = tree.getText(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 130 | EXPECT_EQ(StringPiece16(u"Some text\\"), StringPiece16(text, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 131 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 132 | ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next()); |
| 133 | ASSERT_EQ(nullptr, tree.getElementNamespace(&len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 134 | tag_name = tree.getElementName(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 135 | EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 136 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 137 | ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next()); |
| 138 | ASSERT_EQ(nullptr, tree.getElementNamespace(&len)); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 139 | tag_name = tree.getElementName(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 140 | EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 141 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 142 | ASSERT_EQ(android::ResXMLTree::END_NAMESPACE, tree.next()); |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 143 | namespace_prefix = tree.getNamespacePrefix(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 144 | EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 145 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 146 | namespace_uri = tree.getNamespaceUri(&len); |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 147 | ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 148 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 149 | ASSERT_EQ(android::ResXMLTree::END_DOCUMENT, tree.next()); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 150 | } |
| 151 | |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 152 | TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) { |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 153 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 154 | <View xmlns:tools="http://schemas.android.com/tools" |
| 155 | xmlns:foo="http://schemas.android.com/foo" |
| 156 | foo:bar="Foo" |
| 157 | tools:ignore="MissingTranslation"/>)EOF"); |
| 158 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 159 | android::ResXMLTree tree; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 160 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 161 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 162 | ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 163 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 164 | size_t len; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 165 | const char16_t* namespace_prefix = tree.getNamespacePrefix(&len); |
| 166 | EXPECT_EQ(StringPiece16(namespace_prefix, len), u"foo"); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 167 | |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 168 | const char16_t* namespace_uri = tree.getNamespaceUri(&len); |
| 169 | ASSERT_EQ(StringPiece16(namespace_uri, len), |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 170 | u"http://schemas.android.com/foo"); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 171 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 172 | ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 173 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 174 | EXPECT_EQ(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"), |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 175 | android::NAME_NOT_FOUND); |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 176 | EXPECT_GE(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), 0); |
Alexandria Cornwall | a9ff140 | 2016-08-03 09:44:10 -0700 | [diff] [blame] | 177 | } |
| 178 | |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 179 | TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) { |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 180 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 181 | <View xmlns:android="http://schemas.android.com/apk/res/android" |
| 182 | android:id="@id/id" |
| 183 | class="str" |
| 184 | style="@id/id"/>)EOF"); |
| 185 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 186 | android::ResXMLTree tree; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 187 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 188 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 189 | while (tree.next() != android::ResXMLTree::START_TAG) { |
| 190 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); |
| 191 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT); |
| 192 | } |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 193 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 194 | EXPECT_EQ(tree.indexOfClass(), 0); |
| 195 | EXPECT_EQ(tree.indexOfStyle(), 1); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 196 | } |
| 197 | |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 198 | // The device ResXMLParser in libandroidfw differentiates between empty namespace and null |
| 199 | // namespace. |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 200 | TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) { |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 201 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"android\"/>"); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 202 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 203 | android::ResXMLTree tree; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 204 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 205 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 206 | while (tree.next() != android::ResXMLTree::START_TAG) { |
| 207 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); |
| 208 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT); |
| 209 | } |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 210 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 211 | const StringPiece16 kPackage = u"package"; |
Adam Lesinski | c744ae8 | 2017-05-17 19:28:38 -0700 | [diff] [blame] | 212 | EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), 0); |
Adam Lesinski | 1ab598f | 2015-08-14 14:26:04 -0700 | [diff] [blame] | 213 | } |
| 214 | |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 215 | TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) { |
Adam Lesinski | c744ae8 | 2017-05-17 19:28:38 -0700 | [diff] [blame] | 216 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"\"/>"); |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 217 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 218 | android::ResXMLTree tree; |
Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 219 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 220 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 221 | while (tree.next() != android::ResXMLTree::START_TAG) { |
| 222 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); |
| 223 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT); |
| 224 | } |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 225 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 226 | const StringPiece16 kPackage = u"package"; |
Adam Lesinski | c744ae8 | 2017-05-17 19:28:38 -0700 | [diff] [blame] | 227 | ssize_t idx = tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()); |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 228 | ASSERT_GE(idx, 0); |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 229 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 230 | size_t len; |
| 231 | EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len)); |
Adam Lesinski | e1fda9a | 2016-07-01 14:51:51 -0700 | [diff] [blame] | 232 | } |
| 233 | |
Adam Lesinski | 4ca5697 | 2017-04-26 21:49:53 -0700 | [diff] [blame] | 234 | TEST_F(XmlFlattenerTest, FlattenNonStandardPackageId) { |
| 235 | context_->SetCompilationPackage("com.app.test.feature"); |
| 236 | context_->SetPackageId(0x80); |
| 237 | context_->SetNameManglerPolicy({"com.app.test.feature"}); |
| 238 | |
| 239 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"EOF( |
| 240 | <View xmlns:android="http://schemas.android.com/apk/res/android" |
| 241 | xmlns:app="http://schemas.android.com/apk/res-auto" |
| 242 | android:id="@id/foo" |
| 243 | app:foo="@id/foo" />)EOF"); |
| 244 | |
| 245 | XmlReferenceLinker linker; |
| 246 | ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); |
| 247 | |
| 248 | // The tree needs a custom DynamicRefTable since it is not using a standard app ID (0x7f). |
| 249 | android::DynamicRefTable dynamic_ref_table; |
| 250 | dynamic_ref_table.addMapping(0x80, 0x80); |
| 251 | |
| 252 | android::ResXMLTree tree(&dynamic_ref_table); |
| 253 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
| 254 | |
| 255 | while (tree.next() != android::ResXMLTree::START_TAG) { |
| 256 | ASSERT_NE(android::ResXMLTree::BAD_DOCUMENT, tree.getEventType()); |
| 257 | ASSERT_NE(android::ResXMLTree::END_DOCUMENT, tree.getEventType()); |
| 258 | } |
| 259 | |
| 260 | ssize_t idx; |
| 261 | |
| 262 | idx = tree.indexOfAttribute(xml::kSchemaAndroid, "id"); |
| 263 | ASSERT_GE(idx, 0); |
| 264 | EXPECT_EQ(idx, tree.indexOfID()); |
| 265 | EXPECT_EQ(ResourceId(0x010100d0), ResourceId(tree.getAttributeNameResID(idx))); |
| 266 | |
| 267 | idx = tree.indexOfAttribute(xml::kSchemaAuto, "foo"); |
| 268 | ASSERT_GE(idx, 0); |
| 269 | EXPECT_EQ(ResourceId(0x80010000), ResourceId(tree.getAttributeNameResID(idx))); |
| 270 | EXPECT_EQ(android::Res_value::TYPE_REFERENCE, tree.getAttributeDataType(idx)); |
| 271 | EXPECT_EQ(ResourceId(0x80020000), tree.getAttributeData(idx)); |
| 272 | } |
| 273 | |
Adam Lesinski | 48448e8 | 2017-04-26 15:13:52 -0700 | [diff] [blame] | 274 | TEST_F(XmlFlattenerTest, ProcessEscapedStrings) { |
| 275 | std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom( |
| 276 | R"EOF(<element value="\?hello" pattern="\\d{5}">\\d{5}</element>)EOF"); |
| 277 | |
| 278 | android::ResXMLTree tree; |
| 279 | ASSERT_TRUE(Flatten(doc.get(), &tree)); |
| 280 | |
| 281 | while (tree.next() != android::ResXMLTree::START_TAG) { |
| 282 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); |
| 283 | ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT); |
| 284 | } |
| 285 | |
| 286 | const StringPiece16 kValue = u"value"; |
| 287 | const StringPiece16 kPattern = u"pattern"; |
| 288 | |
| 289 | size_t len; |
| 290 | ssize_t idx; |
| 291 | const char16_t* str16; |
| 292 | |
| 293 | idx = tree.indexOfAttribute(nullptr, 0, kValue.data(), kValue.size()); |
| 294 | ASSERT_GE(idx, 0); |
| 295 | str16 = tree.getAttributeStringValue(idx, &len); |
| 296 | ASSERT_NE(nullptr, str16); |
| 297 | EXPECT_EQ(StringPiece16(u"?hello"), StringPiece16(str16, len)); |
| 298 | |
| 299 | idx = tree.indexOfAttribute(nullptr, 0, kPattern.data(), kPattern.size()); |
| 300 | ASSERT_GE(idx, 0); |
| 301 | str16 = tree.getAttributeStringValue(idx, &len); |
| 302 | ASSERT_NE(nullptr, str16); |
| 303 | EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len)); |
| 304 | |
| 305 | ASSERT_EQ(android::ResXMLTree::TEXT, tree.next()); |
| 306 | str16 = tree.getText(&len); |
| 307 | ASSERT_NE(nullptr, str16); |
| 308 | EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len)); |
| 309 | } |
| 310 | |
Adam Lesinski | cacb28f | 2016-10-19 12:18:14 -0700 | [diff] [blame] | 311 | } // namespace aapt |