blob: 51eb62c2c0ff2c70a4562197c9fc811a2ccd36f8 [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 Lesinski64587af2016-02-18 18:33:06 -080018#include "test/Test.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070019
20namespace aapt {
21
22class XmlReferenceLinkerTest : public ::testing::Test {
23public:
24 void SetUp() override {
25 mContext = test::ContextBuilder()
Adam Lesinskid0f116b2016-07-08 15:00:32 -070026 .setCompilationPackage("com.app.test")
Adam Lesinski1ab598f2015-08-14 14:26:04 -070027 .setNameManglerPolicy(
Adam Lesinskid0f116b2016-07-08 15:00:32 -070028 NameManglerPolicy{ "com.app.test", { "com.android.support" } })
Adam Lesinski64587af2016-02-18 18:33:06 -080029 .addSymbolSource(test::StaticSymbolSourceBuilder()
Adam Lesinski58a20a62016-07-25 17:56:58 -070030 .addPublicSymbol("android:attr/layout_width", ResourceId(0x01010000),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031 test::AttributeBuilder()
32 .setTypeMask(android::ResTable_map::TYPE_ENUM |
33 android::ResTable_map::TYPE_DIMENSION)
Adam Lesinskid0f116b2016-07-08 15:00:32 -070034 .addItem("match_parent", 0xffffffff)
Adam Lesinski1ab598f2015-08-14 14:26:04 -070035 .build())
Adam Lesinski58a20a62016-07-25 17:56:58 -070036 .addPublicSymbol("android:attr/background", ResourceId(0x01010001),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070037 test::AttributeBuilder()
38 .setTypeMask(android::ResTable_map::TYPE_COLOR).build())
Adam Lesinski58a20a62016-07-25 17:56:58 -070039 .addPublicSymbol("android:attr/attr", ResourceId(0x01010002),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070040 test::AttributeBuilder().build())
Adam Lesinski58a20a62016-07-25 17:56:58 -070041 .addPublicSymbol("android:attr/text", ResourceId(0x01010003),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070042 test::AttributeBuilder()
43 .setTypeMask(android::ResTable_map::TYPE_STRING)
44 .build())
45
46 // Add one real symbol that was introduces in v21
Adam Lesinski58a20a62016-07-25 17:56:58 -070047 .addPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070048 test::AttributeBuilder().build())
49
Adam Lesinski467f1712015-11-16 17:35:44 -080050 // Private symbol.
Adam Lesinski58a20a62016-07-25 17:56:58 -070051 .addSymbol("android:color/hidden", ResourceId(0x01020001))
Adam Lesinski467f1712015-11-16 17:35:44 -080052
Adam Lesinski58a20a62016-07-25 17:56:58 -070053 .addPublicSymbol("android:id/id", ResourceId(0x01030000))
54 .addSymbol("com.app.test:id/id", ResourceId(0x7f030000))
55 .addSymbol("com.app.test:color/green", ResourceId(0x7f020000))
56 .addSymbol("com.app.test:color/red", ResourceId(0x7f020001))
57 .addSymbol("com.app.test:attr/colorAccent", ResourceId(0x7f010000),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070058 test::AttributeBuilder()
59 .setTypeMask(android::ResTable_map::TYPE_COLOR).build())
Adam Lesinski58a20a62016-07-25 17:56:58 -070060 .addPublicSymbol("com.app.test:attr/com.android.support$colorAccent",
Adam Lesinski1ab598f2015-08-14 14:26:04 -070061 ResourceId(0x7f010001), test::AttributeBuilder()
62 .setTypeMask(android::ResTable_map::TYPE_COLOR).build())
Adam Lesinski58a20a62016-07-25 17:56:58 -070063 .addPublicSymbol("com.app.test:attr/attr", ResourceId(0x7f010002),
Adam Lesinski1ab598f2015-08-14 14:26:04 -070064 test::AttributeBuilder().build())
65 .build())
66 .build();
67 }
68
69protected:
70 std::unique_ptr<IAaptContext> mContext;
71};
72
Adam Lesinski1ab598f2015-08-14 14:26:04 -070073TEST_F(XmlReferenceLinkerTest, LinkBasicAttributes) {
Adam Lesinski467f1712015-11-16 17:35:44 -080074 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -070075 <View xmlns:android="http://schemas.android.com/apk/res/android"
76 android:layout_width="match_parent"
77 android:background="@color/green"
78 android:text="hello"
79 class="hello" />)EOF");
80
81 XmlReferenceLinker linker;
82 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
83
Adam Lesinski467f1712015-11-16 17:35:44 -080084 xml::Element* viewEl = xml::findRootElement(doc.get());
Adam Lesinski1ab598f2015-08-14 14:26:04 -070085 ASSERT_NE(viewEl, nullptr);
86
Adam Lesinskid0f116b2016-07-08 15:00:32 -070087 xml::Attribute* xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "layout_width");
Adam Lesinski1ab598f2015-08-14 14:26:04 -070088 ASSERT_NE(xmlAttr, nullptr);
89 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -080090 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
91 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x01010000));
Adam Lesinski1ab598f2015-08-14 14:26:04 -070092 ASSERT_NE(xmlAttr->compiledValue, nullptr);
93 ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr);
94
Adam Lesinskid0f116b2016-07-08 15:00:32 -070095 xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "background");
Adam Lesinski1ab598f2015-08-14 14:26:04 -070096 ASSERT_NE(xmlAttr, nullptr);
97 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -080098 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
99 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x01010001));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700100 ASSERT_NE(xmlAttr->compiledValue, nullptr);
101 Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
102 ASSERT_NE(ref, nullptr);
103 AAPT_ASSERT_TRUE(ref->name);
Adam Lesinski58a20a62016-07-25 17:56:58 -0700104 EXPECT_EQ(ref->name.value(), test::parseNameOrDie("color/green")); // Make sure the name
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700105 // didn't change.
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700106 AAPT_ASSERT_TRUE(ref->id);
107 EXPECT_EQ(ref->id.value(), ResourceId(0x7f020000));
108
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700109 xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "text");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700110 ASSERT_NE(xmlAttr, nullptr);
111 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
112 ASSERT_FALSE(xmlAttr->compiledValue); // Strings don't get compiled for memory sake.
113
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700114 xmlAttr = viewEl->findAttribute("", "class");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700115 ASSERT_NE(xmlAttr, nullptr);
116 AAPT_ASSERT_FALSE(xmlAttr->compiledAttribute);
117 ASSERT_EQ(xmlAttr->compiledValue, nullptr);
118}
119
Adam Lesinski467f1712015-11-16 17:35:44 -0800120TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreNotLinked) {
121 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
122 <View xmlns:android="http://schemas.android.com/apk/res/android"
123 android:colorAccent="@android:color/hidden" />)EOF");
124
125 XmlReferenceLinker linker;
126 ASSERT_FALSE(linker.consume(mContext.get(), doc.get()));
127}
128
129TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreLinkedWhenReferenceHasStarPrefix) {
130 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
131 <View xmlns:android="http://schemas.android.com/apk/res/android"
132 android:colorAccent="@*android:color/hidden" />)EOF");
133
134 XmlReferenceLinker linker;
135 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
136}
137
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138TEST_F(XmlReferenceLinkerTest, SdkLevelsAreRecorded) {
Adam Lesinski467f1712015-11-16 17:35:44 -0800139 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140 <View xmlns:android="http://schemas.android.com/apk/res/android"
141 android:colorAccent="#ffffff" />)EOF");
142
143 XmlReferenceLinker linker;
144 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
145 EXPECT_TRUE(linker.getSdkLevels().count(21) == 1);
146}
147
148TEST_F(XmlReferenceLinkerTest, LinkMangledAttributes) {
Adam Lesinski467f1712015-11-16 17:35:44 -0800149 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700150 <View xmlns:support="http://schemas.android.com/apk/res/com.android.support"
151 support:colorAccent="#ff0000" />)EOF");
152
153 XmlReferenceLinker linker;
154 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
155
Adam Lesinski467f1712015-11-16 17:35:44 -0800156 xml::Element* viewEl = xml::findRootElement(doc.get());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700157 ASSERT_NE(viewEl, nullptr);
158
159 xml::Attribute* xmlAttr = viewEl->findAttribute(
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700160 xml::buildPackageNamespace("com.android.support"), "colorAccent");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700161 ASSERT_NE(xmlAttr, nullptr);
162 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -0800163 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
164 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x7f010001));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700165 ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr);
166}
167
168TEST_F(XmlReferenceLinkerTest, LinkAutoResReference) {
Adam Lesinski467f1712015-11-16 17:35:44 -0800169 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700170 <View xmlns:app="http://schemas.android.com/apk/res-auto"
171 app:colorAccent="@app:color/red" />)EOF");
172
173 XmlReferenceLinker linker;
174 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
175
Adam Lesinski467f1712015-11-16 17:35:44 -0800176 xml::Element* viewEl = xml::findRootElement(doc.get());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700177 ASSERT_NE(viewEl, nullptr);
178
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700179 xml::Attribute* xmlAttr = viewEl->findAttribute(xml::kSchemaAuto, "colorAccent");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700180 ASSERT_NE(xmlAttr, nullptr);
181 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -0800182 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
183 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x7f010000));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700184 Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
185 ASSERT_NE(ref, nullptr);
186 AAPT_ASSERT_TRUE(ref->name);
187 AAPT_ASSERT_TRUE(ref->id);
188 EXPECT_EQ(ref->id.value(), ResourceId(0x7f020001));
189}
190
191TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) {
Adam Lesinski467f1712015-11-16 17:35:44 -0800192 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700193 <View xmlns:app="http://schemas.android.com/apk/res/android"
194 app:attr="@app:id/id">
195 <View xmlns:app="http://schemas.android.com/apk/res/com.app.test"
196 app:attr="@app:id/id"/>
197 </View>)EOF");
198
199 XmlReferenceLinker linker;
200 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
201
Adam Lesinski467f1712015-11-16 17:35:44 -0800202 xml::Element* viewEl = xml::findRootElement(doc.get());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700203 ASSERT_NE(viewEl, nullptr);
204
205 // All attributes and references in this element should be referring to "android" (0x01).
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700206 xml::Attribute* xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "attr");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700207 ASSERT_NE(xmlAttr, nullptr);
208 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -0800209 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
210 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x01010002));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700211 Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
212 ASSERT_NE(ref, nullptr);
213 AAPT_ASSERT_TRUE(ref->id);
214 EXPECT_EQ(ref->id.value(), ResourceId(0x01030000));
215
216 ASSERT_FALSE(viewEl->getChildElements().empty());
217 viewEl = viewEl->getChildElements().front();
218 ASSERT_NE(viewEl, nullptr);
219
220 // All attributes and references in this element should be referring to "com.app.test" (0x7f).
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700221 xmlAttr = viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"), "attr");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700222 ASSERT_NE(xmlAttr, nullptr);
223 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -0800224 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
225 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x7f010002));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700226 ref = valueCast<Reference>(xmlAttr->compiledValue.get());
227 ASSERT_NE(ref, nullptr);
228 AAPT_ASSERT_TRUE(ref->id);
229 EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000));
230}
231
232TEST_F(XmlReferenceLinkerTest, LinkViewWithLocalPackageAndAliasOfTheSameName) {
Adam Lesinski467f1712015-11-16 17:35:44 -0800233 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDomForPackageName(mContext.get(), R"EOF(
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700234 <View xmlns:android="http://schemas.android.com/apk/res/com.app.test"
235 android:attr="@id/id"/>)EOF");
236
237 XmlReferenceLinker linker;
238 ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
239
Adam Lesinski467f1712015-11-16 17:35:44 -0800240 xml::Element* viewEl = xml::findRootElement(doc.get());
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700241 ASSERT_NE(viewEl, nullptr);
242
243 // All attributes and references in this element should be referring to "com.app.test" (0x7f).
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700244 xml::Attribute* xmlAttr = viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"),
245 "attr");
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700246 ASSERT_NE(xmlAttr, nullptr);
247 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
Adam Lesinski64587af2016-02-18 18:33:06 -0800248 AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
249 EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), ResourceId(0x7f010002));
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700250 Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
251 ASSERT_NE(ref, nullptr);
252 AAPT_ASSERT_TRUE(ref->id);
253 EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000));
254}
255
256} // namespace aapt