Loading tools/aapt2/cmd/Optimize.cpp +14 −36 Original line number Diff line number Diff line Loading @@ -53,9 +53,9 @@ using ::android::ConfigDescription; using ::android::ResTable_config; using ::android::StringPiece; using ::android::base::ReadFileToString; using ::android::base::WriteStringToFile; using ::android::base::StringAppendF; using ::android::base::StringPrintf; using ::android::base::WriteStringToFile; namespace aapt { Loading Loading @@ -300,29 +300,7 @@ class Optimizer { OptimizeContext* context_; }; bool ExtractObfuscationWhitelistFromConfig(const std::string& path, OptimizeContext* context, OptimizeOptions* options) { std::string contents; if (!ReadFileToString(path, &contents, true)) { context->GetDiagnostics()->Error(DiagMessage() << "failed to parse whitelist from config file: " << path); return false; } for (StringPiece resource_name : util::Tokenize(contents, ',')) { options->table_flattener_options.whitelisted_resources.insert( resource_name.to_string()); } return true; } bool ExtractConfig(const std::string& path, OptimizeContext* context, OptimizeOptions* options) { std::string content; if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) { context->GetDiagnostics()->Error(DiagMessage(path) << "failed reading whitelist"); return false; } bool ParseConfig(const std::string& content, IAaptContext* context, OptimizeOptions* options) { size_t line_no = 0; for (StringPiece line : util::Tokenize(content, '\n')) { line_no++; Loading Loading @@ -351,15 +329,24 @@ bool ExtractConfig(const std::string& path, OptimizeContext* context, for (StringPiece directive : util::Tokenize(directives, ',')) { if (directive == "remove") { options->resources_blacklist.insert(resource_name.ToResourceName()); } else if (directive == "no_obfuscate") { options->table_flattener_options.whitelisted_resources.insert( resource_name.entry.to_string()); } else if (directive == "no_collapse" || directive == "no_obfuscate") { options->table_flattener_options.name_collapse_exemptions.insert( resource_name.ToResourceName()); } } } return true; } bool ExtractConfig(const std::string& path, IAaptContext* context, OptimizeOptions* options) { std::string content; if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) { context->GetDiagnostics()->Error(DiagMessage(path) << "failed reading config file"); return false; } return ParseConfig(content, context, options); } bool ExtractAppDataFromManifest(OptimizeContext* context, const LoadedApk* apk, OptimizeOptions* out_options) { const xml::XmlResource* manifest = apk->GetManifest(); Loading Loading @@ -467,15 +454,6 @@ int OptimizeCommand::Action(const std::vector<std::string>& args) { } } if (options_.table_flattener_options.collapse_key_stringpool) { if (whitelist_path_) { std::string& path = whitelist_path_.value(); if (!ExtractObfuscationWhitelistFromConfig(path, &context, &options_)) { return 1; } } } if (resources_config_path_) { std::string& path = resources_config_path_.value(); if (!ExtractConfig(path, &context, &options_)) { Loading tools/aapt2/cmd/Optimize.h +0 −5 Original line number Diff line number Diff line Loading @@ -78,10 +78,6 @@ class OptimizeCommand : public Command { "All the resources that would be unused on devices of the given densities will be \n" "removed from the APK.", &target_densities_); AddOptionalFlag("--whitelist-path", "Path to the whitelist.cfg file containing whitelisted resources \n" "whose names should not be altered in final resource tables.", &whitelist_path_); AddOptionalFlag("--resources-config-path", "Path to the resources.cfg file containing the list of resources and \n" "directives to each resource. \n" Loading Loading @@ -127,7 +123,6 @@ class OptimizeCommand : public Command { const std::string &file_path); Maybe<std::string> config_path_; Maybe<std::string> whitelist_path_; Maybe<std::string> resources_config_path_; Maybe<std::string> target_densities_; std::vector<std::string> configs_; Loading tools/aapt2/cmd/Optimize_test.cpp 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Optimize.h" #include "AppInfo.h" #include "Diagnostics.h" #include "LoadedApk.h" #include "Resource.h" #include "test/Test.h" using testing::Contains; using testing::Eq; namespace aapt { bool ParseConfig(const std::string&, IAaptContext*, OptimizeOptions*); using OptimizeTest = CommandTestFixture; TEST_F(OptimizeTest, ParseConfigWithNoCollapseExemptions) { const std::string& content = R"( string/foo#no_collapse dimen/bar#no_collapse )"; aapt::test::Context context; OptimizeOptions options; ParseConfig(content, &context, &options); const std::set<ResourceName>& name_collapse_exemptions = options.table_flattener_options.name_collapse_exemptions; ASSERT_THAT(name_collapse_exemptions.size(), Eq(2)); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kString, "foo"))); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kDimen, "bar"))); } TEST_F(OptimizeTest, ParseConfigWithNoObfuscateExemptions) { const std::string& content = R"( string/foo#no_obfuscate dimen/bar#no_obfuscate )"; aapt::test::Context context; OptimizeOptions options; ParseConfig(content, &context, &options); const std::set<ResourceName>& name_collapse_exemptions = options.table_flattener_options.name_collapse_exemptions; ASSERT_THAT(name_collapse_exemptions.size(), Eq(2)); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kString, "foo"))); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kDimen, "bar"))); } } // namespace aapt tools/aapt2/format/binary/TableFlattener.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -228,14 +228,15 @@ class PackageFlattener { public: PackageFlattener(IAaptContext* context, ResourceTablePackage* package, const std::map<size_t, std::string>* shared_libs, bool use_sparse_entries, bool collapse_key_stringpool, const std::set<std::string>& whitelisted_resources) bool collapse_key_stringpool, const std::set<ResourceName>& name_collapse_exemptions) : context_(context), diag_(context->GetDiagnostics()), package_(package), shared_libs_(shared_libs), use_sparse_entries_(use_sparse_entries), collapse_key_stringpool_(collapse_key_stringpool), whitelisted_resources_(whitelisted_resources) { name_collapse_exemptions_(name_collapse_exemptions) { } bool FlattenPackage(BigBuffer* buffer) { Loading Loading @@ -652,11 +653,12 @@ class PackageFlattener { for (ResourceEntry* entry : sorted_entries) { uint32_t local_key_index; ResourceName resource_name({}, type->type, entry->name); if (!collapse_key_stringpool_ || whitelisted_resources_.find(entry->name) != whitelisted_resources_.end()) { name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) { local_key_index = (uint32_t)key_pool_.MakeRef(entry->name).index(); } else { // resource isn't whitelisted, add it as obfuscated value // resource isn't exempt from collapse, add it as obfuscated value local_key_index = (uint32_t)key_pool_.MakeRef(obfuscated_resource_name).index(); } // Group values by configuration. Loading Loading @@ -712,7 +714,7 @@ class PackageFlattener { StringPool type_pool_; StringPool key_pool_; bool collapse_key_stringpool_; const std::set<std::string>& whitelisted_resources_; const std::set<ResourceName>& name_collapse_exemptions_; }; } // namespace Loading Loading @@ -760,7 +762,7 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { PackageFlattener flattener(context, package.get(), &table->included_packages_, options_.use_sparse_entries, options_.collapse_key_stringpool, options_.whitelisted_resources); options_.name_collapse_exemptions); if (!flattener.FlattenPackage(&package_buffer)) { return false; } Loading tools/aapt2/format/binary/TableFlattener.h +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "android-base/macros.h" #include "Resource.h" #include "ResourceTable.h" #include "process/IResourceTableConsumer.h" #include "util/BigBuffer.h" Loading @@ -41,8 +42,8 @@ struct TableFlattenerOptions { // have name indices that point to this single value bool collapse_key_stringpool = false; // Set of whitelisted resource names to avoid altering in key stringpool std::set<std::string> whitelisted_resources; // Set of resources to avoid collapsing to a single entry in key stringpool. std::set<ResourceName> name_collapse_exemptions; // Map from original resource paths to shortened resource paths. std::map<std::string, std::string> shortened_path_map; Loading Loading
tools/aapt2/cmd/Optimize.cpp +14 −36 Original line number Diff line number Diff line Loading @@ -53,9 +53,9 @@ using ::android::ConfigDescription; using ::android::ResTable_config; using ::android::StringPiece; using ::android::base::ReadFileToString; using ::android::base::WriteStringToFile; using ::android::base::StringAppendF; using ::android::base::StringPrintf; using ::android::base::WriteStringToFile; namespace aapt { Loading Loading @@ -300,29 +300,7 @@ class Optimizer { OptimizeContext* context_; }; bool ExtractObfuscationWhitelistFromConfig(const std::string& path, OptimizeContext* context, OptimizeOptions* options) { std::string contents; if (!ReadFileToString(path, &contents, true)) { context->GetDiagnostics()->Error(DiagMessage() << "failed to parse whitelist from config file: " << path); return false; } for (StringPiece resource_name : util::Tokenize(contents, ',')) { options->table_flattener_options.whitelisted_resources.insert( resource_name.to_string()); } return true; } bool ExtractConfig(const std::string& path, OptimizeContext* context, OptimizeOptions* options) { std::string content; if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) { context->GetDiagnostics()->Error(DiagMessage(path) << "failed reading whitelist"); return false; } bool ParseConfig(const std::string& content, IAaptContext* context, OptimizeOptions* options) { size_t line_no = 0; for (StringPiece line : util::Tokenize(content, '\n')) { line_no++; Loading Loading @@ -351,15 +329,24 @@ bool ExtractConfig(const std::string& path, OptimizeContext* context, for (StringPiece directive : util::Tokenize(directives, ',')) { if (directive == "remove") { options->resources_blacklist.insert(resource_name.ToResourceName()); } else if (directive == "no_obfuscate") { options->table_flattener_options.whitelisted_resources.insert( resource_name.entry.to_string()); } else if (directive == "no_collapse" || directive == "no_obfuscate") { options->table_flattener_options.name_collapse_exemptions.insert( resource_name.ToResourceName()); } } } return true; } bool ExtractConfig(const std::string& path, IAaptContext* context, OptimizeOptions* options) { std::string content; if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) { context->GetDiagnostics()->Error(DiagMessage(path) << "failed reading config file"); return false; } return ParseConfig(content, context, options); } bool ExtractAppDataFromManifest(OptimizeContext* context, const LoadedApk* apk, OptimizeOptions* out_options) { const xml::XmlResource* manifest = apk->GetManifest(); Loading Loading @@ -467,15 +454,6 @@ int OptimizeCommand::Action(const std::vector<std::string>& args) { } } if (options_.table_flattener_options.collapse_key_stringpool) { if (whitelist_path_) { std::string& path = whitelist_path_.value(); if (!ExtractObfuscationWhitelistFromConfig(path, &context, &options_)) { return 1; } } } if (resources_config_path_) { std::string& path = resources_config_path_.value(); if (!ExtractConfig(path, &context, &options_)) { Loading
tools/aapt2/cmd/Optimize.h +0 −5 Original line number Diff line number Diff line Loading @@ -78,10 +78,6 @@ class OptimizeCommand : public Command { "All the resources that would be unused on devices of the given densities will be \n" "removed from the APK.", &target_densities_); AddOptionalFlag("--whitelist-path", "Path to the whitelist.cfg file containing whitelisted resources \n" "whose names should not be altered in final resource tables.", &whitelist_path_); AddOptionalFlag("--resources-config-path", "Path to the resources.cfg file containing the list of resources and \n" "directives to each resource. \n" Loading Loading @@ -127,7 +123,6 @@ class OptimizeCommand : public Command { const std::string &file_path); Maybe<std::string> config_path_; Maybe<std::string> whitelist_path_; Maybe<std::string> resources_config_path_; Maybe<std::string> target_densities_; std::vector<std::string> configs_; Loading
tools/aapt2/cmd/Optimize_test.cpp 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Optimize.h" #include "AppInfo.h" #include "Diagnostics.h" #include "LoadedApk.h" #include "Resource.h" #include "test/Test.h" using testing::Contains; using testing::Eq; namespace aapt { bool ParseConfig(const std::string&, IAaptContext*, OptimizeOptions*); using OptimizeTest = CommandTestFixture; TEST_F(OptimizeTest, ParseConfigWithNoCollapseExemptions) { const std::string& content = R"( string/foo#no_collapse dimen/bar#no_collapse )"; aapt::test::Context context; OptimizeOptions options; ParseConfig(content, &context, &options); const std::set<ResourceName>& name_collapse_exemptions = options.table_flattener_options.name_collapse_exemptions; ASSERT_THAT(name_collapse_exemptions.size(), Eq(2)); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kString, "foo"))); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kDimen, "bar"))); } TEST_F(OptimizeTest, ParseConfigWithNoObfuscateExemptions) { const std::string& content = R"( string/foo#no_obfuscate dimen/bar#no_obfuscate )"; aapt::test::Context context; OptimizeOptions options; ParseConfig(content, &context, &options); const std::set<ResourceName>& name_collapse_exemptions = options.table_flattener_options.name_collapse_exemptions; ASSERT_THAT(name_collapse_exemptions.size(), Eq(2)); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kString, "foo"))); EXPECT_THAT(name_collapse_exemptions, Contains(ResourceName({}, ResourceType::kDimen, "bar"))); } } // namespace aapt
tools/aapt2/format/binary/TableFlattener.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -228,14 +228,15 @@ class PackageFlattener { public: PackageFlattener(IAaptContext* context, ResourceTablePackage* package, const std::map<size_t, std::string>* shared_libs, bool use_sparse_entries, bool collapse_key_stringpool, const std::set<std::string>& whitelisted_resources) bool collapse_key_stringpool, const std::set<ResourceName>& name_collapse_exemptions) : context_(context), diag_(context->GetDiagnostics()), package_(package), shared_libs_(shared_libs), use_sparse_entries_(use_sparse_entries), collapse_key_stringpool_(collapse_key_stringpool), whitelisted_resources_(whitelisted_resources) { name_collapse_exemptions_(name_collapse_exemptions) { } bool FlattenPackage(BigBuffer* buffer) { Loading Loading @@ -652,11 +653,12 @@ class PackageFlattener { for (ResourceEntry* entry : sorted_entries) { uint32_t local_key_index; ResourceName resource_name({}, type->type, entry->name); if (!collapse_key_stringpool_ || whitelisted_resources_.find(entry->name) != whitelisted_resources_.end()) { name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) { local_key_index = (uint32_t)key_pool_.MakeRef(entry->name).index(); } else { // resource isn't whitelisted, add it as obfuscated value // resource isn't exempt from collapse, add it as obfuscated value local_key_index = (uint32_t)key_pool_.MakeRef(obfuscated_resource_name).index(); } // Group values by configuration. Loading Loading @@ -712,7 +714,7 @@ class PackageFlattener { StringPool type_pool_; StringPool key_pool_; bool collapse_key_stringpool_; const std::set<std::string>& whitelisted_resources_; const std::set<ResourceName>& name_collapse_exemptions_; }; } // namespace Loading Loading @@ -760,7 +762,7 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { PackageFlattener flattener(context, package.get(), &table->included_packages_, options_.use_sparse_entries, options_.collapse_key_stringpool, options_.whitelisted_resources); options_.name_collapse_exemptions); if (!flattener.FlattenPackage(&package_buffer)) { return false; } Loading
tools/aapt2/format/binary/TableFlattener.h +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "android-base/macros.h" #include "Resource.h" #include "ResourceTable.h" #include "process/IResourceTableConsumer.h" #include "util/BigBuffer.h" Loading @@ -41,8 +42,8 @@ struct TableFlattenerOptions { // have name indices that point to this single value bool collapse_key_stringpool = false; // Set of whitelisted resource names to avoid altering in key stringpool std::set<std::string> whitelisted_resources; // Set of resources to avoid collapsing to a single entry in key stringpool. std::set<ResourceName> name_collapse_exemptions; // Map from original resource paths to shortened resource paths. std::map<std::string, std::string> shortened_path_map; Loading