blob: 3f356d78bbfebdd3c9a3134733a1177da1e9dbd7 [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 Farmercb6c3f92017-11-27 13:19:36 -080025#include "configuration/ConfigurationParser.internal.h"
Shane Farmer74cdea32017-05-12 16:22:36 -070026#include "test/Test.h"
27#include "xml/XmlDom.h"
28
29namespace aapt {
Shane Farmer3edd4722017-09-01 14:34:22 -070030
31namespace configuration {
32void PrintTo(const AndroidSdk& sdk, std::ostream* os) {
33 *os << "SDK: min=" << sdk.min_sdk_version.value_or_default(-1)
34 << ", target=" << sdk.target_sdk_version.value_or_default(-1)
35 << ", max=" << sdk.max_sdk_version.value_or_default(-1);
36}
Shane Farmercb6c3f92017-11-27 13:19:36 -080037
38namespace handler {
Shane Farmer3edd4722017-09-01 14:34:22 -070039
Shane Farmer74cdea32017-05-12 16:22:36 -070040namespace {
41
Shane Farmer67e8a302017-12-06 14:39:10 -080042using ::aapt::configuration::Abi;
43using ::aapt::configuration::AndroidManifest;
44using ::aapt::configuration::AndroidSdk;
Shane Farmercb6c3f92017-11-27 13:19:36 -080045using ::aapt::configuration::ConfiguredArtifact;
Shane Farmer67e8a302017-12-06 14:39:10 -080046using ::aapt::configuration::DeviceFeature;
47using ::aapt::configuration::GlTexture;
48using ::aapt::configuration::Locale;
49using ::aapt::configuration::PostProcessingConfiguration;
50using ::aapt::xml::Element;
51using ::aapt::xml::NodeCast;
Adam Lesinski6b372992017-08-09 10:54:23 -070052using ::android::ResTable_config;
Shane Farmer67e8a302017-12-06 14:39:10 -080053using ::android::base::StringPrintf;
Adam Lesinski6b372992017-08-09 10:54:23 -070054using ::testing::ElementsAre;
Shane Farmercb6c3f92017-11-27 13:19:36 -080055using ::testing::SizeIs;
Shane Farmer74cdea32017-05-12 16:22:36 -070056
57constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
58<post-process xmlns="http://schemas.android.com/tools/aapt">
59 <groups>
60 <abi-group label="arm">
61 <abi>armeabi-v7a</abi>
62 <abi>arm64-v8a</abi>
63 </abi-group>
64 <abi-group label="other">
65 <abi>x86</abi>
66 <abi>mips</abi>
67 </abi-group>
68 <screen-density-group label="large">
69 <screen-density>xhdpi</screen-density>
70 <screen-density>xxhdpi</screen-density>
71 <screen-density>xxxhdpi</screen-density>
72 </screen-density-group>
73 <screen-density-group label="alldpi">
74 <screen-density>ldpi</screen-density>
75 <screen-density>mdpi</screen-density>
76 <screen-density>hdpi</screen-density>
77 <screen-density>xhdpi</screen-density>
78 <screen-density>xxhdpi</screen-density>
79 <screen-density>xxxhdpi</screen-density>
80 </screen-density-group>
81 <locale-group label="europe">
Shane Farmer0a5b2012017-06-22 12:24:12 -070082 <locale>en</locale>
83 <locale>es</locale>
84 <locale>fr</locale>
85 <locale>de</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -070086 </locale-group>
87 <locale-group label="north-america">
Shane Farmer0a5b2012017-06-22 12:24:12 -070088 <locale>en</locale>
89 <locale>es-rMX</locale>
90 <locale>fr-rCA</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -070091 </locale-group>
Shane Farmerefe45392017-08-21 14:39:28 -070092 <android-sdk-group label="v19">
Shane Farmer74cdea32017-05-12 16:22:36 -070093 <android-sdk
Shane Farmer3edd4722017-09-01 14:34:22 -070094 minSdkVersion="19"
95 targetSdkVersion="24"
96 maxSdkVersion="25">
Shane Farmer74cdea32017-05-12 16:22:36 -070097 <manifest>
98 <!--- manifest additions here XSLT? TODO -->
99 </manifest>
100 </android-sdk>
101 </android-sdk-group>
102 <gl-texture-group label="dxt1">
103 <gl-texture name="GL_EXT_texture_compression_dxt1">
104 <texture-path>assets/dxt1/*</texture-path>
105 </gl-texture>
106 </gl-texture-group>
107 <device-feature-group label="low-latency">
108 <supports-feature>android.hardware.audio.low_latency</supports-feature>
109 </device-feature-group>
110 </groups>
111 <artifacts>
112 <artifact-format>
113 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
114 </artifact-format>
115 <artifact
116 name="art1"
117 abi-group="arm"
118 screen-density-group="large"
119 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700120 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700121 gl-texture-group="dxt1"
122 device-feature-group="low-latency"/>
123 <artifact
124 name="art2"
125 abi-group="other"
126 screen-density-group="alldpi"
127 locale-group="north-america"
Shane Farmerefe45392017-08-21 14:39:28 -0700128 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700129 gl-texture-group="dxt1"
130 device-feature-group="low-latency"/>
131 </artifacts>
132</post-process>
133)";
134
135class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
136 public:
137 ConfigurationParserTest() : ConfigurationParser("") {}
138
139 protected:
140 StdErrDiagnostics diag_;
141};
142
Shane Farmerb1027272017-06-14 09:10:28 -0700143TEST_F(ConfigurationParserTest, ForPath_NoFile) {
144 auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
145 EXPECT_FALSE(result);
146}
147
Shane Farmer74cdea32017-05-12 16:22:36 -0700148TEST_F(ConfigurationParserTest, ValidateFile) {
149 auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
Shane Farmercb6c3f92017-11-27 13:19:36 -0800150 auto result = parser.Parse("test.apk");
Shane Farmer74cdea32017-05-12 16:22:36 -0700151 ASSERT_TRUE(result);
Shane Farmercb6c3f92017-11-27 13:19:36 -0800152 const std::vector<OutputArtifact>& value = result.value();
153 EXPECT_THAT(value, SizeIs(2ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700154
Shane Farmercb6c3f92017-11-27 13:19:36 -0800155 const OutputArtifact& a1 = value[0];
156 EXPECT_EQ(a1.name, "art1.apk");
157 EXPECT_THAT(a1.abis, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
158 EXPECT_THAT(a1.screen_densities,
159 ElementsAre(test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
160 test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
161 test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
162 EXPECT_THAT(a1.locales, ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es"),
163 test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
164 EXPECT_EQ(a1.android_sdk.value().min_sdk_version.value(), 19l);
165 EXPECT_THAT(a1.textures, SizeIs(1ul));
166 EXPECT_THAT(a1.features, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700167
Shane Farmercb6c3f92017-11-27 13:19:36 -0800168 const OutputArtifact& a2 = value[1];
169 EXPECT_EQ(a2.name, "art2.apk");
170 EXPECT_THAT(a2.abis, ElementsAre(Abi::kX86, Abi::kMips));
171 EXPECT_THAT(a2.screen_densities,
172 ElementsAre(test::ParseConfigOrDie("ldpi").CopyWithoutSdkVersion(),
173 test::ParseConfigOrDie("mdpi").CopyWithoutSdkVersion(),
174 test::ParseConfigOrDie("hdpi").CopyWithoutSdkVersion(),
175 test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
176 test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
177 test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
178 EXPECT_THAT(a2.locales,
179 ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es-rMX"),
180 test::ParseConfigOrDie("fr-rCA")));
181 EXPECT_EQ(a2.android_sdk.value().min_sdk_version.value(), 19l);
182 EXPECT_THAT(a2.textures, SizeIs(1ul));
183 EXPECT_THAT(a2.features, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700184}
185
186TEST_F(ConfigurationParserTest, InvalidNamespace) {
187 constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
188 <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
189
Shane Farmercb6c3f92017-11-27 13:19:36 -0800190 auto result = ConfigurationParser::ForContents(invalid_ns).Parse("test.apk");
Shane Farmer74cdea32017-05-12 16:22:36 -0700191 ASSERT_FALSE(result);
192}
193
194TEST_F(ConfigurationParserTest, ArtifactAction) {
Shane Farmer810fd182017-09-21 14:37:44 -0700195 PostProcessingConfiguration config;
196 {
197 const auto doc = test::BuildXmlDom(R"xml(
198 <artifact
199 abi-group="arm"
200 screen-density-group="large"
201 locale-group="europe"
202 android-sdk-group="v19"
203 gl-texture-group="dxt1"
204 device-feature-group="low-latency"/>)xml");
205
Shane Farmercb6c3f92017-11-27 13:19:36 -0800206 ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc->root.get()), &diag_));
Shane Farmer810fd182017-09-21 14:37:44 -0700207
Shane Farmercb6c3f92017-11-27 13:19:36 -0800208 EXPECT_THAT(config.artifacts, SizeIs(1ul));
Shane Farmer810fd182017-09-21 14:37:44 -0700209
210 auto& artifact = config.artifacts.back();
211 EXPECT_FALSE(artifact.name); // TODO: make this fail.
212 EXPECT_EQ(1, artifact.version);
213 EXPECT_EQ("arm", artifact.abi_group.value());
214 EXPECT_EQ("large", artifact.screen_density_group.value());
215 EXPECT_EQ("europe", artifact.locale_group.value());
216 EXPECT_EQ("v19", artifact.android_sdk_group.value());
217 EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
218 EXPECT_EQ("low-latency", artifact.device_feature_group.value());
219 }
220
221 {
222 // Perform a second action to ensure we get 2 artifacts.
223 const auto doc = test::BuildXmlDom(R"xml(
224 <artifact
225 abi-group="other"
226 screen-density-group="large"
227 locale-group="europe"
228 android-sdk-group="v19"
229 gl-texture-group="dxt1"
230 device-feature-group="low-latency"/>)xml");
231
Shane Farmercb6c3f92017-11-27 13:19:36 -0800232 ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
233 EXPECT_THAT(config.artifacts, SizeIs(2ul));
Shane Farmer810fd182017-09-21 14:37:44 -0700234 EXPECT_EQ(2, config.artifacts.back().version);
235 }
236
237 {
238 // Perform a third action with a set version code.
239 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer74cdea32017-05-12 16:22:36 -0700240 <artifact
Shane Farmer810fd182017-09-21 14:37:44 -0700241 version="5"
242 abi-group="other"
Shane Farmer74cdea32017-05-12 16:22:36 -0700243 screen-density-group="large"
244 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700245 android-sdk-group="v19"
Shane Farmer74cdea32017-05-12 16:22:36 -0700246 gl-texture-group="dxt1"
Shane Farmer810fd182017-09-21 14:37:44 -0700247 device-feature-group="low-latency"/>)xml");
Shane Farmer74cdea32017-05-12 16:22:36 -0700248
Shane Farmercb6c3f92017-11-27 13:19:36 -0800249 ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
250 EXPECT_THAT(config.artifacts, SizeIs(3ul));
Shane Farmer810fd182017-09-21 14:37:44 -0700251 EXPECT_EQ(5, config.artifacts.back().version);
252 }
Shane Farmer74cdea32017-05-12 16:22:36 -0700253
Shane Farmer810fd182017-09-21 14:37:44 -0700254 {
255 // Perform a fourth action to ensure the version code still increments.
256 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer57669432017-06-19 12:52:04 -0700257 <artifact
258 abi-group="other"
259 screen-density-group="large"
260 locale-group="europe"
Shane Farmerefe45392017-08-21 14:39:28 -0700261 android-sdk-group="v19"
Shane Farmer57669432017-06-19 12:52:04 -0700262 gl-texture-group="dxt1"
Shane Farmer810fd182017-09-21 14:37:44 -0700263 device-feature-group="low-latency"/>)xml");
Shane Farmer57669432017-06-19 12:52:04 -0700264
Shane Farmercb6c3f92017-11-27 13:19:36 -0800265 ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
266 EXPECT_THAT(config.artifacts, SizeIs(4ul));
Shane Farmer810fd182017-09-21 14:37:44 -0700267 EXPECT_EQ(6, config.artifacts.back().version);
268 }
269}
270
271TEST_F(ConfigurationParserTest, DuplicateArtifactVersion) {
272 static constexpr const char* configuration = R"xml(<?xml version="1.0" encoding="utf-8" ?>
273 <pst-process xmlns="http://schemas.android.com/tools/aapt">>
274 <artifacts>
275 <artifact-format>
276 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
277 </artifact-format>
278 <artifact
279 name="art1"
280 abi-group="arm"
281 screen-density-group="large"
282 locale-group="europe"
283 android-sdk-group="v19"
284 gl-texture-group="dxt1"
285 device-feature-group="low-latency"/>
286 <artifact
287 name="art2"
288 version = "1"
289 abi-group="other"
290 screen-density-group="alldpi"
291 locale-group="north-america"
292 android-sdk-group="v19"
293 gl-texture-group="dxt1"
294 device-feature-group="low-latency"/>
295 </artifacts>
296 </post-process>)xml";
Shane Farmercb6c3f92017-11-27 13:19:36 -0800297 auto result = ConfigurationParser::ForContents(configuration).Parse("test.apk");
Shane Farmer810fd182017-09-21 14:37:44 -0700298 ASSERT_FALSE(result);
Shane Farmer74cdea32017-05-12 16:22:36 -0700299}
300
301TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
Shane Farmer810fd182017-09-21 14:37:44 -0700302 const auto doc = test::BuildXmlDom(R"xml(
Shane Farmer74cdea32017-05-12 16:22:36 -0700303 <artifact-format>
304 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
Shane Farmer810fd182017-09-21 14:37:44 -0700305 </artifact-format>)xml");
Shane Farmer74cdea32017-05-12 16:22:36 -0700306
Shane Farmer280be342017-06-21 15:20:15 -0700307 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800308 bool ok = ArtifactFormatTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700309 ASSERT_TRUE(ok);
310 ASSERT_TRUE(config.artifact_format);
311 EXPECT_EQ(
312 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
313 static_cast<std::string>(config.artifact_format.value())
314 );
315}
316
317TEST_F(ConfigurationParserTest, AbiGroupAction) {
318 static constexpr const char* xml = R"xml(
319 <abi-group label="arm">
320 <!-- First comment. -->
321 <abi>
322 armeabi-v7a
323 </abi>
324 <!-- Another comment. -->
325 <abi>arm64-v8a</abi>
326 </abi-group>)xml";
327
328 auto doc = test::BuildXmlDom(xml);
329
Shane Farmer280be342017-06-21 15:20:15 -0700330 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800331 bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700332 ASSERT_TRUE(ok);
333
Shane Farmercb6c3f92017-11-27 13:19:36 -0800334 EXPECT_THAT(config.abi_groups, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700335 ASSERT_EQ(1u, config.abi_groups.count("arm"));
336
337 auto& out = config.abi_groups["arm"];
338 ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
339}
340
341TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
342 static constexpr const char* xml = R"xml(
343 <screen-density-group label="large">
344 <screen-density>xhdpi</screen-density>
345 <screen-density>
346 xxhdpi
347 </screen-density>
348 <screen-density>xxxhdpi</screen-density>
349 </screen-density-group>)xml";
350
351 auto doc = test::BuildXmlDom(xml);
352
Shane Farmer280be342017-06-21 15:20:15 -0700353 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800354 bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700355 ASSERT_TRUE(ok);
356
Shane Farmercb6c3f92017-11-27 13:19:36 -0800357 EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700358 ASSERT_EQ(1u, config.screen_density_groups.count("large"));
359
360 ConfigDescription xhdpi;
361 xhdpi.density = ResTable_config::DENSITY_XHIGH;
362 ConfigDescription xxhdpi;
363 xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
364 ConfigDescription xxxhdpi;
365 xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
366
367 auto& out = config.screen_density_groups["large"];
368 ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
369}
370
371TEST_F(ConfigurationParserTest, LocaleGroupAction) {
372 static constexpr const char* xml = R"xml(
373 <locale-group label="europe">
Shane Farmer0a5b2012017-06-22 12:24:12 -0700374 <locale>en</locale>
375 <locale>es</locale>
376 <locale>fr</locale>
377 <locale>de</locale>
Shane Farmer74cdea32017-05-12 16:22:36 -0700378 </locale-group>)xml";
379
380 auto doc = test::BuildXmlDom(xml);
381
Shane Farmer280be342017-06-21 15:20:15 -0700382 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800383 bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700384 ASSERT_TRUE(ok);
385
386 ASSERT_EQ(1ul, config.locale_groups.size());
387 ASSERT_EQ(1u, config.locale_groups.count("europe"));
388
Shane Farmer0a5b2012017-06-22 12:24:12 -0700389 const auto& out = config.locale_groups["europe"];
Shane Farmer74cdea32017-05-12 16:22:36 -0700390
Shane Farmer0a5b2012017-06-22 12:24:12 -0700391 ConfigDescription en = test::ParseConfigOrDie("en");
392 ConfigDescription es = test::ParseConfigOrDie("es");
393 ConfigDescription fr = test::ParseConfigOrDie("fr");
394 ConfigDescription de = test::ParseConfigOrDie("de");
Shane Farmer74cdea32017-05-12 16:22:36 -0700395
396 ASSERT_THAT(out, ElementsAre(en, es, fr, de));
397}
398
399TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
400 static constexpr const char* xml = R"xml(
Shane Farmerefe45392017-08-21 14:39:28 -0700401 <android-sdk-group label="v19">
Shane Farmer74cdea32017-05-12 16:22:36 -0700402 <android-sdk
Shane Farmer3edd4722017-09-01 14:34:22 -0700403 minSdkVersion="19"
404 targetSdkVersion="24"
405 maxSdkVersion="25">
Shane Farmer74cdea32017-05-12 16:22:36 -0700406 <manifest>
407 <!--- manifest additions here XSLT? TODO -->
408 </manifest>
409 </android-sdk>
410 </android-sdk-group>)xml";
411
412 auto doc = test::BuildXmlDom(xml);
413
Shane Farmer280be342017-06-21 15:20:15 -0700414 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800415 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700416 ASSERT_TRUE(ok);
417
418 ASSERT_EQ(1ul, config.android_sdk_groups.size());
Shane Farmerefe45392017-08-21 14:39:28 -0700419 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
Shane Farmer74cdea32017-05-12 16:22:36 -0700420
Shane Farmerefe45392017-08-21 14:39:28 -0700421 auto& out = config.android_sdk_groups["v19"];
Shane Farmer74cdea32017-05-12 16:22:36 -0700422
423 AndroidSdk sdk;
Shane Farmer3edd4722017-09-01 14:34:22 -0700424 sdk.min_sdk_version = 19;
425 sdk.target_sdk_version = 24;
426 sdk.max_sdk_version = 25;
Shane Farmer74cdea32017-05-12 16:22:36 -0700427 sdk.manifest = AndroidManifest();
428
Shane Farmerefe45392017-08-21 14:39:28 -0700429 ASSERT_EQ(sdk, out);
Shane Farmer74cdea32017-05-12 16:22:36 -0700430}
431
Shane Farmer67e8a302017-12-06 14:39:10 -0800432TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
433 {
434 static constexpr const char* xml = R"xml(
435 <android-sdk-group label="v19">
436 <android-sdk minSdkVersion="19"></android-sdk>
437 </android-sdk-group>)xml";
438
439 auto doc = test::BuildXmlDom(xml);
440
441 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800442 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer67e8a302017-12-06 14:39:10 -0800443 ASSERT_TRUE(ok);
444
445 ASSERT_EQ(1ul, config.android_sdk_groups.size());
446 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
447
448 auto& out = config.android_sdk_groups["v19"];
449 EXPECT_EQ(19, out.min_sdk_version.value());
450 EXPECT_FALSE(out.max_sdk_version);
451 EXPECT_FALSE(out.target_sdk_version);
452 }
453
454 {
455 static constexpr const char* xml = R"xml(
456 <android-sdk-group label="v19">
457 <android-sdk maxSdkVersion="19"></android-sdk>
458 </android-sdk-group>)xml";
459
460 auto doc = test::BuildXmlDom(xml);
461
462 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800463 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer67e8a302017-12-06 14:39:10 -0800464 ASSERT_TRUE(ok);
465
466 ASSERT_EQ(1ul, config.android_sdk_groups.size());
467 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
468
469 auto& out = config.android_sdk_groups["v19"];
470 EXPECT_EQ(19, out.max_sdk_version.value());
471 EXPECT_FALSE(out.min_sdk_version);
472 EXPECT_FALSE(out.target_sdk_version);
473 }
474
475 {
476 static constexpr const char* xml = R"xml(
477 <android-sdk-group label="v19">
478 <android-sdk targetSdkVersion="19"></android-sdk>
479 </android-sdk-group>)xml";
480
481 auto doc = test::BuildXmlDom(xml);
482
483 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800484 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer67e8a302017-12-06 14:39:10 -0800485 ASSERT_TRUE(ok);
486
487 ASSERT_EQ(1ul, config.android_sdk_groups.size());
488 ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));
489
490 auto& out = config.android_sdk_groups["v19"];
491 EXPECT_EQ(19, out.target_sdk_version.value());
492 EXPECT_FALSE(out.min_sdk_version);
493 EXPECT_FALSE(out.max_sdk_version);
494 }
495}
496
497TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
Shane Farmer3edd4722017-09-01 14:34:22 -0700498 static constexpr const char* xml = R"xml(
Shane Farmer67e8a302017-12-06 14:39:10 -0800499 <android-sdk-group label="v19">
Shane Farmer3edd4722017-09-01 14:34:22 -0700500 <android-sdk
Shane Farmer67e8a302017-12-06 14:39:10 -0800501 minSdkVersion="v19"
502 targetSdkVersion="v24"
503 maxSdkVersion="v25">
504 <manifest>
505 <!--- manifest additions here XSLT? TODO -->
506 </manifest>
Shane Farmer3edd4722017-09-01 14:34:22 -0700507 </android-sdk>
508 </android-sdk-group>)xml";
509
510 auto doc = test::BuildXmlDom(xml);
511
512 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800513 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer67e8a302017-12-06 14:39:10 -0800514 ASSERT_FALSE(ok);
515}
516
517TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
518 static constexpr const char* xml = R"xml(
519 <android-sdk-group label="P">
520 <android-sdk
521 minSdkVersion="25"
522 targetSdkVersion="%s"
523 maxSdkVersion="%s">
524 </android-sdk>
525 </android-sdk-group>)xml";
526
527 const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
528 const char* codename = dev_sdk.first.data();
529 const ApiVersion& version = dev_sdk.second;
530
531 auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
532
533 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800534 bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer3edd4722017-09-01 14:34:22 -0700535 ASSERT_TRUE(ok);
536
537 ASSERT_EQ(1ul, config.android_sdk_groups.size());
Adam Lesinski178e6782017-11-02 14:12:38 -0700538 ASSERT_EQ(1u, config.android_sdk_groups.count("P"));
Shane Farmer3edd4722017-09-01 14:34:22 -0700539
Adam Lesinski178e6782017-11-02 14:12:38 -0700540 auto& out = config.android_sdk_groups["P"];
Shane Farmer3edd4722017-09-01 14:34:22 -0700541
542 AndroidSdk sdk;
Shane Farmer67e8a302017-12-06 14:39:10 -0800543 sdk.min_sdk_version = 25;
544 sdk.target_sdk_version = version;
545 sdk.max_sdk_version = version;
Shane Farmer3edd4722017-09-01 14:34:22 -0700546
547 ASSERT_EQ(sdk, out);
548}
549
Shane Farmer74cdea32017-05-12 16:22:36 -0700550TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
551 static constexpr const char* xml = R"xml(
552 <gl-texture-group label="dxt1">
553 <gl-texture name="GL_EXT_texture_compression_dxt1">
554 <texture-path>assets/dxt1/main/*</texture-path>
555 <texture-path>
556 assets/dxt1/test/*
557 </texture-path>
558 </gl-texture>
559 </gl-texture-group>)xml";
560
561 auto doc = test::BuildXmlDom(xml);
562
Shane Farmer280be342017-06-21 15:20:15 -0700563 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800564 bool ok = GlTextureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700565 ASSERT_TRUE(ok);
566
Shane Farmercb6c3f92017-11-27 13:19:36 -0800567 EXPECT_THAT(config.gl_texture_groups, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700568 ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
569
570 auto& out = config.gl_texture_groups["dxt1"];
571
572 GlTexture texture{
573 std::string("GL_EXT_texture_compression_dxt1"),
574 {"assets/dxt1/main/*", "assets/dxt1/test/*"}
575 };
576
577 ASSERT_EQ(1ul, out.size());
578 ASSERT_EQ(texture, out[0]);
579}
580
581TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
582 static constexpr const char* xml = R"xml(
583 <device-feature-group label="low-latency">
584 <supports-feature>android.hardware.audio.low_latency</supports-feature>
585 <supports-feature>
586 android.hardware.audio.pro
587 </supports-feature>
588 </device-feature-group>)xml";
589
590 auto doc = test::BuildXmlDom(xml);
591
Shane Farmer280be342017-06-21 15:20:15 -0700592 PostProcessingConfiguration config;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800593 bool ok = DeviceFeatureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
Shane Farmer74cdea32017-05-12 16:22:36 -0700594 ASSERT_TRUE(ok);
595
Shane Farmercb6c3f92017-11-27 13:19:36 -0800596 EXPECT_THAT(config.device_feature_groups, SizeIs(1ul));
Shane Farmer74cdea32017-05-12 16:22:36 -0700597 ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
598
599 auto& out = config.device_feature_groups["low-latency"];
600
601 DeviceFeature low_latency = "android.hardware.audio.low_latency";
602 DeviceFeature pro = "android.hardware.audio.pro";
603 ASSERT_THAT(out, ElementsAre(low_latency, pro));
604}
605
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700606// Artifact name parser test cases.
607
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700608TEST(ArtifactTest, Simple) {
609 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800610 ConfiguredArtifact x86;
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700611 x86.abi_group = {"x86"};
612
Shane Farmer9ecc0752017-08-24 15:55:36 -0700613 auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700614 ASSERT_TRUE(x86_result);
615 EXPECT_EQ(x86_result.value(), "something.x86.apk");
616
Shane Farmercb6c3f92017-11-27 13:19:36 -0800617 ConfiguredArtifact arm;
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700618 arm.abi_group = {"armeabi-v7a"};
619
Shane Farmer9ecc0752017-08-24 15:55:36 -0700620 {
621 auto arm_result = arm.ToArtifactName("app.${abi}.apk", "", &diag);
622 ASSERT_TRUE(arm_result);
623 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
624 }
625
626 {
627 auto arm_result = arm.ToArtifactName("app.${abi}.apk", "different_name.apk", &diag);
628 ASSERT_TRUE(arm_result);
629 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
630 }
631
632 {
633 auto arm_result = arm.ToArtifactName("${basename}.${abi}.apk", "app.apk", &diag);
634 ASSERT_TRUE(arm_result);
635 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
636 }
637
638 {
639 auto arm_result = arm.ToArtifactName("app.${abi}.${ext}", "app.apk", &diag);
640 ASSERT_TRUE(arm_result);
641 EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
642 }
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700643}
644
645TEST(ArtifactTest, Complex) {
646 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800647 ConfiguredArtifact artifact;
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700648 artifact.abi_group = {"mips64"};
649 artifact.screen_density_group = {"ldpi"};
650 artifact.device_feature_group = {"df1"};
651 artifact.gl_texture_group = {"glx1"};
652 artifact.locale_group = {"en-AU"};
Shane Farmerefe45392017-08-21 14:39:28 -0700653 artifact.android_sdk_group = {"v26"};
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700654
Shane Farmer9ecc0752017-08-24 15:55:36 -0700655 {
656 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700657 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700658 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700659 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700660 }
661
662 {
663 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700664 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700665 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700666 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700667 }
668
669 {
670 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700671 "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700672 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700673 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700674 }
675
676 {
677 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700678 "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.${ext}", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700679 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700680 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700681 }
682
683 {
684 auto result = artifact.ToArtifactName(
Shane Farmerefe45392017-08-21 14:39:28 -0700685 "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}", "app.apk", &diag);
Shane Farmer9ecc0752017-08-24 15:55:36 -0700686 ASSERT_TRUE(result);
Shane Farmerefe45392017-08-21 14:39:28 -0700687 EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
Shane Farmer9ecc0752017-08-24 15:55:36 -0700688 }
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700689}
690
691TEST(ArtifactTest, Missing) {
692 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800693 ConfiguredArtifact x86;
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700694 x86.abi_group = {"x86"};
695
Shane Farmer9ecc0752017-08-24 15:55:36 -0700696 EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
697 EXPECT_FALSE(x86.ToArtifactName("something.apk", "", &diag));
698 EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "something.apk", &diag));
699 EXPECT_FALSE(x86.ToArtifactName("something.apk", "something.apk", &diag));
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700700}
701
702TEST(ArtifactTest, Empty) {
703 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800704 ConfiguredArtifact artifact;
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700705
Shane Farmer9ecc0752017-08-24 15:55:36 -0700706 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
707 EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
708 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
709 EXPECT_TRUE(artifact.ToArtifactName("something.apk", "something.apk", &diag));
Shane Farmer9f0e7f12017-06-22 12:26:44 -0700710}
711
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700712TEST(ArtifactTest, Repeated) {
713 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800714 ConfiguredArtifact artifact;
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700715 artifact.screen_density_group = {"mdpi"};
716
Shane Farmer9ecc0752017-08-24 15:55:36 -0700717 ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
718 EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", "", &diag));
719 ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700720}
721
722TEST(ArtifactTest, Nesting) {
723 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800724 ConfiguredArtifact x86;
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700725 x86.abi_group = {"x86"};
726
Shane Farmer9ecc0752017-08-24 15:55:36 -0700727 EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700728
Shane Farmer9ecc0752017-08-24 15:55:36 -0700729 const Maybe<std::string>& name = x86.ToArtifactName("something.${abi${abi}}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700730 ASSERT_TRUE(name);
731 EXPECT_EQ(name.value(), "something.${abix86}.apk");
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700732}
733
734TEST(ArtifactTest, Recursive) {
735 StdErrDiagnostics diag;
Shane Farmercb6c3f92017-11-27 13:19:36 -0800736 ConfiguredArtifact artifact;
Shane Farmer0a5b2012017-06-22 12:24:12 -0700737 artifact.device_feature_group = {"${gl}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700738 artifact.gl_texture_group = {"glx1"};
739
Shane Farmer9ecc0752017-08-24 15:55:36 -0700740 EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag));
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700741
742 artifact.device_feature_group = {"df1"};
Shane Farmer0a5b2012017-06-22 12:24:12 -0700743 artifact.gl_texture_group = {"${feature}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700744 {
Shane Farmer9ecc0752017-08-24 15:55:36 -0700745 const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700746 ASSERT_TRUE(result);
747 EXPECT_EQ(result.value(), "app.df1.${feature}.apk");
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700748 }
749
750 // This is an invalid case, but should be the only possible case due to the ordering of
751 // replacement.
Shane Farmer0a5b2012017-06-22 12:24:12 -0700752 artifact.device_feature_group = {"${gl}"};
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700753 artifact.gl_texture_group = {"glx1"};
754 {
Shane Farmer9ecc0752017-08-24 15:55:36 -0700755 const auto& result = artifact.ToArtifactName("app.${feature}.apk", "", &diag);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700756 ASSERT_TRUE(result);
Shane Farmer1a21b8c2017-07-21 09:42:42 -0700757 EXPECT_EQ(result.value(), "app.glx1.apk");
758 }
759}
760
Shane Farmer74cdea32017-05-12 16:22:36 -0700761} // namespace
Shane Farmercb6c3f92017-11-27 13:19:36 -0800762} // namespace handler
763} // namespace configuration
Shane Farmer74cdea32017-05-12 16:22:36 -0700764} // namespace aapt