diff options
author | Adam Lesinski <adamlesinski@google.com> | 2015-04-21 13:56:10 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2015-04-22 17:34:55 -0700 |
commit | d5c4f8723c2b2c85b588fa07a5d4e7afb671d257 (patch) | |
tree | 33d2fcaa40a7abf16041ceb522b799ef5534a97f /tools/aapt2 | |
parent | d981c0d4f01bb25ba378e865952cf9d48109b9fe (diff) | |
download | frameworks_base-d5c4f8723c2b2c85b588fa07a5d4e7afb671d257.zip frameworks_base-d5c4f8723c2b2c85b588fa07a5d4e7afb671d257.tar.gz frameworks_base-d5c4f8723c2b2c85b588fa07a5d4e7afb671d257.tar.bz2 |
Properly mangle file names
Change-Id: I49c0f82e8c06f056198eb64b8369d83403b74321
Diffstat (limited to 'tools/aapt2')
-rw-r--r-- | tools/aapt2/BinaryResourceParser.cpp | 7 | ||||
-rw-r--r-- | tools/aapt2/Main.cpp | 342 | ||||
-rw-r--r-- | tools/aapt2/TableFlattener.cpp | 72 | ||||
-rw-r--r-- | tools/aapt2/TableFlattener.h | 5 | ||||
-rw-r--r-- | tools/aapt2/ZipEntry.cpp | 8 | ||||
-rw-r--r-- | tools/aapt2/ZipEntry.h | 5 | ||||
-rw-r--r-- | tools/aapt2/ZipFile.cpp | 7 | ||||
-rw-r--r-- | tools/aapt2/ZipFile.h | 6 | ||||
-rw-r--r-- | tools/aapt2/data/Makefile | 4 | ||||
-rw-r--r-- | tools/aapt2/data/lib/Makefile | 2 | ||||
-rw-r--r-- | tools/aapt2/data/lib/res/layout/main.xml | 4 | ||||
-rw-r--r-- | tools/aapt2/data/lib/res/raw/hello.txt | 1 |
12 files changed, 280 insertions, 183 deletions
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp index 71016c1..326a2ac 100644 --- a/tools/aapt2/BinaryResourceParser.cpp +++ b/tools/aapt2/BinaryResourceParser.cpp @@ -603,6 +603,13 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na mTable->getValueStringPool().makeRef( styleStr, StringPool::Context{1, config})); } else { + if (name.type != ResourceType::kString && + util::stringStartsWith<char16_t>(str, u"res/")) { + // This must be a FileReference. + return util::make_unique<FileReference>(mTable->getValueStringPool().makeRef( + str, StringPool::Context{ 0, config })); + } + // There are no styles associated with this string, so treat it as // a simple string. return util::make_unique<String>( diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 03b9ba4..be806c9 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -25,6 +25,7 @@ #include "Linker.h" #include "ManifestParser.h" #include "ManifestValidator.h" +#include "NameMangler.h" #include "Png.h" #include "ResourceParser.h" #include "ResourceTable.h" @@ -266,22 +267,50 @@ struct CompileItem { struct LinkItem { Source source; - std::string apkPath; + ResourceName name; + ConfigDescription config; + std::string originalPath; + ZipFile* apk; }; -std::string buildFileReference(const CompileItem& item) { +template <typename TChar> +static BasicStringPiece<TChar> getExtension(const BasicStringPiece<TChar>& str) { + auto iter = std::find(str.begin(), str.end(), static_cast<TChar>('.')); + if (iter == str.end()) { + return BasicStringPiece<TChar>(); + } + size_t offset = (iter - str.begin()) + 1; + return str.substr(offset, str.size() - offset); +} + + + +std::string buildFileReference(const ResourceNameRef& name, const ConfigDescription& config, + const StringPiece& extension) { std::stringstream path; - path << "res/" << item.name.type; - if (item.config != ConfigDescription{}) { - path << "-" << item.config; + path << "res/" << name.type; + if (config != ConfigDescription{}) { + path << "-" << config; + } + path << "/" << util::utf16ToUtf8(name.entry); + if (!extension.empty()) { + path << "." << extension; } - path << "/" << util::utf16ToUtf8(item.name.entry) + "." + item.extension; return path.str(); } +std::string buildFileReference(const CompileItem& item) { + return buildFileReference(item.name, item.config, item.extension); +} + +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) { StringPool& pool = table->getValueStringPool(); - StringPool::Ref ref = pool.makeRef(util::utf8ToUtf16(buildFileReference(item))); + StringPool::Ref ref = pool.makeRef(util::utf8ToUtf16(buildFileReference(item)), + StringPool::Context{ 0, item.config }); return table->addResource(item.name, item.config, item.source.line(0), util::make_unique<FileReference>(ref)); } @@ -418,8 +447,8 @@ bool linkXml(const AaptOptions& options, const std::shared_ptr<Resolver>& resolv return false; } - if (outApk->add(outBuffer, item.apkPath.data(), ZipEntry::kCompressDeflated, nullptr) != - android::NO_ERROR) { + if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressDeflated, + nullptr) != android::NO_ERROR) { Logger::error(options.output) << "failed to write linked file '" << item.source << "' to apk." << std::endl; return false; @@ -502,109 +531,6 @@ bool compileManifest(const AaptOptions& options, const std::shared_ptr<Resolver> return true; } -bool loadAppInfo(const Source& source, AppInfo* outInfo) { - std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary); - if (!ifs) { - Logger::error(source) << strerror(errno) << std::endl; - return false; - } - - ManifestParser parser; - std::shared_ptr<XmlPullParser> pullParser = std::make_shared<SourceXmlPullParser>(ifs); - return parser.parse(source, pullParser, outInfo); -} - -static void printCommandsAndDie() { - std::cerr << "The following commands are supported:" << std::endl << std::endl; - std::cerr << "compile compiles a subset of resources" << std::endl; - std::cerr << "link links together compiled resources and libraries" << std::endl; - std::cerr << std::endl; - std::cerr << "run aapt2 with one of the commands and the -h flag for extra details." - << std::endl; - exit(1); -} - -static AaptOptions prepareArgs(int argc, char** argv) { - if (argc < 2) { - std::cerr << "no command specified." << std::endl << std::endl; - printCommandsAndDie(); - } - - const StringPiece command(argv[1]); - argc -= 2; - argv += 2; - - AaptOptions options; - - if (command == "--version" || command == "version") { - std::cout << kAaptVersionStr << std::endl; - exit(0); - } else if (command == "link") { - options.phase = AaptOptions::Phase::Link; - } else if (command == "compile") { - options.phase = AaptOptions::Phase::Compile; - } else { - std::cerr << "invalid command '" << command << "'." << std::endl << std::endl; - printCommandsAndDie(); - } - - if (options.phase == AaptOptions::Phase::Compile) { - flag::requiredFlag("--package", "Android package name", - [&options](const StringPiece& arg) { - options.appInfo.package = util::utf8ToUtf16(arg); - }); - flag::optionalFlag("--binding", "Output directory for binding XML files", - [&options](const StringPiece& arg) { - options.bindingOutput = Source{ arg.toString() }; - }); - flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning", - false, &options.versionStylesAndLayouts); - - } else if (options.phase == AaptOptions::Phase::Link) { - flag::requiredFlag("--manifest", "AndroidManifest.xml of your app", - [&options](const StringPiece& arg) { - options.manifest = Source{ arg.toString() }; - }); - - flag::optionalFlag("-I", "add an Android APK to link against", - [&options](const StringPiece& arg) { - options.libraries.push_back(Source{ arg.toString() }); - }); - - flag::optionalFlag("--java", "directory in which to generate R.java", - [&options](const StringPiece& arg) { - options.generateJavaClass = Source{ arg.toString() }; - }); - } - - // Common flags for all steps. - flag::requiredFlag("-o", "Output path", [&options](const StringPiece& arg) { - options.output = Source{ arg.toString() }; - }); - - bool help = false; - flag::optionalSwitch("-v", "enables verbose logging", true, &options.verbose); - flag::optionalSwitch("-h", "displays this help menu", true, &help); - - // Build the command string for output (eg. "aapt2 compile"). - std::string fullCommand = "aapt2"; - fullCommand += " "; - fullCommand += command.toString(); - - // Actually read the command line flags. - flag::parse(argc, argv, fullCommand); - - if (help) { - flag::usageAndDie(fullCommand); - } - - // Copy all the remaining arguments. - for (const std::string& arg : flag::getArgs()) { - options.input.push_back(Source{ arg }); - } - return options; -} - static bool compileValues(const std::shared_ptr<ResourceTable>& table, const Source& source, const ConfigDescription& config) { std::ifstream in(source.path, std::ifstream::binary); @@ -630,6 +556,7 @@ struct ResourcePathData { * [--/res/]type[-config]/name */ static Maybe<ResourcePathData> extractResourcePathData(const Source& source) { + // TODO(adamlesinski): Use Windows path separator on windows. std::vector<std::string> parts = util::splitAndLowercase(source.path, '/'); if (parts.size() < 2) { Logger::error(source) << "bad resource path." << std::endl; @@ -695,6 +622,38 @@ bool writeResourceTable(const AaptOptions& options, const std::shared_ptr<Resour return true; } +/** + * For each FileReference in the table, adds a LinkItem to the link queue for processing. + */ +static void addApkFilesToLinkQueue(const std::u16string& package, const Source& source, + const std::shared_ptr<ResourceTable>& table, + const std::unique_ptr<ZipFile>& apk, + std::queue<LinkItem>* outLinkQueue) { + bool mangle = package != table->getPackage(); + for (auto& type : *table) { + for (auto& entry : type->entries) { + ResourceName name = { package, type->type, entry->name }; + if (mangle) { + NameMangler::mangle(table->getPackage(), &name.entry); + } + + for (auto& value : entry->values) { + visitFunc<FileReference>(*value.value, [&](FileReference& ref) { + std::string pathUtf8 = util::utf16ToUtf8(*ref.path); + outLinkQueue->push(LinkItem{ + source, name, value.config, pathUtf8, apk.get() }); + // Now rewrite the file path. + if (mangle) { + ref.path = table->getValueStringPool().makeRef(util::utf8ToUtf16( + buildFileReference(name, value.config, + getExtension<char>(pathUtf8)))); + } + }); + } + } + } +} + static constexpr int kOpenFlags = ZipFile::kOpenCreate | ZipFile::kOpenTruncate | ZipFile::kOpenReadWrite; @@ -740,9 +699,14 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT linkedPackages.insert(table->getPackage()); } + std::queue<LinkItem> linkQueue; for (auto& p : apkFiles) { const std::shared_ptr<ResourceTable>& inTable = p.first; + // Collect all FileReferences and add them to the queue for processing. + addApkFilesToLinkQueue(options.appInfo.package, Source{}, inTable, p.second, &linkQueue); + + // Merge the tables. if (!outTable->merge(std::move(*inTable))) { return false; } @@ -779,39 +743,32 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT return false; } - for (auto& p : apkFiles) { - std::unique_ptr<ZipFile>& zipFile = p.second; + for (; !linkQueue.empty(); linkQueue.pop()) { + const LinkItem& item = linkQueue.front(); - // TODO(adamlesinski): Get list of files to read when processing config filter. + ZipEntry* entry = item.apk->getEntryByName(item.originalPath.data()); + if (!entry) { + Logger::error(item.source) << "failed to find '" << item.originalPath << "'." + << std::endl; + return false; + } - const int numEntries = zipFile->getNumEntries(); - for (int i = 0; i < numEntries; i++) { - ZipEntry* entry = zipFile->getEntryByIndex(i); - assert(entry); + if (util::stringEndsWith<char>(item.originalPath, ".xml")) { + void* uncompressedData = item.apk->uncompress(entry); + assert(uncompressedData); - StringPiece filename = entry->getFileName(); - if (!util::stringStartsWith<char>(filename, "res/")) { - continue; + if (!linkXml(options, resolver, item, uncompressedData, entry->getUncompressedLen(), + &outApk)) { + Logger::error(options.output) << "failed to link '" << item.originalPath << "'." + << std::endl; + return false; } - - if (util::stringEndsWith<char>(filename, ".xml")) { - void* uncompressedData = zipFile->uncompress(entry); - assert(uncompressedData); - - LinkItem item = { Source{ filename.toString() }, filename.toString() }; - - if (!linkXml(options, resolver, item, uncompressedData, - entry->getUncompressedLen(), &outApk)) { - Logger::error(options.output) << "failed to link '" << filename << "'." - << std::endl; - return false; - } - } else { - if (outApk.add(zipFile.get(), entry, 0, nullptr) != android::NO_ERROR) { - Logger::error(options.output) << "failed to copy '" << filename << "'." - << std::endl; - return false; - } + } else { + if (outApk.add(item.apk, entry, buildFileReference(item).data(), 0, nullptr) != + android::NO_ERROR) { + Logger::error(options.output) << "failed to copy '" << item.originalPath << "'." + << std::endl; + return false; } } } @@ -957,6 +914,109 @@ bool compile(const AaptOptions& options, const std::shared_ptr<ResourceTable>& t return true; } +bool loadAppInfo(const Source& source, AppInfo* outInfo) { + std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary); + if (!ifs) { + Logger::error(source) << strerror(errno) << std::endl; + return false; + } + + ManifestParser parser; + std::shared_ptr<XmlPullParser> pullParser = std::make_shared<SourceXmlPullParser>(ifs); + return parser.parse(source, pullParser, outInfo); +} + +static void printCommandsAndDie() { + std::cerr << "The following commands are supported:" << std::endl << std::endl; + std::cerr << "compile compiles a subset of resources" << std::endl; + std::cerr << "link links together compiled resources and libraries" << std::endl; + std::cerr << std::endl; + std::cerr << "run aapt2 with one of the commands and the -h flag for extra details." + << std::endl; + exit(1); +} + +static AaptOptions prepareArgs(int argc, char** argv) { + if (argc < 2) { + std::cerr << "no command specified." << std::endl << std::endl; + printCommandsAndDie(); + } + + const StringPiece command(argv[1]); + argc -= 2; + argv += 2; + + AaptOptions options; + + if (command == "--version" || command == "version") { + std::cout << kAaptVersionStr << std::endl; + exit(0); + } else if (command == "link") { + options.phase = AaptOptions::Phase::Link; + } else if (command == "compile") { + options.phase = AaptOptions::Phase::Compile; + } else { + std::cerr << "invalid command '" << command << "'." << std::endl << std::endl; + printCommandsAndDie(); + } + + if (options.phase == AaptOptions::Phase::Compile) { + flag::requiredFlag("--package", "Android package name", + [&options](const StringPiece& arg) { + options.appInfo.package = util::utf8ToUtf16(arg); + }); + flag::optionalFlag("--binding", "Output directory for binding XML files", + [&options](const StringPiece& arg) { + options.bindingOutput = Source{ arg.toString() }; + }); + flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning", + false, &options.versionStylesAndLayouts); + + } else if (options.phase == AaptOptions::Phase::Link) { + flag::requiredFlag("--manifest", "AndroidManifest.xml of your app", + [&options](const StringPiece& arg) { + options.manifest = Source{ arg.toString() }; + }); + + flag::optionalFlag("-I", "add an Android APK to link against", + [&options](const StringPiece& arg) { + options.libraries.push_back(Source{ arg.toString() }); + }); + + flag::optionalFlag("--java", "directory in which to generate R.java", + [&options](const StringPiece& arg) { + options.generateJavaClass = Source{ arg.toString() }; + }); + } + + // Common flags for all steps. + flag::requiredFlag("-o", "Output path", [&options](const StringPiece& arg) { + options.output = Source{ arg.toString() }; + }); + + bool help = false; + flag::optionalSwitch("-v", "enables verbose logging", true, &options.verbose); + flag::optionalSwitch("-h", "displays this help menu", true, &help); + + // Build the command string for output (eg. "aapt2 compile"). + std::string fullCommand = "aapt2"; + fullCommand += " "; + fullCommand += command.toString(); + + // Actually read the command line flags. + flag::parse(argc, argv, fullCommand); + + if (help) { + flag::usageAndDie(fullCommand); + } + + // Copy all the remaining arguments. + for (const std::string& arg : flag::getArgs()) { + options.input.push_back(Source{ arg }); + } + return options; +} + int main(int argc, char** argv) { Logger::setLog(std::make_shared<Log>(std::cerr, std::cerr)); AaptOptions options = prepareArgs(argc, argv); diff --git a/tools/aapt2/TableFlattener.cpp b/tools/aapt2/TableFlattener.cpp index 67c56e7..4aadadc 100644 --- a/tools/aapt2/TableFlattener.cpp +++ b/tools/aapt2/TableFlattener.cpp @@ -43,8 +43,7 @@ struct FlatEntry { */ class MapFlattener : public ConstValueVisitor { public: - MapFlattener(BigBuffer* out, const FlatEntry& flatEntry, - std::vector<std::pair<ResourceNameRef, uint32_t>>& symbols) : + MapFlattener(BigBuffer* out, const FlatEntry& flatEntry, SymbolEntryVector* symbols) : mOut(out), mSymbols(symbols) { mMap = mOut->nextBlock<android::ResTable_map_entry>(); mMap->key.index = flatEntry.entryKey; @@ -65,7 +64,7 @@ public: void flattenParent(const Reference& ref) { if (!ref.id.isValid()) { - mSymbols.push_back({ + mSymbols->push_back({ ResourceNameRef(ref.name), (mOut->size() - mMap->size) + sizeof(*mMap) - sizeof(android::ResTable_entry) }); @@ -80,7 +79,7 @@ public: // Write the key. if (!Res_INTERNALID(key.id.id) && !key.id.isValid()) { - mSymbols.push_back(std::make_pair(ResourceNameRef(key.name), + mSymbols->push_back(std::make_pair(ResourceNameRef(key.name), mOut->size() - sizeof(*outMapEntry))); } outMapEntry->name.ident = key.id.id; @@ -90,7 +89,7 @@ public: if (outMapEntry->value.data == 0x0) { visitFunc<Reference>(value, [&](const Reference& reference) { - mSymbols.push_back(std::make_pair(ResourceNameRef(reference.name), + mSymbols->push_back(std::make_pair(ResourceNameRef(reference.name), mOut->size() - sizeof(outMapEntry->value.data))); }); } @@ -188,16 +187,47 @@ public: private: BigBuffer* mOut; - std::vector<std::pair<ResourceNameRef, uint32_t>>& mSymbols; + SymbolEntryVector* mSymbols; android::ResTable_map_entry* mMap; }; +/** + * Flattens a value, with special handling for References. + */ +struct ValueFlattener : ConstValueVisitor { + ValueFlattener(BigBuffer* out, SymbolEntryVector* symbols) : + result(false), mOut(out), mOutValue(nullptr), mSymbols(symbols) { + mOutValue = mOut->nextBlock<android::Res_value>(); + } + + virtual void visit(const Reference& ref, ValueVisitorArgs& a) override { + visitItem(ref, a); + if (mOutValue->data == 0x0) { + mSymbols->push_back({ + ResourceNameRef(ref.name), + mOut->size() - sizeof(mOutValue->data)}); + } + } + + virtual void visitItem(const Item& item, ValueVisitorArgs&) override { + result = item.flatten(*mOutValue); + mOutValue->size = sizeof(*mOutValue); + } + + bool result; + +private: + BigBuffer* mOut; + android::Res_value* mOutValue; + SymbolEntryVector* mSymbols; +}; + TableFlattener::TableFlattener(Options options) : mOptions(options) { } bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry, - std::vector<std::pair<ResourceNameRef, uint32_t>>& symbolEntries) { + SymbolEntryVector* symbols) { if (flatEntry.value.isItem()) { android::ResTable_entry* entry = out->nextBlock<android::ResTable_entry>(); @@ -218,30 +248,16 @@ bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry, ResTable_entry_source* sourceBlock = out->nextBlock<ResTable_entry_source>(); sourceBlock->pathIndex = flatEntry.sourcePathKey; sourceBlock->line = flatEntry.sourceLine; - entry->size += sizeof(*sourceBlock); } - android::Res_value* outValue = out->nextBlock<android::Res_value>(); - - const Item& item = static_cast<const Item&>(flatEntry.value); - if (!item.flatten(*outValue)) { - return false; - } - - if (outValue->data == 0x0) { - visitFunc<Reference>(item, [&](const Reference& reference) { - symbolEntries.push_back({ - ResourceNameRef(reference.name), - out->size() - sizeof(outValue->data) - }); - }); - } - outValue->size = sizeof(*outValue); - return true; + const Item* item = static_cast<const Item*>(&flatEntry.value); + ValueFlattener flattener(out, symbols); + item->accept(flattener, {}); + return flattener.result; } - MapFlattener flattener(out, flatEntry, symbolEntries); + MapFlattener flattener(out, flatEntry, symbols); flatEntry.value.accept(flattener, {}); return true; } @@ -263,7 +279,7 @@ bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) { return false; } - std::vector<std::pair<ResourceNameRef, uint32_t>> symbolEntries; + SymbolEntryVector symbolEntries; StringPool typePool; StringPool keyPool; @@ -401,7 +417,7 @@ bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) { for (const FlatEntry& flatEntry : entry.second) { assert(flatEntry.entry.entryId < type->entries.size()); indices[flatEntry.entry.entryId] = typeBlock.size() - entryStart; - if (!flattenValue(&typeBlock, flatEntry, symbolEntries)) { + if (!flattenValue(&typeBlock, flatEntry, &symbolEntries)) { Logger::error() << "failed to flatten resource '" << ResourceNameRef { diff --git a/tools/aapt2/TableFlattener.h b/tools/aapt2/TableFlattener.h index 0ae798c..ccbb737 100644 --- a/tools/aapt2/TableFlattener.h +++ b/tools/aapt2/TableFlattener.h @@ -22,6 +22,8 @@ namespace aapt { +using SymbolEntryVector = std::vector<std::pair<ResourceNameRef, uint32_t>>; + struct FlatEntry; /** @@ -49,8 +51,7 @@ struct TableFlattener { bool flatten(BigBuffer* out, const ResourceTable& table); private: - bool flattenValue(BigBuffer* out, const FlatEntry& flatEntry, - std::vector<std::pair<ResourceNameRef, uint32_t>>& symbolEntries); + bool flattenValue(BigBuffer* out, const FlatEntry& flatEntry, SymbolEntryVector* symbols); Options mOptions; }; diff --git a/tools/aapt2/ZipEntry.cpp b/tools/aapt2/ZipEntry.cpp index ad5d84a..891b4e1 100644 --- a/tools/aapt2/ZipEntry.cpp +++ b/tools/aapt2/ZipEntry.cpp @@ -144,9 +144,15 @@ void ZipEntry::initNew(const char* fileName, const char* comment) * Initializes the CDE and the LFH. */ status_t ZipEntry::initFromExternal(const ZipFile* /* pZipFile */, - const ZipEntry* pEntry) + const ZipEntry* pEntry, const char* storageName) { mCDE = pEntry->mCDE; + if (storageName && *storageName != 0) { + mCDE.mFileNameLength = strlen(storageName); + mCDE.mFileName = new unsigned char[mCDE.mFileNameLength + 1]; + strcpy((char*) mCDE.mFileName, storageName); + } + // Check whether we got all the memory needed. if ((mCDE.mFileNameLength > 0 && mCDE.mFileName == NULL) || (mCDE.mFileCommentLength > 0 && mCDE.mFileComment == NULL) || diff --git a/tools/aapt2/ZipEntry.h b/tools/aapt2/ZipEntry.h index d048a3e..2745a43 100644 --- a/tools/aapt2/ZipEntry.h +++ b/tools/aapt2/ZipEntry.h @@ -171,9 +171,10 @@ protected: /* * Initialize the structure with the contents of a ZipEntry from - * another file. + * another file. If fileName is non-NULL, override the name with fileName. */ - status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry); + status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry, + const char* fileName); /* * Add some pad bytes to the LFH. We do this by adding or resizing diff --git a/tools/aapt2/ZipFile.cpp b/tools/aapt2/ZipFile.cpp index 41e59cf..268c15e 100644 --- a/tools/aapt2/ZipFile.cpp +++ b/tools/aapt2/ZipFile.cpp @@ -546,7 +546,7 @@ bail: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - int padding, ZipEntry** ppEntry) + const char* storageName, int padding, ZipEntry** ppEntry) { ZipEntry* pEntry = NULL; status_t result; @@ -570,9 +570,10 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, goto bail; } - result = pEntry->initFromExternal(pSourceZip, pSourceEntry); - if (result != NO_ERROR) + result = pEntry->initFromExternal(pSourceZip, pSourceEntry, storageName); + if (result != NO_ERROR) { goto bail; + } if (padding != 0) { result = pEntry->addPadding(padding); if (result != NO_ERROR) diff --git a/tools/aapt2/ZipFile.h b/tools/aapt2/ZipFile.h index 9cbd1fa..9de92dd 100644 --- a/tools/aapt2/ZipFile.h +++ b/tools/aapt2/ZipFile.h @@ -123,14 +123,16 @@ public: int compressionMethod, ZipEntry** ppEntry); /* - * Add an entry by copying it from another zip file. If "padding" is + * Add an entry by copying it from another zip file. If storageName is + * non-NULL, the entry will be inserted with the name storageName, otherwise + * it will have the same name as the source entry. If "padding" is * nonzero, the specified number of bytes will be added to the "extra" * field in the header. * * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - int padding, ZipEntry** ppEntry); + const char* storageName, int padding, ZipEntry** ppEntry); /* * Mark an entry as having been removed. It is not actually deleted diff --git a/tools/aapt2/data/Makefile b/tools/aapt2/data/Makefile index 5a2a1d1..6b5fafa 100644 --- a/tools/aapt2/data/Makefile +++ b/tools/aapt2/data/Makefile @@ -2,10 +2,8 @@ # Environment dependent variables ## -SHELL := /bin/bash AAPT := aapt2 -ZIP := zip -n .arsc:.png:AndroidManifest.xml -ZIPALIGN := zipalign 4 +ZIPALIGN := zipalign -f 4 FRAMEWORK := ../../../../../out/target/common/obj/APPS/framework-res_intermediates/package-export.apk ## diff --git a/tools/aapt2/data/lib/Makefile b/tools/aapt2/data/lib/Makefile index 2897ff1..8f56c54 100644 --- a/tools/aapt2/data/lib/Makefile +++ b/tools/aapt2/data/lib/Makefile @@ -3,7 +3,7 @@ ## AAPT := aapt2 -ZIPALIGN := zipalign 4 +ZIPALIGN := zipalign -f 4 FRAMEWORK := ../../../../../../out/target/common/obj/APPS/framework-res_intermediates/package-export.apk ## diff --git a/tools/aapt2/data/lib/res/layout/main.xml b/tools/aapt2/data/lib/res/layout/main.xml new file mode 100644 index 0000000..187ed2d --- /dev/null +++ b/tools/aapt2/data/lib/res/layout/main.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"/> diff --git a/tools/aapt2/data/lib/res/raw/hello.txt b/tools/aapt2/data/lib/res/raw/hello.txt new file mode 100644 index 0000000..44fc22b --- /dev/null +++ b/tools/aapt2/data/lib/res/raw/hello.txt @@ -0,0 +1 @@ +Oh howdy there |