AAPT2: Shared library support
Test: make aapt2_tests
Change-Id: I98dddf1367e6c0ac425bb20be46e6ff05f4f2f45
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index 697b07f..3098458 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -217,16 +217,17 @@
class PackageFlattener {
public:
- PackageFlattener(IAaptContext* context, ResourceTablePackage* package, bool use_sparse_entries)
+ PackageFlattener(IAaptContext* context, ResourceTablePackage* package,
+ const std::map<size_t, std::string>* shared_libs, bool use_sparse_entries)
: context_(context),
diag_(context->GetDiagnostics()),
package_(package),
+ shared_libs_(shared_libs),
use_sparse_entries_(use_sparse_entries) {}
bool FlattenPackage(BigBuffer* buffer) {
ChunkWriter pkg_writer(buffer);
- ResTable_package* pkg_header =
- pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
+ ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
pkg_header->id = util::HostToDevice32(package_->id.value());
if (package_->name.size() >= arraysize(pkg_header->name)) {
@@ -253,6 +254,11 @@
// Append the types.
buffer->AppendBuffer(std::move(type_buffer));
+ // If there are libraries (or if the package ID is 0x00), encode a library chunk.
+ if (package_->id.value() == 0x00 || !shared_libs_->empty()) {
+ FlattenLibrarySpec(buffer);
+ }
+
pkg_writer.Finish();
return true;
}
@@ -470,6 +476,10 @@
type_pool_.MakeRef(ToString(type->type));
std::vector<ResourceEntry*> sorted_entries = CollectAndSortEntries(type);
+ if (sorted_entries.empty()) {
+ continue;
+ }
+
if (!FlattenTypeSpec(type, &sorted_entries, buffer)) {
return false;
}
@@ -504,9 +514,38 @@
return true;
}
+ void FlattenLibrarySpec(BigBuffer* buffer) {
+ ChunkWriter lib_writer(buffer);
+ ResTable_lib_header* lib_header =
+ lib_writer.StartChunk<ResTable_lib_header>(RES_TABLE_LIBRARY_TYPE);
+
+ const size_t num_entries = (package_->id.value() == 0x00 ? 1 : 0) + shared_libs_->size();
+ CHECK(num_entries > 0);
+
+ lib_header->count = util::HostToDevice32(num_entries);
+
+ ResTable_lib_entry* lib_entry = buffer->NextBlock<ResTable_lib_entry>(num_entries);
+ if (package_->id.value() == 0x00) {
+ // Add this package
+ lib_entry->packageId = util::HostToDevice32(0x00);
+ strcpy16_htod(lib_entry->packageName, arraysize(lib_entry->packageName),
+ util::Utf8ToUtf16(package_->name));
+ ++lib_entry;
+ }
+
+ for (auto& map_entry : *shared_libs_) {
+ lib_entry->packageId = util::HostToDevice32(map_entry.first);
+ strcpy16_htod(lib_entry->packageName, arraysize(lib_entry->packageName),
+ util::Utf8ToUtf16(map_entry.second));
+ ++lib_entry;
+ }
+ lib_writer.Finish();
+ }
+
IAaptContext* context_;
IDiagnostics* diag_;
ResourceTablePackage* package_;
+ const std::map<size_t, std::string>* shared_libs_;
bool use_sparse_entries_;
StringPool type_pool_;
StringPool key_pool_;
@@ -542,7 +581,8 @@
// Flatten each package.
for (auto& package : table->packages) {
- PackageFlattener flattener(context, package.get(), options_.use_sparse_entries);
+ PackageFlattener flattener(context, package.get(), &table->included_packages_,
+ options_.use_sparse_entries);
if (!flattener.FlattenPackage(&package_buffer)) {
return false;
}