Loading tools/aapt2/link/Link.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -1634,7 +1634,7 @@ class LinkCommand { if (options_.static_lib) { if (options_.table_splitter_options.config_filter != nullptr || options_.table_splitter_options.preferred_density) { !options_.table_splitter_options.preferred_densities.empty()) { context_->GetDiagnostics() ->Warn(DiagMessage() << "can't strip resources when building static library"); Loading Loading @@ -2107,8 +2107,7 @@ int Link(const std::vector<StringPiece>& args) { << "Preferred density must only be a density value"); return 1; } options.table_splitter_options.preferred_density = preferred_density_config.density; options.table_splitter_options.preferred_densities.push_back(preferred_density_config.density); } if (!options.static_lib && stable_id_file_path) { Loading tools/aapt2/split/TableSplitter.cpp +23 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <algorithm> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #include <vector> Loading Loading @@ -124,29 +125,35 @@ class SplitValueSelector { * leaving only the preferred density behind. */ static void MarkNonPreferredDensitiesAsClaimed( uint16_t preferred_density, const ConfigDensityGroups& density_groups, const std::vector<uint16_t>& preferred_densities, const ConfigDensityGroups& density_groups, ConfigClaimedMap* config_claimed_map) { for (auto& entry : density_groups) { const ConfigDescription& config = entry.first; const std::vector<ResourceConfigValue*>& related_values = entry.second; // There can be multiple best values if there are multiple preferred densities. std::unordered_set<ResourceConfigValue*> best_values; // For each preferred density, find the value that is the best. for (uint16_t preferred_density : preferred_densities) { ConfigDescription target_density = config; target_density.density = preferred_density; ResourceConfigValue* best_value = nullptr; for (ResourceConfigValue* this_value : related_values) { if (!best_value) { best_value = this_value; } else if (this_value->config.isBetterThan(best_value->config, &target_density)) { // Claim the previous value so that it is not included in the base. (*config_claimed_map)[best_value] = true; if (!best_value || this_value->config.isBetterThan(best_value->config, &target_density)) { best_value = this_value; } else { // Claim this value so that it is not included in the base. (*config_claimed_map)[this_value] = true; } } CHECK(best_value != nullptr); best_values.insert(best_value); } // Claim all the values that aren't the best so that they will be removed from the base. for (ResourceConfigValue* this_value : related_values) { if (best_values.find(this_value) == best_values.end()) { (*config_claimed_map)[this_value] = true; } } } } bool TableSplitter::VerifySplitConstraints(IAaptContext* context) { Loading Loading @@ -263,8 +270,8 @@ void TableSplitter::SplitTable(ResourceTable* original_table) { } } if (options_.preferred_density) { MarkNonPreferredDensitiesAsClaimed(options_.preferred_density.value(), if (!options_.preferred_densities.empty()) { MarkNonPreferredDensitiesAsClaimed(options_.preferred_densities, density_groups, &config_claimed_map); } Loading tools/aapt2/split/TableSplitter.h +4 −4 Original line number Diff line number Diff line Loading @@ -34,14 +34,14 @@ struct SplitConstraints { struct TableSplitterOptions { /** * The preferred density to keep in the table, stripping out all others. * The preferred densities to keep in the table, stripping out all others. * If empty, no stripping is done. */ Maybe<uint16_t> preferred_density; std::vector<uint16_t> preferred_densities; /** * Configuration filter that determines which resource configuration values * end up in * the final table. * end up in the final table. */ IConfigFilter* config_filter = nullptr; }; Loading tools/aapt2/split/TableSplitter_test.cpp +46 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ TEST(TableSplitterTest, NoSplitPreferredDensity) { .Build(); TableSplitterOptions options; options.preferred_density = ConfigDescription::DENSITY_XHIGH; options.preferred_densities.push_back(ConfigDescription::DENSITY_XHIGH); TableSplitter splitter({}, options); splitter.SplitTable(table.get()); Loading @@ -58,6 +58,51 @@ TEST(TableSplitterTest, NoSplitPreferredDensity) { EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one")); } TEST(TableSplitterTest, NoSplitMultiplePreferredDensities) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddFileReference("android:drawable/icon", "res/drawable-mdpi/icon.png", test::ParseConfigOrDie("mdpi")) .AddFileReference("android:drawable/icon", "res/drawable-hdpi/icon.png", test::ParseConfigOrDie("hdpi")) .AddFileReference("android:drawable/icon", "res/drawable-xhdpi/icon.png", test::ParseConfigOrDie("xhdpi")) .AddFileReference("android:drawable/icon", "res/drawable-xxhdpi/icon.png", test::ParseConfigOrDie("xxhdpi")) .AddSimple("android:string/one") .Build(); TableSplitterOptions options; options.preferred_densities.push_back(ConfigDescription::DENSITY_LOW); options.preferred_densities.push_back(ConfigDescription::DENSITY_XXXHIGH); TableSplitter splitter({}, options); splitter.SplitTable(table.get()); // Densities remaining: // "mdpi" is the closest available density for the requested "ldpi" density. EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("mdpi"))); // "xxhdpi" is the closest available density for the requested "xxxhdpi" density. EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("xxhdpi"))); EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one")); // Removed densities: EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("hdpi"))); EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("xhdpi"))); } TEST(TableSplitterTest, SplitTableByDensity) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() Loading tools/aapt2/strip/Strip.cpp +4 −9 Original line number Diff line number Diff line Loading @@ -79,18 +79,13 @@ class StripCommand { context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK..."); } // TODO(lecesne): Add support for more than one density. if (options_.target_configs.size() > 1) { context_->GetDiagnostics()->Error(DiagMessage() << "Multiple densities not supported at the moment"); return 1; } // Stripping the APK using the TableSplitter with no splits and the target // density as the preferred density. The resource table is modified in // densities as the preferred densities. The resource table is modified in // place in the LoadedApk. TableSplitterOptions splitter_options; splitter_options.preferred_density = options_.target_configs[0].density; for (auto& config : options_.target_configs) { splitter_options.preferred_densities.push_back(config.density); } std::vector<SplitConstraints> splits; TableSplitter splitter(splits, splitter_options); splitter.SplitTable(apk->GetResourceTable()); Loading Loading
tools/aapt2/link/Link.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -1634,7 +1634,7 @@ class LinkCommand { if (options_.static_lib) { if (options_.table_splitter_options.config_filter != nullptr || options_.table_splitter_options.preferred_density) { !options_.table_splitter_options.preferred_densities.empty()) { context_->GetDiagnostics() ->Warn(DiagMessage() << "can't strip resources when building static library"); Loading Loading @@ -2107,8 +2107,7 @@ int Link(const std::vector<StringPiece>& args) { << "Preferred density must only be a density value"); return 1; } options.table_splitter_options.preferred_density = preferred_density_config.density; options.table_splitter_options.preferred_densities.push_back(preferred_density_config.density); } if (!options.static_lib && stable_id_file_path) { Loading
tools/aapt2/split/TableSplitter.cpp +23 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <algorithm> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #include <vector> Loading Loading @@ -124,29 +125,35 @@ class SplitValueSelector { * leaving only the preferred density behind. */ static void MarkNonPreferredDensitiesAsClaimed( uint16_t preferred_density, const ConfigDensityGroups& density_groups, const std::vector<uint16_t>& preferred_densities, const ConfigDensityGroups& density_groups, ConfigClaimedMap* config_claimed_map) { for (auto& entry : density_groups) { const ConfigDescription& config = entry.first; const std::vector<ResourceConfigValue*>& related_values = entry.second; // There can be multiple best values if there are multiple preferred densities. std::unordered_set<ResourceConfigValue*> best_values; // For each preferred density, find the value that is the best. for (uint16_t preferred_density : preferred_densities) { ConfigDescription target_density = config; target_density.density = preferred_density; ResourceConfigValue* best_value = nullptr; for (ResourceConfigValue* this_value : related_values) { if (!best_value) { best_value = this_value; } else if (this_value->config.isBetterThan(best_value->config, &target_density)) { // Claim the previous value so that it is not included in the base. (*config_claimed_map)[best_value] = true; if (!best_value || this_value->config.isBetterThan(best_value->config, &target_density)) { best_value = this_value; } else { // Claim this value so that it is not included in the base. (*config_claimed_map)[this_value] = true; } } CHECK(best_value != nullptr); best_values.insert(best_value); } // Claim all the values that aren't the best so that they will be removed from the base. for (ResourceConfigValue* this_value : related_values) { if (best_values.find(this_value) == best_values.end()) { (*config_claimed_map)[this_value] = true; } } } } bool TableSplitter::VerifySplitConstraints(IAaptContext* context) { Loading Loading @@ -263,8 +270,8 @@ void TableSplitter::SplitTable(ResourceTable* original_table) { } } if (options_.preferred_density) { MarkNonPreferredDensitiesAsClaimed(options_.preferred_density.value(), if (!options_.preferred_densities.empty()) { MarkNonPreferredDensitiesAsClaimed(options_.preferred_densities, density_groups, &config_claimed_map); } Loading
tools/aapt2/split/TableSplitter.h +4 −4 Original line number Diff line number Diff line Loading @@ -34,14 +34,14 @@ struct SplitConstraints { struct TableSplitterOptions { /** * The preferred density to keep in the table, stripping out all others. * The preferred densities to keep in the table, stripping out all others. * If empty, no stripping is done. */ Maybe<uint16_t> preferred_density; std::vector<uint16_t> preferred_densities; /** * Configuration filter that determines which resource configuration values * end up in * the final table. * end up in the final table. */ IConfigFilter* config_filter = nullptr; }; Loading
tools/aapt2/split/TableSplitter_test.cpp +46 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ TEST(TableSplitterTest, NoSplitPreferredDensity) { .Build(); TableSplitterOptions options; options.preferred_density = ConfigDescription::DENSITY_XHIGH; options.preferred_densities.push_back(ConfigDescription::DENSITY_XHIGH); TableSplitter splitter({}, options); splitter.SplitTable(table.get()); Loading @@ -58,6 +58,51 @@ TEST(TableSplitterTest, NoSplitPreferredDensity) { EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one")); } TEST(TableSplitterTest, NoSplitMultiplePreferredDensities) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddFileReference("android:drawable/icon", "res/drawable-mdpi/icon.png", test::ParseConfigOrDie("mdpi")) .AddFileReference("android:drawable/icon", "res/drawable-hdpi/icon.png", test::ParseConfigOrDie("hdpi")) .AddFileReference("android:drawable/icon", "res/drawable-xhdpi/icon.png", test::ParseConfigOrDie("xhdpi")) .AddFileReference("android:drawable/icon", "res/drawable-xxhdpi/icon.png", test::ParseConfigOrDie("xxhdpi")) .AddSimple("android:string/one") .Build(); TableSplitterOptions options; options.preferred_densities.push_back(ConfigDescription::DENSITY_LOW); options.preferred_densities.push_back(ConfigDescription::DENSITY_XXXHIGH); TableSplitter splitter({}, options); splitter.SplitTable(table.get()); // Densities remaining: // "mdpi" is the closest available density for the requested "ldpi" density. EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("mdpi"))); // "xxhdpi" is the closest available density for the requested "xxxhdpi" density. EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("xxhdpi"))); EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one")); // Removed densities: EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("hdpi"))); EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( table.get(), "android:drawable/icon", test::ParseConfigOrDie("xhdpi"))); } TEST(TableSplitterTest, SplitTableByDensity) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() Loading
tools/aapt2/strip/Strip.cpp +4 −9 Original line number Diff line number Diff line Loading @@ -79,18 +79,13 @@ class StripCommand { context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK..."); } // TODO(lecesne): Add support for more than one density. if (options_.target_configs.size() > 1) { context_->GetDiagnostics()->Error(DiagMessage() << "Multiple densities not supported at the moment"); return 1; } // Stripping the APK using the TableSplitter with no splits and the target // density as the preferred density. The resource table is modified in // densities as the preferred densities. The resource table is modified in // place in the LoadedApk. TableSplitterOptions splitter_options; splitter_options.preferred_density = options_.target_configs[0].density; for (auto& config : options_.target_configs) { splitter_options.preferred_densities.push_back(config.density); } std::vector<SplitConstraints> splits; TableSplitter splitter(splits, splitter_options); splitter.SplitTable(apk->GetResourceTable()); Loading