MultiApkGenerator_test.cpp revision 8780eb6e4918ae24fb1ae74d631042c32e41dc3d
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "optimize/MultiApkGenerator.h" 18 19#include <string> 20 21#include "gmock/gmock.h" 22#include "gtest/gtest.h" 23 24#include "LoadedApk.h" 25#include "ResourceTable.h" 26#include "configuration/ConfigurationParser.h" 27#include "filter/Filter.h" 28#include "format/Archive.h" 29#include "format/binary/TableFlattener.h" 30#include "process/IResourceTableConsumer.h" 31#include "test/Context.h" 32#include "test/Test.h" 33 34namespace aapt { 35namespace { 36 37using ::aapt::configuration::Abi; 38using ::aapt::configuration::AndroidSdk; 39using ::aapt::configuration::Artifact; 40using ::aapt::configuration::PostProcessingConfiguration; 41using ::aapt::test::GetValue; 42using ::aapt::test::GetValueForConfig; 43using ::aapt::test::ParseConfigOrDie; 44using ::testing::Eq; 45using ::testing::IsNull; 46using ::testing::Not; 47using ::testing::NotNull; 48using ::testing::PrintToString; 49using ::testing::Return; 50using ::testing::Test; 51using ::testing::_; 52 53/** 54 * Subclass the MultiApkGenerator class so that we can access the protected FilterTable method to 55 * directly test table filter. 56 */ 57class MultiApkGeneratorWrapper : public MultiApkGenerator { 58 public: 59 MultiApkGeneratorWrapper(LoadedApk* apk, IAaptContext* context) 60 : MultiApkGenerator(apk, context) { 61 } 62 63 std::unique_ptr<ResourceTable> FilterTable( 64 const configuration::Artifact& artifact, 65 const configuration::PostProcessingConfiguration& config, const ResourceTable& old_table, 66 FilterChain* pChain) override { 67 return MultiApkGenerator::FilterTable(artifact, config, old_table, pChain); 68 } 69}; 70 71/** MultiApkGenerator test fixture. */ 72class MultiApkGeneratorTest : public ::testing::Test { 73 public: 74 std::unique_ptr<ResourceTable> BuildTable() { 75 return test::ResourceTableBuilder() 76 .AddFileReference(kResourceName, "res/drawable-mdpi/icon.png", mdpi_) 77 .AddFileReference(kResourceName, "res/drawable-hdpi/icon.png", hdpi_) 78 .AddFileReference(kResourceName, "res/drawable-xhdpi/icon.png", xhdpi_) 79 .AddFileReference(kResourceName, "res/drawable-xxhdpi/icon.png", xxhdpi_) 80 .AddFileReference(kResourceName, "res/drawable-v19/icon.xml", v19_) 81 .AddFileReference(kResourceName, "res/drawable-v21/icon.xml", v21_) 82 .AddSimple("android:string/one") 83 .Build(); 84 } 85 86 inline FileReference* ValueForConfig(ResourceTable* table, const ConfigDescription& config) { 87 return GetValueForConfig<FileReference>(table, kResourceName, config); 88 }; 89 90 void SetUp() override { 91 } 92 93 protected: 94 static constexpr const char* kResourceName = "android:drawable/icon"; 95 96 ConfigDescription default_ = ParseConfigOrDie("").CopyWithoutSdkVersion(); 97 ConfigDescription mdpi_ = ParseConfigOrDie("mdpi").CopyWithoutSdkVersion(); 98 ConfigDescription hdpi_ = ParseConfigOrDie("hdpi").CopyWithoutSdkVersion(); 99 ConfigDescription xhdpi_ = ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(); 100 ConfigDescription xxhdpi_ = ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(); 101 ConfigDescription xxxhdpi_ = ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion(); 102 ConfigDescription v19_ = ParseConfigOrDie("v19"); 103 ConfigDescription v21_ = ParseConfigOrDie("v21"); 104}; 105 106TEST_F(MultiApkGeneratorTest, VersionFilterNewerVersion) { 107 std::unique_ptr<ResourceTable> table = BuildTable(); 108 109 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}}; 110 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(19).Build(); 111 PostProcessingConfiguration empty_config; 112 TableFlattenerOptions table_flattener_options; 113 FilterChain chain; 114 115 Artifact x64 = test::ArtifactBuilder() 116 .SetName("${basename}.${sdk}.apk") 117 .SetDensityGroup("xhdpi") 118 .SetAndroidSdk("v23") 119 .Build(); 120 121 auto config = test::PostProcessingConfigurationBuilder() 122 .SetLocaleGroup("en", {"en"}) 123 .SetAbiGroup("x64", {Abi::kX86_64}) 124 .SetDensityGroup("xhdpi", {"xhdpi"}) 125 .SetAndroidSdk("v23", AndroidSdk::ForMinSdk(23)) 126 .AddArtifact(x64) 127 .Build(); 128 129 MultiApkGeneratorWrapper generator{&apk, ctx.get()}; 130 std::unique_ptr<ResourceTable> split = 131 generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain); 132 133 ResourceTable* new_table = split.get(); 134 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull()); 135 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull()); 136 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull()); 137 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull()); 138 EXPECT_THAT(ValueForConfig(new_table, v19_), IsNull()); 139 140 // xhdpi directly matches one of the required dimensions. 141 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull()); 142 // drawable-v21 was converted to drawable. 143 EXPECT_THAT(ValueForConfig(new_table, default_), NotNull()); 144 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull()); 145} 146 147TEST_F(MultiApkGeneratorTest, VersionFilterOlderVersion) { 148 std::unique_ptr<ResourceTable> table = BuildTable(); 149 150 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}}; 151 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build(); 152 PostProcessingConfiguration empty_config; 153 TableFlattenerOptions table_flattener_options; 154 FilterChain chain; 155 156 Artifact x64 = test::ArtifactBuilder() 157 .SetName("${basename}.${sdk}.apk") 158 .SetDensityGroup("xhdpi") 159 .SetAndroidSdk("v4") 160 .Build(); 161 162 auto config = test::PostProcessingConfigurationBuilder() 163 .SetLocaleGroup("en", {"en"}) 164 .SetAbiGroup("x64", {Abi::kX86_64}) 165 .SetDensityGroup("xhdpi", {"xhdpi"}) 166 .SetAndroidSdk("v4", AndroidSdk::ForMinSdk(4)) 167 .AddArtifact(x64) 168 .Build(); 169 170 MultiApkGeneratorWrapper generator{&apk, ctx.get()};; 171 std::unique_ptr<ResourceTable> split = 172 generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain); 173 174 ResourceTable* new_table = split.get(); 175 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull()); 176 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull()); 177 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull()); 178 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull()); 179 180 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull()); 181 EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull()); 182 EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull()); 183 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull()); 184} 185 186TEST_F(MultiApkGeneratorTest, VersionFilterNoVersion) { 187 std::unique_ptr<ResourceTable> table = BuildTable(); 188 189 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}}; 190 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build(); 191 PostProcessingConfiguration empty_config; 192 TableFlattenerOptions table_flattener_options; 193 FilterChain chain; 194 195 Artifact x64 = 196 test::ArtifactBuilder().SetName("${basename}.${sdk}.apk").SetDensityGroup("xhdpi").Build(); 197 198 auto config = test::PostProcessingConfigurationBuilder() 199 .SetLocaleGroup("en", {"en"}) 200 .SetAbiGroup("x64", {Abi::kX86_64}) 201 .SetDensityGroup("xhdpi", {"xhdpi"}) 202 .AddArtifact(x64) 203 .Build(); 204 205 MultiApkGeneratorWrapper generator{&apk, ctx.get()}; 206 std::unique_ptr<ResourceTable> split = 207 generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain); 208 209 ResourceTable* new_table = split.get(); 210 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull()); 211 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull()); 212 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull()); 213 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull()); 214 215 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull()); 216 EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull()); 217 EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull()); 218 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull()); 219} 220 221} // namespace 222} // namespace aapt 223