Skip to content

Commit e3b0119

Browse files
Adam LesinskiAndroid (Google) Code Review
authored andcommitted
Merge "AAPT: Fix resource versioning" into mnc-dev
2 parents b9f30b2 + f45d2fa commit e3b0119

1 file changed

Lines changed: 52 additions & 18 deletions

File tree

tools/aapt/ResourceTable.cpp

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4466,6 +4466,37 @@ static int getMinSdkVersion(const Bundle* bundle) {
44664466
return 0;
44674467
}
44684468

4469+
static bool shouldGenerateVersionedResource(const sp<ResourceTable::ConfigList>& configList,
4470+
const ConfigDescription& sourceConfig,
4471+
const int sdkVersionToGenerate) {
4472+
assert(sdkVersionToGenerate > sourceConfig.sdkVersion);
4473+
const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries
4474+
= configList->getEntries();
4475+
ssize_t idx = entries.indexOfKey(sourceConfig);
4476+
4477+
// The source config came from this list, so it should be here.
4478+
assert(idx >= 0);
4479+
4480+
idx += 1;
4481+
if (static_cast<size_t>(idx) >= entries.size()) {
4482+
// This is the last configuration, so we should generate a versioned resource.
4483+
return true;
4484+
}
4485+
4486+
const ConfigDescription& nextConfig = entries.keyAt(idx);
4487+
4488+
// Build a configuration that is the same as the source config,
4489+
// but with the SDK level of the next config. If they are the same,
4490+
// then they only differ in SDK level. If the next configs SDK level is
4491+
// higher than the one we want to generate, we must generate it.
4492+
ConfigDescription tempConfig(sourceConfig);
4493+
tempConfig.sdkVersion = nextConfig.sdkVersion;
4494+
if (nextConfig == tempConfig) {
4495+
return sdkVersionToGenerate < nextConfig.sdkVersion;
4496+
}
4497+
return false;
4498+
}
4499+
44694500
/**
44704501
* Modifies the entries in the resource table to account for compatibility
44714502
* issues with older versions of Android.
@@ -4574,6 +4605,11 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) {
45744605
for (size_t i = 0; i < sdkCount; i++) {
45754606
const int sdkLevel = attributesToRemove.keyAt(i);
45764607

4608+
if (!shouldGenerateVersionedResource(c, config, sdkLevel)) {
4609+
// There is a style that will override this generated one.
4610+
continue;
4611+
}
4612+
45774613
// Duplicate the entry under the same configuration
45784614
// but with sdkVersion == sdkLevel.
45794615
ConfigDescription newConfig(config);
@@ -4610,13 +4646,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) {
46104646

46114647
const size_t entriesToAddCount = entriesToAdd.size();
46124648
for (size_t i = 0; i < entriesToAddCount; i++) {
4613-
if (entries.indexOfKey(entriesToAdd[i].key) >= 0) {
4614-
// An entry already exists for this config.
4615-
// That means that any attributes that were
4616-
// defined in L in the original bag will be overriden
4617-
// anyways on L devices, so we do nothing.
4618-
continue;
4619-
}
4649+
assert(entries.indexOfKey(entriesToAdd[i].key) < 0);
46204650

46214651
if (bundle->getVerbose()) {
46224652
entriesToAdd[i].value->getPos()
@@ -4662,8 +4692,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
46624692
}
46634693

46644694
sp<XMLNode> newRoot = NULL;
4665-
ConfigDescription newConfig(target->getGroupEntry().toParams());
4666-
newConfig.sdkVersion = SDK_LOLLIPOP_MR1;
4695+
int sdkVersionToGenerate = SDK_LOLLIPOP_MR1;
46674696

46684697
Vector<sp<XMLNode> > nodesToVisit;
46694698
nodesToVisit.push(root);
@@ -4689,9 +4718,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
46894718
// Find the smallest sdk version that we need to synthesize for
46904719
// and do that one. Subsequent versions will be processed on
46914720
// the next pass.
4692-
if (sdkLevel < newConfig.sdkVersion) {
4693-
newConfig.sdkVersion = sdkLevel;
4694-
}
4721+
sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate);
46954722

46964723
if (bundle->getVerbose()) {
46974724
SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
@@ -4721,8 +4748,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
47214748
// Look to see if we already have an overriding v21 configuration.
47224749
sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),
47234750
String16(target->getResourceType()), resourceName);
4724-
if (cl->getEntries().indexOfKey(newConfig) < 0) {
4751+
if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) {
47254752
// We don't have an overriding entry for v21, so we must duplicate this one.
4753+
ConfigDescription newConfig(config);
4754+
newConfig.sdkVersion = sdkVersionToGenerate;
47264755
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
47274756
AaptGroupEntry(newConfig), target->getResourceType());
47284757
String8 resPath = String8::format("res/%s/%s",
@@ -4760,7 +4789,8 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
47604789
return NO_ERROR;
47614790
}
47624791

4763-
void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
4792+
void ResourceTable::getDensityVaryingResources(
4793+
KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
47644794
const ConfigDescription nullConfig;
47654795

47664796
const size_t packageCount = mOrderedPackages.size();
@@ -4771,19 +4801,23 @@ void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<Symbol
47714801
const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs();
47724802
const size_t configCount = configs.size();
47734803
for (size_t c = 0; c < configCount; c++) {
4774-
const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries();
4804+
const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries
4805+
= configs[c]->getEntries();
47754806
const size_t configEntryCount = configEntries.size();
47764807
for (size_t ce = 0; ce < configEntryCount; ce++) {
47774808
const ConfigDescription& config = configEntries.keyAt(ce);
47784809
if (AaptConfig::isDensityOnly(config)) {
47794810
// This configuration only varies with regards to density.
4780-
const Symbol symbol(mOrderedPackages[p]->getName(),
4811+
const Symbol symbol(
4812+
mOrderedPackages[p]->getName(),
47814813
types[t]->getName(),
47824814
configs[c]->getName(),
4783-
getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex()));
4815+
getResId(mOrderedPackages[p], types[t],
4816+
configs[c]->getEntryIndex()));
47844817

47854818
const sp<Entry>& entry = configEntries.valueAt(ce);
4786-
AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos()));
4819+
AaptUtil::appendValue(resources, symbol,
4820+
SymbolDefinition(symbol, config, entry->getPos()));
47874821
}
47884822
}
47894823
}

0 commit comments

Comments
 (0)