Resource Path Obfuscation
This CL allows aapt2 to obfuscate resource paths within the output apk
and move resources to shorter obfuscated paths. This reduces apk size
when there is a large number of resources since the path metadata exists
in 4 places in the apk.
This CL adds two arguments to aapt2, one to enable resource path
obfuscation and one to point to a path to output the path map to (for
later debugging).
Test: make aapt2_tests
Bug: b/75965637
Change-Id: I9cacafe1d17800d673566b2d61b0b88f3fb8d60c
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 328b0be..2e6af18 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -41,6 +41,7 @@
#include "optimize/MultiApkGenerator.h"
#include "optimize/ResourceDeduper.h"
#include "optimize/ResourceFilter.h"
+#include "optimize/ResourcePathShortener.h"
#include "optimize/VersionCollapser.h"
#include "split/TableSplitter.h"
#include "util/Files.h"
@@ -52,6 +53,7 @@
using ::android::ResTable_config;
using ::android::StringPiece;
using ::android::base::ReadFileToString;
+using ::android::base::WriteStringToFile;
using ::android::base::StringAppendF;
using ::android::base::StringPrintf;
@@ -143,6 +145,21 @@
return 1;
}
+ if (options_.shorten_resource_paths) {
+ ResourcePathShortener shortener(options_.table_flattener_options.shortened_path_map);
+ if (!shortener.Consume(context_, apk->GetResourceTable())) {
+ context_->GetDiagnostics()->Error(DiagMessage() << "failed shortening resource paths");
+ return 1;
+ }
+ if (options_.shortened_paths_map_path
+ && !WriteShortenedPathsMap(options_.table_flattener_options.shortened_path_map,
+ options_.shortened_paths_map_path.value())) {
+ context_->GetDiagnostics()->Error(DiagMessage()
+ << "failed to write shortened resource paths to file");
+ return 1;
+ }
+ }
+
// Adjust the SplitConstraints so that their SDK version is stripped if it is less than or
// equal to the minSdk.
options_.split_constraints =
@@ -264,6 +281,15 @@
ArchiveEntry::kAlign, writer);
}
+ bool WriteShortenedPathsMap(const std::map<std::string, std::string> &path_map,
+ const std::string &file_path) {
+ std::stringstream ss;
+ for (auto it = path_map.cbegin(); it != path_map.cend(); ++it) {
+ ss << it->first << " -> " << it->second << "\n";
+ }
+ return WriteStringToFile(ss.str(), file_path);
+ }
+
OptimizeOptions options_;
OptimizeContext* context_;
};
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
index 43bc216..7df9cf7 100644
--- a/tools/aapt2/cmd/Optimize.h
+++ b/tools/aapt2/cmd/Optimize.h
@@ -55,6 +55,12 @@
// Set of artifacts to keep when generating multi-APK splits. If the list is empty, all artifacts
// are kept and will be written as output.
std::unordered_set<std::string> kept_artifacts;
+
+ // Whether or not to shorten resource paths in the APK.
+ bool shorten_resource_paths;
+
+ // Path to the output map of original resource paths to shortened paths.
+ Maybe<std::string> shortened_paths_map_path;
};
class OptimizeCommand : public Command {
@@ -100,6 +106,12 @@
AddOptionalSwitch("--enable-resource-obfuscation",
"Enables obfuscation of key string pool to single value",
&options_.table_flattener_options.collapse_key_stringpool);
+ AddOptionalSwitch("--enable-resource-path-shortening",
+ "Enables shortening of the path of the resources inside the APK.",
+ &options_.shorten_resource_paths);
+ AddOptionalFlag("--resource-path-shortening-map",
+ "Path to output the map of old resource paths to shortened paths.",
+ &options_.shortened_paths_map_path);
AddOptionalSwitch("-v", "Enables verbose logging", &verbose_);
}
@@ -108,6 +120,9 @@
private:
OptimizeOptions options_;
+ bool WriteObfuscatedPathsMap(const std::map<std::string, std::string> &path_map,
+ const std::string &file_path);
+
Maybe<std::string> config_path_;
Maybe<std::string> whitelist_path_;
Maybe<std::string> resources_config_path_;
@@ -121,4 +136,4 @@
}// namespace aapt
-#endif //AAPT2_OPTIMIZE_H
\ No newline at end of file
+#endif //AAPT2_OPTIMIZE_H