Loading tests/FeatureSplit/base/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_USE_AAPT2 := true LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := FeatureSplitBase LOCAL_EXPORT_PACKAGE_RESOURCES := true Loading tests/FeatureSplit/feature1/res/values/values.xml +1 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ <integer name="test_integer2">200</integer> <color name="test_color2">#00ff00</color> <string-array name="string_array2"> <item>@*string/app_title</item> <item>@string/app_title</item> </string-array> </resources> tools/aapt2/ResourceValues.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ bool Reference::Equals(const Value* value) const { bool Reference::Flatten(android::Res_value* out_value) const { const ResourceId resid = id.value_or_default(ResourceId(0)); 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 (dynamic) { Loading tools/aapt2/cmd/Link.cpp +54 −10 Original line number Diff line number Diff line Loading @@ -754,6 +754,9 @@ class LinkCommand { for (auto& entry : asset_source->GetAssignedPackageIds()) { if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) { final_table_.included_packages_[entry.first] = entry.second; } else if (entry.first == kAppPackageId) { // Capture the included base feature package. included_feature_base_ = entry.second; } } Loading Loading @@ -1408,17 +1411,53 @@ class LinkCommand { return false; } if (context_->GetPackageType() == PackageType::kStaticLib) { if (!FlattenTableToPb(table, writer)) { 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) { success = FlattenTableToPb(table, writer); } else { if (!FlattenTable(table, writer)) { context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc"); return false; success = FlattenTable(table, writer); } 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) { Loading Loading @@ -1447,8 +1486,8 @@ class LinkCommand { return 1; } const AppInfo& app_info = maybe_app_info.value(); context_->SetMinSdkVersion(app_info.min_sdk_version.value_or_default(0)); app_info_ = maybe_app_info.value(); context_->SetMinSdkVersion(app_info_.min_sdk_version.value_or_default(0)); context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()}); Loading Loading @@ -1647,7 +1686,7 @@ class LinkCommand { // Generate an AndroidManifest.xml for each split. std::unique_ptr<xml::XmlResource> split_manifest = GenerateSplitManifest(app_info, *split_constraints_iter); GenerateSplitManifest(app_info_, *split_constraints_iter); XmlReferenceLinker linker; if (!linker.Consume(context_, split_manifest.get())) { Loading Loading @@ -1815,6 +1854,8 @@ class LinkCommand { LinkContext* context_; ResourceTable final_table_; AppInfo app_info_; std::unique_ptr<TableMerger> table_merger_; // A pointer to the FileCollection representing the filesystem (not archives). Loading @@ -1830,6 +1871,9 @@ class LinkCommand { // The set of shared libraries being used, mapping their assigned package ID to package name. 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) { Loading tools/aapt2/flatten/TableFlattener.cpp +17 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "android-base/logging.h" #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "ResourceTable.h" #include "ResourceValues.h" Loading Loading @@ -572,14 +573,6 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE); 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. StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool); Loading @@ -587,6 +580,22 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { // Flatten each package. 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_, options_.use_sparse_entries); if (!flattener.FlattenPackage(&package_buffer)) { Loading Loading
tests/FeatureSplit/base/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_USE_AAPT2 := true LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := FeatureSplitBase LOCAL_EXPORT_PACKAGE_RESOURCES := true Loading
tests/FeatureSplit/feature1/res/values/values.xml +1 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ <integer name="test_integer2">200</integer> <color name="test_color2">#00ff00</color> <string-array name="string_array2"> <item>@*string/app_title</item> <item>@string/app_title</item> </string-array> </resources>
tools/aapt2/ResourceValues.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ bool Reference::Equals(const Value* value) const { bool Reference::Flatten(android::Res_value* out_value) const { const ResourceId resid = id.value_or_default(ResourceId(0)); 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 (dynamic) { Loading
tools/aapt2/cmd/Link.cpp +54 −10 Original line number Diff line number Diff line Loading @@ -754,6 +754,9 @@ class LinkCommand { for (auto& entry : asset_source->GetAssignedPackageIds()) { if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) { final_table_.included_packages_[entry.first] = entry.second; } else if (entry.first == kAppPackageId) { // Capture the included base feature package. included_feature_base_ = entry.second; } } Loading Loading @@ -1408,17 +1411,53 @@ class LinkCommand { return false; } if (context_->GetPackageType() == PackageType::kStaticLib) { if (!FlattenTableToPb(table, writer)) { 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) { success = FlattenTableToPb(table, writer); } else { if (!FlattenTable(table, writer)) { context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc"); return false; success = FlattenTable(table, writer); } 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) { Loading Loading @@ -1447,8 +1486,8 @@ class LinkCommand { return 1; } const AppInfo& app_info = maybe_app_info.value(); context_->SetMinSdkVersion(app_info.min_sdk_version.value_or_default(0)); app_info_ = maybe_app_info.value(); context_->SetMinSdkVersion(app_info_.min_sdk_version.value_or_default(0)); context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()}); Loading Loading @@ -1647,7 +1686,7 @@ class LinkCommand { // Generate an AndroidManifest.xml for each split. std::unique_ptr<xml::XmlResource> split_manifest = GenerateSplitManifest(app_info, *split_constraints_iter); GenerateSplitManifest(app_info_, *split_constraints_iter); XmlReferenceLinker linker; if (!linker.Consume(context_, split_manifest.get())) { Loading Loading @@ -1815,6 +1854,8 @@ class LinkCommand { LinkContext* context_; ResourceTable final_table_; AppInfo app_info_; std::unique_ptr<TableMerger> table_merger_; // A pointer to the FileCollection representing the filesystem (not archives). Loading @@ -1830,6 +1871,9 @@ class LinkCommand { // The set of shared libraries being used, mapping their assigned package ID to package name. 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) { Loading
tools/aapt2/flatten/TableFlattener.cpp +17 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "android-base/logging.h" #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "ResourceTable.h" #include "ResourceValues.h" Loading Loading @@ -572,14 +573,6 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE); 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. StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool); Loading @@ -587,6 +580,22 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { // Flatten each package. 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_, options_.use_sparse_entries); if (!flattener.FlattenPackage(&package_buffer)) { Loading