From 121c6e8aa037efcbd047bdd5f53e6686a07fa002 Mon Sep 17 00:00:00 2001 From: Donald Chai Date: Wed, 12 Jun 2019 12:51:57 -0700 Subject: [PATCH] [aapt2] Add "link" option to override styles instead of overlaying. For normal app development, the desired linking semantics are: * styleables - take union of all definitions * all other resources - take last non-weak definition This differs from the semantics needed in other scenarios, where merging/overlaying styles is desired. Bug: 134525082 Change-Id: Iac0c43ca2ecf1f3fddc9c3367f8914c12c9258e1 Tested: aapt2_tests --- tools/aapt2/cmd/Link.cpp | 2 + tools/aapt2/cmd/Link.h | 5 ++ tools/aapt2/cmd/Link_test.cpp | 84 ++++++++++++++++++++++++++- tools/aapt2/link/TableMerger.cpp | 27 +++++---- tools/aapt2/link/TableMerger.h | 2 + tools/aapt2/link/TableMerger_test.cpp | 47 +++++++++++++++ 6 files changed, 155 insertions(+), 12 deletions(-) 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