[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
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 32ed1dd..bf8f043 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -171,4 +171,86 @@
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"(<resources>
+ <style name="MyStyle">
+ <item name="android:textColor">#123</item>
+ </style>
+ </resources>)",
+ compiled_files_dir, &diag));
+ ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
+ R"(<resources>
+ <style name="MyStyle">
+ <item name="android:background">#456</item>
+ </style>
+ </resources>)",
+ override_files_dir, &diag));
+
+
+ const std::string out_apk = GetTestPath("out.apk");
+ std::vector<std::string> 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<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+ const Style* actual_style = test::GetValue<Style>(
+ apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
+ ASSERT_NE(actual_style, nullptr);
+ ASSERT_EQ(actual_style->entries.size(), 2);
+ EXPECT_EQ(actual_style->entries[0].key.id, 0x01010098); // android:textColor
+ EXPECT_EQ(actual_style->entries[1].key.id, 0x010100d4); // android:background
+}
+
+TEST_F(LinkTest, OverrideStylesInsteadOfOverlaying) {
+ 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"(<resources>
+ <style name="MyStyle">
+ <item name="android:textColor">#123</item>
+ </style>
+ </resources>)",
+ compiled_files_dir, &diag));
+ ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
+ R"(<resources>
+ <style name="MyStyle">
+ <item name="android:background">#456</item>
+ </style>
+ </resources>)",
+ override_files_dir, &diag));
+
+
+ const std::string out_apk = GetTestPath("out.apk");
+ std::vector<std::string> 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<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+ const Style* actual_style = test::GetValue<Style>(
+ apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
+ ASSERT_NE(actual_style, nullptr);
+ ASSERT_EQ(actual_style->entries.size(), 1);
+ EXPECT_EQ(actual_style->entries[0].key.id, 0x010100d4); // android:background
+}
+
+} // namespace aapt