blob: ef99355e5b5fb8c6da429dcac5e1566781f30559 [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
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 "link/Linkers.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070018
Adam Lesinski64587af2016-02-18 18:33:06 -080019#include "test/Test.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070020
Adam Lesinskia45893a2017-05-30 15:19:02 -070021using ::testing::IsNull;
22using ::testing::NotNull;
23
Adam Lesinski1ab598f2015-08-14 14:26:04 -070024namespace aapt {
25
26class XmlReferenceLinkerTest : public ::testing::Test {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070027 public:
28 void SetUp() override {
Adam Lesinski38665542016-12-28 12:25:46 -050029 context_ = test::ContextBuilder()
30 .SetCompilationPackage("com.app.test")
31 .SetNameManglerPolicy(NameManglerPolicy{"com.app.test", {"com.android.support"}})
32 .AddSymbolSource(
33 test::StaticSymbolSourceBuilder()
34 .AddPublicSymbol("android:attr/layout_width", ResourceId(0x01010000),
35 test::AttributeBuilder()
36 .SetTypeMask(android::ResTable_map::TYPE_ENUM |
37 android::ResTable_map::TYPE_DIMENSION)
38 .AddItem("match_parent", 0xffffffff)
39 .Build())
40 .AddPublicSymbol("android:attr/background", ResourceId(0x01010001),
41 test::AttributeBuilder()
42 .SetTypeMask(android::ResTable_map::TYPE_COLOR)
43 .Build())
44 .AddPublicSymbol("android:attr/attr", ResourceId(0x01010002),
45 test::AttributeBuilder().Build())
46 .AddPublicSymbol("android:attr/text", ResourceId(0x01010003),
47 test::AttributeBuilder()
48 .SetTypeMask(android::ResTable_map::TYPE_STRING)
49 .Build())
Adam Lesinski1ab598f2015-08-14 14:26:04 -070050
Adam Lesinski38665542016-12-28 12:25:46 -050051 // Add one real symbol that was introduces in v21
52 .AddPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435),
53 test::AttributeBuilder().Build())
Adam Lesinski1ab598f2015-08-14 14:26:04 -070054
Adam Lesinski38665542016-12-28 12:25:46 -050055 // Private symbol.
56 .AddSymbol("android:color/hidden", ResourceId(0x01020001))
Adam Lesinski467f1712015-11-16 17:35:44 -080057
Adam Lesinski38665542016-12-28 12:25:46 -050058 .AddPublicSymbol("android:id/id", ResourceId(0x01030000))
59 .AddSymbol("com.app.test:id/id", ResourceId(0x7f030000))
60 .AddSymbol("com.app.test:color/green", ResourceId(0x7f020000))
61 .AddSymbol("com.app.test:color/red", ResourceId(0x7f020001))
62 .AddSymbol("com.app.test:attr/colorAccent", ResourceId(0x7f010000),
63 test::AttributeBuilder()
64 .SetTypeMask(android::ResTable_map::TYPE_COLOR)
65 .Build())
66 .AddPublicSymbol("com.app.test:attr/com.android.support$colorAccent",
67 ResourceId(0x7f010001),
68 test::AttributeBuilder()
69 .SetTypeMask(android::ResTable_map::TYPE_COLOR)
70 .Build())
71 .AddPublicSymbol("com.app.test:attr/attr", ResourceId(0x7f010002),
72 test::AttributeBuilder().Build())
73 .Build())
74 .Build();
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -070076
Adam Lesinskicacb28f2016-10-19 12:18:14 -070077 protected:
Adam Lesinskice5e56e2016-10-21 17:56:45 -070078 std::unique_ptr<IAaptContext> context_;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070079};
80
Adam Lesinski1ab598f2015-08-14 14:26:04 -070081TEST_F(XmlReferenceLinkerTest, LinkBasicAttributes) {
Adam Lesinski6b372992017-08-09 10:54:23 -070082 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
83 <View xmlns:android="http://schemas.android.com/apk/res/android"
84 android:layout_width="match_parent"
85 android:background="@color/green"
86 android:text="hello"
87 android:attr="\?hello"
88 nonAaptAttr="1"
89 nonAaptAttrRef="@id/id"
90 class="hello" />)");
Adam Lesinski1ab598f2015-08-14 14:26:04 -070091
Adam Lesinskicacb28f2016-10-19 12:18:14 -070092 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070093 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070094
Adam Lesinski6b372992017-08-09 10:54:23 -070095 xml::Element* view_el = doc->root.get();
Adam Lesinskia45893a2017-05-30 15:19:02 -070096 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -070097
Adam Lesinski38665542016-12-28 12:25:46 -050098 xml::Attribute* xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "layout_width");
Adam Lesinskia45893a2017-05-30 15:19:02 -070099 ASSERT_THAT(xml_attr, NotNull());
100 ASSERT_TRUE(xml_attr->compiled_attribute);
101 EXPECT_EQ(make_value(ResourceId(0x01010000)), xml_attr->compiled_attribute.value().id);
102 EXPECT_THAT(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()), NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700103
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700104 xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "background");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700105 ASSERT_THAT(xml_attr, NotNull());
106 ASSERT_TRUE(xml_attr->compiled_attribute);
107 EXPECT_EQ(make_value(ResourceId(0x01010001)), xml_attr->compiled_attribute.value().id);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700108 Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
Adam Lesinskia45893a2017-05-30 15:19:02 -0700109 ASSERT_THAT(ref, NotNull());
110 EXPECT_EQ(make_value(test::ParseNameOrDie("color/green")), ref->name); // Make sure the name
111 // didn't change.
112 EXPECT_EQ(make_value(ResourceId(0x7f020000)), ref->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700113
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700114 xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "text");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700115 ASSERT_THAT(xml_attr, NotNull());
116 EXPECT_TRUE(xml_attr->compiled_attribute);
117 EXPECT_THAT(xml_attr->compiled_value, IsNull()); // Strings don't get compiled for memory sake.
Adam Lesinski38665542016-12-28 12:25:46 -0500118
Adam Lesinski48448e82017-04-26 15:13:52 -0700119 xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "attr");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700120 ASSERT_THAT(xml_attr, NotNull());
121 EXPECT_TRUE(xml_attr->compiled_attribute);
122 EXPECT_THAT(xml_attr->compiled_value, IsNull()); // Should be a plain string.
Adam Lesinski48448e82017-04-26 15:13:52 -0700123
Adam Lesinski38665542016-12-28 12:25:46 -0500124 xml_attr = view_el->FindAttribute("", "nonAaptAttr");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700125 ASSERT_THAT(xml_attr, NotNull());
126 EXPECT_FALSE(xml_attr->compiled_attribute);
127 EXPECT_THAT(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()), NotNull());
Adam Lesinski38665542016-12-28 12:25:46 -0500128
129 xml_attr = view_el->FindAttribute("", "nonAaptAttrRef");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700130 ASSERT_THAT(xml_attr, NotNull());
131 EXPECT_FALSE(xml_attr->compiled_attribute);
132 EXPECT_THAT(ValueCast<Reference>(xml_attr->compiled_value.get()), NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700133
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700134 xml_attr = view_el->FindAttribute("", "class");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700135 ASSERT_THAT(xml_attr, NotNull());
136 EXPECT_FALSE(xml_attr->compiled_attribute);
137 EXPECT_THAT(xml_attr->compiled_value, IsNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138}
139
Adam Lesinski467f1712015-11-16 17:35:44 -0800140TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreNotLinked) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700141 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
142 <View xmlns:android="http://schemas.android.com/apk/res/android"
143 android:colorAccent="@android:color/hidden" />)");
Adam Lesinski467f1712015-11-16 17:35:44 -0800144
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700146 ASSERT_FALSE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski467f1712015-11-16 17:35:44 -0800147}
148
Adam Lesinski38665542016-12-28 12:25:46 -0500149TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreLinkedWhenReferenceHasStarPrefix) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700150 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinski467f1712015-11-16 17:35:44 -0800151 <View xmlns:android="http://schemas.android.com/apk/res/android"
Adam Lesinski6b372992017-08-09 10:54:23 -0700152 android:colorAccent="@*android:color/hidden" />)");
Adam Lesinski467f1712015-11-16 17:35:44 -0800153
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700154 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700155 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski467f1712015-11-16 17:35:44 -0800156}
157
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700158TEST_F(XmlReferenceLinkerTest, LinkMangledAttributes) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700159 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
160 <View xmlns:support="http://schemas.android.com/apk/res/com.android.support"
161 support:colorAccent="#ff0000" />)");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700162
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700163 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700164 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700165
Adam Lesinski6b372992017-08-09 10:54:23 -0700166 xml::Element* view_el = doc->root.get();
Adam Lesinskia45893a2017-05-30 15:19:02 -0700167 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700168
Adam Lesinski38665542016-12-28 12:25:46 -0500169 xml::Attribute* xml_attr =
170 view_el->FindAttribute(xml::BuildPackageNamespace("com.android.support"), "colorAccent");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700171 ASSERT_THAT(xml_attr, NotNull());
172 ASSERT_TRUE(xml_attr->compiled_attribute);
173 EXPECT_EQ(make_value(ResourceId(0x7f010001)), xml_attr->compiled_attribute.value().id);
174 EXPECT_THAT(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()), NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700175}
176
177TEST_F(XmlReferenceLinkerTest, LinkAutoResReference) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700178 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
179 <View xmlns:app="http://schemas.android.com/apk/res-auto"
180 app:colorAccent="@app:color/red" />)");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700181
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700182 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700183 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700184
Adam Lesinski6b372992017-08-09 10:54:23 -0700185 xml::Element* view_el = doc->root.get();
Adam Lesinskia45893a2017-05-30 15:19:02 -0700186 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700187
Adam Lesinski38665542016-12-28 12:25:46 -0500188 xml::Attribute* xml_attr = view_el->FindAttribute(xml::kSchemaAuto, "colorAccent");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700189 ASSERT_THAT(xml_attr, NotNull());
190 ASSERT_TRUE(xml_attr->compiled_attribute);
191 EXPECT_EQ(make_value(ResourceId(0x7f010000)), xml_attr->compiled_attribute.value().id);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700192 Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
Adam Lesinskia45893a2017-05-30 15:19:02 -0700193 ASSERT_THAT(ref, NotNull());
194 ASSERT_TRUE(ref->name);
195 EXPECT_EQ(make_value(ResourceId(0x7f020001)), ref->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700196}
197
198TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700199 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
200 <View xmlns:app="http://schemas.android.com/apk/res/android" app:attr="@app:id/id">
201 <View xmlns:app="http://schemas.android.com/apk/res/com.app.test" app:attr="@app:id/id"/>
202 </View>)");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700203
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700204 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700205 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700206
Adam Lesinski6b372992017-08-09 10:54:23 -0700207 xml::Element* view_el = doc->root.get();
Adam Lesinskia45893a2017-05-30 15:19:02 -0700208 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700209
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210 // All attributes and references in this element should be referring to
211 // "android" (0x01).
Adam Lesinski38665542016-12-28 12:25:46 -0500212 xml::Attribute* xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "attr");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700213 ASSERT_THAT(xml_attr, NotNull());
214 ASSERT_TRUE(xml_attr->compiled_attribute);
215 EXPECT_EQ(make_value(ResourceId(0x01010002)), xml_attr->compiled_attribute.value().id);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700216 Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
Adam Lesinskia45893a2017-05-30 15:19:02 -0700217 ASSERT_THAT(ref, NotNull());
218 EXPECT_EQ(make_value(ResourceId(0x01030000)), ref->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700219
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700220 ASSERT_FALSE(view_el->GetChildElements().empty());
221 view_el = view_el->GetChildElements().front();
Adam Lesinskia45893a2017-05-30 15:19:02 -0700222 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700223
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700224 // All attributes and references in this element should be referring to
225 // "com.app.test" (0x7f).
Adam Lesinski38665542016-12-28 12:25:46 -0500226 xml_attr = view_el->FindAttribute(xml::BuildPackageNamespace("com.app.test"), "attr");
Adam Lesinskia45893a2017-05-30 15:19:02 -0700227 ASSERT_THAT(xml_attr, NotNull());
228 ASSERT_TRUE(xml_attr->compiled_attribute);
229 EXPECT_EQ(make_value(ResourceId(0x7f010002)), xml_attr->compiled_attribute.value().id);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700230 ref = ValueCast<Reference>(xml_attr->compiled_value.get());
Adam Lesinskia45893a2017-05-30 15:19:02 -0700231 ASSERT_THAT(ref, NotNull());
232 EXPECT_EQ(make_value(ResourceId(0x7f030000)), ref->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700233}
234
235TEST_F(XmlReferenceLinkerTest, LinkViewWithLocalPackageAndAliasOfTheSameName) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700236 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
237 <View xmlns:android="http://schemas.android.com/apk/res/com.app.test"
238 android:attr="@id/id"/>)");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700239
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700240 XmlReferenceLinker linker;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700241 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700242
Adam Lesinski6b372992017-08-09 10:54:23 -0700243 xml::Element* view_el = doc->root.get();
Adam Lesinskia45893a2017-05-30 15:19:02 -0700244 ASSERT_THAT(view_el, NotNull());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700245
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700246 // All attributes and references in this element should be referring to
247 // "com.app.test" (0x7f).
Adam Lesinskia45893a2017-05-30 15:19:02 -0700248 xml::Attribute* xml_attr = view_el->FindAttribute(xml::BuildPackageNamespace("com.app.test"), "attr");
249 ASSERT_THAT(xml_attr, NotNull());
250 ASSERT_TRUE(xml_attr->compiled_attribute);
251 EXPECT_EQ(make_value(ResourceId(0x7f010002)), xml_attr->compiled_attribute.value().id);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700252 Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
Adam Lesinskia45893a2017-05-30 15:19:02 -0700253 ASSERT_THAT(ref, NotNull());
254 EXPECT_EQ(make_value(ResourceId(0x7f030000)), ref->id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700255}
256
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700257} // namespace aapt