blob: 2d303e220f8f7acaeabfeb604889c53e5af48472 [file] [log] [blame]
Shane Farmer0a5b2012017-06-22 12:24:12 -07001/*
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"
Adam Lesinski46708052017-09-29 14:49:15 -070028#include "format/Archive.h"
29#include "format/binary/TableFlattener.h"
Shane Farmer0a5b2012017-06-22 12:24:12 -070030#include "process/IResourceTableConsumer.h"
31#include "test/Context.h"
32#include "test/Test.h"
33
34namespace aapt {
35namespace {
36
37using ::aapt::configuration::Abi;
Shane Farmerefe45392017-08-21 14:39:28 -070038using ::aapt::configuration::AndroidSdk;
Shane Farmer0a5b2012017-06-22 12:24:12 -070039using ::aapt::configuration::Artifact;
40using ::aapt::configuration::PostProcessingConfiguration;
Shane Farmerefe45392017-08-21 14:39:28 -070041using ::aapt::test::GetValue;
42using ::aapt::test::GetValueForConfig;
43using ::aapt::test::ParseConfigOrDie;
Shane Farmer0a5b2012017-06-22 12:24:12 -070044using ::testing::Eq;
Shane Farmerefe45392017-08-21 14:39:28 -070045using ::testing::IsNull;
46using ::testing::Not;
47using ::testing::NotNull;
48using ::testing::PrintToString;
Shane Farmer0a5b2012017-06-22 12:24:12 -070049using ::testing::Return;
Shane Farmerefe45392017-08-21 14:39:28 -070050using ::testing::Test;
Shane Farmer0a5b2012017-06-22 12:24:12 -070051using ::testing::_;
52
Shane Farmerefe45392017-08-21 14:39:28 -070053/**
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,
Shane Farmer20ac0342017-11-29 16:55:05 -080066 IAaptContext* context, FilterChain* filter_chain) override {
67 return MultiApkGenerator::FilterTable(artifact, config, old_table, context, filter_chain);
Shane Farmerefe45392017-08-21 14:39:28 -070068 }
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
Shane Farmerefe45392017-08-21 14:39:28 -0700106TEST_F(MultiApkGeneratorTest, VersionFilterNewerVersion) {
107 std::unique_ptr<ResourceTable> table = BuildTable();
108
Adam Lesinski8780eb62017-10-31 17:44:39 -0700109 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
Shane Farmerefe45392017-08-21 14:39:28 -0700110 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"})
Shane Farmer3edd4722017-09-01 14:34:22 -0700125 .SetAndroidSdk("v23", AndroidSdk::ForMinSdk(23))
Shane Farmerefe45392017-08-21 14:39:28 -0700126 .AddArtifact(x64)
127 .Build();
128
129 MultiApkGeneratorWrapper generator{&apk, ctx.get()};
130 std::unique_ptr<ResourceTable> split =
Shane Farmer20ac0342017-11-29 16:55:05 -0800131 generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700132
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
Adam Lesinski8780eb62017-10-31 17:44:39 -0700150 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
Shane Farmerefe45392017-08-21 14:39:28 -0700151 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"})
Shane Farmer3edd4722017-09-01 14:34:22 -0700166 .SetAndroidSdk("v4", AndroidSdk::ForMinSdk(4))
Shane Farmerefe45392017-08-21 14:39:28 -0700167 .AddArtifact(x64)
168 .Build();
169
170 MultiApkGeneratorWrapper generator{&apk, ctx.get()};;
171 std::unique_ptr<ResourceTable> split =
Shane Farmer20ac0342017-11-29 16:55:05 -0800172 generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700173
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
Adam Lesinski8780eb62017-10-31 17:44:39 -0700189 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}};
Shane Farmerefe45392017-08-21 14:39:28 -0700190 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 =
Shane Farmer20ac0342017-11-29 16:55:05 -0800207 generator.FilterTable(x64, config, *apk.GetResourceTable(), ctx.get(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700208
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());
Shane Farmer0a5b2012017-06-22 12:24:12 -0700219}
220
221} // namespace
222} // namespace aapt