174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer/*
274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Copyright (C) 2017 The Android Open Source Project
374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Licensed under the Apache License, Version 2.0 (the "License");
574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * you may not use this file except in compliance with the License.
674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * You may obtain a copy of the License at
774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *      http://www.apache.org/licenses/LICENSE-2.0
974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer *
1074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * Unless required by applicable law or agreed to in writing, software
1174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * distributed under the License is distributed on an "AS IS" BASIS,
1274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * See the License for the specific language governing permissions and
1474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer * limitations under the License.
1574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer */
1674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
1774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "configuration/ConfigurationParser.h"
1874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
1974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include <string>
2074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2167e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer#include "android-base/stringprintf.h"
2274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "androidfw/ResourceTypes.h"
2374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer#include "SdkConstants.h"
25cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer#include "configuration/ConfigurationParser.internal.h"
2674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "test/Test.h"
2774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer#include "xml/XmlDom.h"
2874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
2974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmernamespace aapt {
303edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
313edd47264335cf609ac6e733db77522f7c959c3fShane Farmernamespace configuration {
323edd47264335cf609ac6e733db77522f7c959c3fShane Farmervoid PrintTo(const AndroidSdk& sdk, std::ostream* os) {
3378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  *os << "SDK: min=" << sdk.min_sdk_version
343edd47264335cf609ac6e733db77522f7c959c3fShane Farmer      << ", target=" << sdk.target_sdk_version.value_or_default(-1)
353edd47264335cf609ac6e733db77522f7c959c3fShane Farmer      << ", max=" << sdk.max_sdk_version.value_or_default(-1);
363edd47264335cf609ac6e733db77522f7c959c3fShane Farmer}
37cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer
3878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmerbool operator==(const ConfiguredArtifact& lhs, const ConfiguredArtifact& rhs) {
3978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  return lhs.name == rhs.name && lhs.abi_group == rhs.abi_group &&
4078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer         lhs.screen_density_group == rhs.screen_density_group &&
4178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer         lhs.locale_group == rhs.locale_group && lhs.android_sdk == rhs.android_sdk &&
4278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer         lhs.device_feature_group == rhs.device_feature_group &&
4378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer         lhs.gl_texture_group == rhs.gl_texture_group;
4478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer}
4578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
4678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmerstd::ostream& operator<<(std::ostream& out, const Maybe<std::string>& value) {
4778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  PrintTo(value, &out);
4878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  return out;
4978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer}
5078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
5178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmervoid PrintTo(const ConfiguredArtifact& artifact, std::ostream* os) {
5278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  *os << "\n{"
5378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      << "\n  name: " << artifact.name << "\n  sdk: " << artifact.android_sdk
5478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      << "\n  abi: " << artifact.abi_group << "\n  density: " << artifact.screen_density_group
5578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      << "\n  locale: " << artifact.locale_group
5678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      << "\n  features: " << artifact.device_feature_group
5778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      << "\n  textures: " << artifact.gl_texture_group << "\n}\n";
5878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer}
5978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
60cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmernamespace handler {
613edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
6274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmernamespace {
6374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
6467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::Abi;
6567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::AndroidManifest;
6667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::AndroidSdk;
67cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmerusing ::aapt::configuration::ConfiguredArtifact;
6867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::DeviceFeature;
6978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmerusing ::aapt::configuration::ExtractConfiguration;
7067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::GlTexture;
7167e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::Locale;
7267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::configuration::PostProcessingConfiguration;
7367e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::xml::Element;
7467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::aapt::xml::NodeCast;
756b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiusing ::android::ResTable_config;
7667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmerusing ::android::base::StringPrintf;
776b372991296c9f2bd6f8f8847dcd23d50970d06dAdam Lesinskiusing ::testing::ElementsAre;
7878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmerusing ::testing::Eq;
79cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmerusing ::testing::SizeIs;
8078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmerusing ::testing::StrEq;
8174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
8274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerconstexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
8374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer<post-process xmlns="http://schemas.android.com/tools/aapt">
8478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <abi-groups>
8511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <abi-group label="other" version-code-order="2">
8674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>x86</abi>
8774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>mips</abi>
8874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </abi-group>
8911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <abi-group label="arm" version-code-order="1">
9011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer      <abi>armeabi-v7a</abi>
9111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer      <abi>arm64-v8a</abi>
9211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    </abi-group>
9378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </abi-groups>
9478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <screen-density-groups>
9511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <screen-density-group label="large" version-code-order="2">
9674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
9774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxhdpi</screen-density>
9874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
9974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>
10011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <screen-density-group label="alldpi" version-code-order="1">
10174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>ldpi</screen-density>
10274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>mdpi</screen-density>
10374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>hdpi</screen-density>
10474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
10574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxhdpi</screen-density>
10674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
10774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>
10878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </screen-density-groups>
10978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <locale-groups>
11011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <locale-group label="europe" version-code-order="1">
1110a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>en</locale>
1120a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>es</locale>
1130a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>fr</locale>
1140a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>de</locale>
11574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>
11611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <locale-group label="north-america" version-code-order="2">
1170a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>en</locale>
1180a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>es-rMX</locale>
1190a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>fr-rCA</locale>
12074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>
12111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <locale-group label="all" version-code-order="-1">
12211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer      <locale />
12311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    </locale-group>
12478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </locale-groups>
12578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <android-sdks>
12678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    <android-sdk
12778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    	  label="v19"
12878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        minSdkVersion="19"
12978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        targetSdkVersion="24"
13078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        maxSdkVersion="25">
13178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      <manifest>
13278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        <!--- manifest additions here XSLT? TODO -->
13378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      </manifest>
13478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    </android-sdk>
13578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </android-sdks>
13678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <gl-texture-groups>
13711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <gl-texture-group label="dxt1" version-code-order="2">
13874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <gl-texture name="GL_EXT_texture_compression_dxt1">
13974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>assets/dxt1/*</texture-path>
14074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </gl-texture>
14174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </gl-texture-group>
14278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </gl-texture-groups>
14378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  <device-feature-groups>
14411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <device-feature-group label="low-latency" version-code-order="2">
14574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>android.hardware.audio.low_latency</supports-feature>
14674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </device-feature-group>
14778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  </device-feature-groups>
14874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  <artifacts>
14974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact-format>
15074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
15174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </artifact-format>
15274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact
15374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        name="art1"
15474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        abi-group="arm"
15574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        screen-density-group="large"
15674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        locale-group="europe"
15778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        android-sdk="v19"
15874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        gl-texture-group="dxt1"
15974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        device-feature-group="low-latency"/>
16074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact
16174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        name="art2"
16274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        abi-group="other"
16374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        screen-density-group="alldpi"
16474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        locale-group="north-america"
16578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        android-sdk="v19"
16674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        gl-texture-group="dxt1"
16774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        device-feature-group="low-latency"/>
16874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  </artifacts>
16974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer</post-process>
17074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer)";
17174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
17274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmerclass ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
17374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer public:
17478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ConfigurationParserTest() : ConfigurationParser("", "config.xml") {
17578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
17674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
17774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer protected:
17874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  StdErrDiagnostics diag_;
17974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer};
18074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
181b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane FarmerTEST_F(ConfigurationParserTest, ForPath_NoFile) {
182b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer  auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
183b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer  EXPECT_FALSE(result);
184b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer}
185b102727771b9ac3d28d4f9b0a4a54b98bd1af958Shane Farmer
18678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane FarmerTEST_F(ConfigurationParserTest, ExtractConfiguration) {
18778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  Maybe<PostProcessingConfiguration> maybe_config =
18878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      ExtractConfiguration(kValidConfig, "dummy.xml", &diag_);
18978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
19078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  PostProcessingConfiguration config = maybe_config.value();
19178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
19278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& arm = config.abi_groups["arm"];
19378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& other = config.abi_groups["other"];
19411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(arm.order, 1);
19511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(other.order, 2);
19678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
19778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& large = config.screen_density_groups["large"];
19878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& alldpi = config.screen_density_groups["alldpi"];
19911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(large.order, 2);
20011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(alldpi.order, 1);
20178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
20278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& north_america = config.locale_groups["north-america"];
20378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& europe = config.locale_groups["europe"];
20411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto& all = config.locale_groups["all"];
20578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  // Checked in reverse to make sure access order does not matter.
20611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(north_america.order, 2);
20711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(europe.order, 1);
20811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(all.order, -1);
20911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(3ul, config.locale_groups.size());
21078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer}
21178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
21274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ValidateFile) {
21378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto parser = ConfigurationParser::ForContents(kValidConfig, "conf.xml").WithDiagnostics(&diag_);
214cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  auto result = parser.Parse("test.apk");
21574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(result);
216cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  const std::vector<OutputArtifact>& value = result.value();
217cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(value, SizeIs(2ul));
218cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer
219cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  const OutputArtifact& a1 = value[0];
220cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_EQ(a1.name, "art1.apk");
22178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ(a1.version, 1);
222cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a1.abis, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
223cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a1.screen_densities,
224cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer              ElementsAre(test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
225cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
226cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
227cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a1.locales, ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es"),
228cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                                      test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
22978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_TRUE(a1.android_sdk);
23078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_TRUE(a1.android_sdk.value().min_sdk_version);
23178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19l);
232cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a1.textures, SizeIs(1ul));
233cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a1.features, SizeIs(1ul));
234cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer
235cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  const OutputArtifact& a2 = value[1];
236cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_EQ(a2.name, "art2.apk");
23778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ(a2.version, 2);
238cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a2.abis, ElementsAre(Abi::kX86, Abi::kMips));
239cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a2.screen_densities,
240cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer              ElementsAre(test::ParseConfigOrDie("ldpi").CopyWithoutSdkVersion(),
241cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("mdpi").CopyWithoutSdkVersion(),
242cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("hdpi").CopyWithoutSdkVersion(),
243cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
244cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
245cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
246cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a2.locales,
247cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer              ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es-rMX"),
248cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer                          test::ParseConfigOrDie("fr-rCA")));
24978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_TRUE(a2.android_sdk);
25078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_TRUE(a2.android_sdk.value().min_sdk_version);
25178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19l);
252cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a2.textures, SizeIs(1ul));
253cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(a2.features, SizeIs(1ul));
25474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
25574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
25678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane FarmerTEST_F(ConfigurationParserTest, ConfiguredArtifactOrdering) {
25778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  // Create a base builder with the configuration groups but no artifacts to allow it to be copied.
25878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  test::PostProcessingConfigurationBuilder base_builder = test::PostProcessingConfigurationBuilder()
25978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer                                                              .AddAbiGroup("arm")
26078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer                                                              .AddAbiGroup("arm64")
26178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer                                                              .AddAndroidSdk("v23", 23)
26278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer                                                              .AddAndroidSdk("v19", 19);
26378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
26478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  {
26578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    // Test version ordering.
26678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact v23;
26778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    v23.android_sdk = {"v23"};
26878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact v19;
26978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    v19.android_sdk = {"v19"};
27078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
27178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    test::PostProcessingConfigurationBuilder builder = base_builder;
27278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    PostProcessingConfiguration config = builder.AddArtifact(v23).AddArtifact(v19).Build();
27378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
27478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    config.SortArtifacts();
27578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_THAT(config.artifacts, SizeIs(2));
27678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[0], Eq(v19));
27778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[1], Eq(v23));
27878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
27978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
28078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  {
28178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    // Test ABI ordering.
28278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm;
28378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.android_sdk = {"v19"};
28478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.abi_group = {"arm"};
28578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm64;
28678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm64.android_sdk = {"v19"};
28778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm64.abi_group = {"arm64"};
28878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
28978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    test::PostProcessingConfigurationBuilder builder = base_builder;
29078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    PostProcessingConfiguration config = builder.AddArtifact(arm64).AddArtifact(arm).Build();
29178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
29278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    config.SortArtifacts();
29378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_THAT(config.artifacts, SizeIs(2));
29478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[0], Eq(arm));
29578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[1], Eq(arm64));
29678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
29778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
29878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  {
29978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    // Test Android SDK has precedence over ABI.
30078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm;
30178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.android_sdk = {"v23"};
30278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.abi_group = {"arm"};
30378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm64;
30478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm64.android_sdk = {"v19"};
30578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm64.abi_group = {"arm64"};
30678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
30778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    test::PostProcessingConfigurationBuilder builder = base_builder;
30878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    PostProcessingConfiguration config = builder.AddArtifact(arm64).AddArtifact(arm).Build();
30978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
31078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    config.SortArtifacts();
31178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_THAT(config.artifacts, SizeIs(2));
31278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[0], Eq(arm64));
31378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[1], Eq(arm));
31478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
31578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
31678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  {
31778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    // Test version is better than ABI.
31878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm;
31978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.abi_group = {"arm"};
32078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact v19;
32178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    v19.android_sdk = {"v19"};
32278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
32378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    test::PostProcessingConfigurationBuilder builder = base_builder;
32478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    PostProcessingConfiguration config = builder.AddArtifact(v19).AddArtifact(arm).Build();
32578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
32678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    config.SortArtifacts();
32778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_THAT(config.artifacts, SizeIs(2));
32878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[0], Eq(arm));
32978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[1], Eq(v19));
33078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
33178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
33278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  {
33378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    // Test version is sorted higher than no version.
33478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact arm;
33578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    arm.abi_group = {"arm"};
33678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ConfiguredArtifact v19;
33778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    v19.abi_group = {"arm"};
33878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    v19.android_sdk = {"v19"};
33978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
34078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    test::PostProcessingConfigurationBuilder builder = base_builder;
34178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    PostProcessingConfiguration config = builder.AddArtifact(v19).AddArtifact(arm).Build();
34278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
34378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    config.SortArtifacts();
34478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_THAT(config.artifacts, SizeIs(2));
34578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[0], Eq(arm));
34678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_THAT(config.artifacts[1], Eq(v19));
34778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  }
34878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer}
34978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer
35074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, InvalidNamespace) {
35174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
35278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
35374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
35478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto result = ConfigurationParser::ForContents(invalid_ns, "config.xml").Parse("test.apk");
35574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_FALSE(result);
35674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
35774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
35874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ArtifactAction) {
359810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer  PostProcessingConfiguration config;
36078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  const auto doc = test::BuildXmlDom(R"xml(
361810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer      <artifact
362810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer          abi-group="arm"
363810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer          screen-density-group="large"
364810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer          locale-group="europe"
36578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer          android-sdk="v19"
366810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer          gl-texture-group="dxt1"
367810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer          device-feature-group="low-latency"/>)xml");
368810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer
36978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc->root.get()), &diag_));
370810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer
37178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_THAT(config.artifacts, SizeIs(1ul));
372810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer
37378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& artifact = config.artifacts.back();
37478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_FALSE(artifact.name);  // TODO: make this fail.
37578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("arm", artifact.abi_group.value());
37678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("large", artifact.screen_density_group.value());
37778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("europe", artifact.locale_group.value());
37878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("v19", artifact.android_sdk.value());
37978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
38078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  EXPECT_EQ("low-latency", artifact.device_feature_group.value());
38174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
38274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
38374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ArtifactFormatAction) {
384810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer  const auto doc = test::BuildXmlDom(R"xml(
38574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    <artifact-format>
38674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
387810fd184356a76fc0fa35d07212df10b7e058063Shane Farmer    </artifact-format>)xml");
38874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
389280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
390cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = ArtifactFormatTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
39174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
39274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(config.artifact_format);
39374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  EXPECT_EQ(
39474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
39574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      static_cast<std::string>(config.artifact_format.value())
39674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  );
39774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
39874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
39974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, AbiGroupAction) {
40074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
40111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <abi-group label="arm"  version-code-order="2">
40274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <!-- First comment. -->
40374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>
40474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        armeabi-v7a
40574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </abi>
40674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <!-- Another comment. -->
40774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <abi>arm64-v8a</abi>
40874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </abi-group>)xml";
40974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
41074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
41174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
412280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
413cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
41474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
41574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
416cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(config.abi_groups, SizeIs(1ul));
41774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.abi_groups.count("arm"));
41874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
41978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.abi_groups["arm"].entry;
42074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
42174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
42274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
42339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, AbiGroupAction_EmptyGroup) {
42411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml =
42511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer      R"xml(<abi-group label="arm64-v8a" version-code-order="3"/>)xml";
42639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
42739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
42839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
42939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
43039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
43139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_TRUE(ok);
43239e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
43339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  EXPECT_THAT(config.abi_groups, SizeIs(1ul));
43439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_EQ(1u, config.abi_groups.count("arm64-v8a"));
43539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
43611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto& out = config.abi_groups["arm64-v8a"];
43711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  ASSERT_THAT(out.entry, ElementsAre(Abi::kArm64V8a));
43811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(3, out.order);
43911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer}
44011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
44111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane FarmerTEST_F(ConfigurationParserTest, AbiGroupAction_EmptyGroup_NoOrder) {
44211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml = R"xml(<abi-group label="arm64-v8a"/>)xml";
44311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
44411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto doc = test::BuildXmlDom(xml);
44511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
44611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  PostProcessingConfiguration config;
44711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
44811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  ASSERT_FALSE(ok);
44939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
45039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
45139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, AbiGroupAction_InvalidEmptyGroup) {
45211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml = R"xml(<abi-group label="arm" order="2"/>)xml";
45339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
45439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
45539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
45639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
45739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
45839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_FALSE(ok);
45939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
46039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
46174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
46274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
46311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <screen-density-group label="large" version-code-order="2">
46474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xhdpi</screen-density>
46574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>
46674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        xxhdpi
46774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </screen-density>
46874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <screen-density>xxxhdpi</screen-density>
46974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </screen-density-group>)xml";
47074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
47174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
47274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
473280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
474cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
47574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
47674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
477cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
47874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.screen_density_groups.count("large"));
47974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
48074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xhdpi;
48174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xhdpi.density = ResTable_config::DENSITY_XHIGH;
48274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xxhdpi;
48374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
48474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ConfigDescription xxxhdpi;
48574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
48674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
48778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.screen_density_groups["large"].entry;
48874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
48974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
49074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
49139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, ScreenDensityGroupAction_EmtpyGroup) {
49211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml =
49311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer      R"xml(<screen-density-group label="xhdpi" version-code-order="4"/>)xml";
49439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
49539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
49639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
49739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
49839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
49939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_TRUE(ok);
50039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
50139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
50239e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_EQ(1u, config.screen_density_groups.count("xhdpi"));
50339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
50439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ConfigDescription xhdpi;
50539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  xhdpi.density = ResTable_config::DENSITY_XHIGH;
50639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
50711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto& out = config.screen_density_groups["xhdpi"];
50811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_THAT(out.entry, ElementsAre(xhdpi));
50911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(4, out.order);
51011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer}
51111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
51211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane FarmerTEST_F(ConfigurationParserTest, ScreenDensityGroupAction_EmtpyGroup_NoVersion) {
51311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml = R"xml(<screen-density-group label="xhdpi"/>)xml";
51411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
51511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto doc = test::BuildXmlDom(xml);
51611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
51711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  PostProcessingConfiguration config;
51811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
51911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  ASSERT_FALSE(ok);
52039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
52139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
52239e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, ScreenDensityGroupAction_InvalidEmtpyGroup) {
52339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  static constexpr const char* xml = R"xml(<screen-density-group label="really-big-screen"/>)xml";
52439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
52539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
52639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
52739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
52839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
52939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_FALSE(ok);
53039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
53139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
53274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, LocaleGroupAction) {
53374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
53411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <locale-group label="europe" version-code-order="2">
5350a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>en</locale>
5360a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>es</locale>
5370a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>fr</locale>
5380a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer      <locale>de</locale>
53974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </locale-group>)xml";
54074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
54174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
54274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
543280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
544cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
54574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
54674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
54774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, config.locale_groups.size());
54874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.locale_groups.count("europe"));
54974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
55078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  const auto& out = config.locale_groups["europe"].entry;
55174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
5520a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  ConfigDescription en = test::ParseConfigOrDie("en");
5530a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  ConfigDescription es = test::ParseConfigOrDie("es");
5540a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  ConfigDescription fr = test::ParseConfigOrDie("fr");
5550a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  ConfigDescription de = test::ParseConfigOrDie("de");
55674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
55774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(en, es, fr, de));
55874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
55974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
56039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, LocaleGroupAction_EmtpyGroup) {
56111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml = R"xml(<locale-group label="en" version-code-order="6"/>)xml";
56239e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
56339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
56439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
56539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
56639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
56739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_TRUE(ok);
56839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
56939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_EQ(1ul, config.locale_groups.size());
57039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_EQ(1u, config.locale_groups.count("en"));
57139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
57211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  const auto& out = config.locale_groups["en"];
57339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
57439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ConfigDescription en = test::ParseConfigOrDie("en");
57539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
57611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_THAT(out.entry, ElementsAre(en));
57711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_EQ(6, out.order);
57811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer}
57911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
58011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane FarmerTEST_F(ConfigurationParserTest, LocaleGroupAction_EmtpyGroup_NoOrder) {
58111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  static constexpr const char* xml = R"xml(<locale-group label="en"/>)xml";
58211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
58311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  auto doc = test::BuildXmlDom(xml);
58411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
58511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  PostProcessingConfiguration config;
58611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
58711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  ASSERT_FALSE(ok);
58839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
58939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
59039e474f4b4a975d8befa1e8f4cbedab5f47a43faShane FarmerTEST_F(ConfigurationParserTest, LocaleGroupAction_InvalidEmtpyGroup) {
59139e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  static constexpr const char* xml = R"xml(<locale-group label="arm64"/>)xml";
59239e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
59339e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  auto doc = test::BuildXmlDom(xml);
59439e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
59539e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  PostProcessingConfiguration config;
59639e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
59739e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer  ASSERT_FALSE(ok);
59839e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer}
59939e474f4b4a975d8befa1e8f4cbedab5f47a43faShane Farmer
60074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
60174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
60278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      <android-sdk label="v19"
6033edd47264335cf609ac6e733db77522f7c959c3fShane Farmer          minSdkVersion="19"
6043edd47264335cf609ac6e733db77522f7c959c3fShane Farmer          targetSdkVersion="24"
6053edd47264335cf609ac6e733db77522f7c959c3fShane Farmer          maxSdkVersion="25">
60674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <manifest>
60774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          <!--- manifest additions here XSLT? TODO -->
60874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        </manifest>
60978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      </android-sdk>)xml";
61074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
61174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
61274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
613280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
61478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
61574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
61674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
61778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_EQ(1ul, config.android_sdks.size());
61878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_EQ(1u, config.android_sdks.count("v19"));
61974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
62078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.android_sdks["v19"];
62174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
62274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  AndroidSdk sdk;
6233edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  sdk.min_sdk_version = 19;
6243edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  sdk.target_sdk_version = 24;
6253edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  sdk.max_sdk_version = 25;
62674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  sdk.manifest = AndroidManifest();
62774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
628efe45392c300f922e8328281a0aab8260c1d171dShane Farmer  ASSERT_EQ(sdk, out);
62974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
63074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
63167e8a3074d7ef42734d44f3a8d87635e201bd660Shane FarmerTEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
63267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  {
63378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    const char* xml = "<android-sdk label='v19' minSdkVersion='19'></android-sdk>";
63467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    auto doc = test::BuildXmlDom(xml);
63567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
63667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    PostProcessingConfiguration config;
63778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
63867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    ASSERT_TRUE(ok);
63967e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
64078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1ul, config.android_sdks.size());
64178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1u, config.android_sdks.count("v19"));
64267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
64378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    auto& out = config.android_sdks["v19"];
64478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_EQ(19, out.min_sdk_version);
64567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_FALSE(out.max_sdk_version);
64667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_FALSE(out.target_sdk_version);
64767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  }
64867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
64967e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  {
65078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    const char* xml =
65178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        "<android-sdk label='v19' minSdkVersion='19' maxSdkVersion='19'></android-sdk>";
65267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    auto doc = test::BuildXmlDom(xml);
65367e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
65467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    PostProcessingConfiguration config;
65578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
65667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    ASSERT_TRUE(ok);
65767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
65878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1ul, config.android_sdks.size());
65978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1u, config.android_sdks.count("v19"));
66067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
66178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    auto& out = config.android_sdks["v19"];
66267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_EQ(19, out.max_sdk_version.value());
66378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_EQ(19, out.min_sdk_version);
66467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_FALSE(out.target_sdk_version);
66567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  }
66667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
66767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  {
66878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    const char* xml =
66978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        "<android-sdk label='v19' minSdkVersion='19' targetSdkVersion='19'></android-sdk>";
67067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    auto doc = test::BuildXmlDom(xml);
67167e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
67267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    PostProcessingConfiguration config;
67378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
67467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    ASSERT_TRUE(ok);
67567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
67678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1ul, config.android_sdks.size());
67778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    ASSERT_EQ(1u, config.android_sdks.count("v19"));
67867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
67978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    auto& out = config.android_sdks["v19"];
68067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_EQ(19, out.target_sdk_version.value());
68178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    EXPECT_EQ(19, out.min_sdk_version);
68267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer    EXPECT_FALSE(out.max_sdk_version);
68367e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  }
68467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer}
68567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
68667e8a3074d7ef42734d44f3a8d87635e201bd660Shane FarmerTEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
68767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  static constexpr const char* xml = R"xml(
68878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    <android-sdk
68978c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        label="v19"
69078c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        minSdkVersion="v19"
69178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        targetSdkVersion="v24"
69278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        maxSdkVersion="v25">
69378c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      <manifest>
69478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer        <!--- manifest additions here XSLT? TODO -->
69578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      </manifest>
69678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer    </android-sdk>)xml";
69767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
69867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  auto doc = test::BuildXmlDom(xml);
69967e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
70067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  PostProcessingConfiguration config;
70178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
70267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  ASSERT_FALSE(ok);
70367e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer}
70467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
7053edd47264335cf609ac6e733db77522f7c959c3fShane FarmerTEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
7063edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  static constexpr const char* xml = R"xml(
7073edd47264335cf609ac6e733db77522f7c959c3fShane Farmer      <android-sdk
70878c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer          label="P"
70967e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer          minSdkVersion="25"
71067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer          targetSdkVersion="%s"
71167e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer          maxSdkVersion="%s">
71278c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer      </android-sdk>)xml";
7133edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
71467e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
71567e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  const char* codename = dev_sdk.first.data();
71667e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  const ApiVersion& version = dev_sdk.second;
71767e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer
71867e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
7193edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
7203edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  PostProcessingConfiguration config;
72178c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
7223edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  ASSERT_TRUE(ok);
7233edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
72478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_EQ(1ul, config.android_sdks.size());
72578c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  ASSERT_EQ(1u, config.android_sdks.count("P"));
7263edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
72778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.android_sdks["P"];
7283edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
7293edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  AndroidSdk sdk;
73067e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  sdk.min_sdk_version = 25;
73167e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  sdk.target_sdk_version = version;
73267e8a3074d7ef42734d44f3a8d87635e201bd660Shane Farmer  sdk.max_sdk_version = version;
7333edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
7343edd47264335cf609ac6e733db77522f7c959c3fShane Farmer  ASSERT_EQ(sdk, out);
7353edd47264335cf609ac6e733db77522f7c959c3fShane Farmer}
7363edd47264335cf609ac6e733db77522f7c959c3fShane Farmer
73774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, GlTextureGroupAction) {
73874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
73911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <gl-texture-group label="dxt1" version-code-order="2">
74074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <gl-texture name="GL_EXT_texture_compression_dxt1">
74174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>assets/dxt1/main/*</texture-path>
74274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        <texture-path>
74374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer          assets/dxt1/test/*
74474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        </texture-path>
74574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </gl-texture>
74674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </gl-texture-group>)xml";
74774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
74874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
74974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
750280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
751cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = GlTextureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
75274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
75374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
754cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(config.gl_texture_groups, SizeIs(1ul));
75574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
75674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
75778c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.gl_texture_groups["dxt1"].entry;
75874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
75974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  GlTexture texture{
76074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      std::string("GL_EXT_texture_compression_dxt1"),
76174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      {"assets/dxt1/main/*", "assets/dxt1/test/*"}
76274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  };
76374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
76474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1ul, out.size());
76574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(texture, out[0]);
76674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
76774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
76874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane FarmerTEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
76974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  static constexpr const char* xml = R"xml(
77011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer    <device-feature-group label="low-latency" version-code-order="2">
77174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>android.hardware.audio.low_latency</supports-feature>
77274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      <supports-feature>
77374cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer        android.hardware.audio.pro
77474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer      </supports-feature>
77574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer    </device-feature-group>)xml";
77674cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
77774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  auto doc = test::BuildXmlDom(xml);
77874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
779280be34fa6311de90dff6c595a147fd5a182223dShane Farmer  PostProcessingConfiguration config;
780cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  bool ok = DeviceFeatureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
78174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_TRUE(ok);
78274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
783cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  EXPECT_THAT(config.device_feature_groups, SizeIs(1ul));
78474cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
78574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
78678c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  auto& out = config.device_feature_groups["low-latency"].entry;
78774cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
78874cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  DeviceFeature low_latency = "android.hardware.audio.low_latency";
78974cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  DeviceFeature pro = "android.hardware.audio.pro";
79074cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer  ASSERT_THAT(out, ElementsAre(low_latency, pro));
79174cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}
79274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer
79311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane FarmerTEST_F(ConfigurationParserTest, Group_Valid) {
79411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  Group<int32_t> group;
79511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item1"].order = 1;
79611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item2"].order = 2;
79711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item3"].order = 3;
79811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item4"].order = 4;
79911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item5"].order = 5;
80011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item6"].order = 6;
80111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
80211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_TRUE(IsGroupValid(group, "test", &diag_));
80311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer}
80411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
80511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane FarmerTEST_F(ConfigurationParserTest, Group_OverlappingOrder) {
80611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  Group<int32_t> group;
80711cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item1"].order = 1;
80811cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item2"].order = 2;
80911cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item3"].order = 3;
81011cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item4"].order = 2;
81111cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item5"].order = 5;
81211cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  group["item6"].order = 1;
81311cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
81411cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer  EXPECT_FALSE(IsGroupValid(group, "test", &diag_));
81511cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer}
81611cdc1cf7ab2e915611e2bb7264bd312012a9b64Shane Farmer
8171a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer// Artifact name parser test cases.
8181a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
8199f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane FarmerTEST(ArtifactTest, Simple) {
8209f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  StdErrDiagnostics diag;
821cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact x86;
8229f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  x86.abi_group = {"x86"};
8239f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
8249ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
8259f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  ASSERT_TRUE(x86_result);
8269f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  EXPECT_EQ(x86_result.value(), "something.x86.apk");
8279f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
828cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact arm;
8299f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  arm.abi_group = {"armeabi-v7a"};
8309f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
8319ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8329ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto arm_result = arm.ToArtifactName("app.${abi}.apk", "", &diag);
8339ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(arm_result);
8349ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
8359ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8369ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8379ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8389ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto arm_result = arm.ToArtifactName("app.${abi}.apk", "different_name.apk", &diag);
8399ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(arm_result);
8409ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
8419ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8429ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8439ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8449ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto arm_result = arm.ToArtifactName("${basename}.${abi}.apk", "app.apk", &diag);
8459ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(arm_result);
8469ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
8479ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8489ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8499ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8509ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto arm_result = arm.ToArtifactName("app.${abi}.${ext}", "app.apk", &diag);
8519ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(arm_result);
8529ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
8539ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8549f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer}
8559f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
8569f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane FarmerTEST(ArtifactTest, Complex) {
8579f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  StdErrDiagnostics diag;
858cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact artifact;
8599f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  artifact.abi_group = {"mips64"};
8609f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  artifact.screen_density_group = {"ldpi"};
8619f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  artifact.device_feature_group = {"df1"};
8629f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  artifact.gl_texture_group = {"glx1"};
8639f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  artifact.locale_group = {"en-AU"};
86478c43d7bee2a476d6edffe0a4368eb6fcef38c31Shane Farmer  artifact.android_sdk = {"v26"};
8659f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
8669ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8679ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto result = artifact.ToArtifactName(
868efe45392c300f922e8328281a0aab8260c1d171dShane Farmer        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "", &diag);
8699ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(result);
870efe45392c300f922e8328281a0aab8260c1d171dShane Farmer    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
8719ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8729ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8739ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8749ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto result = artifact.ToArtifactName(
875efe45392c300f922e8328281a0aab8260c1d171dShane Farmer        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
8769ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(result);
877efe45392c300f922e8328281a0aab8260c1d171dShane Farmer    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
8789ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8799ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8809ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8819ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto result = artifact.ToArtifactName(
882efe45392c300f922e8328281a0aab8260c1d171dShane Farmer        "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
8839ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(result);
884efe45392c300f922e8328281a0aab8260c1d171dShane Farmer    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
8859ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8869ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8879ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8889ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto result = artifact.ToArtifactName(
889efe45392c300f922e8328281a0aab8260c1d171dShane Farmer        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.${ext}", "app.apk", &diag);
8909ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(result);
891efe45392c300f922e8328281a0aab8260c1d171dShane Farmer    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
8929ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
8939ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer
8949ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  {
8959ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    auto result = artifact.ToArtifactName(
896efe45392c300f922e8328281a0aab8260c1d171dShane Farmer        "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}", "app.apk", &diag);
8979ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    ASSERT_TRUE(result);
898efe45392c300f922e8328281a0aab8260c1d171dShane Farmer    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
8999ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  }
9009f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer}
9019f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
9029f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane FarmerTEST(ArtifactTest, Missing) {
9039f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  StdErrDiagnostics diag;
904cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact x86;
9059f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  x86.abi_group = {"x86"};
9069f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
9079ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
9089ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(x86.ToArtifactName("something.apk", "", &diag));
9099ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "something.apk", &diag));
9109ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(x86.ToArtifactName("something.apk", "something.apk", &diag));
9119f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer}
9129f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
9139f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane FarmerTEST(ArtifactTest, Empty) {
9149f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer  StdErrDiagnostics diag;
915cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact artifact;
9169f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
9179ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
9189ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
9199ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
9209ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_TRUE(artifact.ToArtifactName("something.apk", "something.apk", &diag));
9219f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer}
9229f0e7f1dbade4b35b85e23954fa2b7c31d5f2009Shane Farmer
9231a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane FarmerTEST(ArtifactTest, Repeated) {
9241a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  StdErrDiagnostics diag;
925cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact artifact;
9261a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  artifact.screen_density_group = {"mdpi"};
9271a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9289ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
9299ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", "", &diag));
9309ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
9311a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer}
9321a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9331a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane FarmerTEST(ArtifactTest, Nesting) {
9341a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  StdErrDiagnostics diag;
935cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact x86;
9361a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  x86.abi_group = {"x86"};
9371a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9389ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));
9391a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9409ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  const Maybe<std::string>& name = x86.ToArtifactName("something.${abi${abi}}.apk", "", &diag);
9410a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  ASSERT_TRUE(name);
9420a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  EXPECT_EQ(name.value(), "something.${abix86}.apk");
9431a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer}
9441a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9451a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane FarmerTEST(ArtifactTest, Recursive) {
9461a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  StdErrDiagnostics diag;
947cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer  ConfiguredArtifact artifact;
9480a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  artifact.device_feature_group = {"${gl}"};
9491a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  artifact.gl_texture_group = {"glx1"};
9501a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9519ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer  EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag));
9521a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9531a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  artifact.device_feature_group = {"df1"};
9540a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  artifact.gl_texture_group = {"${feature}"};
9551a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  {
9569ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag);
9570a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer    ASSERT_TRUE(result);
9580a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer    EXPECT_EQ(result.value(), "app.df1.${feature}.apk");
9591a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  }
9601a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
9611a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  // This is an invalid case, but should be the only possible case due to the ordering of
9621a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  // replacement.
9630a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer  artifact.device_feature_group = {"${gl}"};
9641a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  artifact.gl_texture_group = {"glx1"};
9651a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  {
9669ecc0751e30086c0668c8fe5758f14fc5acf5ae8Shane Farmer    const auto& result = artifact.ToArtifactName("app.${feature}.apk", "", &diag);
9670a5b201156f1dd01a7da7b7674798ed57cfafc5aShane Farmer    ASSERT_TRUE(result);
9681a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer    EXPECT_EQ(result.value(), "app.glx1.apk");
9691a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer  }
9701a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer}
9711a21b8c04153b5b73a477ebd0622b24f3bbfc603Shane Farmer
97274cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}  // namespace
973cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer}  // namespace handler
974cb6c3f9b880160c35785b1780b282fdf92952b90Shane Farmer}  // namespace configuration
97574cdea34cd6dce8bf9b4adaa2cd7cb02330120d5Shane Farmer}  // namespace aapt
976