diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-11-05 12:30:25 -0800 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2014-11-05 12:30:25 -0800 |
commit | 685d363d7a3e8833edc9368a3c59b69755e0ba29 (patch) | |
tree | e04662b84ae8cc05665206336a148928c23b7cab /tools/aapt | |
parent | b3d260222fd003c8b537bb9f86625a200bd0f999 (diff) | |
parent | fb96e54ba8d43a9f3162c92760e53ab61c7486ff (diff) | |
download | frameworks_base-685d363d7a3e8833edc9368a3c59b69755e0ba29.zip frameworks_base-685d363d7a3e8833edc9368a3c59b69755e0ba29.tar.gz frameworks_base-685d363d7a3e8833edc9368a3c59b69755e0ba29.tar.bz2 |
Merge commit 'fb96e54' into manualmerge
Conflicts:
tools/aapt/Resource.cpp
Change-Id: I4147c3550e9426f3429146eaeb16f10ba76b5b15
Diffstat (limited to 'tools/aapt')
-rw-r--r-- | tools/aapt/AaptConfig.cpp | 19 | ||||
-rw-r--r-- | tools/aapt/AaptConfig.h | 6 | ||||
-rw-r--r-- | tools/aapt/Resource.cpp | 70 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.cpp | 32 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.h | 13 | ||||
-rw-r--r-- | tools/aapt/SourcePos.cpp | 6 | ||||
-rw-r--r-- | tools/aapt/SourcePos.h | 2 | ||||
-rw-r--r-- | tools/aapt/Symbol.h | 95 |
8 files changed, 238 insertions, 5 deletions
diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp index f447462..848d9a1 100644 --- a/tools/aapt/AaptConfig.cpp +++ b/tools/aapt/AaptConfig.cpp @@ -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 diff --git a/tools/aapt/AaptConfig.h b/tools/aapt/AaptConfig.h index 2963539..f73a508 100644 --- a/tools/aapt/AaptConfig.h +++ b/tools/aapt/AaptConfig.h @@ -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 diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index a4f4dd1..5bb2ce1 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -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" @@ -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 @@ -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; @@ -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++) { @@ -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, diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 4cca57f..2339840 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -6,6 +6,7 @@ #include "ResourceTable.h" +#include "AaptUtil.h" #include "XMLNode.h" #include "ResourceFilter.h" #include "ResourceIdCache.h" @@ -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())); + } + } + } + } + } +} diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index eac5dd3..db392c8 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -7,15 +7,16 @@ #ifndef RESOURCE_TABLE_H #define RESOURCE_TABLE_H -#include "ConfigDescription.h" -#include "StringPool.h" -#include "SourcePos.h" -#include "ResourceFilter.h" - #include <map> #include <queue> #include <set> +#include "ConfigDescription.h" +#include "ResourceFilter.h" +#include "SourcePos.h" +#include "StringPool.h" +#include "Symbol.h" + using namespace std; class XMLNode; @@ -543,6 +544,8 @@ public: DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping; }; + void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources); + private: void writePublicDefinitions(const String16& package, FILE* fp, bool pub); sp<Package> getPackage(const String16& package); diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp index ae25047..3864320 100644 --- a/tools/aapt/SourcePos.cpp +++ b/tools/aapt/SourcePos.cpp @@ -141,6 +141,12 @@ SourcePos::printf(const char* fmt, ...) const } bool +SourcePos::operator<(const SourcePos& rhs) const +{ + return (file < rhs.file) || (line < rhs.line); +} + +bool SourcePos::hasErrors() { return g_errors.size() > 0; diff --git a/tools/aapt/SourcePos.h b/tools/aapt/SourcePos.h index 4ce817f..13cfb9d 100644 --- a/tools/aapt/SourcePos.h +++ b/tools/aapt/SourcePos.h @@ -21,6 +21,8 @@ public: void warning(const char* fmt, ...) const; void printf(const char* fmt, ...) const; + bool operator<(const SourcePos& rhs) const; + static bool hasErrors(); static void printErrors(FILE* to); }; diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h new file mode 100644 index 0000000..e157541 --- /dev/null +++ b/tools/aapt/Symbol.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 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 AAPT_SYMBOL_H +#define AAPT_SYMBOL_H + +#include <utils/String8.h> +#include <utils/String16.h> + +#include "ConfigDescription.h" +#include "SourcePos.h" + +/** + * A resource symbol, not attached to any configuration or context. + */ +struct Symbol { + inline Symbol(); + inline Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i); + inline android::String8 toString() const; + inline bool operator<(const Symbol& rhs) const; + + android::String16 package; + android::String16 type; + android::String16 name; + uint32_t id; + +}; + +/** + * A specific defintion of a symbol, defined with a configuration and a definition site. + */ +struct SymbolDefinition { + inline SymbolDefinition(); + inline SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src); + inline bool operator<(const SymbolDefinition& rhs) const; + + Symbol symbol; + ConfigDescription config; + SourcePos source; +}; + +// +// Implementations +// + +Symbol::Symbol() { +} + +Symbol::Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i) + : package(p) + , type(t) + , name(n) + , id(i) { +} + +android::String8 Symbol::toString() const { + return android::String8::format("%s:%s/%s (0x%08x)", + android::String8(package).string(), + android::String8(type).string(), + android::String8(name).string(), + (int) id); +} + +bool Symbol::operator<(const Symbol& rhs) const { + return (package < rhs.package) || (type < rhs.type) || (name < rhs.name) || (id < rhs.id); +} + +SymbolDefinition::SymbolDefinition() { +} + +SymbolDefinition::SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src) + : symbol(s) + , config(c) + , source(src) { +} + +bool SymbolDefinition::operator<(const SymbolDefinition& rhs) const { + return (symbol < rhs.symbol) || (config < rhs.config) || (source < rhs.source); +} + +#endif // AAPT_SYMBOL_H + |