Aapt2 Optimize: Exempt particular resources from path shortening
Design: go/no_path_shorten
Bug: b/246845175
Test: Added new atests and verified affected atests pass
Change-Id: I4d5b48ea9f0efd4740823101b9a3d776d151a808
diff --git a/tools/aapt2/optimize/Obfuscator.cpp b/tools/aapt2/optimize/Obfuscator.cpp
index cc21093..8f12f735 100644
--- a/tools/aapt2/optimize/Obfuscator.cpp
+++ b/tools/aapt2/optimize/Obfuscator.cpp
@@ -83,13 +83,18 @@
};
static bool HandleShortenFilePaths(ResourceTable* table,
- std::map<std::string, std::string>& shortened_path_map) {
+ std::map<std::string, std::string>& shortened_path_map,
+ const std::set<ResourceName>& path_shorten_exemptions) {
// used to detect collisions
std::unordered_set<std::string> shortened_paths;
std::set<FileReference*, PathComparator> file_refs;
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
+ ResourceName resource_name({}, type->named_type, entry->name);
+ if (path_shorten_exemptions.find(resource_name) != path_shorten_exemptions.end()) {
+ continue;
+ }
for (auto& config_value : entry->values) {
FileReference* file_ref = ValueCast<FileReference>(config_value->value.get());
if (file_ref) {
@@ -188,7 +193,8 @@
HandleCollapseKeyStringPool(table, options_.collapse_key_stringpool,
options_.name_collapse_exemptions, options_.id_resource_map);
if (shorten_resource_paths_) {
- return HandleShortenFilePaths(table, options_.shortened_path_map);
+ return HandleShortenFilePaths(table, options_.shortened_path_map,
+ options_.path_shorten_exemptions);
}
return true;
}
diff --git a/tools/aapt2/optimize/Obfuscator_test.cpp b/tools/aapt2/optimize/Obfuscator_test.cpp
index 7f57b71..940cf10 100644
--- a/tools/aapt2/optimize/Obfuscator_test.cpp
+++ b/tools/aapt2/optimize/Obfuscator_test.cpp
@@ -28,6 +28,7 @@
using ::testing::AnyOf;
using ::testing::Eq;
using ::testing::HasSubstr;
+using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::Not;
using ::testing::NotNull;
@@ -102,6 +103,44 @@
ASSERT_THAT(path_map.find("res/color-mdp-v21/colorlist.xml"), Eq(path_map.end()));
}
+TEST(ObfuscatorTest, SkipPathShortenExemptions) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddFileReference("android:drawable/xmlfile", "res/drawables/xmlfile.xml")
+ .AddFileReference("android:drawable/xmlfile2", "res/drawables/xmlfile2.xml")
+ .AddString("android:string/string", "res/should/still/be/the/same.png")
+ .Build();
+
+ OptimizeOptions options{.shorten_resource_paths = true};
+ TableFlattenerOptions& flattenerOptions = options.table_flattener_options;
+ flattenerOptions.path_shorten_exemptions.insert(
+ ResourceName({}, ResourceType::kDrawable, "xmlfile"));
+ std::map<std::string, std::string>& path_map = options.table_flattener_options.shortened_path_map;
+ ASSERT_TRUE(Obfuscator(options).Consume(context.get(), table.get()));
+
+ // Expect that the path map to not contain the first drawable which is in exemption set
+ EXPECT_THAT(path_map.find("res/drawables/xmlfile.xml"), Eq(path_map.end()));
+
+ // Expect that the path map to contain the second drawable which is not in exemption set
+ EXPECT_THAT(path_map.find("res/drawables/xmlfile2.xml"), Not(Eq(path_map.end())));
+
+ FileReference* ref = GetValue<FileReference>(table.get(), "android:drawable/xmlfile");
+ EXPECT_THAT(ref, NotNull());
+ ASSERT_THAT(HasFailure(), IsFalse());
+ // The path of first drawable in exemption was not changed
+ EXPECT_THAT("res/drawables/xmlfile.xml", Eq(*ref->path));
+
+ // The file path of second drawable not in exemption set was changed
+ EXPECT_THAT(path_map.at("res/drawables/xmlfile2.xml"), Not(Eq("res/drawables/xmlfile2.xml")));
+
+ FileReference* ref2 = GetValue<FileReference>(table.get(), "android:drawable/xmlfile2");
+ ASSERT_THAT(ref, NotNull());
+ // The map of second drawable not in exemption correctly points to the new location of the file
+ EXPECT_THAT(path_map["res/drawables/xmlfile2.xml"], Eq(*ref2->path));
+}
+
TEST(ObfuscatorTest, KeepExtensions) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();