summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2015-05-14 17:58:14 -0700
committerAdam Lesinski <adamlesinski@google.com>2015-05-14 20:56:10 -0700
commit39c353a6caada777348c14f6dc9abee2d4d9a3be (patch)
tree697823578d99994617ab8cea0fa002d8b5e5bcbf /tools
parentb731c3d944ccf46b7d0115f63b63eee5ab8abf1a (diff)
downloadframeworks_base-39c353a6caada777348c14f6dc9abee2d4d9a3be.zip
frameworks_base-39c353a6caada777348c14f6dc9abee2d4d9a3be.tar.gz
frameworks_base-39c353a6caada777348c14f6dc9abee2d4d9a3be.tar.bz2
AAPT2: Fix layout versioning
Change-Id: I37190cf8a1f0a81c068aeb2b5326b3b3080f75a5
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt2/Main.cpp70
-rw-r--r--tools/aapt2/data/Makefile2
2 files changed, 58 insertions, 14 deletions
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 025ede5..91639c5 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -189,16 +189,16 @@ void versionStylesForCompat(const std::shared_ptr<ResourceTable>& table) {
}
struct CompileItem {
- Source source;
ResourceName name;
ConfigDescription config;
+ Source source;
std::string extension;
};
struct LinkItem {
- Source source;
ResourceName name;
ConfigDescription config;
+ Source source;
std::string originalPath;
ZipFile* apk;
std::u16string originalPackage;
@@ -236,7 +236,8 @@ std::string buildFileReference(const LinkItem& item) {
return buildFileReference(item.name, item.config, getExtension<char>(item.originalPath));
}
-bool addFileReference(const std::shared_ptr<ResourceTable>& table, const CompileItem& item) {
+template <typename T>
+bool addFileReference(const std::shared_ptr<ResourceTable>& table, const T& item) {
StringPool& pool = table->getValueStringPool();
StringPool::Ref ref = pool.makeRef(util::utf8ToUtf16(buildFileReference(item)),
StringPool::Context{ 0, item.config });
@@ -334,9 +335,40 @@ bool compileXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>
return true;
}
-bool linkXml(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver,
- const LinkItem& item, const void* data, size_t dataLen, ZipFile* outApk,
- std::queue<LinkItem>* outQueue) {
+/**
+ * Determines if a layout should be auto generated based on SDK level. We do not
+ * generate a layout if there is already a layout defined whose SDK version is greater than
+ * the one we want to generate.
+ */
+bool shouldGenerateVersionedResource(const std::shared_ptr<const ResourceTable>& table,
+ const ResourceName& name, const ConfigDescription& config,
+ int sdkVersionToGenerate) {
+ assert(sdkVersionToGenerate > config.sdkVersion);
+ const ResourceTableType* type;
+ const ResourceEntry* entry;
+ std::tie(type, entry) = table->findResource(name);
+ assert(type && entry);
+
+ auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), config,
+ [](const ResourceConfigValue& lhs, const ConfigDescription& config) -> bool {
+ return lhs.config < config;
+ });
+
+ assert(iter != entry->values.end());
+ ++iter;
+
+ if (iter == entry->values.end()) {
+ return true;
+ }
+
+ ConfigDescription newConfig = config;
+ newConfig.sdkVersion = sdkVersionToGenerate;
+ return newConfig < iter->config;
+}
+
+bool linkXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
+ const std::shared_ptr<IResolver>& resolver, const LinkItem& item,
+ const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue) {
std::shared_ptr<android::ResXMLTree> tree = std::make_shared<android::ResXMLTree>();
if (tree->setTo(data, dataLen, false) != android::NO_ERROR) {
return false;
@@ -376,9 +408,21 @@ bool linkXml(const AaptOptions& options, const std::shared_ptr<IResolver>& resol
if (minStrippedSdk.value() > 0) {
// Something was stripped, so let's generate a new file
// with the version of the smallest SDK version stripped.
- LinkItem newWork = item;
- newWork.config.sdkVersion = minStrippedSdk.value();
- outQueue->push(newWork);
+ // We can only generate a versioned layout if there doesn't exist a layout
+ // with sdk version greater than the current one but less than the one we
+ // want to generate.
+ if (shouldGenerateVersionedResource(table, item.name, item.config,
+ minStrippedSdk.value())) {
+ LinkItem newWork = item;
+ newWork.config.sdkVersion = minStrippedSdk.value();
+ outQueue->push(newWork);
+
+ if (!addFileReference(table, newWork)) {
+ Logger::error(options.output) << "failed to add auto-versioned resource '"
+ << newWork.name << "'." << std::endl;
+ return false;
+ }
+ }
}
if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressDeflated,
@@ -604,7 +648,7 @@ static void addApkFilesToLinkQueue(const std::u16string& package, const Source&
newSource.path += "/";
newSource.path += pathUtf8;
outLinkQueue->push(LinkItem{
- newSource, name, value.config, pathUtf8, apk.get(),
+ name, value.config, newSource, pathUtf8, apk.get(),
table->getPackage() });
// Now rewrite the file path.
if (mangle) {
@@ -743,8 +787,8 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT
void* uncompressedData = item.apk->uncompress(entry);
assert(uncompressedData);
- if (!linkXml(options, resolver, item, uncompressedData, entry->getUncompressedLen(),
- &outApk, &linkQueue)) {
+ if (!linkXml(options, outTable, resolver, item, uncompressedData,
+ entry->getUncompressedLen(), &outApk, &linkQueue)) {
Logger::error(options.output) << "failed to link '" << item.originalPath << "'."
<< std::endl;
return false;
@@ -862,9 +906,9 @@ bool compile(const AaptOptions& options, const std::shared_ptr<ResourceTable>& t
}
compileQueue.push(CompileItem{
- source,
ResourceName{ table->getPackage(), *type, pathData.name },
pathData.config,
+ source,
pathData.extension
});
}
diff --git a/tools/aapt2/data/Makefile b/tools/aapt2/data/Makefile
index 6b5fafa..ce5201b 100644
--- a/tools/aapt2/data/Makefile
+++ b/tools/aapt2/data/Makefile
@@ -49,7 +49,7 @@ $(info PRIVATE_INTERMEDIATE_TABLES = $(PRIVATE_INTERMEDIATE_TABLES))
# returns: out/values-v4.apk: res/values-v4/styles.xml res/values-v4/colors.xml
define make-collect-rule
$(LOCAL_OUT)/$1.apk: $(filter $(LOCAL_RESOURCE_DIR)/$1/%,$(PRIVATE_RESOURCES))
- $(AAPT) compile --package $(LOCAL_PACKAGE) --binding $(LOCAL_GEN) -o $$@ $$^
+ $(AAPT) compile --package $(LOCAL_PACKAGE) -o $$@ $$^
endef
# Collect: out/values-v4.apk <- res/values-v4/styles.xml res/values-v4/colors.xml