blob: 29ad25f79ab98961a98a8a64c298c34920ac1a4e [file] [log] [blame]
Adam Lesinskic744ae82017-05-17 19:28:38 -07001/*
2 * Copyright (C) 2017 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/XmlCompatVersioner.h"
18
19#include "Linkers.h"
20#include "test/Test.h"
21
Adam Lesinski6b372992017-08-09 10:54:23 -070022using ::aapt::test::ValueEq;
23using ::testing::Eq;
24using ::testing::IsNull;
25using ::testing::NotNull;
26using ::testing::SizeIs;
27
Adam Lesinskic744ae82017-05-17 19:28:38 -070028namespace aapt {
29
30constexpr auto TYPE_DIMENSION = android::ResTable_map::TYPE_DIMENSION;
31constexpr auto TYPE_STRING = android::ResTable_map::TYPE_STRING;
32
33struct R {
34 struct attr {
35 enum : uint32_t {
36 paddingLeft = 0x010100d6u, // (API 1)
37 paddingRight = 0x010100d8u, // (API 1)
38 progressBarPadding = 0x01010319u, // (API 11)
39 paddingStart = 0x010103b3u, // (API 17)
40 paddingHorizontal = 0x0101053du, // (API 26)
41 };
42 };
43};
44
45class XmlCompatVersionerTest : public ::testing::Test {
46 public:
47 void SetUp() override {
48 context_ =
49 test::ContextBuilder()
50 .SetCompilationPackage("com.app")
51 .SetPackageId(0x7f)
52 .SetPackageType(PackageType::kApp)
53 .SetMinSdkVersion(SDK_GINGERBREAD)
54 .AddSymbolSource(
55 test::StaticSymbolSourceBuilder()
56 .AddPublicSymbol("android:attr/paddingLeft", R::attr::paddingLeft,
57 util::make_unique<Attribute>(false, TYPE_DIMENSION))
58 .AddPublicSymbol("android:attr/paddingRight", R::attr::paddingRight,
59 util::make_unique<Attribute>(false, TYPE_DIMENSION))
60 .AddPublicSymbol("android:attr/progressBarPadding", R::attr::progressBarPadding,
61 util::make_unique<Attribute>(false, TYPE_DIMENSION))
62 .AddPublicSymbol("android:attr/paddingStart", R::attr::paddingStart,
63 util::make_unique<Attribute>(false, TYPE_DIMENSION))
64 .AddPublicSymbol("android:attr/paddingHorizontal", R::attr::paddingHorizontal,
65 util::make_unique<Attribute>(false, TYPE_DIMENSION))
66 .AddSymbol("com.app:attr/foo", ResourceId(0x7f010000),
67 util::make_unique<Attribute>(false, TYPE_STRING))
68 .Build())
69 .Build();
70 }
71
72 protected:
73 std::unique_ptr<IAaptContext> context_;
74};
75
76TEST_F(XmlCompatVersionerTest, NoRulesOnlyStripsAndCopies) {
Adam Lesinski6b372992017-08-09 10:54:23 -070077 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -070078 <View xmlns:android="http://schemas.android.com/apk/res/android"
79 xmlns:app="http://schemas.android.com/apk/res-auto"
80 android:paddingHorizontal="24dp"
81 app:foo="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -070082 foo="bar"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -070083
84 XmlReferenceLinker linker;
85 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
86
87 XmlCompatVersioner::Rules rules;
88 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
89
90 XmlCompatVersioner versioner(&rules);
91 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
92 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -070093 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -070094
95 xml::Element* el;
96
97 // Source XML file's sdkVersion == 0, so the first one must also have the same sdkVersion.
Adam Lesinski6b372992017-08-09 10:54:23 -070098 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
99 el = versioned_docs[0]->root.get();
100 ASSERT_THAT(el, NotNull());
101 EXPECT_THAT(el->attributes, SizeIs(2u));
102 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
103 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
104 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700105
Adam Lesinski6b372992017-08-09 10:54:23 -0700106 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
107 el = versioned_docs[1]->root.get();
108 ASSERT_THAT(el, NotNull());
109 EXPECT_THAT(el->attributes, SizeIs(3u));
110 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), NotNull());
111 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
112 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700113}
114
115TEST_F(XmlCompatVersionerTest, SingleRule) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700116 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700117 <View xmlns:android="http://schemas.android.com/apk/res/android"
118 xmlns:app="http://schemas.android.com/apk/res-auto"
119 android:paddingHorizontal="24dp"
120 app:foo="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -0700121 foo="bar"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700122
123 XmlReferenceLinker linker;
124 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
125
126 XmlCompatVersioner::Rules rules;
127 rules[R::attr::paddingHorizontal] =
128 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
129 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(false, TYPE_DIMENSION)},
130 ReplacementAttr{"paddingRight", R::attr::paddingRight,
131 Attribute(false, TYPE_DIMENSION)}}));
132
133 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
134
135 XmlCompatVersioner versioner(&rules);
136 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
137 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700138 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700139
140 xml::Element* el;
141
Adam Lesinski6b372992017-08-09 10:54:23 -0700142 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
143 el = versioned_docs[0]->root.get();
144 ASSERT_THAT(el, NotNull());
145 EXPECT_THAT(el->attributes, SizeIs(4u));
146 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
147 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
148 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700149
150 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700151 ASSERT_THAT(attr, NotNull());
152 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700153 ASSERT_TRUE(attr->compiled_attribute);
154
155 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700156 ASSERT_THAT(attr, NotNull());
157 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700158 ASSERT_TRUE(attr->compiled_attribute);
159
Adam Lesinski6b372992017-08-09 10:54:23 -0700160 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
161 el = versioned_docs[1]->root.get();
162 ASSERT_THAT(el, NotNull());
163 EXPECT_THAT(el->attributes, SizeIs(5u));
164 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), NotNull());
165 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
166 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700167
168 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700169 ASSERT_THAT(attr, NotNull());
170 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700171 ASSERT_TRUE(attr->compiled_attribute);
172
173 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700174 ASSERT_THAT(attr, NotNull());
175 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700176 ASSERT_TRUE(attr->compiled_attribute);
177}
178
179TEST_F(XmlCompatVersionerTest, ChainedRule) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700180 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700181 <View xmlns:android="http://schemas.android.com/apk/res/android"
Adam Lesinski6b372992017-08-09 10:54:23 -0700182 android:paddingHorizontal="24dp" />)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700183
184 XmlReferenceLinker linker;
185 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
186
187 XmlCompatVersioner::Rules rules;
188 rules[R::attr::progressBarPadding] =
189 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
190 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(false, TYPE_DIMENSION)},
191 ReplacementAttr{"paddingRight", R::attr::paddingRight,
192 Attribute(false, TYPE_DIMENSION)}}));
193 rules[R::attr::paddingHorizontal] =
194 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>({ReplacementAttr{
195 "progressBarPadding", R::attr::progressBarPadding, Attribute(false, TYPE_DIMENSION)}}));
196
197 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
198
199 XmlCompatVersioner versioner(&rules);
200 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
201 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700202 ASSERT_THAT(versioned_docs, SizeIs(3u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700203
204 xml::Element* el;
205
Adam Lesinski6b372992017-08-09 10:54:23 -0700206 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
207 el = versioned_docs[0]->root.get();
208 ASSERT_THAT(el, NotNull());
209 EXPECT_THAT(el->attributes, SizeIs(2u));
210 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700211
212 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700213 ASSERT_THAT(attr, NotNull());
214 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700215 ASSERT_TRUE(attr->compiled_attribute);
216
217 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700218 ASSERT_THAT(attr, NotNull());
219 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700220 ASSERT_TRUE(attr->compiled_attribute);
221
Adam Lesinski6b372992017-08-09 10:54:23 -0700222 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_HONEYCOMB));
223 el = versioned_docs[1]->root.get();
224 ASSERT_THAT(el, NotNull());
225 EXPECT_THAT(el->attributes, SizeIs(1u));
226 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
227 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingLeft"), IsNull());
228 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingRight"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700229
230 attr = el->FindAttribute(xml::kSchemaAndroid, "progressBarPadding");
Adam Lesinski6b372992017-08-09 10:54:23 -0700231 ASSERT_THAT(attr, NotNull());
232 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700233 ASSERT_TRUE(attr->compiled_attribute);
234
Adam Lesinski6b372992017-08-09 10:54:23 -0700235 EXPECT_THAT(versioned_docs[2]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
236 el = versioned_docs[2]->root.get();
237 ASSERT_THAT(el, NotNull());
238 EXPECT_THAT(el->attributes, SizeIs(2u));
239 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingLeft"), IsNull());
240 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingRight"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700241
242 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal");
Adam Lesinski6b372992017-08-09 10:54:23 -0700243 ASSERT_THAT(attr, NotNull());
244 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700245 ASSERT_TRUE(attr->compiled_attribute);
246
247 attr = el->FindAttribute(xml::kSchemaAndroid, "progressBarPadding");
Adam Lesinski6b372992017-08-09 10:54:23 -0700248 ASSERT_THAT(attr, NotNull());
249 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700250 ASSERT_TRUE(attr->compiled_attribute);
251}
252
253TEST_F(XmlCompatVersionerTest, DegradeRuleOverridesExistingAttribute) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700254 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700255 <View xmlns:android="http://schemas.android.com/apk/res/android"
256 android:paddingHorizontal="24dp"
257 android:paddingLeft="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -0700258 android:paddingRight="16dp"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700259
260 XmlReferenceLinker linker;
261 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
262
Adam Lesinski6b372992017-08-09 10:54:23 -0700263 Item* padding_horizontal_value =
264 doc->root->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal")->compiled_value.get();
265 ASSERT_THAT(padding_horizontal_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700266
267 XmlCompatVersioner::Rules rules;
268 rules[R::attr::paddingHorizontal] =
269 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
270 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(false, TYPE_DIMENSION)},
271 ReplacementAttr{"paddingRight", R::attr::paddingRight,
272 Attribute(false, TYPE_DIMENSION)}}));
273
274 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
275
276 XmlCompatVersioner versioner(&rules);
277 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
278 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700279 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700280
281 xml::Element* el;
282
Adam Lesinski6b372992017-08-09 10:54:23 -0700283 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
284 el = versioned_docs[0]->root.get();
285 ASSERT_THAT(el, NotNull());
286 EXPECT_THAT(el->attributes, SizeIs(2u));
287 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700288
289 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700290 ASSERT_THAT(attr, NotNull());
291 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700292 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinski6b372992017-08-09 10:54:23 -0700293 ASSERT_THAT(*attr->compiled_value, ValueEq(padding_horizontal_value));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700294
295 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700296 ASSERT_THAT(attr, NotNull());
297 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700298 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinski6b372992017-08-09 10:54:23 -0700299 ASSERT_THAT(*attr->compiled_value, ValueEq(padding_horizontal_value));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700300
Adam Lesinski6b372992017-08-09 10:54:23 -0700301 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
302 el = versioned_docs[1]->root.get();
303 ASSERT_THAT(el, NotNull());
304 EXPECT_THAT(el->attributes, SizeIs(3u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700305
306 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal");
Adam Lesinski6b372992017-08-09 10:54:23 -0700307 ASSERT_THAT(attr, NotNull());
308 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700309 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinski6b372992017-08-09 10:54:23 -0700310 ASSERT_THAT(*attr->compiled_value, ValueEq(padding_horizontal_value));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700311
312 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700313 ASSERT_THAT(attr, NotNull());
314 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700315 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinski6b372992017-08-09 10:54:23 -0700316 ASSERT_THAT(*attr->compiled_value, ValueEq(padding_horizontal_value));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700317
318 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700319 ASSERT_THAT(attr, NotNull());
320 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700321 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinski6b372992017-08-09 10:54:23 -0700322 ASSERT_THAT(*attr->compiled_value, ValueEq(padding_horizontal_value));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700323}
324
325} // namespace aapt