Loading libs/androidfw/ResourceTypes.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -3645,8 +3645,12 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag Entry entry; status_t err = getEntry(grp, t, e, &desiredConfig, &entry); if (err != NO_ERROR) { // Only log the failure when we're not running on the host as // part of a tool. The caller will do its own logging. #ifndef STATIC_ANDROIDFW_FOR_TOOLS ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n", resID, t, e, err); #endif return err; } Loading tools/aapt/AaptConfig.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -794,4 +794,23 @@ bool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMa return a.diff(b) == axisMask; } bool isDensityOnly(const ResTable_config& config) { if (config.density == ResTable_config::DENSITY_NONE) { return false; } if (config.density == ResTable_config::DENSITY_ANY) { if (config.sdkVersion != SDK_L) { // Someone modified the sdkVersion from the default, this is not safe to assume. return false; } } else if (config.sdkVersion != SDK_DONUT) { return false; } const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION; const ConfigDescription nullConfig; return (nullConfig.diff(config) & ~mask) == 0; } } // namespace AaptConfig tools/aapt/AaptConfig.h +6 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,12 @@ android::String8 getVersion(const android::ResTable_config& config); */ bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask); /** * Returns true if the configuration only has the density specified. In the case * of 'anydpi', the version is ignored. */ bool isDensityOnly(const android::ResTable_config& config); } // namespace AaptConfig #endif // __AAPT_CONFIG_H tools/aapt/Resource.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ // Build resource files from raw assets. // #include "AaptAssets.h" #include "AaptUtil.h" #include "AaptXml.h" #include "CacheUpdater.h" #include "CrunchCache.h" Loading @@ -13,10 +14,14 @@ #include "Main.h" #include "ResourceTable.h" #include "StringPool.h" #include "Symbol.h" #include "WorkQueue.h" #include "XMLNode.h" #include <algorithm> // STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary. #if HAVE_PRINTF_ZD # define ZD "%zd" # define ZD_TYPE ssize_t Loading Loading @@ -1580,6 +1585,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil // Re-flatten because we may have added new resource IDs // -------------------------------------------------------------- ResTable finalResTable; sp<AaptFile> resFile; Loading @@ -1590,6 +1596,13 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil return err; } KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources; if (builder->getSplits().size() > 1) { // Only look for density varying resources if we're generating // splits. table.getDensityVaryingResources(densityVaryingResources); } Vector<sp<ApkSplit> >& splits = builder->getSplits(); const size_t numSplits = splits.size(); for (size_t i = 0; i < numSplits; i++) { Loading @@ -1613,6 +1626,63 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil return err; } } else { ResTable resTable; err = resTable.add(flattenedTable->getData(), flattenedTable->getSize()); if (err != NO_ERROR) { fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n", split->getPrintableName().string()); return err; } bool hasError = false; const std::set<ConfigDescription>& splitConfigs = split->getConfigs(); for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin(); iter != splitConfigs.end(); ++iter) { const ConfigDescription& config = *iter; if (AaptConfig::isDensityOnly(config)) { // Each density only split must contain all // density only resources. Res_value val; resTable.setParameters(&config); const size_t densityVaryingResourceCount = densityVaryingResources.size(); for (size_t k = 0; k < densityVaryingResourceCount; k++) { const Symbol& symbol = densityVaryingResources.keyAt(k); ssize_t block = resTable.getResource(symbol.id, &val, true); if (block < 0) { // Maybe it's in the base? finalResTable.setParameters(&config); block = finalResTable.getResource(symbol.id, &val, true); } if (block < 0) { hasError = true; SourcePos().error("%s has no definition for density split '%s'", symbol.toString().string(), config.toString().string()); if (bundle->getVerbose()) { const Vector<SymbolDefinition>& defs = densityVaryingResources[k]; const size_t defCount = std::min(size_t(5), defs.size()); for (size_t d = 0; d < defCount; d++) { const SymbolDefinition& def = defs[d]; def.source.error("%s has definition for %s", symbol.toString().string(), def.config.toString().string()); } if (defCount < defs.size()) { SourcePos().error("and %d more ...", (int) (defs.size() - defCount)); } } } } } } if (hasError) { return UNKNOWN_ERROR; } // Generate the AndroidManifest for this split. sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"), AaptGroupEntry(), String8()); err = generateAndroidManifestForSplit(bundle, assets, split, Loading tools/aapt/ResourceTable.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ #include "ResourceTable.h" #include "AaptUtil.h" #include "XMLNode.h" #include "ResourceFilter.h" #include "ResourceIdCache.h" Loading Loading @@ -4517,3 +4518,34 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, return NO_ERROR; } void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { const ConfigDescription nullConfig; const size_t packageCount = mOrderedPackages.size(); for (size_t p = 0; p < packageCount; p++) { const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes(); const size_t typeCount = types.size(); for (size_t t = 0; t < typeCount; t++) { const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const size_t configCount = configs.size(); for (size_t c = 0; c < configCount; c++) { const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const size_t configEntryCount = configEntries.size(); for (size_t ce = 0; ce < configEntryCount; ce++) { const ConfigDescription& config = configEntries.keyAt(ce); if (AaptConfig::isDensityOnly(config)) { // This configuration only varies with regards to density. const Symbol symbol(mOrderedPackages[p]->getName(), types[t]->getName(), configs[c]->getName(), getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); const sp<Entry>& entry = configEntries.valueAt(ce); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); } } } } } } Loading
libs/androidfw/ResourceTypes.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -3645,8 +3645,12 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag Entry entry; status_t err = getEntry(grp, t, e, &desiredConfig, &entry); if (err != NO_ERROR) { // Only log the failure when we're not running on the host as // part of a tool. The caller will do its own logging. #ifndef STATIC_ANDROIDFW_FOR_TOOLS ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n", resID, t, e, err); #endif return err; } Loading
tools/aapt/AaptConfig.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -794,4 +794,23 @@ bool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMa return a.diff(b) == axisMask; } bool isDensityOnly(const ResTable_config& config) { if (config.density == ResTable_config::DENSITY_NONE) { return false; } if (config.density == ResTable_config::DENSITY_ANY) { if (config.sdkVersion != SDK_L) { // Someone modified the sdkVersion from the default, this is not safe to assume. return false; } } else if (config.sdkVersion != SDK_DONUT) { return false; } const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION; const ConfigDescription nullConfig; return (nullConfig.diff(config) & ~mask) == 0; } } // namespace AaptConfig
tools/aapt/AaptConfig.h +6 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,12 @@ android::String8 getVersion(const android::ResTable_config& config); */ bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask); /** * Returns true if the configuration only has the density specified. In the case * of 'anydpi', the version is ignored. */ bool isDensityOnly(const android::ResTable_config& config); } // namespace AaptConfig #endif // __AAPT_CONFIG_H
tools/aapt/Resource.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ // Build resource files from raw assets. // #include "AaptAssets.h" #include "AaptUtil.h" #include "AaptXml.h" #include "CacheUpdater.h" #include "CrunchCache.h" Loading @@ -13,10 +14,14 @@ #include "Main.h" #include "ResourceTable.h" #include "StringPool.h" #include "Symbol.h" #include "WorkQueue.h" #include "XMLNode.h" #include <algorithm> // STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary. #if HAVE_PRINTF_ZD # define ZD "%zd" # define ZD_TYPE ssize_t Loading Loading @@ -1580,6 +1585,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil // Re-flatten because we may have added new resource IDs // -------------------------------------------------------------- ResTable finalResTable; sp<AaptFile> resFile; Loading @@ -1590,6 +1596,13 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil return err; } KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources; if (builder->getSplits().size() > 1) { // Only look for density varying resources if we're generating // splits. table.getDensityVaryingResources(densityVaryingResources); } Vector<sp<ApkSplit> >& splits = builder->getSplits(); const size_t numSplits = splits.size(); for (size_t i = 0; i < numSplits; i++) { Loading @@ -1613,6 +1626,63 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil return err; } } else { ResTable resTable; err = resTable.add(flattenedTable->getData(), flattenedTable->getSize()); if (err != NO_ERROR) { fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n", split->getPrintableName().string()); return err; } bool hasError = false; const std::set<ConfigDescription>& splitConfigs = split->getConfigs(); for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin(); iter != splitConfigs.end(); ++iter) { const ConfigDescription& config = *iter; if (AaptConfig::isDensityOnly(config)) { // Each density only split must contain all // density only resources. Res_value val; resTable.setParameters(&config); const size_t densityVaryingResourceCount = densityVaryingResources.size(); for (size_t k = 0; k < densityVaryingResourceCount; k++) { const Symbol& symbol = densityVaryingResources.keyAt(k); ssize_t block = resTable.getResource(symbol.id, &val, true); if (block < 0) { // Maybe it's in the base? finalResTable.setParameters(&config); block = finalResTable.getResource(symbol.id, &val, true); } if (block < 0) { hasError = true; SourcePos().error("%s has no definition for density split '%s'", symbol.toString().string(), config.toString().string()); if (bundle->getVerbose()) { const Vector<SymbolDefinition>& defs = densityVaryingResources[k]; const size_t defCount = std::min(size_t(5), defs.size()); for (size_t d = 0; d < defCount; d++) { const SymbolDefinition& def = defs[d]; def.source.error("%s has definition for %s", symbol.toString().string(), def.config.toString().string()); } if (defCount < defs.size()) { SourcePos().error("and %d more ...", (int) (defs.size() - defCount)); } } } } } } if (hasError) { return UNKNOWN_ERROR; } // Generate the AndroidManifest for this split. sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"), AaptGroupEntry(), String8()); err = generateAndroidManifestForSplit(bundle, assets, split, Loading
tools/aapt/ResourceTable.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ #include "ResourceTable.h" #include "AaptUtil.h" #include "XMLNode.h" #include "ResourceFilter.h" #include "ResourceIdCache.h" Loading Loading @@ -4517,3 +4518,34 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, return NO_ERROR; } void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { const ConfigDescription nullConfig; const size_t packageCount = mOrderedPackages.size(); for (size_t p = 0; p < packageCount; p++) { const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes(); const size_t typeCount = types.size(); for (size_t t = 0; t < typeCount; t++) { const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const size_t configCount = configs.size(); for (size_t c = 0; c < configCount; c++) { const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); const size_t configEntryCount = configEntries.size(); for (size_t ce = 0; ce < configEntryCount; ce++) { const ConfigDescription& config = configEntries.keyAt(ce); if (AaptConfig::isDensityOnly(config)) { // This configuration only varies with regards to density. const Symbol symbol(mOrderedPackages[p]->getName(), types[t]->getName(), configs[c]->getName(), getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); const sp<Entry>& entry = configEntries.valueAt(ce); AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); } } } } } }