Loading tools/aapt/ResourceTable.cpp +52 −18 Original line number Original line Diff line number Diff line Loading @@ -4466,6 +4466,37 @@ static int getMinSdkVersion(const Bundle* bundle) { return 0; return 0; } } static bool shouldGenerateVersionedResource(const sp<ResourceTable::ConfigList>& configList, const ConfigDescription& sourceConfig, const int sdkVersionToGenerate) { assert(sdkVersionToGenerate > sourceConfig.sdkVersion); const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries = configList->getEntries(); ssize_t idx = entries.indexOfKey(sourceConfig); // The source config came from this list, so it should be here. assert(idx >= 0); idx += 1; if (static_cast<size_t>(idx) >= entries.size()) { // This is the last configuration, so we should generate a versioned resource. return true; } const ConfigDescription& nextConfig = entries.keyAt(idx); // Build a configuration that is the same as the source config, // but with the SDK level of the next config. If they are the same, // then they only differ in SDK level. If the next configs SDK level is // higher than the one we want to generate, we must generate it. ConfigDescription tempConfig(sourceConfig); tempConfig.sdkVersion = nextConfig.sdkVersion; if (nextConfig == tempConfig) { return sdkVersionToGenerate < nextConfig.sdkVersion; } return false; } /** /** * Modifies the entries in the resource table to account for compatibility * Modifies the entries in the resource table to account for compatibility * issues with older versions of Android. * issues with older versions of Android. Loading Loading @@ -4574,6 +4605,11 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { for (size_t i = 0; i < sdkCount; i++) { for (size_t i = 0; i < sdkCount; i++) { const int sdkLevel = attributesToRemove.keyAt(i); const int sdkLevel = attributesToRemove.keyAt(i); if (!shouldGenerateVersionedResource(c, config, sdkLevel)) { // There is a style that will override this generated one. continue; } // Duplicate the entry under the same configuration // Duplicate the entry under the same configuration // but with sdkVersion == sdkLevel. // but with sdkVersion == sdkLevel. ConfigDescription newConfig(config); ConfigDescription newConfig(config); Loading Loading @@ -4610,13 +4646,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { const size_t entriesToAddCount = entriesToAdd.size(); const size_t entriesToAddCount = entriesToAdd.size(); for (size_t i = 0; i < entriesToAddCount; i++) { for (size_t i = 0; i < entriesToAddCount; i++) { if (entries.indexOfKey(entriesToAdd[i].key) >= 0) { assert(entries.indexOfKey(entriesToAdd[i].key) < 0); // An entry already exists for this config. // That means that any attributes that were // defined in L in the original bag will be overriden // anyways on L devices, so we do nothing. continue; } if (bundle->getVerbose()) { if (bundle->getVerbose()) { entriesToAdd[i].value->getPos() entriesToAdd[i].value->getPos() Loading Loading @@ -4662,8 +4692,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, } } sp<XMLNode> newRoot = NULL; sp<XMLNode> newRoot = NULL; ConfigDescription newConfig(target->getGroupEntry().toParams()); int sdkVersionToGenerate = SDK_LOLLIPOP_MR1; newConfig.sdkVersion = SDK_LOLLIPOP_MR1; Vector<sp<XMLNode> > nodesToVisit; Vector<sp<XMLNode> > nodesToVisit; nodesToVisit.push(root); nodesToVisit.push(root); Loading @@ -4689,9 +4718,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Find the smallest sdk version that we need to synthesize for // Find the smallest sdk version that we need to synthesize for // and do that one. Subsequent versions will be processed on // and do that one. Subsequent versions will be processed on // the next pass. // the next pass. if (sdkLevel < newConfig.sdkVersion) { sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate); newConfig.sdkVersion = sdkLevel; } if (bundle->getVerbose()) { if (bundle->getVerbose()) { SourcePos(node->getFilename(), node->getStartLineNumber()).printf( SourcePos(node->getFilename(), node->getStartLineNumber()).printf( Loading Loading @@ -4721,8 +4748,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Look to see if we already have an overriding v21 configuration. // Look to see if we already have an overriding v21 configuration. sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), String16(target->getResourceType()), resourceName); String16(target->getResourceType()), resourceName); if (cl->getEntries().indexOfKey(newConfig) < 0) { if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) { // We don't have an overriding entry for v21, so we must duplicate this one. // We don't have an overriding entry for v21, so we must duplicate this one. ConfigDescription newConfig(config); newConfig.sdkVersion = sdkVersionToGenerate; sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), AaptGroupEntry(newConfig), target->getResourceType()); AaptGroupEntry(newConfig), target->getResourceType()); String8 resPath = String8::format("res/%s/%s", String8 resPath = String8::format("res/%s/%s", Loading Loading @@ -4760,7 +4789,8 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, return NO_ERROR; return NO_ERROR; } } void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { void ResourceTable::getDensityVaryingResources( KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { const ConfigDescription nullConfig; const ConfigDescription nullConfig; const size_t packageCount = mOrderedPackages.size(); const size_t packageCount = mOrderedPackages.size(); Loading @@ -4771,19 +4801,23 @@ void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<Symbol const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const size_t configCount = configs.size(); const size_t configCount = configs.size(); for (size_t c = 0; c < configCount; c++) { for (size_t c = 0; c < configCount; c++) { const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const size_t configEntryCount = configEntries.size(); const size_t configEntryCount = configEntries.size(); for (size_t ce = 0; ce < configEntryCount; ce++) { for (size_t ce = 0; ce < configEntryCount; ce++) { const ConfigDescription& config = configEntries.keyAt(ce); const ConfigDescription& config = configEntries.keyAt(ce); if (AaptConfig::isDensityOnly(config)) { if (AaptConfig::isDensityOnly(config)) { // This configuration only varies with regards to density. // This configuration only varies with regards to density. const Symbol symbol(mOrderedPackages[p]->getName(), const Symbol symbol( mOrderedPackages[p]->getName(), types[t]->getName(), types[t]->getName(), configs[c]->getName(), configs[c]->getName(), getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); const sp<Entry>& entry = configEntries.valueAt(ce); const sp<Entry>& entry = configEntries.valueAt(ce); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); } } } } } } Loading Loading
tools/aapt/ResourceTable.cpp +52 −18 Original line number Original line Diff line number Diff line Loading @@ -4466,6 +4466,37 @@ static int getMinSdkVersion(const Bundle* bundle) { return 0; return 0; } } static bool shouldGenerateVersionedResource(const sp<ResourceTable::ConfigList>& configList, const ConfigDescription& sourceConfig, const int sdkVersionToGenerate) { assert(sdkVersionToGenerate > sourceConfig.sdkVersion); const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries = configList->getEntries(); ssize_t idx = entries.indexOfKey(sourceConfig); // The source config came from this list, so it should be here. assert(idx >= 0); idx += 1; if (static_cast<size_t>(idx) >= entries.size()) { // This is the last configuration, so we should generate a versioned resource. return true; } const ConfigDescription& nextConfig = entries.keyAt(idx); // Build a configuration that is the same as the source config, // but with the SDK level of the next config. If they are the same, // then they only differ in SDK level. If the next configs SDK level is // higher than the one we want to generate, we must generate it. ConfigDescription tempConfig(sourceConfig); tempConfig.sdkVersion = nextConfig.sdkVersion; if (nextConfig == tempConfig) { return sdkVersionToGenerate < nextConfig.sdkVersion; } return false; } /** /** * Modifies the entries in the resource table to account for compatibility * Modifies the entries in the resource table to account for compatibility * issues with older versions of Android. * issues with older versions of Android. Loading Loading @@ -4574,6 +4605,11 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { for (size_t i = 0; i < sdkCount; i++) { for (size_t i = 0; i < sdkCount; i++) { const int sdkLevel = attributesToRemove.keyAt(i); const int sdkLevel = attributesToRemove.keyAt(i); if (!shouldGenerateVersionedResource(c, config, sdkLevel)) { // There is a style that will override this generated one. continue; } // Duplicate the entry under the same configuration // Duplicate the entry under the same configuration // but with sdkVersion == sdkLevel. // but with sdkVersion == sdkLevel. ConfigDescription newConfig(config); ConfigDescription newConfig(config); Loading Loading @@ -4610,13 +4646,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { const size_t entriesToAddCount = entriesToAdd.size(); const size_t entriesToAddCount = entriesToAdd.size(); for (size_t i = 0; i < entriesToAddCount; i++) { for (size_t i = 0; i < entriesToAddCount; i++) { if (entries.indexOfKey(entriesToAdd[i].key) >= 0) { assert(entries.indexOfKey(entriesToAdd[i].key) < 0); // An entry already exists for this config. // That means that any attributes that were // defined in L in the original bag will be overriden // anyways on L devices, so we do nothing. continue; } if (bundle->getVerbose()) { if (bundle->getVerbose()) { entriesToAdd[i].value->getPos() entriesToAdd[i].value->getPos() Loading Loading @@ -4662,8 +4692,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, } } sp<XMLNode> newRoot = NULL; sp<XMLNode> newRoot = NULL; ConfigDescription newConfig(target->getGroupEntry().toParams()); int sdkVersionToGenerate = SDK_LOLLIPOP_MR1; newConfig.sdkVersion = SDK_LOLLIPOP_MR1; Vector<sp<XMLNode> > nodesToVisit; Vector<sp<XMLNode> > nodesToVisit; nodesToVisit.push(root); nodesToVisit.push(root); Loading @@ -4689,9 +4718,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Find the smallest sdk version that we need to synthesize for // Find the smallest sdk version that we need to synthesize for // and do that one. Subsequent versions will be processed on // and do that one. Subsequent versions will be processed on // the next pass. // the next pass. if (sdkLevel < newConfig.sdkVersion) { sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate); newConfig.sdkVersion = sdkLevel; } if (bundle->getVerbose()) { if (bundle->getVerbose()) { SourcePos(node->getFilename(), node->getStartLineNumber()).printf( SourcePos(node->getFilename(), node->getStartLineNumber()).printf( Loading Loading @@ -4721,8 +4748,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Look to see if we already have an overriding v21 configuration. // Look to see if we already have an overriding v21 configuration. sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), String16(target->getResourceType()), resourceName); String16(target->getResourceType()), resourceName); if (cl->getEntries().indexOfKey(newConfig) < 0) { if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) { // We don't have an overriding entry for v21, so we must duplicate this one. // We don't have an overriding entry for v21, so we must duplicate this one. ConfigDescription newConfig(config); newConfig.sdkVersion = sdkVersionToGenerate; sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), AaptGroupEntry(newConfig), target->getResourceType()); AaptGroupEntry(newConfig), target->getResourceType()); String8 resPath = String8::format("res/%s/%s", String8 resPath = String8::format("res/%s/%s", Loading Loading @@ -4760,7 +4789,8 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, return NO_ERROR; return NO_ERROR; } } void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { void ResourceTable::getDensityVaryingResources( KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { const ConfigDescription nullConfig; const ConfigDescription nullConfig; const size_t packageCount = mOrderedPackages.size(); const size_t packageCount = mOrderedPackages.size(); Loading @@ -4771,19 +4801,23 @@ void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<Symbol const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const size_t configCount = configs.size(); const size_t configCount = configs.size(); for (size_t c = 0; c < configCount; c++) { for (size_t c = 0; c < configCount; c++) { const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const size_t configEntryCount = configEntries.size(); const size_t configEntryCount = configEntries.size(); for (size_t ce = 0; ce < configEntryCount; ce++) { for (size_t ce = 0; ce < configEntryCount; ce++) { const ConfigDescription& config = configEntries.keyAt(ce); const ConfigDescription& config = configEntries.keyAt(ce); if (AaptConfig::isDensityOnly(config)) { if (AaptConfig::isDensityOnly(config)) { // This configuration only varies with regards to density. // This configuration only varies with regards to density. const Symbol symbol(mOrderedPackages[p]->getName(), const Symbol symbol( mOrderedPackages[p]->getName(), types[t]->getName(), types[t]->getName(), configs[c]->getName(), configs[c]->getName(), getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); const sp<Entry>& entry = configEntries.valueAt(ce); const sp<Entry>& entry = configEntries.valueAt(ce); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); } } } } } } Loading