summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/aapt2/cmd/Optimize.cpp36
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.cpp365
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.h102
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.internal.h122
-rw-r--r--tools/aapt2/configuration/ConfigurationParser_test.cpp142
-rw-r--r--tools/aapt2/filter/AbiFilter.cpp2
-rw-r--r--tools/aapt2/optimize/MultiApkGenerator.cpp154
-rw-r--r--tools/aapt2/optimize/MultiApkGenerator.h14
-rw-r--r--tools/aapt2/optimize/MultiApkGenerator_test.cpp64
-rw-r--r--tools/aapt2/test/Builders.cpp62
-rw-r--r--tools/aapt2/test/Builders.h32
11 files changed, 545 insertions, 550 deletions
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index eaadfd82629e..d8bb9992c152 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -44,8 +44,7 @@
#include "util/Util.h"
using ::aapt::configuration::Abi;
-using ::aapt::configuration::Artifact;
-using ::aapt::configuration::PostProcessingConfiguration;
+using ::aapt::configuration::OutputArtifact;
using ::android::ResTable_config;
using ::android::StringPiece;
using ::android::base::ReadFileToString;
@@ -74,7 +73,7 @@ struct OptimizeOptions {
TableFlattenerOptions table_flattener_options;
- Maybe<PostProcessingConfiguration> configuration;
+ Maybe<std::vector<OutputArtifact>> apk_artifacts;
// Set of artifacts to keep when generating multi-APK splits. If the list is empty, all artifacts
// are kept and will be written as output.
@@ -199,14 +198,11 @@ class OptimizeCommand {
++split_constraints_iter;
}
- if (options_.configuration && options_.output_dir) {
+ if (options_.apk_artifacts && options_.output_dir) {
MultiApkGenerator generator{apk.get(), context_};
MultiApkGeneratorOptions generator_options = {
- options_.output_dir.value(),
- options_.configuration.value(),
- options_.table_flattener_options,
- options_.kept_artifacts,
- };
+ options_.output_dir.value(), options_.apk_artifacts.value(),
+ options_.table_flattener_options, options_.kept_artifacts};
if (!generator.FromBaseApk(generator_options)) {
return 1;
}
@@ -423,29 +419,27 @@ int Optimize(const std::vector<StringPiece>& args) {
std::string& path = config_path.value();
Maybe<ConfigurationParser> for_path = ConfigurationParser::ForPath(path);
if (for_path) {
- options.configuration = for_path.value().WithDiagnostics(diag).Parse();
+ options.apk_artifacts = for_path.value().WithDiagnostics(diag).Parse(apk_path);
+ if (!options.apk_artifacts) {
+ diag->Error(DiagMessage() << "Failed to parse the output artifact list");
+ return 1;
+ }
+
} else {
diag->Error(DiagMessage() << "Could not parse config file " << path);
return 1;
}
if (print_only) {
- std::vector<std::string> names;
- const PostProcessingConfiguration& config = options.configuration.value();
- if (!config.AllArtifactNames(file::GetFilename(apk_path), &names, diag)) {
- diag->Error(DiagMessage() << "Failed to generate output artifact list");
- return 1;
- }
-
- for (const auto& name : names) {
- std::cout << name << std::endl;
+ for (const OutputArtifact& artifact : options.apk_artifacts.value()) {
+ std::cout << artifact.name << std::endl;
}
return 0;
}
if (!kept_artifacts.empty()) {
- for (const auto& artifact_str : kept_artifacts) {
- for (const auto& artifact : util::Tokenize(artifact_str, ',')) {
+ for (const std::string& artifact_str : kept_artifacts) {
+ for (const StringPiece& artifact : util::Tokenize(artifact_str, ',')) {
options.kept_artifacts.insert(artifact.to_string());
}
}
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 852ff176ed7d..ebc523f096db 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -28,6 +28,7 @@
#include "ConfigDescription.h"
#include "Diagnostics.h"
#include "ResourceUtils.h"
+#include "configuration/ConfigurationParser.internal.h"
#include "io/File.h"
#include "io/FileSystem.h"
#include "io/StringStream.h"
@@ -45,11 +46,22 @@ namespace {
using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidManifest;
using ::aapt::configuration::AndroidSdk;
-using ::aapt::configuration::Artifact;
-using ::aapt::configuration::PostProcessingConfiguration;
+using ::aapt::configuration::ConfiguredArtifact;
+using ::aapt::configuration::DeviceFeature;
+using ::aapt::configuration::Entry;
using ::aapt::configuration::GlTexture;
using ::aapt::configuration::Group;
using ::aapt::configuration::Locale;
+using ::aapt::configuration::OutputArtifact;
+using ::aapt::configuration::PostProcessingConfiguration;
+using ::aapt::configuration::handler::AbiGroupTagHandler;
+using ::aapt::configuration::handler::AndroidSdkGroupTagHandler;
+using ::aapt::configuration::handler::ArtifactFormatTagHandler;
+using ::aapt::configuration::handler::ArtifactTagHandler;
+using ::aapt::configuration::handler::DeviceFeatureGroupTagHandler;
+using ::aapt::configuration::handler::GlTextureGroupTagHandler;
+using ::aapt::configuration::handler::LocaleGroupTagHandler;
+using ::aapt::configuration::handler::ScreenDensityGroupTagHandler;
using ::aapt::io::IFile;
using ::aapt::io::RegularFile;
using ::aapt::io::StringInputStream;
@@ -59,19 +71,16 @@ using ::aapt::xml::NodeCast;
using ::aapt::xml::XmlActionExecutor;
using ::aapt::xml::XmlActionExecutorPolicy;
using ::aapt::xml::XmlNodeAction;
-using ::android::base::ReadFileToString;
using ::android::StringPiece;
+using ::android::base::ReadFileToString;
-const std::unordered_map<std::string, Abi> kStringToAbiMap = {
+const std::unordered_map<StringPiece, Abi> kStringToAbiMap = {
{"armeabi", Abi::kArmeV6}, {"armeabi-v7a", Abi::kArmV7a}, {"arm64-v8a", Abi::kArm64V8a},
{"x86", Abi::kX86}, {"x86_64", Abi::kX86_64}, {"mips", Abi::kMips},
{"mips64", Abi::kMips64}, {"universal", Abi::kUniversal},
};
-const std::map<Abi, std::string> kAbiToStringMap = {
- {Abi::kArmeV6, "armeabi"}, {Abi::kArmV7a, "armeabi-v7a"}, {Abi::kArm64V8a, "arm64-v8a"},
- {Abi::kX86, "x86"}, {Abi::kX86_64, "x86_64"}, {Abi::kMips, "mips"},
- {Abi::kMips64, "mips64"}, {Abi::kUniversal, "universal"},
-};
+const std::array<StringPiece, 8> kAbiToStringMap = {
+ {"armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64", "universal"}};
constexpr const char* kAaptXmlNs = "http://schemas.android.com/tools/aapt";
@@ -106,12 +115,25 @@ class NamespaceVisitor : public xml::Visitor {
}
};
-} // namespace
+/** Copies the values referenced in a configuration group to the target list. */
+template <typename T>
+bool CopyXmlReferences(const Maybe<std::string>& name, const Group<T>& groups,
+ std::vector<T>* target) {
+ // If there was no item configured, there is nothing to do and no error.
+ if (!name) {
+ return true;
+ }
-namespace configuration {
+ // If the group could not be found, then something is wrong.
+ auto group = groups.find(name.value());
+ if (group == groups.end()) {
+ return false;
+ }
-const std::string& AbiToString(Abi abi) {
- return kAbiToStringMap.find(abi)->second;
+ for (const T& item : group->second) {
+ target->push_back(item);
+ }
+ return true;
}
/**
@@ -119,8 +141,8 @@ const std::string& AbiToString(Abi abi) {
* success, or false if the either the placeholder is not found in the name, or the value is not
* present and the placeholder was.
*/
-static bool ReplacePlaceholder(const StringPiece& placeholder, const Maybe<StringPiece>& value,
- std::string* name, IDiagnostics* diag) {
+bool ReplacePlaceholder(const StringPiece& placeholder, const Maybe<StringPiece>& value,
+ std::string* name, IDiagnostics* diag) {
size_t offset = name->find(placeholder.data());
bool found = (offset != std::string::npos);
@@ -152,6 +174,160 @@ static bool ReplacePlaceholder(const StringPiece& placeholder, const Maybe<Strin
}
/**
+ * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
+ * element was successfully processed, otherwise returns false.
+ */
+using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag)>;
+
+/** Binds an ActionHandler to the current configuration being populated. */
+xml::XmlNodeAction::ActionFuncWithDiag Bind(configuration::PostProcessingConfiguration* config,
+ const ActionHandler& handler) {
+ return [config, handler](xml::Element* root_element, SourcePathDiagnostics* diag) {
+ return handler(config, root_element, diag);
+ };
+}
+
+/** Returns the binary reprasentation of the XML configuration. */
+Maybe<PostProcessingConfiguration> ExtractConfiguration(const std::string& contents,
+ IDiagnostics* diag) {
+ StringInputStream in(contents);
+ std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, diag, Source("config.xml"));
+ if (!doc) {
+ return {};
+ }
+
+ // Strip any namespaces from the XML as the XmlActionExecutor ignores anything with a namespace.
+ Element* root = doc->root.get();
+ if (root == nullptr) {
+ diag->Error(DiagMessage() << "Could not find the root element in the XML document");
+ return {};
+ }
+
+ std::string& xml_ns = root->namespace_uri;
+ if (!xml_ns.empty()) {
+ if (xml_ns != kAaptXmlNs) {
+ diag->Error(DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
+ return {};
+ }
+
+ xml_ns.clear();
+ NamespaceVisitor visitor;
+ root->Accept(&visitor);
+ }
+
+ XmlActionExecutor executor;
+ XmlNodeAction& root_action = executor["post-process"];
+ XmlNodeAction& artifacts_action = root_action["artifacts"];
+ XmlNodeAction& groups_action = root_action["groups"];
+
+ PostProcessingConfiguration config;
+
+ // Parse the artifact elements.
+ artifacts_action["artifact"].Action(Bind(&config, ArtifactTagHandler));
+ artifacts_action["artifact-format"].Action(Bind(&config, ArtifactFormatTagHandler));
+
+ // Parse the different configuration groups.
+ groups_action["abi-group"].Action(Bind(&config, AbiGroupTagHandler));
+ groups_action["screen-density-group"].Action(Bind(&config, ScreenDensityGroupTagHandler));
+ groups_action["locale-group"].Action(Bind(&config, LocaleGroupTagHandler));
+ groups_action["android-sdk-group"].Action(Bind(&config, AndroidSdkGroupTagHandler));
+ groups_action["gl-texture-group"].Action(Bind(&config, GlTextureGroupTagHandler));
+ groups_action["device-feature-group"].Action(Bind(&config, DeviceFeatureGroupTagHandler));
+
+ if (!executor.Execute(XmlActionExecutorPolicy::kNone, diag, doc.get())) {
+ diag->Error(DiagMessage() << "Could not process XML document");
+ return {};
+ }
+
+ return {config};
+}
+
+/** Converts a ConfiguredArtifact into an OutputArtifact. */
+Maybe<OutputArtifact> ToOutputArtifact(const ConfiguredArtifact& artifact,
+ const std::string& apk_name,
+ const PostProcessingConfiguration& config,
+ IDiagnostics* diag) {
+ if (!artifact.name && !config.artifact_format) {
+ diag->Error(
+ DiagMessage() << "Artifact does not have a name and no global name template defined");
+ return {};
+ }
+
+ Maybe<std::string> artifact_name =
+ (artifact.name) ? artifact.Name(apk_name, diag)
+ : artifact.ToArtifactName(config.artifact_format.value(), apk_name, diag);
+
+ if (!artifact_name) {
+ diag->Error(DiagMessage() << "Could not determine split APK artifact name");
+ return {};
+ }
+
+ OutputArtifact output_artifact;
+ output_artifact.name = artifact_name.value();
+
+ SourcePathDiagnostics src_diag{{output_artifact.name}, diag};
+ bool has_errors = false;
+
+ if (!CopyXmlReferences(artifact.abi_group, config.abi_groups, &output_artifact.abis)) {
+ src_diag.Error(DiagMessage() << "Could not lookup required ABIs: "
+ << artifact.abi_group.value());
+ has_errors = true;
+ }
+
+ if (!CopyXmlReferences(artifact.locale_group, config.locale_groups, &output_artifact.locales)) {
+ src_diag.Error(DiagMessage() << "Could not lookup required locales: "
+ << artifact.locale_group.value());
+ has_errors = true;
+ }
+
+ if (!CopyXmlReferences(artifact.screen_density_group, config.screen_density_groups,
+ &output_artifact.screen_densities)) {
+ src_diag.Error(DiagMessage() << "Could not lookup required screen densities: "
+ << artifact.screen_density_group.value());
+ has_errors = true;
+ }
+
+ if (!CopyXmlReferences(artifact.device_feature_group, config.device_feature_groups,
+ &output_artifact.features)) {
+ src_diag.Error(DiagMessage() << "Could not lookup required device features: "
+ << artifact.device_feature_group.value());
+ has_errors = true;
+ }
+
+ if (!CopyXmlReferences(artifact.gl_texture_group, config.gl_texture_groups,
+ &output_artifact.textures)) {
+ src_diag.Error(DiagMessage() << "Could not lookup required OpenGL texture formats: "
+ << artifact.gl_texture_group.value());
+ has_errors = true;
+ }
+
+ if (artifact.android_sdk_group) {
+ auto entry = config.android_sdk_groups.find(artifact.android_sdk_group.value());
+ if (entry == config.android_sdk_groups.end()) {
+ src_diag.Error(DiagMessage() << "Could not lookup required Android SDK version: "
+ << artifact.android_sdk_group.value());
+ has_errors = true;
+ } else {
+ output_artifact.android_sdk = {entry->second};
+ }
+ }
+
+ if (has_errors) {
+ return {};
+ }
+ return {output_artifact};
+}
+
+} // namespace
+
+namespace configuration {
+
+const StringPiece& AbiToString(Abi abi) {
+ return kAbiToStringMap.at(static_cast<size_t>(abi));
+}
+
+/**
* Returns the common artifact base name from a template string.
*/
Maybe<std::string> ToBaseName(std::string result, const StringPiece& apk_name, IDiagnostics* diag) {
@@ -186,8 +362,9 @@ Maybe<std::string> ToBaseName(std::string result, const StringPiece& apk_name, I
return result;
}
-Maybe<std::string> Artifact::ToArtifactName(const StringPiece& format, const StringPiece& apk_name,
- IDiagnostics* diag) const {
+Maybe<std::string> ConfiguredArtifact::ToArtifactName(const StringPiece& format,
+ const StringPiece& apk_name,
+ IDiagnostics* diag) const {
Maybe<std::string> base = ToBaseName(format.to_string(), apk_name, diag);
if (!base) {
return {};
@@ -221,7 +398,7 @@ Maybe<std::string> Artifact::ToArtifactName(const StringPiece& format, const Str
return result;
}
-Maybe<std::string> Artifact::Name(const StringPiece& apk_name, IDiagnostics* diag) const {
+Maybe<std::string> ConfiguredArtifact::Name(const StringPiece& apk_name, IDiagnostics* diag) const {
if (!name) {
return {};
}
@@ -229,31 +406,6 @@ Maybe<std::string> Artifact::Name(const StringPiece& apk_name, IDiagnostics* dia
return ToBaseName(name.value(), apk_name, diag);
}
-bool PostProcessingConfiguration::AllArtifactNames(const StringPiece& apk_name,
- std::vector<std::string>* artifact_names,
- IDiagnostics* diag) const {
- for (const auto& artifact : artifacts) {
- Maybe<std::string> name;
- if (artifact.name) {
- name = artifact.Name(apk_name, diag);
- } else {
- if (!artifact_format) {
- diag->Error(DiagMessage() << "No global artifact template and an artifact name is missing");
- return false;
- }
- name = artifact.ToArtifactName(artifact_format.value(), apk_name, diag);
- }
-
- if (!name) {
- return false;
- }
-
- artifact_names->push_back(std::move(name.value()));
- }
-
- return true;
-}
-
} // namespace configuration
/** Returns a ConfigurationParser for the file located at the provided path. */
@@ -270,86 +422,58 @@ ConfigurationParser::ConfigurationParser(std::string contents)
diag_(&noop_) {
}
-Maybe<PostProcessingConfiguration> ConfigurationParser::Parse() {
- StringInputStream in(contents_);
- std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, diag_, Source("config.xml"));
- if (!doc) {
- return {};
- }
-
- // Strip any namespaces from the XML as the XmlActionExecutor ignores anything with a namespace.
- Element* root = doc->root.get();
- if (root == nullptr) {
- diag_->Error(DiagMessage() << "Could not find the root element in the XML document");
- return {};
- }
-
- std::string& xml_ns = root->namespace_uri;
- if (!xml_ns.empty()) {
- if (xml_ns != kAaptXmlNs) {
- diag_->Error(DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
- return {};
- }
-
- xml_ns.clear();
- NamespaceVisitor visitor;
- root->Accept(&visitor);
- }
-
- XmlActionExecutor executor;
- XmlNodeAction& root_action = executor["post-process"];
- XmlNodeAction& artifacts_action = root_action["artifacts"];
- XmlNodeAction& groups_action = root_action["groups"];
-
- PostProcessingConfiguration config;
-
- // Helper to bind a static method to an action handler in the DOM executor.
- auto bind_handler =
- [&config](std::function<bool(PostProcessingConfiguration*, Element*, IDiagnostics*)> h)
- -> XmlNodeAction::ActionFuncWithDiag {
- return std::bind(h, &config, std::placeholders::_1, std::placeholders::_2);
- };
-
- // Parse the artifact elements.
- artifacts_action["artifact"].Action(bind_handler(artifact_handler_));
- artifacts_action["artifact-format"].Action(bind_handler(artifact_format_handler_));
-
- // Parse the different configuration groups.
- groups_action["abi-group"].Action(bind_handler(abi_group_handler_));
- groups_action["screen-density-group"].Action(bind_handler(screen_density_group_handler_));
- groups_action["locale-group"].Action(bind_handler(locale_group_handler_));
- groups_action["android-sdk-group"].Action(bind_handler(android_sdk_group_handler_));
- groups_action["gl-texture-group"].Action(bind_handler(gl_texture_group_handler_));
- groups_action["device-feature-group"].Action(bind_handler(device_feature_group_handler_));
-
- if (!executor.Execute(XmlActionExecutorPolicy::kNone, diag_, doc.get())) {
- diag_->Error(DiagMessage() << "Could not process XML document");
+Maybe<std::vector<OutputArtifact>> ConfigurationParser::Parse(
+ const android::StringPiece& apk_path) {
+ Maybe<PostProcessingConfiguration> maybe_config = ExtractConfiguration(contents_, diag_);
+ if (!maybe_config) {
return {};
}
-
- // TODO: Validate all references in the configuration are valid. It should be safe to assume from
- // this point on that any references from one section to another will be present.
+ const PostProcessingConfiguration& config = maybe_config.value();
// TODO: Automatically arrange artifacts so that they match Play Store multi-APK requirements.
// see: https://developer.android.com/google/play/publishing/multiple-apks.html
//
// For now, make sure the version codes are unique.
- std::vector<Artifact>& artifacts = config.artifacts;
+ std::vector<ConfiguredArtifact> artifacts = config.artifacts;
std::sort(artifacts.begin(), artifacts.end());
if (std::adjacent_find(artifacts.begin(), artifacts.end()) != artifacts.end()) {
diag_->Error(DiagMessage() << "Configuration has duplicate versions");
return {};
}
- return {config};
+ const std::string& apk_name = file::GetFilename(apk_path).to_string();
+ const StringPiece ext = file::GetExtension(apk_name);
+ const std::string base_name = apk_name.substr(0, apk_name.size() - ext.size());
+
+ // Convert from a parsed configuration to a list of artifacts for processing.
+ std::vector<OutputArtifact> output_artifacts;
+ bool has_errors = false;
+
+ for (const ConfiguredArtifact& artifact : artifacts) {
+ Maybe<OutputArtifact> output_artifact = ToOutputArtifact(artifact, apk_name, config, diag_);
+ if (!output_artifact) {
+ // Defer return an error condition so that all errors are reported.
+ has_errors = true;
+ } else {
+ output_artifacts.push_back(std::move(output_artifact.value()));
+ }
+ }
+
+ if (has_errors) {
+ return {};
+ }
+ return {output_artifacts};
}
-ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+namespace configuration {
+namespace handler {
+
+bool ArtifactTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
// This will be incremented later so the first version will always be different to the base APK.
int current_version = (config->artifacts.empty()) ? 0 : config->artifacts.back().version;
- Artifact artifact{};
+ ConfiguredArtifact artifact{};
Maybe<int> version;
for (const auto& attr : root_element->attributes) {
if (attr.name == "name") {
@@ -380,8 +504,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
return true;
};
-ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool ArtifactFormatTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* /* diag */) {
for (auto& node : root_element->children) {
xml::Text* t;
if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
@@ -392,8 +516,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_
return true;
};
-ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool AbiGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -420,8 +544,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
return valid;
};
-ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -461,8 +585,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_han
return valid;
};
-ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -502,8 +626,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
return valid;
};
-ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool AndroidSdkGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -560,8 +684,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handle
return valid;
};
-ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool GlTextureGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -603,8 +727,8 @@ ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler
return valid;
};
-ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_handler_ =
- [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+bool DeviceFeatureGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
+ IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -632,4 +756,7 @@ ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_han
return valid;
};
+} // namespace handler
+} // namespace configuration
+
} // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index c5d3284c33f4..ca5891025c92 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -30,54 +30,6 @@ namespace aapt {
namespace configuration {
-/** A mapping of group labels to group of configuration items. */
-template<class T>
-using Group = std::unordered_map<std::string, std::vector<T>>;
-
-/** A mapping of group label to a single configuration item. */
-template <class T>
-using Entry = std::unordered_map<std::string, T>;
-
-/** Output artifact configuration options. */
-struct Artifact {
- /** Name to use for output of processing foo.apk -> foo.<name>.apk. */
- Maybe<std::string> name;
- /**
- * Value to add to the base Android manifest versionCode. If it is not present in the
- * configuration file, it is set to the previous artifact + 1. If the first artifact does not have
- * a value, artifacts are a 1 based index.
- */
- int version;
- /** If present, uses the ABI group with this name. */
- Maybe<std::string> abi_group;
- /** If present, uses the screen density group with this name. */
- Maybe<std::string> screen_density_group;
- /** If present, uses the locale group with this name. */
- Maybe<std::string> locale_group;
- /** If present, uses the Android SDK group with this name. */
- Maybe<std::string> android_sdk_group;
- /** If present, uses the device feature group with this name. */
- Maybe<std::string> device_feature_group;
- /** If present, uses the OpenGL texture group with this name. */
- Maybe<std::string> gl_texture_group;
-
- /** Convert an artifact name template into a name string based on configuration contents. */
- Maybe<std::string> ToArtifactName(const android::StringPiece& format,
- const android::StringPiece& apk_name, IDiagnostics* diag) const;
-
- /** Convert an artifact name template into a name string based on configuration contents. */
- Maybe<std::string> Name(const android::StringPiece& apk_name, IDiagnostics* diag) const;
-
- bool operator<(const Artifact& rhs) const {
- // TODO(safarmer): Order by play store multi-APK requirements.
- return version < rhs.version;
- }
-
- bool operator==(const Artifact& rhs) const {
- return version == rhs.version;
- }
-};
-
/** Enumeration of currently supported ABIs. */
enum class Abi {
kArmeV6,
@@ -91,7 +43,7 @@ enum class Abi {
};
/** Helper method to convert an ABI to a string representing the path within the APK. */
-const std::string& AbiToString(Abi abi);
+const android::StringPiece& AbiToString(Abi abi);
/**
* Represents an individual locale. When a locale is included, it must be
@@ -151,22 +103,16 @@ struct GlTexture {
}
};
-/** AAPT2 XML configuration file binary representation. */
-struct PostProcessingConfiguration {
- // TODO: Support named artifacts?
- std::vector<Artifact> artifacts;
- Maybe<std::string> artifact_format;
-
- Group<Abi> abi_groups;
- Group<ConfigDescription> screen_density_groups;
- Group<ConfigDescription> locale_groups;
- Entry<AndroidSdk> android_sdk_groups;
- Group<DeviceFeature> device_feature_groups;
- Group<GlTexture> gl_texture_groups;
-
- /** Helper method that generates a list of artifact names and returns true on success. */
- bool AllArtifactNames(const android::StringPiece& apk_name,
- std::vector<std::string>* artifact_names, IDiagnostics* diag) const;
+/** An artifact with all the details pulled from the PostProcessingConfiguration. */
+struct OutputArtifact {
+ std::string name;
+ int version;
+ std::vector<Abi> abis;
+ std::vector<ConfigDescription> screen_densities;
+ std::vector<ConfigDescription> locales;
+ Maybe<AndroidSdk> android_sdk;
+ std::vector<DeviceFeature> features;
+ std::vector<GlTexture> textures;
};
} // namespace configuration
@@ -202,7 +148,7 @@ class ConfigurationParser {
* Parses the configuration file and returns the results. If the configuration could not be parsed
* the result is empty and any errors will be displayed with the provided diagnostics context.
*/
- Maybe<configuration::PostProcessingConfiguration> Parse();
+ Maybe<std::vector<configuration::OutputArtifact>> Parse(const android::StringPiece& apk_path);
protected:
/**
@@ -217,30 +163,6 @@ class ConfigurationParser {
return diag_;
}
- /**
- * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
- * element was successfully processed, otherwise returns false.
- */
- using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
- xml::Element* element, IDiagnostics* diag)>;
-
- /** Handler for <artifact> tags. */
- static ActionHandler artifact_handler_;
- /** Handler for <artifact-format> tags. */
- static ActionHandler artifact_format_handler_;
- /** Handler for <abi-group> tags. */
- static ActionHandler abi_group_handler_;
- /** Handler for <screen-density-group> tags. */
- static ActionHandler screen_density_group_handler_;
- /** Handler for <locale-group> tags. */
- static ActionHandler locale_group_handler_;
- /** Handler for <android-sdk-group> tags. */
- static ActionHandler android_sdk_group_handler_;
- /** Handler for <gl-texture-group> tags. */
- static ActionHandler gl_texture_group_handler_;
- /** Handler for <device-feature-group> tags. */
- static ActionHandler device_feature_group_handler_;
-
private:
/** The contents of the configuration file to parse. */
const std::string contents_;
diff --git a/tools/aapt2/configuration/ConfigurationParser.internal.h b/tools/aapt2/configuration/ConfigurationParser.internal.h
new file mode 100644
index 000000000000..7657ebd70a8b
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser.internal.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT2_CONFIGURATIONPARSER_INTERNAL_H
+#define AAPT2_CONFIGURATIONPARSER_INTERNAL_H
+
+namespace aapt {
+namespace configuration {
+
+/** A mapping of group labels to group of configuration items. */
+template <class T>
+using Group = std::unordered_map<std::string, std::vector<T>>;
+
+/** A mapping of group label to a single configuration item. */
+template <class T>
+using Entry = std::unordered_map<std::string, T>;
+
+/** Output artifact configuration options. */
+struct ConfiguredArtifact {
+ /** Name to use for output of processing foo.apk -> foo.<name>.apk. */
+ Maybe<std::string> name;
+ /**
+ * Value to add to the base Android manifest versionCode. If it is not present in the
+ * configuration file, it is set to the previous artifact + 1. If the first artifact does not have
+ * a value, artifacts are a 1 based index.
+ */
+ int version;
+ /** If present, uses the ABI group with this name. */
+ Maybe<std::string> abi_group;
+ /** If present, uses the screen density group with this name. */
+ Maybe<std::string> screen_density_group;
+ /** If present, uses the locale group with this name. */
+ Maybe<std::string> locale_group;
+ /** If present, uses the Android SDK group with this name. */
+ Maybe<std::string> android_sdk_group;
+ /** If present, uses the device feature group with this name. */
+ Maybe<std::string> device_feature_group;
+ /** If present, uses the OpenGL texture group with this name. */
+ Maybe<std::string> gl_texture_group;
+
+ /** Convert an artifact name template into a name string based on configuration contents. */
+ Maybe<std::string> ToArtifactName(const android::StringPiece& format,
+ const android::StringPiece& apk_name, IDiagnostics* diag) const;
+
+ /** Convert an artifact name template into a name string based on configuration contents. */
+ Maybe<std::string> Name(const android::StringPiece& apk_name, IDiagnostics* diag) const;
+
+ bool operator<(const ConfiguredArtifact& rhs) const {
+ // TODO(safarmer): Order by play store multi-APK requirements.
+ return version < rhs.version;
+ }
+
+ bool operator==(const ConfiguredArtifact& rhs) const {
+ return version == rhs.version;
+ }
+};
+
+/** AAPT2 XML configuration file binary representation. */
+struct PostProcessingConfiguration {
+ // TODO: Support named artifacts?
+ std::vector<ConfiguredArtifact> artifacts;
+ Maybe<std::string> artifact_format;
+
+ Group<Abi> abi_groups;
+ Group<ConfigDescription> screen_density_groups;
+ Group<ConfigDescription> locale_groups;
+ Entry<AndroidSdk> android_sdk_groups;
+ Group<DeviceFeature> device_feature_groups;
+ Group<GlTexture> gl_texture_groups;
+};
+
+namespace handler {
+
+/** Handler for <artifact> tags. */
+bool ArtifactTagHandler(configuration::PostProcessingConfiguration* config, xml::Element* element,
+ IDiagnostics* diag);
+
+/** Handler for <artifact-format> tags. */
+bool ArtifactFormatTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+/** Handler for <abi-group> tags. */
+bool AbiGroupTagHandler(configuration::PostProcessingConfiguration* config, xml::Element* element,
+ IDiagnostics* diag);
+
+/** Handler for <screen-density-group> tags. */
+bool ScreenDensityGroupTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+/** Handler for <locale-group> tags. */
+bool LocaleGroupTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+/** Handler for <android-sdk-group> tags. */
+bool AndroidSdkGroupTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+/** Handler for <gl-texture-group> tags. */
+bool GlTextureGroupTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+/** Handler for <device-feature-group> tags. */
+bool DeviceFeatureGroupTagHandler(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag);
+
+} // namespace handler
+} // namespace configuration
+} // namespace aapt
+#endif // AAPT2_CONFIGURATIONPARSER_INTERNAL_H
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index f7153c822bbc..3f356d78bbfe 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -22,6 +22,7 @@
#include "androidfw/ResourceTypes.h"
#include "SdkConstants.h"
+#include "configuration/ConfigurationParser.internal.h"
#include "test/Test.h"
#include "xml/XmlDom.h"
@@ -33,14 +34,15 @@ void PrintTo(const AndroidSdk& sdk, std::ostream* os) {
<< ", target=" << sdk.target_sdk_version.value_or_default(-1)
<< ", max=" << sdk.max_sdk_version.value_or_default(-1);
}
-} // namespace configuration
+
+namespace handler {
namespace {
using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidManifest;
using ::aapt::configuration::AndroidSdk;
-using ::aapt::configuration::Artifact;
+using ::aapt::configuration::ConfiguredArtifact;
using ::aapt::configuration::DeviceFeature;
using ::aapt::configuration::GlTexture;
using ::aapt::configuration::Locale;
@@ -50,6 +52,7 @@ using ::aapt::xml::NodeCast;
using ::android::ResTable_config;
using ::android::base::StringPrintf;
using ::testing::ElementsAre;
+using ::testing::SizeIs;
constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
<post-process xmlns="http://schemas.android.com/tools/aapt">
@@ -144,44 +147,47 @@ TEST_F(ConfigurationParserTest, ForPath_NoFile) {
TEST_F(ConfigurationParserTest, ValidateFile) {
auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
- auto result = parser.Parse();
+ auto result = parser.Parse("test.apk");
ASSERT_TRUE(result);
- PostProcessingConfiguration& value = result.value();
- EXPECT_EQ(2ul, value.artifacts.size());
- ASSERT_TRUE(value.artifact_format);
- EXPECT_EQ(
- "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
- value.artifact_format.value()
- );
-
- EXPECT_EQ(2ul, value.abi_groups.size());
- EXPECT_EQ(2ul, value.abi_groups["arm"].size());
- EXPECT_EQ(2ul, value.abi_groups["other"].size());
-
- EXPECT_EQ(2ul, value.screen_density_groups.size());
- EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
- EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
-
- EXPECT_EQ(2ul, value.locale_groups.size());
- EXPECT_EQ(4ul, value.locale_groups["europe"].size());
- EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
-
- EXPECT_EQ(1ul, value.android_sdk_groups.size());
- EXPECT_TRUE(value.android_sdk_groups["v19"].min_sdk_version);
- EXPECT_EQ(19, value.android_sdk_groups["v19"].min_sdk_version.value());
-
- EXPECT_EQ(1ul, value.gl_texture_groups.size());
- EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
-
- EXPECT_EQ(1ul, value.device_feature_groups.size());
- EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
+ const std::vector<OutputArtifact>& value = result.value();
+ EXPECT_THAT(value, SizeIs(2ul));
+
+ const OutputArtifact& a1 = value[0];
+ EXPECT_EQ(a1.name, "art1.apk");
+ EXPECT_THAT(a1.abis, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
+ EXPECT_THAT(a1.screen_densities,
+ ElementsAre(test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
+ EXPECT_THAT(a1.locales, ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es"),
+ test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
+ EXPECT_EQ(a1.android_sdk.value().min_sdk_version.value(), 19l);
+ EXPECT_THAT(a1.textures, SizeIs(1ul));
+ EXPECT_THAT(a1.features, SizeIs(1ul));
+
+ const OutputArtifact& a2 = value[1];
+ EXPECT_EQ(a2.name, "art2.apk");
+ EXPECT_THAT(a2.abis, ElementsAre(Abi::kX86, Abi::kMips));
+ EXPECT_THAT(a2.screen_densities,
+ ElementsAre(test::ParseConfigOrDie("ldpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("mdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("hdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
+ test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
+ EXPECT_THAT(a2.locales,
+ ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es-rMX"),
+ test::ParseConfigOrDie("fr-rCA")));
+ EXPECT_EQ(a2.android_sdk.value().min_sdk_version.value(), 19l);
+ EXPECT_THAT(a2.textures, SizeIs(1ul));
+ EXPECT_THAT(a2.features, SizeIs(1ul));
}
TEST_F(ConfigurationParserTest, InvalidNamespace) {
constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
<post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
- auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
+ auto result = ConfigurationParser::ForContents(invalid_ns).Parse("test.apk");
ASSERT_FALSE(result);
}
@@ -197,9 +203,9 @@ TEST_F(ConfigurationParserTest, ArtifactAction) {
gl-texture-group="dxt1"
device-feature-group="low-latency"/>)xml");
- ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc->root.get()), &diag_));
+ ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc->root.get()), &diag_));
- EXPECT_EQ(1ul, config.artifacts.size());
+ EXPECT_THAT(config.artifacts, SizeIs(1ul));
auto& artifact = config.artifacts.back();
EXPECT_FALSE(artifact.name); // TODO: make this fail.
@@ -223,8 +229,8 @@ TEST_F(ConfigurationParserTest, ArtifactAction) {
gl-texture-group="dxt1"
device-feature-group="low-latency"/>)xml");
- ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
- EXPECT_EQ(2ul, config.artifacts.size());
+ ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
+ EXPECT_THAT(config.artifacts, SizeIs(2ul));
EXPECT_EQ(2, config.artifacts.back().version);
}
@@ -240,8 +246,8 @@ TEST_F(ConfigurationParserTest, ArtifactAction) {
gl-texture-group="dxt1"
device-feature-group="low-latency"/>)xml");
- ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
- EXPECT_EQ(3ul, config.artifacts.size());
+ ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
+ EXPECT_THAT(config.artifacts, SizeIs(3ul));
EXPECT_EQ(5, config.artifacts.back().version);
}
@@ -256,8 +262,8 @@ TEST_F(ConfigurationParserTest, ArtifactAction) {
gl-texture-group="dxt1"
device-feature-group="low-latency"/>)xml");
- ASSERT_TRUE(artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
- EXPECT_EQ(4ul, config.artifacts.size());
+ ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
+ EXPECT_THAT(config.artifacts, SizeIs(4ul));
EXPECT_EQ(6, config.artifacts.back().version);
}
}
@@ -288,7 +294,7 @@ TEST_F(ConfigurationParserTest, DuplicateArtifactVersion) {
device-feature-group="low-latency"/>
</artifacts>
</post-process>)xml";
- auto result = ConfigurationParser::ForContents(configuration).Parse();
+ auto result = ConfigurationParser::ForContents(configuration).Parse("test.apk");
ASSERT_FALSE(result);
}
@@ -299,7 +305,7 @@ TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
</artifact-format>)xml");
PostProcessingConfiguration config;
- bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = ArtifactFormatTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_TRUE(config.artifact_format);
EXPECT_EQ(
@@ -322,10 +328,10 @@ TEST_F(ConfigurationParserTest, AbiGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
- EXPECT_EQ(1ul, config.abi_groups.size());
+ EXPECT_THAT(config.abi_groups, SizeIs(1ul));
ASSERT_EQ(1u, config.abi_groups.count("arm"));
auto& out = config.abi_groups["arm"];
@@ -345,11 +351,10 @@ TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok =
- screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
- EXPECT_EQ(1ul, config.screen_density_groups.size());
+ EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
ASSERT_EQ(1u, config.screen_density_groups.count("large"));
ConfigDescription xhdpi;
@@ -375,7 +380,7 @@ TEST_F(ConfigurationParserTest, LocaleGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.locale_groups.size());
@@ -407,7 +412,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.android_sdk_groups.size());
@@ -434,7 +439,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.android_sdk_groups.size());
@@ -455,7 +460,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.android_sdk_groups.size());
@@ -476,7 +481,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.android_sdk_groups.size());
@@ -505,7 +510,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_FALSE(ok);
}
@@ -526,7 +531,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
PostProcessingConfiguration config;
- bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = AndroidSdkGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_EQ(1ul, config.android_sdk_groups.size());
@@ -556,10 +561,10 @@ TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = GlTextureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
- EXPECT_EQ(1ul, config.gl_texture_groups.size());
+ EXPECT_THAT(config.gl_texture_groups, SizeIs(1ul));
ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
auto& out = config.gl_texture_groups["dxt1"];
@@ -585,11 +590,10 @@ TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
auto doc = test::BuildXmlDom(xml);
PostProcessingConfiguration config;
- bool ok
- = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+ bool ok = DeviceFeatureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
- EXPECT_EQ(1ul, config.device_feature_groups.size());
+ EXPECT_THAT(config.device_feature_groups, SizeIs(1ul));
ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
auto& out = config.device_feature_groups["low-latency"];
@@ -603,14 +607,14 @@ TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
TEST(ArtifactTest, Simple) {
StdErrDiagnostics diag;
- Artifact x86;
+ ConfiguredArtifact x86;
x86.abi_group = {"x86"};
auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
ASSERT_TRUE(x86_result);
EXPECT_EQ(x86_result.value(), "something.x86.apk");
- Artifact arm;
+ ConfiguredArtifact arm;
arm.abi_group = {"armeabi-v7a"};
{
@@ -640,7 +644,7 @@ TEST(ArtifactTest, Simple) {
TEST(ArtifactTest, Complex) {
StdErrDiagnostics diag;
- Artifact artifact;
+ ConfiguredArtifact artifact;
artifact.abi_group = {"mips64"};
artifact.screen_density_group = {"ldpi"};
artifact.device_feature_group = {"df1"};
@@ -686,7 +690,7 @@ TEST(ArtifactTest, Complex) {
TEST(ArtifactTest, Missing) {
StdErrDiagnostics diag;
- Artifact x86;
+ ConfiguredArtifact x86;
x86.abi_group = {"x86"};
EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
@@ -697,7 +701,7 @@ TEST(ArtifactTest, Missing) {
TEST(ArtifactTest, Empty) {
StdErrDiagnostics diag;
- Artifact artifact;
+ ConfiguredArtifact artifact;
EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
@@ -707,7 +711,7 @@ TEST(ArtifactTest, Empty) {
TEST(ArtifactTest, Repeated) {
StdErrDiagnostics diag;
- Artifact artifact;
+ ConfiguredArtifact artifact;
artifact.screen_density_group = {"mdpi"};
ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
@@ -717,7 +721,7 @@ TEST(ArtifactTest, Repeated) {
TEST(ArtifactTest, Nesting) {
StdErrDiagnostics diag;
- Artifact x86;
+ ConfiguredArtifact x86;
x86.abi_group = {"x86"};
EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));
@@ -729,7 +733,7 @@ TEST(ArtifactTest, Nesting) {
TEST(ArtifactTest, Recursive) {
StdErrDiagnostics diag;
- Artifact artifact;
+ ConfiguredArtifact artifact;
artifact.device_feature_group = {"${gl}"};
artifact.gl_texture_group = {"glx1"};
@@ -755,4 +759,6 @@ TEST(ArtifactTest, Recursive) {
}
} // namespace
+} // namespace handler
+} // namespace configuration
} // namespace aapt
diff --git a/tools/aapt2/filter/AbiFilter.cpp b/tools/aapt2/filter/AbiFilter.cpp
index cb96235f98f9..9ace82ad4af7 100644
--- a/tools/aapt2/filter/AbiFilter.cpp
+++ b/tools/aapt2/filter/AbiFilter.cpp
@@ -25,7 +25,7 @@ namespace aapt {
std::unique_ptr<AbiFilter> AbiFilter::FromAbiList(const std::vector<configuration::Abi>& abi_list) {
std::unordered_set<std::string> abi_set;
for (auto& abi : abi_list) {
- abi_set.insert(configuration::AbiToString(abi));
+ abi_set.insert(configuration::AbiToString(abi).to_string());
}
// Make unique by hand as the constructor is private.
return std::unique_ptr<AbiFilter>(new AbiFilter(abi_set));
diff --git a/tools/aapt2/optimize/MultiApkGenerator.cpp b/tools/aapt2/optimize/MultiApkGenerator.cpp
index e2d738aec5a2..16898d6f3e03 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator.cpp
@@ -40,33 +40,11 @@
namespace aapt {
using ::aapt::configuration::AndroidSdk;
-using ::aapt::configuration::Artifact;
-using ::aapt::configuration::PostProcessingConfiguration;
+using ::aapt::configuration::OutputArtifact;
using ::aapt::xml::kSchemaAndroid;
using ::aapt::xml::XmlResource;
using ::android::StringPiece;
-namespace {
-
-Maybe<AndroidSdk> GetAndroidSdk(const Artifact& artifact, const PostProcessingConfiguration& config,
- IDiagnostics* diag) {
- if (!artifact.android_sdk_group) {
- return {};
- }
-
- const std::string& group_name = artifact.android_sdk_group.value();
- auto group = config.android_sdk_groups.find(group_name);
- // TODO: Remove validation when configuration parser ensures referential integrity.
- if (group == config.android_sdk_groups.end()) {
- diag->Error(DiagMessage() << "could not find referenced group '" << group_name << "'");
- return {};
- }
-
- return group->second;
-}
-
-} // namespace
-
/**
* Context wrapper that allows the min Android SDK value to be overridden.
*/
@@ -115,8 +93,9 @@ class ContextWrapper : public IAaptContext {
min_sdk_ = min_sdk;
}
- void SetSource(const Source& source) {
- source_diag_ = util::make_unique<SourcePathDiagnostics>(source, context_->GetDiagnostics());
+ void SetSource(const std::string& source) {
+ source_diag_ =
+ util::make_unique<SourcePathDiagnostics>(Source{source}, context_->GetDiagnostics());
}
private:
@@ -142,82 +121,60 @@ MultiApkGenerator::MultiApkGenerator(LoadedApk* apk, IAaptContext* context)
bool MultiApkGenerator::FromBaseApk(const MultiApkGeneratorOptions& options) {
// TODO(safarmer): Handle APK version codes for the generated APKs.
- const PostProcessingConfiguration& config = options.config;
-
- const std::string& apk_name = file::GetFilename(apk_->GetSource().path).to_string();
- const StringPiece ext = file::GetExtension(apk_name);
- const std::string base_name = apk_name.substr(0, apk_name.rfind(ext.to_string()));
std::unordered_set<std::string> artifacts_to_keep = options.kept_artifacts;
std::unordered_set<std::string> filtered_artifacts;
std::unordered_set<std::string> kept_artifacts;
// For now, just write out the stripped APK since ABI splitting doesn't modify anything else.
- for (const Artifact& artifact : config.artifacts) {
- SourcePathDiagnostics diag{{apk_name}, context_->GetDiagnostics()};
-
+ for (const OutputArtifact& artifact : options.apk_artifacts) {
FilterChain filters;
- if (!artifact.name && !config.artifact_format) {
- diag.Error(
- DiagMessage() << "Artifact does not have a name and no global name template defined");
- return false;
- }
-
- Maybe<std::string> maybe_artifact_name =
- (artifact.name) ? artifact.Name(apk_name, &diag)
- : artifact.ToArtifactName(config.artifact_format.value(), apk_name, &diag);
-
- if (!maybe_artifact_name) {
- diag.Error(DiagMessage() << "Could not determine split APK artifact name");
- return false;
- }
-
- const std::string& artifact_name = maybe_artifact_name.value();
-
ContextWrapper wrapped_context{context_};
- wrapped_context.SetSource({artifact_name});
+ wrapped_context.SetSource(artifact.name);
if (!options.kept_artifacts.empty()) {
- const auto& it = artifacts_to_keep.find(artifact_name);
+ const auto& it = artifacts_to_keep.find(artifact.name);
if (it == artifacts_to_keep.end()) {
- filtered_artifacts.insert(artifact_name);
+ filtered_artifacts.insert(artifact.name);
if (context_->IsVerbose()) {
- context_->GetDiagnostics()->Note(DiagMessage(artifact_name) << "skipping artifact");
+ context_->GetDiagnostics()->Note(DiagMessage(artifact.name) << "skipping artifact");
}
continue;
} else {
artifacts_to_keep.erase(it);
- kept_artifacts.insert(artifact_name);
+ kept_artifacts.insert(artifact.name);
}
}
std::unique_ptr<ResourceTable> table =
- FilterTable(artifact, config, *apk_->GetResourceTable(), &wrapped_context, &filters);
+ FilterTable(context_, artifact, *apk_->GetResourceTable(), &filters);
if (!table) {
return false;
}
+ IDiagnostics* diag = wrapped_context.GetDiagnostics();
+
std::unique_ptr<XmlResource> manifest;
- if (!UpdateManifest(artifact, config, &manifest, &diag)) {
- diag.Error(DiagMessage() << "could not update AndroidManifest.xml for output artifact");
+ if (!UpdateManifest(artifact, &manifest, diag)) {
+ diag->Error(DiagMessage() << "could not update AndroidManifest.xml for output artifact");
return false;
}
std::string out = options.out_dir;
if (!file::mkdirs(out)) {
- diag.Warn(DiagMessage() << "could not create out dir: " << out);
+ diag->Warn(DiagMessage() << "could not create out dir: " << out);
}
- file::AppendPath(&out, artifact_name);
+ file::AppendPath(&out, artifact.name);
if (context_->IsVerbose()) {
- diag.Note(DiagMessage() << "Generating split: " << out);
+ diag->Note(DiagMessage() << "Generating split: " << out);
}
- std::unique_ptr<IArchiveWriter> writer = CreateZipFileArchiveWriter(&diag, out);
+ std::unique_ptr<IArchiveWriter> writer = CreateZipFileArchiveWriter(diag, out);
if (context_->IsVerbose()) {
- diag.Note(DiagMessage() << "Writing output: " << out);
+ diag->Note(DiagMessage() << "Writing output: " << out);
}
filters.AddFilter(util::make_unique<SignatureFilter>());
@@ -254,64 +211,34 @@ bool MultiApkGenerator::FromBaseApk(const MultiApkGeneratorOptions& options) {
return true;
}
-std::unique_ptr<ResourceTable> MultiApkGenerator::FilterTable(
- const configuration::Artifact& artifact,
- const configuration::PostProcessingConfiguration& config, const ResourceTable& old_table,
- IAaptContext* context, FilterChain* filters) {
+std::unique_ptr<ResourceTable> MultiApkGenerator::FilterTable(IAaptContext* context,
+ const OutputArtifact& artifact,
+ const ResourceTable& old_table,
+ FilterChain* filters) {
TableSplitterOptions splits;
AxisConfigFilter axis_filter;
ContextWrapper wrapped_context{context};
+ wrapped_context.SetSource(artifact.name);
- if (artifact.abi_group) {
- const std::string& group_name = artifact.abi_group.value();
-
- auto group = config.abi_groups.find(group_name);
- // TODO: Remove validation when configuration parser ensures referential integrity.
- if (group == config.abi_groups.end()) {
- context->GetDiagnostics()->Error(DiagMessage() << "could not find referenced ABI group '"
- << group_name << "'");
- return {};
- }
- filters->AddFilter(AbiFilter::FromAbiList(group->second));
+ if (!artifact.abis.empty()) {
+ filters->AddFilter(AbiFilter::FromAbiList(artifact.abis));
}
- if (artifact.screen_density_group) {
- const std::string& group_name = artifact.screen_density_group.value();
-
- auto group = config.screen_density_groups.find(group_name);
- // TODO: Remove validation when configuration parser ensures referential integrity.
- if (group == config.screen_density_groups.end()) {
- context->GetDiagnostics()->Error(DiagMessage()
- << "could not find referenced group '" << group_name << "'");
- return {};
- }
-
- const std::vector<ConfigDescription>& densities = group->second;
- for (const auto& density_config : densities) {
+ if (!artifact.screen_densities.empty()) {
+ for (const auto& density_config : artifact.screen_densities) {
splits.preferred_densities.push_back(density_config.density);
}
}
- if (artifact.locale_group) {
- const std::string& group_name = artifact.locale_group.value();
- auto group = config.locale_groups.find(group_name);
- // TODO: Remove validation when configuration parser ensures referential integrity.
- if (group == config.locale_groups.end()) {
- context->GetDiagnostics()->Error(DiagMessage()
- << "could not find referenced group '" << group_name << "'");
- return {};
- }
-
- const std::vector<ConfigDescription>& locales = group->second;
- for (const auto& locale : locales) {
+ if (!artifact.locales.empty()) {
+ for (const auto& locale : artifact.locales) {
axis_filter.AddConfig(locale);
}
splits.config_filter = &axis_filter;
}
- Maybe<AndroidSdk> sdk = GetAndroidSdk(artifact, config, context->GetDiagnostics());
- if (sdk && sdk.value().min_sdk_version) {
- wrapped_context.SetMinSdkVersion(sdk.value().min_sdk_version.value());
+ if (artifact.android_sdk && artifact.android_sdk.value().min_sdk_version) {
+ wrapped_context.SetMinSdkVersion(artifact.android_sdk.value().min_sdk_version.value());
}
std::unique_ptr<ResourceTable> table = old_table.Clone();
@@ -327,8 +254,7 @@ std::unique_ptr<ResourceTable> MultiApkGenerator::FilterTable(
return table;
}
-bool MultiApkGenerator::UpdateManifest(const Artifact& artifact,
- const PostProcessingConfiguration& config,
+bool MultiApkGenerator::UpdateManifest(const OutputArtifact& artifact,
std::unique_ptr<XmlResource>* updated_manifest,
IDiagnostics* diag) {
const xml::XmlResource* apk_manifest = apk_->GetManifest();
@@ -367,10 +293,9 @@ bool MultiApkGenerator::UpdateManifest(const Artifact& artifact,
versionCode->compiled_value = ResourceUtils::TryParseInt(std::to_string(new_version));
// Check to see if the minSdkVersion needs to be updated.
- Maybe<AndroidSdk> maybe_sdk = GetAndroidSdk(artifact, config, diag);
- if (maybe_sdk) {
+ if (artifact.android_sdk) {
// TODO(safarmer): Handle the rest of the Android SDK.
- const AndroidSdk& android_sdk = maybe_sdk.value();
+ const AndroidSdk& android_sdk = artifact.android_sdk.value();
if (xml::Element* uses_sdk_el = manifest_el->FindChild({}, "uses-sdk")) {
if (xml::Attribute* min_sdk_attr =
@@ -392,10 +317,7 @@ bool MultiApkGenerator::UpdateManifest(const Artifact& artifact,
}
}
- if (artifact.screen_density_group) {
- auto densities = config.screen_density_groups.find(artifact.screen_density_group.value());
- CHECK(densities != config.screen_density_groups.end()) << "Missing density group";
-
+ if (!artifact.screen_densities.empty()) {
xml::Element* screens_el = manifest_el->FindChild({}, "compatible-screens");
if (!screens_el) {
// create a new element.
@@ -408,7 +330,7 @@ bool MultiApkGenerator::UpdateManifest(const Artifact& artifact,
screens_el->GetChildElements().clear();
}
- for (const auto& density : densities->second) {
+ for (const auto& density : artifact.screen_densities) {
std::unique_ptr<xml::Element> screen_el = util::make_unique<xml::Element>();
screen_el->name = "screen";
const char* density_str = density.toString().string();
diff --git a/tools/aapt2/optimize/MultiApkGenerator.h b/tools/aapt2/optimize/MultiApkGenerator.h
index dedb610e1caa..19f64cc0e588 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.h
+++ b/tools/aapt2/optimize/MultiApkGenerator.h
@@ -20,6 +20,7 @@
#include <memory>
#include <string>
#include <unordered_set>
+#include <vector>
#include "Diagnostics.h"
#include "LoadedApk.h"
@@ -29,7 +30,7 @@ namespace aapt {
struct MultiApkGeneratorOptions {
std::string out_dir;
- configuration::PostProcessingConfiguration config;
+ std::vector<configuration::OutputArtifact> apk_artifacts;
TableFlattenerOptions table_flattener_options;
std::unordered_set<std::string> kept_artifacts;
};
@@ -49,18 +50,17 @@ class MultiApkGenerator {
bool FromBaseApk(const MultiApkGeneratorOptions& options);
protected:
- virtual std::unique_ptr<ResourceTable> FilterTable(
- const configuration::Artifact& artifact,
- const configuration::PostProcessingConfiguration& config, const ResourceTable& old_table,
- IAaptContext* context, FilterChain* chain);
+ virtual std::unique_ptr<ResourceTable> FilterTable(IAaptContext* context,
+ const configuration::OutputArtifact& artifact,
+ const ResourceTable& old_table,
+ FilterChain* chain);
private:
IDiagnostics* GetDiagnostics() {
return context_->GetDiagnostics();
}
- bool UpdateManifest(const configuration::Artifact& artifact,
- const configuration::PostProcessingConfiguration& config,
+ bool UpdateManifest(const configuration::OutputArtifact& artifact,
std::unique_ptr<xml::XmlResource>* updated_manifest, IDiagnostics* diag);
LoadedApk* apk_;
diff --git a/tools/aapt2/optimize/MultiApkGenerator_test.cpp b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
index 2d303e220f8f..e1d951fc9776 100644
--- a/tools/aapt2/optimize/MultiApkGenerator_test.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
@@ -36,8 +36,7 @@ namespace {
using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidSdk;
-using ::aapt::configuration::Artifact;
-using ::aapt::configuration::PostProcessingConfiguration;
+using ::aapt::configuration::OutputArtifact;
using ::aapt::test::GetValue;
using ::aapt::test::GetValueForConfig;
using ::aapt::test::ParseConfigOrDie;
@@ -48,7 +47,6 @@ using ::testing::NotNull;
using ::testing::PrintToString;
using ::testing::Return;
using ::testing::Test;
-using ::testing::_;
/**
* Subclass the MultiApkGenerator class so that we can access the protected FilterTable method to
@@ -60,11 +58,11 @@ class MultiApkGeneratorWrapper : public MultiApkGenerator {
: MultiApkGenerator(apk, context) {
}
- std::unique_ptr<ResourceTable> FilterTable(
- const configuration::Artifact& artifact,
- const configuration::PostProcessingConfiguration& config, const ResourceTable& old_table,
- IAaptContext* context, FilterChain* filter_chain) override {
- return MultiApkGenerator::FilterTable(artifact, config, old_table, context, filter_chain);
+ std::unique_ptr<ResourceTable> FilterTable(IAaptContext* context,
+ const configuration::OutputArtifact& artifact,
+ const ResourceTable& old_table,
+ FilterChain* filter_chain) override {
+ return MultiApkGenerator::FilterTable(context, artifact, old_table, filter_chain);
}
};
@@ -108,27 +106,13 @@ TEST_F(MultiApkGeneratorTest, VersionFilterNewerVersion) {
LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(19).Build();
- PostProcessingConfiguration empty_config;
- TableFlattenerOptions table_flattener_options;
FilterChain chain;
- Artifact x64 = test::ArtifactBuilder()
- .SetName("${basename}.${sdk}.apk")
- .SetDensityGroup("xhdpi")
- .SetAndroidSdk("v23")
- .Build();
-
- auto config = test::PostProcessingConfigurationBuilder()
- .SetLocaleGroup("en", {"en"})
- .SetAbiGroup("x64", {Abi::kX86_64})
- .SetDensityGroup("xhdpi", {"xhdpi"})
- .SetAndroidSdk("v23", AndroidSdk::ForMinSdk(23))
- .AddArtifact(x64)
- .Build();
+ OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).SetAndroidSdk(23).Build();
MultiApkGeneratorWrapper generator{&apk, ctx.get()};
std::unique_ptr<ResourceTable> split =
- generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
+ generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
ResourceTable* new_table = split.get();
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
@@ -149,27 +133,13 @@ TEST_F(MultiApkGeneratorTest, VersionFilterOlderVersion) {
LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
- PostProcessingConfiguration empty_config;
- TableFlattenerOptions table_flattener_options;
FilterChain chain;
- Artifact x64 = test::ArtifactBuilder()
- .SetName("${basename}.${sdk}.apk")
- .SetDensityGroup("xhdpi")
- .SetAndroidSdk("v4")
- .Build();
-
- auto config = test::PostProcessingConfigurationBuilder()
- .SetLocaleGroup("en", {"en"})
- .SetAbiGroup("x64", {Abi::kX86_64})
- .SetDensityGroup("xhdpi", {"xhdpi"})
- .SetAndroidSdk("v4", AndroidSdk::ForMinSdk(4))
- .AddArtifact(x64)
- .Build();
+ OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).SetAndroidSdk(4).Build();
MultiApkGeneratorWrapper generator{&apk, ctx.get()};;
std::unique_ptr<ResourceTable> split =
- generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
+ generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
ResourceTable* new_table = split.get();
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
@@ -188,23 +158,13 @@ TEST_F(MultiApkGeneratorTest, VersionFilterNoVersion) {
LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
- PostProcessingConfiguration empty_config;
- TableFlattenerOptions table_flattener_options;
FilterChain chain;
- Artifact x64 =
- test::ArtifactBuilder().SetName("${basename}.${sdk}.apk").SetDensityGroup("xhdpi").Build();
-
- auto config = test::PostProcessingConfigurationBuilder()
- .SetLocaleGroup("en", {"en"})
- .SetAbiGroup("x64", {Abi::kX86_64})
- .SetDensityGroup("xhdpi", {"xhdpi"})
- .AddArtifact(x64)
- .Build();
+ OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).Build();
MultiApkGeneratorWrapper generator{&apk, ctx.get()};
std::unique_ptr<ResourceTable> split =
- generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
+ generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
ResourceTable* new_table = split.get();
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
diff --git a/tools/aapt2/test/Builders.cpp b/tools/aapt2/test/Builders.cpp
index ecec63f3cf31..88897a8afac3 100644
--- a/tools/aapt2/test/Builders.cpp
+++ b/tools/aapt2/test/Builders.cpp
@@ -25,7 +25,7 @@
using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidSdk;
-using ::aapt::configuration::Artifact;
+using ::aapt::configuration::ConfiguredArtifact;
using ::aapt::io::StringInputStream;
using ::android::StringPiece;
@@ -221,72 +221,32 @@ std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* contex
return doc;
}
-PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::SetAbiGroup(
- const std::string& name, const std::vector<Abi>& abis) {
- config_.abi_groups[name] = abis;
- return *this;
-}
-
-PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::SetLocaleGroup(
- const std::string& name, const std::vector<std::string>& locales) {
- auto& group = config_.locale_groups[name];
- for (const auto& locale : locales) {
- group.push_back(ParseConfigOrDie(locale));
- }
- return *this;
-}
-
-PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::SetDensityGroup(
- const std::string& name, const std::vector<std::string>& densities) {
- auto& group = config_.screen_density_groups[name];
- for (const auto& density : densities) {
- group.push_back(ParseConfigOrDie(density));
- }
- return *this;
-}
-
-PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::SetAndroidSdk(
- const std::string& name, const AndroidSdk& sdk) {
- config_.android_sdk_groups[name] = sdk;
- return *this;
-}
-
-PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddArtifact(
- const Artifact& artifact) {
- config_.artifacts.push_back(artifact);
- return *this;
-}
-
-configuration::PostProcessingConfiguration PostProcessingConfigurationBuilder::Build() {
- return config_;
-}
-
ArtifactBuilder& ArtifactBuilder::SetName(const std::string& name) {
- artifact_.name = {name};
+ artifact_.name = name;
return *this;
}
-ArtifactBuilder& ArtifactBuilder::SetAbiGroup(const std::string& name) {
- artifact_.abi_group = {name};
+ArtifactBuilder& ArtifactBuilder::AddAbi(configuration::Abi abi) {
+ artifact_.abis.push_back(abi);
return *this;
}
-ArtifactBuilder& ArtifactBuilder::SetDensityGroup(const std::string& name) {
- artifact_.screen_density_group = {name};
+ArtifactBuilder& ArtifactBuilder::AddDensity(const ConfigDescription& density) {
+ artifact_.screen_densities.push_back(density);
return *this;
}
-ArtifactBuilder& ArtifactBuilder::SetLocaleGroup(const std::string& name) {
- artifact_.locale_group = {name};
+ArtifactBuilder& ArtifactBuilder::AddLocale(const ConfigDescription& locale) {
+ artifact_.locales.push_back(locale);
return *this;
}
-ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(const std::string& name) {
- artifact_.android_sdk_group = {name};
+ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(int min_sdk) {
+ artifact_.android_sdk = {AndroidSdk::ForMinSdk(min_sdk)};
return *this;
}
-configuration::Artifact ArtifactBuilder::Build() {
+configuration::OutputArtifact ArtifactBuilder::Build() {
return artifact_;
}
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index 4cdfc33e92e3..2f83b78ffb2a 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -25,6 +25,7 @@
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "configuration/ConfigurationParser.h"
+#include "configuration/ConfigurationParser.internal.h"
#include "process/IResourceTableConsumer.h"
#include "test/Common.h"
#include "util/Maybe.h"
@@ -154,38 +155,19 @@ std::unique_ptr<xml::XmlResource> BuildXmlDom(const android::StringPiece& str);
std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
const android::StringPiece& str);
-class PostProcessingConfigurationBuilder {
- public:
- PostProcessingConfigurationBuilder() = default;
-
- PostProcessingConfigurationBuilder& SetAbiGroup(const std::string& name,
- const std::vector<configuration::Abi>& abis);
- PostProcessingConfigurationBuilder& SetLocaleGroup(const std::string& name,
- const std::vector<std::string>& locales);
- PostProcessingConfigurationBuilder& SetDensityGroup(const std::string& name,
- const std::vector<std::string>& densities);
- PostProcessingConfigurationBuilder& SetAndroidSdk(const std::string& name,
- const configuration::AndroidSdk& sdk);
- PostProcessingConfigurationBuilder& AddArtifact(const configuration::Artifact& artifact);
- configuration::PostProcessingConfiguration Build();
-
- private:
- configuration::PostProcessingConfiguration config_;
-};
-
class ArtifactBuilder {
public:
ArtifactBuilder() = default;
ArtifactBuilder& SetName(const std::string& name);
- ArtifactBuilder& SetAbiGroup(const std::string& name);
- ArtifactBuilder& SetDensityGroup(const std::string& name);
- ArtifactBuilder& SetLocaleGroup(const std::string& name);
- ArtifactBuilder& SetAndroidSdk(const std::string& name);
- configuration::Artifact Build();
+ ArtifactBuilder& AddAbi(configuration::Abi abi);
+ ArtifactBuilder& AddDensity(const ConfigDescription& density);
+ ArtifactBuilder& AddLocale(const ConfigDescription& locale);
+ ArtifactBuilder& SetAndroidSdk(int min_sdk);
+ configuration::OutputArtifact Build();
private:
- configuration::Artifact artifact_;
+ configuration::OutputArtifact artifact_;
};
} // namespace test