blob: 7d87eb8831e80c69fd12a363d0ac640c7d91de02 [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
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +020034using ::android::ConfigDescription;
35
Shane Farmer0a5b2012017-06-22 12:24:12 -070036namespace aapt {
37namespace {
38
39using ::aapt::configuration::Abi;
Shane Farmerefe45392017-08-21 14:39:28 -070040using ::aapt::configuration::AndroidSdk;
Shane Farmercb6c3f92017-11-27 13:19:36 -080041using ::aapt::configuration::OutputArtifact;
Shane Farmerefe45392017-08-21 14:39:28 -070042using ::aapt::test::GetValue;
43using ::aapt::test::GetValueForConfig;
44using ::aapt::test::ParseConfigOrDie;
Shane Farmer0a5b2012017-06-22 12:24:12 -070045using ::testing::Eq;
Shane Farmerefe45392017-08-21 14:39:28 -070046using ::testing::IsNull;
47using ::testing::Not;
48using ::testing::NotNull;
49using ::testing::PrintToString;
Shane Farmer0a5b2012017-06-22 12:24:12 -070050using ::testing::Return;
Shane Farmerefe45392017-08-21 14:39:28 -070051using ::testing::Test;
Shane Farmer0a5b2012017-06-22 12:24:12 -070052
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
Shane Farmercb6c3f92017-11-27 13:19:36 -080063 std::unique_ptr<ResourceTable> FilterTable(IAaptContext* context,
64 const configuration::OutputArtifact& artifact,
65 const ResourceTable& old_table,
66 FilterChain* filter_chain) override {
67 return MultiApkGenerator::FilterTable(context, artifact, old_table, 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
corysmith@google.comf7db43e2018-03-13 12:04:10 -0400109 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}, kBinary};
Shane Farmerefe45392017-08-21 14:39:28 -0700110 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(19).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700111 FilterChain chain;
112
Shane Farmercb6c3f92017-11-27 13:19:36 -0800113 OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).SetAndroidSdk(23).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700114
115 MultiApkGeneratorWrapper generator{&apk, ctx.get()};
116 std::unique_ptr<ResourceTable> split =
Shane Farmercb6c3f92017-11-27 13:19:36 -0800117 generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700118
119 ResourceTable* new_table = split.get();
120 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
121 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
122 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
123 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
124 EXPECT_THAT(ValueForConfig(new_table, v19_), IsNull());
125
126 // xhdpi directly matches one of the required dimensions.
127 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
128 // drawable-v21 was converted to drawable.
129 EXPECT_THAT(ValueForConfig(new_table, default_), NotNull());
130 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
131}
132
133TEST_F(MultiApkGeneratorTest, VersionFilterOlderVersion) {
134 std::unique_ptr<ResourceTable> table = BuildTable();
135
corysmith@google.comf7db43e2018-03-13 12:04:10 -0400136 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}, kBinary};
Shane Farmerefe45392017-08-21 14:39:28 -0700137 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700138 FilterChain chain;
139
Shane Farmercb6c3f92017-11-27 13:19:36 -0800140 OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).SetAndroidSdk(4).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700141
142 MultiApkGeneratorWrapper generator{&apk, ctx.get()};;
143 std::unique_ptr<ResourceTable> split =
Shane Farmercb6c3f92017-11-27 13:19:36 -0800144 generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700145
146 ResourceTable* new_table = split.get();
147 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
148 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
149 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
150 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
151
152 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
153 EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull());
154 EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull());
155 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
156}
157
158TEST_F(MultiApkGeneratorTest, VersionFilterNoVersion) {
159 std::unique_ptr<ResourceTable> table = BuildTable();
160
corysmith@google.comf7db43e2018-03-13 12:04:10 -0400161 LoadedApk apk = {{"test.apk"}, {}, std::move(table), {}, kBinary};
Shane Farmerefe45392017-08-21 14:39:28 -0700162 std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700163 FilterChain chain;
164
Shane Farmercb6c3f92017-11-27 13:19:36 -0800165 OutputArtifact artifact = test::ArtifactBuilder().AddDensity(xhdpi_).Build();
Shane Farmerefe45392017-08-21 14:39:28 -0700166
167 MultiApkGeneratorWrapper generator{&apk, ctx.get()};
168 std::unique_ptr<ResourceTable> split =
Shane Farmercb6c3f92017-11-27 13:19:36 -0800169 generator.FilterTable(ctx.get(), artifact, *apk.GetResourceTable(), &chain);
Shane Farmerefe45392017-08-21 14:39:28 -0700170
171 ResourceTable* new_table = split.get();
172 EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
173 EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
174 EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
175 EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
176
177 EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
178 EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull());
179 EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull());
180 EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
Shane Farmer0a5b2012017-06-22 12:24:12 -0700181}
182
183} // namespace
184} // namespace aapt