summaryrefslogtreecommitdiff
path: root/tools/aapt2/cmd/Link.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/cmd/Link.cpp')
-rw-r--r--tools/aapt2/cmd/Link.cpp92
1 files changed, 53 insertions, 39 deletions
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 13e090d9d843..ee6a764966f0 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -25,6 +25,7 @@
#include <vector>
#include "android-base/errors.h"
+#include "android-base/expected.h"
#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "androidfw/Locale.h"
@@ -74,10 +75,25 @@
using ::aapt::io::FileInputStream;
using ::android::ConfigDescription;
using ::android::StringPiece;
+using ::android::base::expected;
using ::android::base::StringPrintf;
+using ::android::base::unexpected;
namespace aapt {
+namespace {
+
+expected<ResourceTablePackage*, const char*> GetStaticLibraryPackage(ResourceTable* table) {
+ // Resource tables built by aapt2 always contain one package. This is a post condition of
+ // VerifyNoExternalPackages.
+ if (table->packages.size() != 1u) {
+ return unexpected("static library contains more than one package");
+ }
+ return table->packages.back().get();
+}
+
+} // namespace
+
constexpr uint8_t kAndroidPackageId = 0x01;
class LinkContext : public IAaptContext {
@@ -633,13 +649,18 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv
const ResourceFile& file = doc->file;
dst_path = ResourceUtils::BuildResourceFileName(file, context_->GetNameMangler());
- std::unique_ptr<FileReference> file_ref =
+ auto file_ref =
util::make_unique<FileReference>(table->string_pool.MakeRef(dst_path));
file_ref->SetSource(doc->file.source);
+
// Update the output format of this XML file.
file_ref->type = XmlFileTypeForOutputFormat(options_.output_format);
- if (!table->AddResourceMangled(file.name, file.config, {}, std::move(file_ref),
- context_->GetDiagnostics())) {
+ bool result = table->AddResource(NewResourceBuilder(file.name)
+ .SetValue(std::move(file_ref), file.config)
+ .SetAllowMangled(true)
+ .Build(),
+ context_->GetDiagnostics());
+ if (!result) {
return false;
}
}
@@ -842,18 +863,15 @@ class Linker {
ResourceTable* table = static_apk->GetResourceTable();
// If we are using --no-static-lib-packages, we need to rename the package of this table to
- // our compilation package.
- if (options_.no_static_lib_packages) {
- // Since package names can differ, and multiple packages can exist in a ResourceTable,
- // we place the requirement that all static libraries are built with the package
- // ID 0x7f. So if one is not found, this is an error.
- if (ResourceTablePackage* pkg = table->FindPackageById(kAppPackageId)) {
- pkg->name = context_->GetCompilationPackage();
- } else {
- context_->GetDiagnostics()->Error(DiagMessage(path)
- << "no package with ID 0x7f found in static library");
+ // our compilation package so the symbol package name does not get mangled into the entry
+ // name.
+ if (options_.no_static_lib_packages && !table->packages.empty()) {
+ auto lib_package_result = GetStaticLibraryPackage(table);
+ if (!lib_package_result.has_value()) {
+ context_->GetDiagnostics()->Error(DiagMessage(path) << lib_package_result.error());
return false;
}
+ lib_package_result.value()->name = context_->GetCompilationPackage();
}
context_->GetExternalSymbols()->AppendSource(
@@ -982,8 +1000,7 @@ class Linker {
// stripped, or there is an error and false is returned.
bool VerifyNoExternalPackages() {
auto is_ext_package_func = [&](const std::unique_ptr<ResourceTablePackage>& pkg) -> bool {
- return context_->GetCompilationPackage() != pkg->name || !pkg->id ||
- pkg->id.value() != context_->GetPackageId();
+ return context_->GetCompilationPackage() != pkg->name;
};
bool error = false;
@@ -1027,19 +1044,11 @@ class Linker {
bool VerifyNoIdsSet() {
for (const auto& package : final_table_.packages) {
for (const auto& type : package->types) {
- if (type->id) {
- context_->GetDiagnostics()->Error(DiagMessage() << "type " << type->type << " has ID "
- << StringPrintf("%02x", type->id.value())
- << " assigned");
- return false;
- }
-
for (const auto& entry : type->entries) {
if (entry->id) {
ResourceNameRef res_name(package->name, type->type, entry->name);
- context_->GetDiagnostics()->Error(
- DiagMessage() << "entry " << res_name << " has ID "
- << StringPrintf("%02x", entry->id.value()) << " assigned");
+ context_->GetDiagnostics()->Error(DiagMessage() << "resource " << res_name << " has ID "
+ << entry->id.value() << " assigned");
return false;
}
}
@@ -1313,12 +1322,17 @@ class Linker {
}
ResourceTable* table = apk->GetResourceTable();
- ResourceTablePackage* pkg = table->FindPackageById(kAppPackageId);
- if (!pkg) {
- context_->GetDiagnostics()->Error(DiagMessage(input) << "static library has no package");
+ if (table->packages.empty()) {
+ return true;
+ }
+
+ auto lib_package_result = GetStaticLibraryPackage(table);
+ if (!lib_package_result.has_value()) {
+ context_->GetDiagnostics()->Error(DiagMessage(input) << lib_package_result.error());
return false;
}
+ ResourceTablePackage* pkg = lib_package_result.value();
bool result;
if (options_.no_static_lib_packages) {
// Merge all resources as if they were in the compilation package. This is the old behavior
@@ -1365,11 +1379,11 @@ class Linker {
res_name = mangled_name.value();
}
- std::unique_ptr<Id> id = util::make_unique<Id>();
+ auto id = util::make_unique<Id>();
id->SetSource(source.WithLine(exported_symbol.line));
- bool result =
- final_table_.AddResourceMangled(res_name, ConfigDescription::DefaultConfig(),
- std::string(), std::move(id), context_->GetDiagnostics());
+ bool result = final_table_.AddResource(
+ NewResourceBuilder(res_name).SetValue(std::move(id)).SetAllowMangled(true).Build(),
+ context_->GetDiagnostics());
if (!result) {
return false;
}
@@ -1750,7 +1764,7 @@ class Linker {
// anything else being generated, which includes the Java classes.
// If required, the package name is modifed before flattening, and then modified back
// to its original name.
- ResourceTablePackage* package_to_rewrite = nullptr;
+ std::optional<ResourceTablePackageView> package_to_rewrite;
// Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80
// or higher] as invalid. In order to work around this limitation, we allow the use
// of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the
@@ -1764,10 +1778,11 @@ class Linker {
// The base APK is included, and this is a feature split. If the base package is
// the same as this package, then we are building an old style Android Instant Apps feature
// split and must apply this workaround to avoid requiring namespaces support.
- package_to_rewrite = table->FindPackage(context_->GetCompilationPackage());
- if (package_to_rewrite != nullptr) {
+ auto table_view = table->GetPartitionedView();
+ if (!table_view.packages.empty() &&
+ table_view.packages.back().name == context_->GetCompilationPackage()) {
+ package_to_rewrite = std::move(table_view.packages.back());
CHECK_EQ(1u, table->packages.size()) << "can't change name of package when > 1 package";
-
std::string new_package_name =
StringPrintf("%s.%s", package_to_rewrite->name.c_str(),
app_info_.split_name.value_or_default("feature").c_str());
@@ -1783,7 +1798,7 @@ class Linker {
bool success = FlattenTable(table, options_.output_format, writer);
- if (package_to_rewrite != nullptr) {
+ if (package_to_rewrite.has_value()) {
// Change the name back.
package_to_rewrite->name = context_->GetCompilationPackage();
if (package_to_rewrite->id) {
@@ -1925,8 +1940,7 @@ class Linker {
for (auto& entry : type->entries) {
ResourceName name(package->name, type->type, entry->name);
// The IDs are guaranteed to exist.
- options_.stable_id_map[std::move(name)] =
- ResourceId(package->id.value(), type->id.value(), entry->id.value());
+ options_.stable_id_map[std::move(name)] = entry->id.value();
}
}
}