AAPT2: Introduce notion of 'product' to ResourceTable
This allows us to preserve the various product definitions during the compile
phase, and allows us to select the product in the link phase.
This allows compiled files to remain product-independent, so that they do not need
to be recompiled when switching targets.
Bug:25958912
Change-Id: Iaa7eed25c834b67a39cdc9be43613e8b5ab6cdd7
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index c7e603e..459c330 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -18,9 +18,7 @@
#include "ResourceTable.h"
#include "SdkConstants.h"
#include "ValueVisitor.h"
-
#include "link/Linkers.h"
-#include "util/Comparators.h"
#include <algorithm>
#include <cassert>
@@ -31,7 +29,12 @@
const int sdkVersionToGenerate) {
assert(sdkVersionToGenerate > config.sdkVersion);
const auto endIter = entry->values.end();
- auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThanConfig);
+ auto iter = entry->values.begin();
+ for (; iter != endIter; ++iter) {
+ if ((*iter)->config == config) {
+ break;
+ }
+ }
// The source config came from this list, so it should be here.
assert(iter != entry->values.end());
@@ -45,10 +48,10 @@
// are no higher sdk level versions of this resource.
ConfigDescription tempConfig(config);
for (; iter != endIter; ++iter) {
- tempConfig.sdkVersion = iter->config.sdkVersion;
- if (tempConfig == iter->config) {
+ tempConfig.sdkVersion = (*iter)->config.sdkVersion;
+ if (tempConfig == (*iter)->config) {
// The two configs are the same, check the sdk version.
- return sdkVersionToGenerate < iter->config.sdkVersion;
+ return sdkVersionToGenerate < (*iter)->config.sdkVersion;
}
}
@@ -65,14 +68,14 @@
for (auto& entry : type->entries) {
for (size_t i = 0; i < entry->values.size(); i++) {
- ResourceConfigValue& configValue = entry->values[i];
- if (configValue.config.sdkVersion >= SDK_LOLLIPOP_MR1) {
+ ResourceConfigValue* configValue = entry->values[i].get();
+ if (configValue->config.sdkVersion >= SDK_LOLLIPOP_MR1) {
// If this configuration is only used on L-MR1 then we don't need
// to do anything since we use private attributes since that version.
continue;
}
- if (Style* style = valueCast<Style>(configValue.value.get())) {
+ if (Style* style = valueCast<Style>(configValue->value.get())) {
Maybe<size_t> minSdkStripped;
std::vector<Style::Entry> stripped;
@@ -82,7 +85,7 @@
// Find the SDK level that is higher than the configuration allows.
const size_t sdkLevel = findAttributeSdkLevel(iter->key.id.value());
- if (sdkLevel > std::max<size_t>(configValue.config.sdkVersion, 1)) {
+ if (sdkLevel > std::max<size_t>(configValue->config.sdkVersion, 1)) {
// Record that we are about to strip this.
stripped.emplace_back(std::move(*iter));
@@ -105,10 +108,10 @@
// there is no other defined resource for the version we want to
// generate.
if (shouldGenerateVersionedResource(entry.get(),
- configValue.config,
+ configValue->config,
minSdkStripped.value())) {
// Let's create a new Style for this versioned resource.
- ConfigDescription newConfig(configValue.config);
+ ConfigDescription newConfig(configValue->config);
newConfig.sdkVersion = minSdkStripped.value();
std::unique_ptr<Style> newStyle(style->clone(&table->stringPool));
@@ -121,14 +124,8 @@
std::make_move_iterator(stripped.end()));
// Insert the new Resource into the correct place.
- auto iter = std::lower_bound(entry->values.begin(),
- entry->values.end(),
- newConfig,
- cmp::lessThanConfig);
-
- entry->values.insert(
- iter,
- ResourceConfigValue{ newConfig, std::move(newStyle) });
+ entry->findOrCreateValue(newConfig, {})->value =
+ std::move(newStyle);
}
}
}