blob: 72a97b273cb097d702d2a23870494d5646a26a5f [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
133TEST_F(ConfigurationParserTest, ValidateFile) {
134 auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
135 auto result = parser.Parse();
136 ASSERT_TRUE(result);
137 Configuration& value = result.value();
138 EXPECT_EQ(2ul, value.artifacts.size());
139 ASSERT_TRUE(value.artifact_format);
140 EXPECT_EQ(
141 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
142 value.artifact_format.value()
143 );
144
145 EXPECT_EQ(2ul, value.abi_groups.size());
146 EXPECT_EQ(2ul, value.abi_groups["arm"].size());
147 EXPECT_EQ(2ul, value.abi_groups["other"].size());
148
149 EXPECT_EQ(2ul, value.screen_density_groups.size());
150 EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
151 EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
152
153 EXPECT_EQ(3ul, value.locale_groups.size());
154 EXPECT_EQ(4ul, value.locale_groups["europe"].size());
155 EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
156 EXPECT_EQ(1ul, value.locale_groups["all"].size());
157
158 EXPECT_EQ(1ul, value.android_sdk_groups.size());
159 EXPECT_EQ(1ul, value.android_sdk_groups["19"].size());
160
161 EXPECT_EQ(1ul, value.gl_texture_groups.size());
162 EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
163
164 EXPECT_EQ(1ul, value.device_feature_groups.size());
165 EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
166}
167
168TEST_F(ConfigurationParserTest, InvalidNamespace) {
169 constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
170 <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
171
172 auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
173 ASSERT_FALSE(result);
174}
175
176TEST_F(ConfigurationParserTest, ArtifactAction) {
177 static constexpr const char* xml = R"xml(
178 <artifact
179 abi-group="arm"
180 screen-density-group="large"
181 locale-group="europe"
182 android-sdk-group="19"
183 gl-texture-group="dxt1"
184 device-feature-group="low-latency"/>)xml";
185
186 auto doc = test::BuildXmlDom(xml);
187
188 Configuration config;
189 bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
190 ASSERT_TRUE(ok);
191
192 EXPECT_EQ(1ul, config.artifacts.size());
193
194 auto& artifact = config.artifacts.begin()->second;
195 EXPECT_EQ("", artifact.name); // TODO: make this fail.
196 EXPECT_EQ("arm", artifact.abi_group.value());
197 EXPECT_EQ("large", artifact.screen_density_group.value());
198 EXPECT_EQ("europe", artifact.locale_group.value());
199 EXPECT_EQ("19", artifact.android_sdk_group.value());
200 EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
201 EXPECT_EQ("low-latency", artifact.device_feature_group.value());
202}
203
204TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
205 static constexpr const char* xml = R"xml(
206 <artifact-format>
207 ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
208 </artifact-format>)xml";
209
210 auto doc = test::BuildXmlDom(xml);
211
212 Configuration config;
213 bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
214 ASSERT_TRUE(ok);
215 ASSERT_TRUE(config.artifact_format);
216 EXPECT_EQ(
217 "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
218 static_cast<std::string>(config.artifact_format.value())
219 );
220}
221
222TEST_F(ConfigurationParserTest, AbiGroupAction) {
223 static constexpr const char* xml = R"xml(
224 <abi-group label="arm">
225 <!-- First comment. -->
226 <abi>
227 armeabi-v7a
228 </abi>
229 <!-- Another comment. -->
230 <abi>arm64-v8a</abi>
231 </abi-group>)xml";
232
233 auto doc = test::BuildXmlDom(xml);
234
235 Configuration config;
236 bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
237 ASSERT_TRUE(ok);
238
239 EXPECT_EQ(1ul, config.abi_groups.size());
240 ASSERT_EQ(1u, config.abi_groups.count("arm"));
241
242 auto& out = config.abi_groups["arm"];
243 ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
244}
245
246TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
247 static constexpr const char* xml = R"xml(
248 <screen-density-group label="large">
249 <screen-density>xhdpi</screen-density>
250 <screen-density>
251 xxhdpi
252 </screen-density>
253 <screen-density>xxxhdpi</screen-density>
254 </screen-density-group>)xml";
255
256 auto doc = test::BuildXmlDom(xml);
257
258 Configuration config;
259 bool ok =
260 screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
261 ASSERT_TRUE(ok);
262
263 EXPECT_EQ(1ul, config.screen_density_groups.size());
264 ASSERT_EQ(1u, config.screen_density_groups.count("large"));
265
266 ConfigDescription xhdpi;
267 xhdpi.density = ResTable_config::DENSITY_XHIGH;
268 ConfigDescription xxhdpi;
269 xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
270 ConfigDescription xxxhdpi;
271 xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
272
273 auto& out = config.screen_density_groups["large"];
274 ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
275}
276
277TEST_F(ConfigurationParserTest, LocaleGroupAction) {
278 static constexpr const char* xml = R"xml(
279 <locale-group label="europe">
280 <locale lang="en"/>
281 <locale lang="es"/>
282 <locale lang="fr"/>
283 <locale lang="de"/>
284 </locale-group>)xml";
285
286 auto doc = test::BuildXmlDom(xml);
287
288 Configuration config;
289 bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
290 ASSERT_TRUE(ok);
291
292 ASSERT_EQ(1ul, config.locale_groups.size());
293 ASSERT_EQ(1u, config.locale_groups.count("europe"));
294
295 auto& out = config.locale_groups["europe"];
296
297 Locale en;
298 en.lang = std::string("en");
299 Locale es;
300 es.lang = std::string("es");
301 Locale fr;
302 fr.lang = std::string("fr");
303 Locale de;
304 de.lang = std::string("de");
305
306 ASSERT_THAT(out, ElementsAre(en, es, fr, de));
307}
308
309TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
310 static constexpr const char* xml = R"xml(
311 <android-sdk-group label="19">
312 <android-sdk
313 minSdkVersion="19"
314 targetSdkVersion="24"
315 maxSdkVersion="25">
316 <manifest>
317 <!--- manifest additions here XSLT? TODO -->
318 </manifest>
319 </android-sdk>
320 </android-sdk-group>)xml";
321
322 auto doc = test::BuildXmlDom(xml);
323
324 Configuration config;
325 bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
326 ASSERT_TRUE(ok);
327
328 ASSERT_EQ(1ul, config.android_sdk_groups.size());
329 ASSERT_EQ(1u, config.android_sdk_groups.count("19"));
330
331 auto& out = config.android_sdk_groups["19"];
332
333 AndroidSdk sdk;
334 sdk.min_sdk_version = std::string("19");
335 sdk.target_sdk_version = std::string("24");
336 sdk.max_sdk_version = std::string("25");
337 sdk.manifest = AndroidManifest();
338
339 ASSERT_EQ(1ul, out.size());
340 ASSERT_EQ(sdk, out[0]);
341}
342
343TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
344 static constexpr const char* xml = R"xml(
345 <gl-texture-group label="dxt1">
346 <gl-texture name="GL_EXT_texture_compression_dxt1">
347 <texture-path>assets/dxt1/main/*</texture-path>
348 <texture-path>
349 assets/dxt1/test/*
350 </texture-path>
351 </gl-texture>
352 </gl-texture-group>)xml";
353
354 auto doc = test::BuildXmlDom(xml);
355
356 Configuration config;
357 bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
358 ASSERT_TRUE(ok);
359
360 EXPECT_EQ(1ul, config.gl_texture_groups.size());
361 ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
362
363 auto& out = config.gl_texture_groups["dxt1"];
364
365 GlTexture texture{
366 std::string("GL_EXT_texture_compression_dxt1"),
367 {"assets/dxt1/main/*", "assets/dxt1/test/*"}
368 };
369
370 ASSERT_EQ(1ul, out.size());
371 ASSERT_EQ(texture, out[0]);
372}
373
374TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
375 static constexpr const char* xml = R"xml(
376 <device-feature-group label="low-latency">
377 <supports-feature>android.hardware.audio.low_latency</supports-feature>
378 <supports-feature>
379 android.hardware.audio.pro
380 </supports-feature>
381 </device-feature-group>)xml";
382
383 auto doc = test::BuildXmlDom(xml);
384
385 Configuration config;
386 bool ok
387 = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
388 ASSERT_TRUE(ok);
389
390 EXPECT_EQ(1ul, config.device_feature_groups.size());
391 ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
392
393 auto& out = config.device_feature_groups["low-latency"];
394
395 DeviceFeature low_latency = "android.hardware.audio.low_latency";
396 DeviceFeature pro = "android.hardware.audio.pro";
397 ASSERT_THAT(out, ElementsAre(low_latency, pro));
398}
399
400} // namespace
401} // namespace aapt