diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 4b977225fd015..04d12f829e3cc 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -1691,6 +1691,8 @@ class Linker { TableMergerOptions table_merger_options; table_merger_options.auto_add_overlay = options_.auto_add_overlay; + table_merger_options.override_styles_instead_of_overlaying = + options_.override_styles_instead_of_overlaying; table_merger_options.strict_visibility = options_.strict_visibility; table_merger_ = util::make_unique(context_, &final_table_, table_merger_options); diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index 5b0653ed53bd7..37765f6b5d088 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -42,6 +42,7 @@ struct LinkOptions { std::vector assets_dirs; bool output_to_directory = false; bool auto_add_overlay = false; + bool override_styles_instead_of_overlaying = false; OutputFormat output_format = OutputFormat::kApk; // Java/Proguard options. @@ -242,6 +243,10 @@ class LinkCommand : public Command { "Allows the addition of new resources in overlays without\n" " tags.", &options_.auto_add_overlay); + AddOptionalSwitch("--override-styles-instead-of-overlaying", + "Causes styles defined in -R resources to replace previous definitions\n" + "instead of merging into them\n", + &options_.override_styles_instead_of_overlaying); AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.", &options_.manifest_fixer_options.rename_manifest_package); AddOptionalFlag("--rename-instrumentation-target-package", diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp index 32ed1dd81b3ff..bf8f043f6b68b 100644 --- a/tools/aapt2/cmd/Link_test.cpp +++ b/tools/aapt2/cmd/Link_test.cpp @@ -171,4 +171,86 @@ TEST_F(LinkTest, NoCompressResources) { EXPECT_FALSE(file->WasCompressed()); } -} // namespace aapt \ No newline at end of file +TEST_F(LinkTest, OverlayStyles) { + StdErrDiagnostics diag; + const std::string compiled_files_dir = GetTestPath("compiled"); + const std::string override_files_dir = GetTestPath("compiled-override"); + ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), + R"( + + )", + compiled_files_dir, &diag)); + ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"), + R"( + + )", + override_files_dir, &diag)); + + + const std::string out_apk = GetTestPath("out.apk"); + std::vector link_args = { + "--manifest", GetDefaultManifest(kDefaultPackageName), + "-o", out_apk, + }; + const auto override_files = file::FindFiles(override_files_dir, &diag); + for (const auto &override_file : override_files.value()) { + link_args.push_back("-R"); + link_args.push_back(file::BuildPath({override_files_dir, override_file})); + } + ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag)); + + std::unique_ptr apk = LoadedApk::LoadApkFromPath(out_apk, &diag); + const Style* actual_style = test::GetValue + )", + compiled_files_dir, &diag)); + ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"), + R"( + + )", + override_files_dir, &diag)); + + + const std::string out_apk = GetTestPath("out.apk"); + std::vector link_args = { + "--manifest", GetDefaultManifest(kDefaultPackageName), + "--override-styles-instead-of-overlaying", + "-o", out_apk, + }; + const auto override_files = file::FindFiles(override_files_dir, &diag); + for (const auto &override_file : override_files.value()) { + link_args.push_back("-R"); + link_args.push_back(file::BuildPath({override_files_dir, override_file})); + } + ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag)); + + std::unique_ptr apk = LoadedApk::LoadApkFromPath(out_apk, &diag); + const Style* actual_style = test::GetValue