223 lines
8.5 KiB
C++
223 lines
8.5 KiB
C++
/*
|
|
* Copyright (C) 2017 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/MultiApkGenerator.h"
|
|
|
|
#include <string>
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "LoadedApk.h"
|
|
#include "ResourceTable.h"
|
|
#include "configuration/ConfigurationParser.h"
|
|
#include "filter/Filter.h"
|
|
#include "format/Archive.h"
|
|
#include "format/binary/TableFlattener.h"
|
|
#include "process/IResourceTableConsumer.h"
|
|
#include "test/Context.h"
|
|
#include "test/Test.h"
|
|
|
|
namespace aapt {
|
|
namespace {
|
|
|
|
using ::aapt::configuration::Abi;
|
|
using ::aapt::configuration::AndroidSdk;
|
|
using ::aapt::configuration::Artifact;
|
|
using ::aapt::configuration::PostProcessingConfiguration;
|
|
using ::aapt::test::GetValue;
|
|
using ::aapt::test::GetValueForConfig;
|
|
using ::aapt::test::ParseConfigOrDie;
|
|
using ::testing::Eq;
|
|
using ::testing::IsNull;
|
|
using ::testing::Not;
|
|
using ::testing::NotNull;
|
|
using ::testing::PrintToString;
|
|
using ::testing::Return;
|
|
using ::testing::Test;
|
|
using ::testing::_;
|
|
|
|
/**
|
|
* Subclass the MultiApkGenerator class so that we can access the protected FilterTable method to
|
|
* directly test table filter.
|
|
*/
|
|
class MultiApkGeneratorWrapper : public MultiApkGenerator {
|
|
public:
|
|
MultiApkGeneratorWrapper(LoadedApk* apk, IAaptContext* context)
|
|
: MultiApkGenerator(apk, context) {
|
|
}
|
|
|
|
std::unique_ptr<ResourceTable> FilterTable(
|
|
const configuration::Artifact& artifact,
|
|
const configuration::PostProcessingConfiguration& config, const ResourceTable& old_table,
|
|
FilterChain* pChain) override {
|
|
return MultiApkGenerator::FilterTable(artifact, config, old_table, pChain);
|
|
}
|
|
};
|
|
|
|
/** MultiApkGenerator test fixture. */
|
|
class MultiApkGeneratorTest : public ::testing::Test {
|
|
public:
|
|
std::unique_ptr<ResourceTable> BuildTable() {
|
|
return test::ResourceTableBuilder()
|
|
.AddFileReference(kResourceName, "res/drawable-mdpi/icon.png", mdpi_)
|
|
.AddFileReference(kResourceName, "res/drawable-hdpi/icon.png", hdpi_)
|
|
.AddFileReference(kResourceName, "res/drawable-xhdpi/icon.png", xhdpi_)
|
|
.AddFileReference(kResourceName, "res/drawable-xxhdpi/icon.png", xxhdpi_)
|
|
.AddFileReference(kResourceName, "res/drawable-v19/icon.xml", v19_)
|
|
.AddFileReference(kResourceName, "res/drawable-v21/icon.xml", v21_)
|
|
.AddSimple("android:string/one")
|
|
.Build();
|
|
}
|
|
|
|
inline FileReference* ValueForConfig(ResourceTable* table, const ConfigDescription& config) {
|
|
return GetValueForConfig<FileReference>(table, kResourceName, config);
|
|
};
|
|
|
|
void SetUp() override {
|
|
}
|
|
|
|
protected:
|
|
static constexpr const char* kResourceName = "android:drawable/icon";
|
|
|
|
ConfigDescription default_ = ParseConfigOrDie("").CopyWithoutSdkVersion();
|
|
ConfigDescription mdpi_ = ParseConfigOrDie("mdpi").CopyWithoutSdkVersion();
|
|
ConfigDescription hdpi_ = ParseConfigOrDie("hdpi").CopyWithoutSdkVersion();
|
|
ConfigDescription xhdpi_ = ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion();
|
|
ConfigDescription xxhdpi_ = ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion();
|
|
ConfigDescription xxxhdpi_ = ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion();
|
|
ConfigDescription v19_ = ParseConfigOrDie("v19");
|
|
ConfigDescription v21_ = ParseConfigOrDie("v21");
|
|
};
|
|
|
|
TEST_F(MultiApkGeneratorTest, VersionFilterNewerVersion) {
|
|
std::unique_ptr<ResourceTable> table = BuildTable();
|
|
|
|
LoadedApk apk = {{"test.apk"}, {}, std::move(table)};
|
|
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(19).Build();
|
|
PostProcessingConfiguration empty_config;
|
|
TableFlattenerOptions table_flattener_options;
|
|
FilterChain chain;
|
|
|
|
Artifact x64 = test::ArtifactBuilder()
|
|
.SetName("${basename}.${sdk}.apk")
|
|
.SetDensityGroup("xhdpi")
|
|
.SetAndroidSdk("v23")
|
|
.Build();
|
|
|
|
auto config = test::PostProcessingConfigurationBuilder()
|
|
.SetLocaleGroup("en", {"en"})
|
|
.SetAbiGroup("x64", {Abi::kX86_64})
|
|
.SetDensityGroup("xhdpi", {"xhdpi"})
|
|
.SetAndroidSdk("v23", AndroidSdk::ForMinSdk(23))
|
|
.AddArtifact(x64)
|
|
.Build();
|
|
|
|
MultiApkGeneratorWrapper generator{&apk, ctx.get()};
|
|
std::unique_ptr<ResourceTable> split =
|
|
generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain);
|
|
|
|
ResourceTable* new_table = split.get();
|
|
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, v19_), IsNull());
|
|
|
|
// xhdpi directly matches one of the required dimensions.
|
|
EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
|
|
// drawable-v21 was converted to drawable.
|
|
EXPECT_THAT(ValueForConfig(new_table, default_), NotNull());
|
|
EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
|
|
}
|
|
|
|
TEST_F(MultiApkGeneratorTest, VersionFilterOlderVersion) {
|
|
std::unique_ptr<ResourceTable> table = BuildTable();
|
|
|
|
LoadedApk apk = {{"test.apk"}, {}, std::move(table)};
|
|
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
|
|
PostProcessingConfiguration empty_config;
|
|
TableFlattenerOptions table_flattener_options;
|
|
FilterChain chain;
|
|
|
|
Artifact x64 = test::ArtifactBuilder()
|
|
.SetName("${basename}.${sdk}.apk")
|
|
.SetDensityGroup("xhdpi")
|
|
.SetAndroidSdk("v4")
|
|
.Build();
|
|
|
|
auto config = test::PostProcessingConfigurationBuilder()
|
|
.SetLocaleGroup("en", {"en"})
|
|
.SetAbiGroup("x64", {Abi::kX86_64})
|
|
.SetDensityGroup("xhdpi", {"xhdpi"})
|
|
.SetAndroidSdk("v4", AndroidSdk::ForMinSdk(4))
|
|
.AddArtifact(x64)
|
|
.Build();
|
|
|
|
MultiApkGeneratorWrapper generator{&apk, ctx.get()};;
|
|
std::unique_ptr<ResourceTable> split =
|
|
generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain);
|
|
|
|
ResourceTable* new_table = split.get();
|
|
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
|
|
|
|
EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull());
|
|
EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
|
|
}
|
|
|
|
TEST_F(MultiApkGeneratorTest, VersionFilterNoVersion) {
|
|
std::unique_ptr<ResourceTable> table = BuildTable();
|
|
|
|
LoadedApk apk = {{"test.apk"}, {}, std::move(table)};
|
|
std::unique_ptr<IAaptContext> ctx = test::ContextBuilder().SetMinSdkVersion(1).Build();
|
|
PostProcessingConfiguration empty_config;
|
|
TableFlattenerOptions table_flattener_options;
|
|
FilterChain chain;
|
|
|
|
Artifact x64 =
|
|
test::ArtifactBuilder().SetName("${basename}.${sdk}.apk").SetDensityGroup("xhdpi").Build();
|
|
|
|
auto config = test::PostProcessingConfigurationBuilder()
|
|
.SetLocaleGroup("en", {"en"})
|
|
.SetAbiGroup("x64", {Abi::kX86_64})
|
|
.SetDensityGroup("xhdpi", {"xhdpi"})
|
|
.AddArtifact(x64)
|
|
.Build();
|
|
|
|
MultiApkGeneratorWrapper generator{&apk, ctx.get()};
|
|
std::unique_ptr<ResourceTable> split =
|
|
generator.FilterTable(x64, config, *apk.GetResourceTable(), &chain);
|
|
|
|
ResourceTable* new_table = split.get();
|
|
EXPECT_THAT(ValueForConfig(new_table, mdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, hdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxhdpi_), IsNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, xxxhdpi_), IsNull());
|
|
|
|
EXPECT_THAT(ValueForConfig(new_table, xhdpi_), NotNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, v19_), NotNull());
|
|
EXPECT_THAT(ValueForConfig(new_table, v21_), NotNull());
|
|
EXPECT_THAT(GetValue<Id>(new_table, "android:string/one"), NotNull());
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace aapt
|