Merge "AAPT2: Workaround for feature splits without namespacing" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
751e69b38b
@@ -17,6 +17,7 @@
|
|||||||
LOCAL_PATH:= $(call my-dir)
|
LOCAL_PATH:= $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_USE_AAPT2 := true
|
||||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
LOCAL_PACKAGE_NAME := FeatureSplitBase
|
LOCAL_PACKAGE_NAME := FeatureSplitBase
|
||||||
LOCAL_EXPORT_PACKAGE_RESOURCES := true
|
LOCAL_EXPORT_PACKAGE_RESOURCES := true
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<integer name="test_integer2">200</integer>
|
<integer name="test_integer2">200</integer>
|
||||||
<color name="test_color2">#00ff00</color>
|
<color name="test_color2">#00ff00</color>
|
||||||
<string-array name="string_array2">
|
<string-array name="string_array2">
|
||||||
<item>@*string/app_title</item>
|
<item>@string/app_title</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ bool Reference::Equals(const Value* value) const {
|
|||||||
bool Reference::Flatten(android::Res_value* out_value) const {
|
bool Reference::Flatten(android::Res_value* out_value) const {
|
||||||
const ResourceId resid = id.value_or_default(ResourceId(0));
|
const ResourceId resid = id.value_or_default(ResourceId(0));
|
||||||
const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId &&
|
const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId &&
|
||||||
resid.package_id() != kAppPackageId;
|
resid.package_id() < kAppPackageId;
|
||||||
|
|
||||||
if (reference_type == Reference::Type::kResource) {
|
if (reference_type == Reference::Type::kResource) {
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
|
|||||||
@@ -754,6 +754,9 @@ class LinkCommand {
|
|||||||
for (auto& entry : asset_source->GetAssignedPackageIds()) {
|
for (auto& entry : asset_source->GetAssignedPackageIds()) {
|
||||||
if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) {
|
if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) {
|
||||||
final_table_.included_packages_[entry.first] = entry.second;
|
final_table_.included_packages_[entry.first] = entry.second;
|
||||||
|
} else if (entry.first == kAppPackageId) {
|
||||||
|
// Capture the included base feature package.
|
||||||
|
included_feature_base_ = entry.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1408,17 +1411,53 @@ class LinkCommand {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hack to fix b/68820737.
|
||||||
|
// We need to modify the ResourceTable's package name, but that should NOT affect
|
||||||
|
// 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;
|
||||||
|
if (context_->GetPackageId() > kAppPackageId &&
|
||||||
|
included_feature_base_ == make_value(context_->GetCompilationPackage())) {
|
||||||
|
// 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) {
|
||||||
|
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());
|
||||||
|
|
||||||
|
if (context_->IsVerbose()) {
|
||||||
|
context_->GetDiagnostics()->Note(
|
||||||
|
DiagMessage() << "rewriting resource package name for feature split to '"
|
||||||
|
<< new_package_name << "'");
|
||||||
|
}
|
||||||
|
package_to_rewrite->name = new_package_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success;
|
||||||
if (context_->GetPackageType() == PackageType::kStaticLib) {
|
if (context_->GetPackageType() == PackageType::kStaticLib) {
|
||||||
if (!FlattenTableToPb(table, writer)) {
|
success = FlattenTableToPb(table, writer);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!FlattenTable(table, writer)) {
|
success = FlattenTable(table, writer);
|
||||||
context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc");
|
}
|
||||||
return false;
|
|
||||||
|
if (package_to_rewrite != nullptr) {
|
||||||
|
// Change the name back.
|
||||||
|
package_to_rewrite->name = context_->GetCompilationPackage();
|
||||||
|
if (package_to_rewrite->id) {
|
||||||
|
table->included_packages_.erase(package_to_rewrite->id.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
if (!success) {
|
||||||
|
context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resource table");
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Run(const std::vector<std::string>& input_files) {
|
int Run(const std::vector<std::string>& input_files) {
|
||||||
@@ -1447,8 +1486,8 @@ class LinkCommand {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppInfo& app_info = maybe_app_info.value();
|
app_info_ = maybe_app_info.value();
|
||||||
context_->SetMinSdkVersion(app_info.min_sdk_version.value_or_default(0));
|
context_->SetMinSdkVersion(app_info_.min_sdk_version.value_or_default(0));
|
||||||
|
|
||||||
context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()});
|
context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()});
|
||||||
|
|
||||||
@@ -1647,7 +1686,7 @@ class LinkCommand {
|
|||||||
|
|
||||||
// Generate an AndroidManifest.xml for each split.
|
// Generate an AndroidManifest.xml for each split.
|
||||||
std::unique_ptr<xml::XmlResource> split_manifest =
|
std::unique_ptr<xml::XmlResource> split_manifest =
|
||||||
GenerateSplitManifest(app_info, *split_constraints_iter);
|
GenerateSplitManifest(app_info_, *split_constraints_iter);
|
||||||
|
|
||||||
XmlReferenceLinker linker;
|
XmlReferenceLinker linker;
|
||||||
if (!linker.Consume(context_, split_manifest.get())) {
|
if (!linker.Consume(context_, split_manifest.get())) {
|
||||||
@@ -1815,6 +1854,8 @@ class LinkCommand {
|
|||||||
LinkContext* context_;
|
LinkContext* context_;
|
||||||
ResourceTable final_table_;
|
ResourceTable final_table_;
|
||||||
|
|
||||||
|
AppInfo app_info_;
|
||||||
|
|
||||||
std::unique_ptr<TableMerger> table_merger_;
|
std::unique_ptr<TableMerger> table_merger_;
|
||||||
|
|
||||||
// A pointer to the FileCollection representing the filesystem (not archives).
|
// A pointer to the FileCollection representing the filesystem (not archives).
|
||||||
@@ -1830,6 +1871,9 @@ class LinkCommand {
|
|||||||
|
|
||||||
// The set of shared libraries being used, mapping their assigned package ID to package name.
|
// The set of shared libraries being used, mapping their assigned package ID to package name.
|
||||||
std::map<size_t, std::string> shared_libs_;
|
std::map<size_t, std::string> shared_libs_;
|
||||||
|
|
||||||
|
// The package name of the base application, if it is included.
|
||||||
|
Maybe<std::string> included_feature_base_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
|
int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "android-base/logging.h"
|
#include "android-base/logging.h"
|
||||||
#include "android-base/macros.h"
|
#include "android-base/macros.h"
|
||||||
|
#include "android-base/stringprintf.h"
|
||||||
|
|
||||||
#include "ResourceTable.h"
|
#include "ResourceTable.h"
|
||||||
#include "ResourceValues.h"
|
#include "ResourceValues.h"
|
||||||
@@ -572,14 +573,6 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
|
|||||||
ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE);
|
ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE);
|
||||||
table_header->packageCount = util::HostToDevice32(table->packages.size());
|
table_header->packageCount = util::HostToDevice32(table->packages.size());
|
||||||
|
|
||||||
// Write a self mapping entry for this package if the ID is non-standard (0x7f).
|
|
||||||
if (context->GetPackageType() == PackageType::kApp) {
|
|
||||||
const uint8_t package_id = context->GetPackageId();
|
|
||||||
if (package_id != kFrameworkPackageId && package_id != kAppPackageId) {
|
|
||||||
table->included_packages_[package_id] = context->GetCompilationPackage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flatten the values string pool.
|
// Flatten the values string pool.
|
||||||
StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool);
|
StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool);
|
||||||
|
|
||||||
@@ -587,6 +580,22 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
|
|||||||
|
|
||||||
// Flatten each package.
|
// Flatten each package.
|
||||||
for (auto& package : table->packages) {
|
for (auto& package : table->packages) {
|
||||||
|
if (context->GetPackageType() == PackageType::kApp) {
|
||||||
|
// Write a self mapping entry for this package if the ID is non-standard (0x7f).
|
||||||
|
const uint8_t package_id = package->id.value();
|
||||||
|
if (package_id != kFrameworkPackageId && package_id != kAppPackageId) {
|
||||||
|
auto result = table->included_packages_.insert({package_id, package->name});
|
||||||
|
if (!result.second && result.first->second != package->name) {
|
||||||
|
// A mapping for this package ID already exists, and is a different package. Error!
|
||||||
|
context->GetDiagnostics()->Error(
|
||||||
|
DiagMessage() << android::base::StringPrintf(
|
||||||
|
"can't map package ID %02x to '%s'. Already mapped to '%s'", package_id,
|
||||||
|
package->name.c_str(), result.first->second.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PackageFlattener flattener(context, package.get(), &table->included_packages_,
|
PackageFlattener flattener(context, package.get(), &table->included_packages_,
|
||||||
options_.use_sparse_entries);
|
options_.use_sparse_entries);
|
||||||
if (!flattener.FlattenPackage(&package_buffer)) {
|
if (!flattener.FlattenPackage(&package_buffer)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user