blob: a8c385823fa909985e1028f521125d96dee2f325 [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
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23
24#include "androidfw/ResourceTypes.h"
25
26#include "test/Test.h"
27#include "xml/XmlDom.h"
28
29namespace aapt {
30namespace {
31
32using android::ResTable_config;
33using configuration::Abi;
34using configuration::AndroidSdk;
35using configuration::Configuration;
36using configuration::DeviceFeature;
37using configuration::GlTexture;
38using configuration::Locale;
39using configuration::AndroidManifest;
40using testing::ElementsAre;
41using xml::Element;
42using xml::NodeCast;
43
44constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
45<post-process xmlns="http://schemas.android.com/tools/aapt">
46 <groups>
47 <abi-group label="arm">
48 <abi>armeabi-v7a</abi>
49 <abi>arm64-v8a</abi>
50 </abi-group>
51 <abi-group label="other">
52 <abi>x86</abi>
53 <abi>mips</abi>
54 </abi-group>
55 <screen-density-group label="large">
56 <screen-density>xhdpi</screen-density>
57 <screen-density>xxhdpi</screen-density>
58 <screen-density>xxxhdpi</screen-density>
59 </screen-density-group>
60 <screen-density-group label="alldpi">
61 <screen-density>ldpi</screen-density>
62 <screen-density>mdpi</screen-density>
63 <screen-density>hdpi</screen-density>
64 <screen-density>xhdpi</screen-density>
65 <screen-density>xxhdpi</screen-density>
66 <screen-density>xxxhdpi</screen-density>
67 </screen-density-group>
68 <locale-group label="europe">
69 <locale lang="en"/>
70 <locale lang="es"/>
71 <locale lang="fr"/>
72 <locale lang="de"/>
73 </locale-group>
74 <locale-group label="north-america">
75 <locale lang="en"/>
76 <locale lang="es" region="MX"/>
77 <locale lang="fr" region="CA"/>
78 </locale-group>
79 <locale-group label="all">
80 <locale/>
81 </locale-group>
82 <android-sdk-group label="19">
83 <android-sdk
84 minSdkVersion="19"
85 targetSdkVersion="24"
86 maxSdkVersion="25">
87 <manifest>
88 <!--- manifest additions here XSLT? TODO -->
89 </manifest>
90 </android-sdk>
91 </android-sdk-group>
92 <gl-texture-group label="dxt1">
93 <gl-texture name="GL_EXT_texture_compression_dxt1">
94 <texture-path>assets/dxt1/*</texture-path>
95 </gl-texture>
96 </gl-texture-group>
97 <device-feature-group label="low-latency">
98 <supports-feature>android.hardware.audio.low_latency</supports-feature>
99 </device-feature-group>
100 </groups>
101 <artifacts>
102 <artifact-format>
103 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
104 </artifact-format>
105 <artifact
106 name="art1"
107 abi-group="arm"
108 screen-density-group="large"
109 locale-group="europe"
110 android-sdk-group="19"
111 gl-texture-group="dxt1"
112 device-feature-group="low-latency"/>
113 <artifact
114 name="art2"
115 abi-group="other"
116 screen-density-group="alldpi"
117 locale-group="north-america"
118 android-sdk-group="19"
119 gl-texture-group="dxt1"
120 device-feature-group="low-latency"/>
121 </artifacts>
122</post-process>
123)";
124
125class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
126 public:
127 ConfigurationParserTest() : ConfigurationParser("") {}
128
129 protected:
130 StdErrDiagnostics diag_;
131};
132
Shane Farmerb1027272017-06-14 09:10:28 -0700133TEST_F(ConfigurationParserTest, ForPath_NoFile) {
134 auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
135 EXPECT_FALSE(result);
136}
137
Shane Farmer74cdea32017-05-12 16:22:36 -0700138TEST_F(ConfigurationParserTest, ValidateFile) {
139 auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
140 auto result = parser.Parse();
141 ASSERT_TRUE(result);
142 Configuration& value = result.value();
143 EXPECT_EQ(2ul, value.artifacts.size());
144 ASSERT_TRUE(value.artifact_format);
145 EXPECT_EQ(
146 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
147 value.artifact_format.value()
148 );
149
150 EXPECT_EQ(2ul, value.abi_groups.size());
151 EXPECT_EQ(2ul, value.abi_groups["arm"].size());
152 EXPECT_EQ(2ul, value.abi_groups["other"].size());
153
154 EXPECT_EQ(2ul, value.screen_density_groups.size());
155 EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
156 EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
157
158 EXPECT_EQ(3ul, value.locale_groups.size());
159 EXPECT_EQ(4ul, value.locale_groups["europe"].size());
160 EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
161 EXPECT_EQ(1ul, value.locale_groups["all"].size());
162
163 EXPECT_EQ(1ul, value.android_sdk_groups.size());
164 EXPECT_EQ(1ul, value.android_sdk_groups["19"].size());
165
166 EXPECT_EQ(1ul, value.gl_texture_groups.size());
167 EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
168
169 EXPECT_EQ(1ul, value.device_feature_groups.size());
170 EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
171}
172
173TEST_F(ConfigurationParserTest, InvalidNamespace) {
174 constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
175 <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
176
177 auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
178 ASSERT_FALSE(result);
179}
180
181TEST_F(ConfigurationParserTest, ArtifactAction) {
182 static constexpr const char* xml = R"xml(
183 <artifact
184 abi-group="arm"
185 screen-density-group="large"
186 locale-group="europe"
187 android-sdk-group="19"
188 gl-texture-group="dxt1"
189 device-feature-group="low-latency"/>)xml";
190
191 auto doc = test::BuildXmlDom(xml);
192
193 Configuration config;
194 bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
195 ASSERT_TRUE(ok);
196
197 EXPECT_EQ(1ul, config.artifacts.size());
198
Shane Farmer57669432017-06-19 12:52:04 -0700199 auto& artifact = config.artifacts.front();
Shane Farmer74cdea32017-05-12 16:22:36 -0700200 EXPECT_EQ("", artifact.name); // TODO: make this fail.
201 EXPECT_EQ("arm", artifact.abi_group.value());
202 EXPECT_EQ("large", artifact.screen_density_group.value());
203 EXPECT_EQ("europe", artifact.locale_group.value());
204 EXPECT_EQ("19", artifact.android_sdk_group.value());
205 EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
206 EXPECT_EQ("low-latency", artifact.device_feature_group.value());
Shane Farmer57669432017-06-19 12:52:04 -0700207
208 // Perform a second action to ensure we get 2 artifacts.
209 static constexpr const char* second = R"xml(
210 <artifact
211 abi-group="other"
212 screen-density-group="large"
213 locale-group="europe"
214 android-sdk-group="19"
215 gl-texture-group="dxt1"
216 device-feature-group="low-latency"/>)xml";
217 doc = test::BuildXmlDom(second);
218
219 ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
220 ASSERT_TRUE(ok);
221 EXPECT_EQ(2ul, config.artifacts.size());
Shane Farmer74cdea32017-05-12 16:22:36 -0700222}
223
224TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
225 static constexpr const char* xml = R"xml(
226 <artifact-format>
227 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
228 </artifact-format>)xml";
229
230 auto doc = test::BuildXmlDom(xml);
231
232 Configuration config;
233 bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
234 ASSERT_TRUE(ok);
235 ASSERT_TRUE(config.artifact_format);
236 EXPECT_EQ(
237 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
238 static_cast<std::string>(config.artifact_format.value())
239 );
240}
241
242TEST_F(ConfigurationParserTest, AbiGroupAction) {
243 static constexpr const char* xml = R"xml(
244 <abi-group label="arm">
245 <!-- First comment. -->
246 <abi>
247 armeabi-v7a
248 </abi>
249 <!-- Another comment. -->
250 <abi>arm64-v8a</abi>
251 </abi-group>)xml";
252
253 auto doc = test::BuildXmlDom(xml);
254
255 Configuration config;
256 bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
257 ASSERT_TRUE(ok);
258
259 EXPECT_EQ(1ul, config.abi_groups.size());
260 ASSERT_EQ(1u, config.abi_groups.count("arm"));
261
262 auto& out = config.abi_groups["arm"];
263 ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
264}
265
266TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
267 static constexpr const char* xml = R"xml(
268 <screen-density-group label="large">
269 <screen-density>xhdpi</screen-density>
270 <screen-density>
271 xxhdpi
272 </screen-density>
273 <screen-density>xxxhdpi</screen-density>
274 </screen-density-group>)xml";
275
276 auto doc = test::BuildXmlDom(xml);
277
278 Configuration config;
279 bool ok =
280 screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
281 ASSERT_TRUE(ok);
282
283 EXPECT_EQ(1ul, config.screen_density_groups.size());
284 ASSERT_EQ(1u, config.screen_density_groups.count("large"));
285
286 ConfigDescription xhdpi;
287 xhdpi.density = ResTable_config::DENSITY_XHIGH;
288 ConfigDescription xxhdpi;
289 xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
290 ConfigDescription xxxhdpi;
291 xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
292
293 auto& out = config.screen_density_groups["large"];
294 ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
295}
296
297TEST_F(ConfigurationParserTest, LocaleGroupAction) {
298 static constexpr const char* xml = R"xml(
299 <locale-group label="europe">
300 <locale lang="en"/>
301 <locale lang="es"/>
302 <locale lang="fr"/>
303 <locale lang="de"/>
304 </locale-group>)xml";
305
306 auto doc = test::BuildXmlDom(xml);
307
308 Configuration config;
309 bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
310 ASSERT_TRUE(ok);
311
312 ASSERT_EQ(1ul, config.locale_groups.size());
313 ASSERT_EQ(1u, config.locale_groups.count("europe"));
314
315 auto& out = config.locale_groups["europe"];
316
317 Locale en;
318 en.lang = std::string("en");
319 Locale es;
320 es.lang = std::string("es");
321 Locale fr;
322 fr.lang = std::string("fr");
323 Locale de;
324 de.lang = std::string("de");
325
326 ASSERT_THAT(out, ElementsAre(en, es, fr, de));
327}
328
329TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
330 static constexpr const char* xml = R"xml(
331 <android-sdk-group label="19">
332 <android-sdk
333 minSdkVersion="19"
334 targetSdkVersion="24"
335 maxSdkVersion="25">
336 <manifest>
337 <!--- manifest additions here XSLT? TODO -->
338 </manifest>
339 </android-sdk>
340 </android-sdk-group>)xml";
341
342 auto doc = test::BuildXmlDom(xml);
343
344 Configuration config;
345 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
346 ASSERT_TRUE(ok);
347
348 ASSERT_EQ(1ul, config.android_sdk_groups.size());
349 ASSERT_EQ(1u, config.android_sdk_groups.count("19"));
350
351 auto& out = config.android_sdk_groups["19"];
352
353 AndroidSdk sdk;
354 sdk.min_sdk_version = std::string("19");
355 sdk.target_sdk_version = std::string("24");
356 sdk.max_sdk_version = std::string("25");
357 sdk.manifest = AndroidManifest();
358
359 ASSERT_EQ(1ul, out.size());
360 ASSERT_EQ(sdk, out[0]);
361}
362
363TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
364 static constexpr const char* xml = R"xml(
365 <gl-texture-group label="dxt1">
366 <gl-texture name="GL_EXT_texture_compression_dxt1">
367 <texture-path>assets/dxt1/main/*</texture-path>
368 <texture-path>
369 assets/dxt1/test/*
370 </texture-path>
371 </gl-texture>
372 </gl-texture-group>)xml";
373
374 auto doc = test::BuildXmlDom(xml);
375
376 Configuration config;
377 bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
378 ASSERT_TRUE(ok);
379
380 EXPECT_EQ(1ul, config.gl_texture_groups.size());
381 ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
382
383 auto& out = config.gl_texture_groups["dxt1"];
384
385 GlTexture texture{
386 std::string("GL_EXT_texture_compression_dxt1"),
387 {"assets/dxt1/main/*", "assets/dxt1/test/*"}
388 };
389
390 ASSERT_EQ(1ul, out.size());
391 ASSERT_EQ(texture, out[0]);
392}
393
394TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
395 static constexpr const char* xml = R"xml(
396 <device-feature-group label="low-latency">
397 <supports-feature>android.hardware.audio.low_latency</supports-feature>
398 <supports-feature>
399 android.hardware.audio.pro
400 </supports-feature>
401 </device-feature-group>)xml";
402
403 auto doc = test::BuildXmlDom(xml);
404
405 Configuration config;
406 bool ok
407 = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
408 ASSERT_TRUE(ok);
409
410 EXPECT_EQ(1ul, config.device_feature_groups.size());
411 ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
412
413 auto& out = config.device_feature_groups["low-latency"];
414
415 DeviceFeature low_latency = "android.hardware.audio.low_latency";
416 DeviceFeature pro = "android.hardware.audio.pro";
417 ASSERT_THAT(out, ElementsAre(low_latency, pro));
418}
419
420} // namespace
421} // namespace aapt