blob: f7153c822bbc122b30cb6cbd347a490cba4c5154 [file] [log] [blame]
Shane Farmer74cdea32017-05-12 16:22:36 -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 "configuration/ConfigurationParser.h"
18
19#include <string>
20
Shane Farmer67e8a302017-12-06 14:39:10 -080021#include "android-base/stringprintf.h"
Shane Farmer74cdea32017-05-12 16:22:36 -070022#include "androidfw/ResourceTypes.h"
23
Shane Farmer67e8a302017-12-06 14:39:10 -080024#include "SdkConstants.h"
Shane Farmer74cdea32017-05-12 16:22:36 -070025#include "test/Test.h"
26#include "xml/XmlDom.h"
27
28namespace aapt {
Shane Farmer3edd4722017-09-01 14:34:22 -070029
30namespace configuration {
31void PrintTo(const AndroidSdk& sdk, std::ostream* os) {
32 *os << "SDK: min=" << sdk.min_sdk_version.value_or_default(-1)
33 << ", target=" << sdk.target_sdk_version.value_or_default(-1)
34 << ", max=" << sdk.max_sdk_version.value_or_default(-1);
35}
36} // namespace configuration
37
Shane Farmer74cdea32017-05-12 16:22:36 -070038namespace {
39
Shane Farmer67e8a302017-12-06 14:39:10 -080040using ::aapt::configuration::Abi;
41using ::aapt::configuration::AndroidManifest;
42using ::aapt::configuration::AndroidSdk;
43using ::aapt::configuration::Artifact;
44using ::aapt::configuration::DeviceFeature;
45using ::aapt::configuration::GlTexture;
46using ::aapt::configuration::Locale;
47using ::aapt::configuration::PostProcessingConfiguration;
48using ::aapt::xml::Element;
49using ::aapt::xml::NodeCast;
Adam Lesinski6b372992017-08-09 10:54:23 -070050using ::android::ResTable_config;
Shane Farmer67e8a302017-12-06 14:39:10 -080051using ::android::base::StringPrintf;
Adam Lesinski6b372992017-08-09 10:54:23 -070052using ::testing::ElementsAre;
Shane Farmer74cdea32017-05-12 16:22:36 -070053
54constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
55<post-process xmlns="http://schemas.android.com/tools/aapt">
56 <groups>
57 <abi-group label="arm">
58 <abi>armeabi-v7a</abi>
59 <abi>arm64-v8a</abi>
60 </abi-group>
61 <abi-group label="other">
62 <abi>x86</abi>
63 <abi>mips</abi>
64 </abi-group>
65 <screen-density-group label="large">
66 <screen-density>xhdpi</screen-density>
67 <screen-density>xxhdpi</screen-density>
68 <screen-density>xxxhdpi</screen-density>
69 </screen-density-group>
70 <screen-density-group label="alldpi">
71 <screen-density>ldpi</screen-density>
72 <screen-density>mdpi</screen-density>
73 <screen-density>hdpi</screen-density>
74 <screen-density>xhdpi</screen-density>
75 <screen-density>xxhdpi</screen-density>
76 <screen-density>xxxhdpi</screen-density>
77 </screen-density-group>
78 <locale-group label="europe">
Shane Farmer0a5b2012017-06-22 12:24:12 -070079 <locale>en</locale>
80 <locale>es</locale>
81 <locale>fr</locale>
82 <locale>de</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -070083 </locale-group>
84 <locale-group label="north-america">
Shane Farmer0a5b2012017-06-22 12:24:12 -070085 <locale>en</locale>
86 <locale>es-rMX</locale>
87 <locale>fr-rCA</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -070088 </locale-group>
Shane Farmerefe45392017-08-21 14:39:28 -070089 <android-sdk-group label="v19">
Shane Farmer74cdea32017-05-12 16:22:36 -070090 <android-sdk
Shane Farmer3edd4722017-09-01 14:34:22 -070091 minSdkVersion="19"
92 targetSdkVersion="24"
93 maxSdkVersion="25">
Shane Farmer74cdea32017-05-12 16:22:36 -070094 <manifest>
95 <!--- manifest additions here XSLT? TODO -->
96 </manifest>
97 </android-sdk>
98 </android-sdk-group>
99 <gl-texture-group label="dxt1">
100 <gl-texture name="GL_EXT_texture_compression_dxt1">
101 <texture-path>assets/dxt1/*</texture-path>
102 </gl-texture>
103 </gl-texture-group>
104 <device-feature-group label="low-latency">
105 <supports-feature>android.hardware.audio.low_latency</supports-feature>
106 </device-feature-group>
107 </groups>
108 <artifacts>
109 <artifact-format>
110 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
111 </artifact-format>
112 <artifact
113 name="art1"
114 abi-group="arm"
115 screen-density-group="large"
116 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700117 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700118 gl-texture-group="dxt1"
119 device-feature-group="low-latency"/>
120 <artifact
121 name="art2"
122 abi-group="other"
123 screen-density-group="alldpi"
124 locale-group="north-america"
Shane Farmerefe45392017-08-21 14:39:28 -0700125 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700126 gl-texture-group="dxt1"
127 device-feature-group="low-latency"/>
128 </artifacts>
129</post-process>
130)";
131
132class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
133 public:
134 ConfigurationParserTest() : ConfigurationParser("") {}
135
136 protected:
137 StdErrDiagnostics diag_;
138};
139
Shane Farmerb1027272017-06-14 09:10:28 -0700140TEST_F(ConfigurationParserTest, ForPath_NoFile) {
141 auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
142 EXPECT_FALSE(result);
143}
144
Shane Farmer74cdea32017-05-12 16:22:36 -0700145TEST_F(ConfigurationParserTest, ValidateFile) {
146 auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
147 auto result = parser.Parse();
148 ASSERT_TRUE(result);
Shane Farmer280be342017-06-21 15:20:15 -0700149 PostProcessingConfiguration& value = result.value();
Shane Farmer74cdea32017-05-12 16:22:36 -0700150 EXPECT_EQ(2ul, value.artifacts.size());
151 ASSERT_TRUE(value.artifact_format);
152 EXPECT_EQ(
153 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
154 value.artifact_format.value()
155 );
156
157 EXPECT_EQ(2ul, value.abi_groups.size());
158 EXPECT_EQ(2ul, value.abi_groups["arm"].size());
159 EXPECT_EQ(2ul, value.abi_groups["other"].size());
160
161 EXPECT_EQ(2ul, value.screen_density_groups.size());
162 EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
163 EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
164
Shane Farmer0a5b2012017-06-22 12:24:12 -0700165 EXPECT_EQ(2ul, value.locale_groups.size());
Shane Farmer74cdea32017-05-12 16:22:36 -0700166 EXPECT_EQ(4ul, value.locale_groups["europe"].size());
167 EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
Shane Farmer74cdea32017-05-12 16:22:36 -0700168
169 EXPECT_EQ(1ul, value.android_sdk_groups.size());
Shane Farmerefe45392017-08-21 14:39:28 -0700170 EXPECT_TRUE(value.android_sdk_groups["v19"].min_sdk_version);
Shane Farmer3edd4722017-09-01 14:34:22 -0700171 EXPECT_EQ(19, value.android_sdk_groups["v19"].min_sdk_version.value());
Shane Farmer74cdea32017-05-12 16:22:36 -0700172
173 EXPECT_EQ(1ul, value.gl_texture_groups.size());
174 EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
175
176 EXPECT_EQ(1ul, value.device_feature_groups.size());
177 EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
178}
179
180TEST_F(ConfigurationParserTest, InvalidNamespace) {
181 constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
182 <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
183
184 auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
185 ASSERT_FALSE(result);
186}
187
188TEST_F(ConfigurationParserTest, ArtifactAction) {
Shane Farmer810fd182017-09-21 14:37:44 -0700189 PostProcessingConfiguration config;
190 {
191 const auto doc = test::BuildXmlDom(R"xml(
192 <artifact
193 abi-group="arm"
194 screen-density-group="large"
195 locale-group="europe"
196 android-sdk-group="v19"
197 gl-texture-group="dxt1"
198 device-feature-group="low-latency"/>)xml");
199
200 ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc->root.get()), &diag_));
201
202 EXPECT_EQ(1ul, config.artifacts.size());
203
204 auto& artifact = config.artifacts.back();
205 EXPECT_FALSE(artifact.name); // TODO: make this fail.
206 EXPECT_EQ(1, artifact.version);
207 EXPECT_EQ("arm", artifact.abi_group.value());
208 EXPECT_EQ("large", artifact.screen_density_group.value());
209 EXPECT_EQ("europe", artifact.locale_group.value());
210 EXPECT_EQ("v19", artifact.android_sdk_group.value());
211 EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
212 EXPECT_EQ("low-latency", artifact.device_feature_group.value());
213 }
214
215 {
216 // Perform a second action to ensure we get 2 artifacts.
217 const auto doc = test::BuildXmlDom(R"xml(
218 <artifact
219 abi-group="other"
220 screen-density-group="large"
221 locale-group="europe"
222 android-sdk-group="v19"
223 gl-texture-group="dxt1"
224 device-feature-group="low-latency"/>)xml");
225
226 ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
227 EXPECT_EQ(2ul, config.artifacts.size());
228 EXPECT_EQ(2, config.artifacts.back().version);
229 }
230
231 {
232 // Perform a third action with a set version code.
233 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer74cdea32017-05-12 16:22:36 -0700234 <artifact
Shane Farmer810fd182017-09-21 14:37:44 -0700235 version="5"
236 abi-group="other"
Shane Farmer74cdea32017-05-12 16:22:36 -0700237 screen-density-group="large"
238 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700239 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700240 gl-texture-group="dxt1"
Shane Farmer810fd182017-09-21 14:37:44 -0700241 device-feature-group="low-latency"/>)xml");
Shane Farmer74cdea32017-05-12 16:22:36 -0700242
Shane Farmer810fd182017-09-21 14:37:44 -0700243 ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
244 EXPECT_EQ(3ul, config.artifacts.size());
245 EXPECT_EQ(5, config.artifacts.back().version);
246 }
Shane Farmer74cdea32017-05-12 16:22:36 -0700247
Shane Farmer810fd182017-09-21 14:37:44 -0700248 {
249 // Perform a fourth action to ensure the version code still increments.
250 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer57669432017-06-19 12:52:04 -0700251 <artifact
252 abi-group="other"
253 screen-density-group="large"
254 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700255 android-sdk-group="v19"
Shane Farmer57669432017-06-19 12:52:04 -0700256 gl-texture-group="dxt1"
Shane Farmer810fd182017-09-21 14:37:44 -0700257 device-feature-group="low-latency"/>)xml");
Shane Farmer57669432017-06-19 12:52:04 -0700258
Shane Farmer810fd182017-09-21 14:37:44 -0700259 ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
260 EXPECT_EQ(4ul, config.artifacts.size());
261 EXPECT_EQ(6, config.artifacts.back().version);
262 }
263}
264
265TEST_F(ConfigurationParserTest, DuplicateArtifactVersion) {
266 static constexpr const char* configuration = R"xml(<?xml version="1.0" encoding="utf-8" ?>
267 <pst-process xmlns="http://schemas.android.com/tools/aapt">>
268 <artifacts>
269 <artifact-format>
270 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
271 </artifact-format>
272 <artifact
273 name="art1"
274 abi-group="arm"
275 screen-density-group="large"
276 locale-group="europe"
277 android-sdk-group="v19"
278 gl-texture-group="dxt1"
279 device-feature-group="low-latency"/>
280 <artifact
281 name="art2"
282 version = "1"
283 abi-group="other"
284 screen-density-group="alldpi"
285 locale-group="north-america"
286 android-sdk-group="v19"
287 gl-texture-group="dxt1"
288 device-feature-group="low-latency"/>
289 </artifacts>
290 </post-process>)xml";
291 auto result = ConfigurationParser::ForContents(configuration).Parse();
292 ASSERT_FALSE(result);
Shane Farmer74cdea32017-05-12 16:22:36 -0700293}
294
295TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
Shane Farmer810fd182017-09-21 14:37:44 -0700296 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer74cdea32017-05-12 16:22:36 -0700297 <artifact-format>
298 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
Shane Farmer810fd182017-09-21 14:37:44 -0700299 </artifact-format>)xml");
Shane Farmer74cdea32017-05-12 16:22:36 -0700300
Shane Farmer280be342017-06-21 15:20:15 -0700301 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700302 bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
303 ASSERT_TRUE(ok);
304 ASSERT_TRUE(config.artifact_format);
305 EXPECT_EQ(
306 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
307 static_cast<std::string>(config.artifact_format.value())
308 );
309}
310
311TEST_F(ConfigurationParserTest, AbiGroupAction) {
312 static constexpr const char* xml = R"xml(
313 <abi-group label="arm">
314 <!-- First comment. -->
315 <abi>
316 armeabi-v7a
317 </abi>
318 <!-- Another comment. -->
319 <abi>arm64-v8a</abi>
320 </abi-group>)xml";
321
322 auto doc = test::BuildXmlDom(xml);
323
Shane Farmer280be342017-06-21 15:20:15 -0700324 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700325 bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
326 ASSERT_TRUE(ok);
327
328 EXPECT_EQ(1ul, config.abi_groups.size());
329 ASSERT_EQ(1u, config.abi_groups.count("arm"));
330
331 auto& out = config.abi_groups["arm"];
332 ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
333}
334
335TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
336 static constexpr const char* xml = R"xml(
337 <screen-density-group label="large">
338 <screen-density>xhdpi</screen-density>
339 <screen-density>
340 xxhdpi
341 </screen-density>
342 <screen-density>xxxhdpi</screen-density>
343 </screen-density-group>)xml";
344
345 auto doc = test::BuildXmlDom(xml);
346
Shane Farmer280be342017-06-21 15:20:15 -0700347 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700348 bool ok =
349 screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
350 ASSERT_TRUE(ok);
351
352 EXPECT_EQ(1ul, config.screen_density_groups.size());
353 ASSERT_EQ(1u, config.screen_density_groups.count("large"));
354
355 ConfigDescription xhdpi;
356 xhdpi.density = ResTable_config::DENSITY_XHIGH;
357 ConfigDescription xxhdpi;
358 xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
359 ConfigDescription xxxhdpi;
360 xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
361
362 auto& out = config.screen_density_groups["large"];
363 ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
364}
365
366TEST_F(ConfigurationParserTest, LocaleGroupAction) {
367 static constexpr const char* xml = R"xml(
368 <locale-group label="europe">
Shane Farmer0a5b2012017-06-22 12:24:12 -0700369 <locale>en</locale>
370 <locale>es</locale>
371 <locale>fr</locale>
372 <locale>de</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -0700373 </locale-group>)xml";
374
375 auto doc = test::BuildXmlDom(xml);
376
Shane Farmer280be342017-06-21 15:20:15 -0700377 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700378 bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
379 ASSERT_TRUE(ok);
380
381 ASSERT_EQ(1ul, config.locale_groups.size());
382 ASSERT_EQ(1u, config.locale_groups.count("europe"));
383
Shane Farmer0a5b2012017-06-22 12:24:12 -0700384 const auto& out = config.locale_groups["europe"];
Shane Farmer74cdea32017-05-12 16:22:36 -0700385
Shane Farmer0a5b2012017-06-22 12:24:12 -0700386 ConfigDescription en = test::ParseConfigOrDie("en");
387 ConfigDescription es = test::ParseConfigOrDie("es");
388 ConfigDescription fr = test::ParseConfigOrDie("fr");
389 ConfigDescription de = test::ParseConfigOrDie("de");
Shane Farmer74cdea32017-05-12 16:22:36 -0700390
391 ASSERT_THAT(out, ElementsAre(en, es, fr, de));
392}
393
394TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
395 static constexpr const char* xml = R"xml(
Shane Farmerefe45392017-08-21 14:39:28 -0700396 <android-sdk-group label="v19">
Shane Farmer74cdea32017-05-12 16:22:36 -0700397 <android-sdk
Shane Farmer3edd4722017-09-01 14:34:22 -0700398 minSdkVersion="19"
399 targetSdkVersion="24"
400 maxSdkVersion="25">
Shane Farmer74cdea32017-05-12 16:22:36 -0700401 <manifest>
402 <!--- manifest additions here XSLT? TODO -->
403 </manifest>
404 </android-sdk>
405 </android-sdk-group>)xml";
406
407 auto doc = test::BuildXmlDom(xml);
408
Shane Farmer280be342017-06-21 15:20:15 -0700409 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700410 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
411 ASSERT_TRUE(ok);
412
413 ASSERT_EQ(1ul, config.android_sdk_groups.size());
Shane Farmerefe45392017-08-21 14:39:28 -0700414 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
Shane Farmer74cdea32017-05-12 16:22:36 -0700415
Shane Farmerefe45392017-08-21 14:39:28 -0700416 auto& out = config.android_sdk_groups["v19"];
Shane Farmer74cdea32017-05-12 16:22:36 -0700417
418 AndroidSdk sdk;
Shane Farmer3edd4722017-09-01 14:34:22 -0700419 sdk.min_sdk_version = 19;
420 sdk.target_sdk_version = 24;
421 sdk.max_sdk_version = 25;
Shane Farmer74cdea32017-05-12 16:22:36 -0700422 sdk.manifest = AndroidManifest();
423
Shane Farmerefe45392017-08-21 14:39:28 -0700424 ASSERT_EQ(sdk, out);
Shane Farmer74cdea32017-05-12 16:22:36 -0700425}
426
Shane Farmer67e8a302017-12-06 14:39:10 -0800427TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
428 {
429 static constexpr const char* xml = R"xml(
430 <android-sdk-group label="v19">
431 <android-sdk minSdkVersion="19"></android-sdk>
432 </android-sdk-group>)xml";
433
434 auto doc = test::BuildXmlDom(xml);
435
436 PostProcessingConfiguration config;
437 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
438 ASSERT_TRUE(ok);
439
440 ASSERT_EQ(1ul, config.android_sdk_groups.size());
441 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
442
443 auto& out = config.android_sdk_groups["v19"];
444 EXPECT_EQ(19, out.min_sdk_version.value());
445 EXPECT_FALSE(out.max_sdk_version);
446 EXPECT_FALSE(out.target_sdk_version);
447 }
448
449 {
450 static constexpr const char* xml = R"xml(
451 <android-sdk-group label="v19">
452 <android-sdk maxSdkVersion="19"></android-sdk>
453 </android-sdk-group>)xml";
454
455 auto doc = test::BuildXmlDom(xml);
456
457 PostProcessingConfiguration config;
458 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
459 ASSERT_TRUE(ok);
460
461 ASSERT_EQ(1ul, config.android_sdk_groups.size());
462 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
463
464 auto& out = config.android_sdk_groups["v19"];
465 EXPECT_EQ(19, out.max_sdk_version.value());
466 EXPECT_FALSE(out.min_sdk_version);
467 EXPECT_FALSE(out.target_sdk_version);
468 }
469
470 {
471 static constexpr const char* xml = R"xml(
472 <android-sdk-group label="v19">
473 <android-sdk targetSdkVersion="19"></android-sdk>
474 </android-sdk-group>)xml";
475
476 auto doc = test::BuildXmlDom(xml);
477
478 PostProcessingConfiguration config;
479 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
480 ASSERT_TRUE(ok);
481
482 ASSERT_EQ(1ul, config.android_sdk_groups.size());
483 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
484
485 auto& out = config.android_sdk_groups["v19"];
486 EXPECT_EQ(19, out.target_sdk_version.value());
487 EXPECT_FALSE(out.min_sdk_version);
488 EXPECT_FALSE(out.max_sdk_version);
489 }
490}
491
492TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
Shane Farmer3edd4722017-09-01 14:34:22 -0700493 static constexpr const char* xml = R"xml(
Shane Farmer67e8a302017-12-06 14:39:10 -0800494 <android-sdk-group label="v19">
Shane Farmer3edd4722017-09-01 14:34:22 -0700495 <android-sdk
Shane Farmer67e8a302017-12-06 14:39:10 -0800496 minSdkVersion="v19"
497 targetSdkVersion="v24"
498 maxSdkVersion="v25">
499 <manifest>
500 <!--- manifest additions here XSLT? TODO -->
501 </manifest>
Shane Farmer3edd4722017-09-01 14:34:22 -0700502 </android-sdk>
503 </android-sdk-group>)xml";
504
505 auto doc = test::BuildXmlDom(xml);
506
507 PostProcessingConfiguration config;
508 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer67e8a302017-12-06 14:39:10 -0800509 ASSERT_FALSE(ok);
510}
511
512TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
513 static constexpr const char* xml = R"xml(
514 <android-sdk-group label="P">
515 <android-sdk
516 minSdkVersion="25"
517 targetSdkVersion="%s"
518 maxSdkVersion="%s">
519 </android-sdk>
520 </android-sdk-group>)xml";
521
522 const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
523 const char* codename = dev_sdk.first.data();
524 const ApiVersion& version = dev_sdk.second;
525
526 auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
527
528 PostProcessingConfiguration config;
529 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer3edd4722017-09-01 14:34:22 -0700530 ASSERT_TRUE(ok);
531
532 ASSERT_EQ(1ul, config.android_sdk_groups.size());
Adam Lesinski178e6782017-11-02 14:12:38 -0700533 ASSERT_EQ(1u, config.android_sdk_groups.count("P"));
Shane Farmer3edd4722017-09-01 14:34:22 -0700534
Adam Lesinski178e6782017-11-02 14:12:38 -0700535 auto& out = config.android_sdk_groups["P"];
Shane Farmer3edd4722017-09-01 14:34:22 -0700536
537 AndroidSdk sdk;
Shane Farmer67e8a302017-12-06 14:39:10 -0800538 sdk.min_sdk_version = 25;
539 sdk.target_sdk_version = version;
540 sdk.max_sdk_version = version;
Shane Farmer3edd4722017-09-01 14:34:22 -0700541
542 ASSERT_EQ(sdk, out);
543}
544
Shane Farmer74cdea32017-05-12 16:22:36 -0700545TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
546 static constexpr const char* xml = R"xml(
547 <gl-texture-group label="dxt1">
548 <gl-texture name="GL_EXT_texture_compression_dxt1">
549 <texture-path>assets/dxt1/main/*</texture-path>
550 <texture-path>
551 assets/dxt1/test/*
552 </texture-path>
553 </gl-texture>
554 </gl-texture-group>)xml";
555
556 auto doc = test::BuildXmlDom(xml);
557
Shane Farmer280be342017-06-21 15:20:15 -0700558 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700559 bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
560 ASSERT_TRUE(ok);
561
562 EXPECT_EQ(1ul, config.gl_texture_groups.size());
563 ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
564
565 auto& out = config.gl_texture_groups["dxt1"];
566
567 GlTexture texture{
568 std::string("GL_EXT_texture_compression_dxt1"),
569 {"assets/dxt1/main/*", "assets/dxt1/test/*"}
570 };
571
572 ASSERT_EQ(1ul, out.size());
573 ASSERT_EQ(texture, out[0]);
574}
575
576TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
577 static constexpr const char* xml = R"xml(
578 <device-feature-group label="low-latency">
579 <supports-feature>android.hardware.audio.low_latency</supports-feature>
580 <supports-feature>
581 android.hardware.audio.pro
582 </supports-feature>
583 </device-feature-group>)xml";
584
585 auto doc = test::BuildXmlDom(xml);
586
Shane Farmer280be342017-06-21 15:20:15 -0700587 PostProcessingConfiguration config;
Shane Farmer74cdea32017-05-12 16:22:36 -0700588 bool ok
589 = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
590 ASSERT_TRUE(ok);
591
592 EXPECT_EQ(1ul, config.device_feature_groups.size());
593 ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
594
595 auto& out = config.device_feature_groups["low-latency"];
596
597 DeviceFeature low_latency = "android.hardware.audio.low_latency";
598 DeviceFeature pro = "android.hardware.audio.pro";
599 ASSERT_THAT(out, ElementsAre(low_latency, pro));
600}
601
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700602// Artifact name parser test cases.
603
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700604TEST(ArtifactTest, Simple) {
605 StdErrDiagnostics diag;
606 Artifact x86;
607 x86.abi_group = {"x86"};
608
Shane Farmer9ecc0752017-08-24 15:55:36 -0700609 auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700610 ASSERT_TRUE(x86_result);
611 EXPECT_EQ(x86_result.value(), "something.x86.apk");
612
613 Artifact arm;
614 arm.abi_group = {"armeabi-v7a"};
615
Shane Farmer9ecc0752017-08-24 15:55:36 -0700616 {
617 auto arm_result = arm.ToArtifactName("app.${abi}.apk", "", &diag);
618 ASSERT_TRUE(arm_result);
619 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
620 }
621
622 {
623 auto arm_result = arm.ToArtifactName("app.${abi}.apk", "different_name.apk", &diag);
624 ASSERT_TRUE(arm_result);
625 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
626 }
627
628 {
629 auto arm_result = arm.ToArtifactName("${basename}.${abi}.apk", "app.apk", &diag);
630 ASSERT_TRUE(arm_result);
631 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
632 }
633
634 {
635 auto arm_result = arm.ToArtifactName("app.${abi}.${ext}", "app.apk", &diag);
636 ASSERT_TRUE(arm_result);
637 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
638 }
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700639}
640
641TEST(ArtifactTest, Complex) {
642 StdErrDiagnostics diag;
643 Artifact artifact;
644 artifact.abi_group = {"mips64"};
645 artifact.screen_density_group = {"ldpi"};
646 artifact.device_feature_group = {"df1"};
647 artifact.gl_texture_group = {"glx1"};
648 artifact.locale_group = {"en-AU"};
Shane Farmerefe45392017-08-21 14:39:28 -0700649 artifact.android_sdk_group = {"v26"};
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700650
Shane Farmer9ecc0752017-08-24 15:55:36 -0700651 {
652 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700653 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700654 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700655 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700656 }
657
658 {
659 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700660 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700661 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700662 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700663 }
664
665 {
666 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700667 "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700668 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700669 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700670 }
671
672 {
673 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700674 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.${ext}", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700675 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700676 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700677 }
678
679 {
680 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700681 "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700682 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700683 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700684 }
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700685}
686
687TEST(ArtifactTest, Missing) {
688 StdErrDiagnostics diag;
689 Artifact x86;
690 x86.abi_group = {"x86"};
691
Shane Farmer9ecc0752017-08-24 15:55:36 -0700692 EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
693 EXPECT_FALSE(x86.ToArtifactName("something.apk", "", &diag));
694 EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "something.apk", &diag));
695 EXPECT_FALSE(x86.ToArtifactName("something.apk", "something.apk", &diag));
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700696}
697
698TEST(ArtifactTest, Empty) {
699 StdErrDiagnostics diag;
700 Artifact artifact;
701
Shane Farmer9ecc0752017-08-24 15:55:36 -0700702 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
703 EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
704 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
705 EXPECT_TRUE(artifact.ToArtifactName("something.apk", "something.apk", &diag));
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700706}
707
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700708TEST(ArtifactTest, Repeated) {
709 StdErrDiagnostics diag;
710 Artifact artifact;
711 artifact.screen_density_group = {"mdpi"};
712
Shane Farmer9ecc0752017-08-24 15:55:36 -0700713 ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
714 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", "", &diag));
715 ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700716}
717
718TEST(ArtifactTest, Nesting) {
719 StdErrDiagnostics diag;
720 Artifact x86;
721 x86.abi_group = {"x86"};
722
Shane Farmer9ecc0752017-08-24 15:55:36 -0700723 EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700724
Shane Farmer9ecc0752017-08-24 15:55:36 -0700725 const Maybe<std::string>& name = x86.ToArtifactName("something.${abi${abi}}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700726 ASSERT_TRUE(name);
727 EXPECT_EQ(name.value(), "something.${abix86}.apk");
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700728}
729
730TEST(ArtifactTest, Recursive) {
731 StdErrDiagnostics diag;
732 Artifact artifact;
Shane Farmer0a5b2012017-06-22 12:24:12 -0700733 artifact.device_feature_group = {"${gl}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700734 artifact.gl_texture_group = {"glx1"};
735
Shane Farmer9ecc0752017-08-24 15:55:36 -0700736 EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700737
738 artifact.device_feature_group = {"df1"};
Shane Farmer0a5b2012017-06-22 12:24:12 -0700739 artifact.gl_texture_group = {"${feature}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700740 {
Shane Farmer9ecc0752017-08-24 15:55:36 -0700741 const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700742 ASSERT_TRUE(result);
743 EXPECT_EQ(result.value(), "app.df1.${feature}.apk");
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700744 }
745
746 // This is an invalid case, but should be the only possible case due to the ordering of
747 // replacement.
Shane Farmer0a5b2012017-06-22 12:24:12 -0700748 artifact.device_feature_group = {"${gl}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700749 artifact.gl_texture_group = {"glx1"};
750 {
Shane Farmer9ecc0752017-08-24 15:55:36 -0700751 const auto& result = artifact.ToArtifactName("app.${feature}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700752 ASSERT_TRUE(result);
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700753 EXPECT_EQ(result.value(), "app.glx1.apk");
754 }
755}
756
Shane Farmer74cdea32017-05-12 16:22:36 -0700757} // namespace
758} // namespace aapt