diff options
Diffstat (limited to 'libs/androidfw/tests')
25 files changed, 508 insertions, 334 deletions
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk deleted file mode 100644 index 921fd147aa80..000000000000 --- a/libs/androidfw/tests/Android.mk +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright (C) 2014 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. -# - -# ========================================================== -# Setup some common variables for the different build -# targets here. -# ========================================================== -LOCAL_PATH:= $(call my-dir) - -testFiles := \ - ApkAssets_test.cpp \ - AppAsLib_test.cpp \ - Asset_test.cpp \ - AssetManager2_test.cpp \ - AttributeFinder_test.cpp \ - AttributeResolution_test.cpp \ - ByteBucketArray_test.cpp \ - Config_test.cpp \ - ConfigLocale_test.cpp \ - Idmap_test.cpp \ - LoadedArsc_test.cpp \ - ResourceUtils_test.cpp \ - ResTable_test.cpp \ - Split_test.cpp \ - StringPiece_test.cpp \ - TestHelpers.cpp \ - TestMain.cpp \ - Theme_test.cpp \ - TypeWrappers_test.cpp \ - ZipUtils_test.cpp - -benchmarkFiles := \ - AssetManager2_bench.cpp \ - BenchMain.cpp \ - BenchmarkHelpers.cpp \ - SparseEntry_bench.cpp \ - TestHelpers.cpp \ - Theme_bench.cpp - -androidfw_test_cflags := \ - -Wall \ - -Werror \ - -Wunused \ - -Wunreachable-code \ - -Wno-missing-field-initializers - -# gtest is broken. -androidfw_test_cflags += -Wno-unnamed-type-template-args - -# ========================================================== -# Build the host tests: libandroidfw_tests -# ========================================================== -include $(CLEAR_VARS) - -LOCAL_MODULE := libandroidfw_tests -LOCAL_CFLAGS := $(androidfw_test_cflags) -LOCAL_SRC_FILES := $(testFiles) -LOCAL_STATIC_LIBRARIES := \ - libandroidfw \ - libbase \ - libutils \ - libcutils \ - liblog \ - libz \ - libziparchive -LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data - -include $(BUILD_HOST_NATIVE_TEST) - -# ========================================================== -# Build the device tests: libandroidfw_tests -# ========================================================== -ifneq ($(SDK_ONLY),true) -include $(CLEAR_VARS) - -LOCAL_MODULE := libandroidfw_tests -LOCAL_CFLAGS := $(androidfw_test_cflags) -LOCAL_SRC_FILES := $(testFiles) \ - BackupData_test.cpp \ - ObbFile_test.cpp \ - -LOCAL_SHARED_LIBRARIES := \ - libandroidfw \ - libbase \ - libcutils \ - libutils \ - libui \ - libziparchive -LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data - -include $(BUILD_NATIVE_TEST) - -# ========================================================== -# Build the device benchmarks: libandroidfw_benchmarks -# ========================================================== -include $(CLEAR_VARS) - -LOCAL_MODULE := libandroidfw_benchmarks -LOCAL_CFLAGS := $(androidfw_test_cflags) -LOCAL_SRC_FILES := $(benchmarkFiles) -LOCAL_STATIC_LIBRARIES := \ - libgoogle-benchmark -LOCAL_SHARED_LIBRARIES := \ - libandroidfw \ - libbase \ - libcutils \ - libutils \ - libziparchive -LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data - -include $(BUILD_NATIVE_TEST) -endif # Not SDK_ONLY - diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp index c85b0b98ca5e..6c43a67e602f 100644 --- a/libs/androidfw/tests/ApkAssets_test.cpp +++ b/libs/androidfw/tests/ApkAssets_test.cpp @@ -17,12 +17,15 @@ #include "androidfw/ApkAssets.h" #include "android-base/file.h" +#include "android-base/test_utils.h" #include "android-base/unique_fd.h" +#include "androidfw/Util.h" #include "TestHelpers.h" #include "data/basic/R.h" -using com::android::basic::R; +using ::android::base::unique_fd; +using ::com::android::basic::R; namespace android { @@ -30,7 +33,31 @@ TEST(ApkAssetsTest, LoadApk) { std::unique_ptr<const ApkAssets> loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); ASSERT_NE(nullptr, loaded_apk); - EXPECT_NE(nullptr, loaded_apk->GetLoadedArsc()); + + const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc(); + ASSERT_NE(nullptr, loaded_arsc); + + const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000); + ASSERT_NE(nullptr, loaded_package); + + std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml"); + ASSERT_NE(nullptr, asset); +} + +TEST(ApkAssetsTest, LoadApkFromFd) { + const std::string path = GetTestDataPath() + "/basic/basic.apk"; + unique_fd fd(::open(path.c_str(), O_RDONLY | O_BINARY)); + ASSERT_GE(fd.get(), 0); + + std::unique_ptr<const ApkAssets> loaded_apk = + ApkAssets::LoadFromFd(std::move(fd), path, false /*system*/, false /*force_shared_lib*/); + ASSERT_NE(nullptr, loaded_apk); + + const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc(); + ASSERT_NE(nullptr, loaded_arsc); + + const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000); + ASSERT_NE(nullptr, loaded_package); std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml"); ASSERT_NE(nullptr, asset); @@ -54,6 +81,37 @@ TEST(ApkAssetsTest, LoadApkAsSharedLibrary) { EXPECT_TRUE(loaded_arsc->GetPackages()[0]->IsDynamic()); } +TEST(ApkAssetsTest, LoadApkWithIdmap) { + std::string contents; + ResTable target_table; + const std::string target_path = GetTestDataPath() + "/basic/basic.apk"; + ASSERT_TRUE(ReadFileFromZipToString(target_path, "resources.arsc", &contents)); + ASSERT_EQ(NO_ERROR, target_table.add(contents.data(), contents.size(), 0, true /*copyData*/)); + + ResTable overlay_table; + const std::string overlay_path = GetTestDataPath() + "/overlay/overlay.apk"; + ASSERT_TRUE(ReadFileFromZipToString(overlay_path, "resources.arsc", &contents)); + ASSERT_EQ(NO_ERROR, overlay_table.add(contents.data(), contents.size(), 0, true /*copyData*/)); + + util::unique_cptr<void> idmap_data; + void* temp_data; + size_t idmap_len; + + ASSERT_EQ(NO_ERROR, target_table.createIdmap(overlay_table, 0u, 0u, target_path.c_str(), + overlay_path.c_str(), &temp_data, &idmap_len)); + idmap_data.reset(temp_data); + + TemporaryFile tf; + ASSERT_TRUE(base::WriteFully(tf.fd, idmap_data.get(), idmap_len)); + close(tf.fd); + + // Open something so that the destructor of TemporaryFile closes a valid fd. + tf.fd = open("/dev/null", O_WRONLY); + + std::unique_ptr<const ApkAssets> loaded_overlay_apk = ApkAssets::LoadOverlay(tf.path); + ASSERT_NE(nullptr, loaded_overlay_apk); +} + TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) { std::unique_ptr<const ApkAssets> loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); @@ -79,7 +137,7 @@ TEST(ApkAssetsTest, OpenUncompressedAssetFd) { ASSERT_NE(nullptr, asset); off64_t start, length; - base::unique_fd fd(asset->openFileDescriptor(&start, &length)); + unique_fd fd(asset->openFileDescriptor(&start, &length)); EXPECT_GE(fd.get(), 0); lseek64(fd.get(), start, SEEK_SET); diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp index 67de741b1b66..85e8f25394e9 100644 --- a/libs/androidfw/tests/AssetManager2_bench.cpp +++ b/libs/androidfw/tests/AssetManager2_bench.cpp @@ -23,7 +23,6 @@ #include "androidfw/ResourceTypes.h" #include "BenchmarkHelpers.h" -#include "TestHelpers.h" #include "data/basic/R.h" #include "data/libclient/R.h" #include "data/styles/R.h" @@ -82,37 +81,6 @@ static void BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State& state) { } BENCHMARK(BM_AssetManagerLoadFrameworkAssetsOld); -static void GetResourceBenchmark(const std::vector<std::string>& paths, - const ResTable_config* config, uint32_t resid, - benchmark::State& state) { - std::vector<std::unique_ptr<const ApkAssets>> apk_assets; - std::vector<const ApkAssets*> apk_assets_ptrs; - for (const std::string& path : paths) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); - if (apk == nullptr) { - state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str()); - return; - } - apk_assets_ptrs.push_back(apk.get()); - apk_assets.push_back(std::move(apk)); - } - - AssetManager2 assetmanager; - assetmanager.SetApkAssets(apk_assets_ptrs); - if (config != nullptr) { - assetmanager.SetConfiguration(*config); - } - - Res_value value; - ResTable_config selected_config; - uint32_t flags; - - while (state.KeepRunning()) { - assetmanager.GetResource(resid, false /* may_be_bag */, 0u /* density_override */, &value, - &selected_config, &flags); - } -} - static void BM_AssetManagerGetResource(benchmark::State& state) { GetResourceBenchmark({GetTestDataPath() + "/basic/basic.apk"}, nullptr /*config*/, basic::R::integer::number1, state); diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index fcae53b322b3..92462a6cfadf 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -317,7 +317,7 @@ TEST_F(AssetManager2Test, ResolveReferenceToResource) { EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); EXPECT_EQ(basic::R::integer::ref2, value.data); - uint32_t last_ref; + uint32_t last_ref = 0u; cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref); ASSERT_NE(kInvalidCookie, cookie); EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); @@ -340,7 +340,7 @@ TEST_F(AssetManager2Test, ResolveReferenceToBag) { EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); EXPECT_EQ(basic::R::array::integerArray1, value.data); - uint32_t last_ref; + uint32_t last_ref = 0u; cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref); ASSERT_NE(kInvalidCookie, cookie); EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); @@ -348,6 +348,25 @@ TEST_F(AssetManager2Test, ResolveReferenceToBag) { EXPECT_EQ(basic::R::array::integerArray1, last_ref); } +TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) { + AssetManager2 assetmanager; + assetmanager.SetApkAssets({basic_assets_.get()}); + + ResTable_config selected_config; + memset(&selected_config, 0, sizeof(selected_config)); + + uint32_t flags = 0u; + + // Create some kind of Res_value that is NOT a reference. + Res_value value; + value.dataType = Res_value::TYPE_STRING; + value.data = 0; + + uint32_t last_ref = basic::R::string::test1; + EXPECT_EQ(1, assetmanager.ResolveReference(1, &value, &selected_config, &flags, &last_ref)); + EXPECT_EQ(basic::R::string::test1, last_ref); +} + static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations, const ResTable_config& configuration) { return configurations.count(configuration) > 0; diff --git a/libs/androidfw/tests/BenchMain.cpp b/libs/androidfw/tests/BenchMain.cpp index 105c5f9551b7..58fc54a4a04c 100644 --- a/libs/androidfw/tests/BenchMain.cpp +++ b/libs/androidfw/tests/BenchMain.cpp @@ -18,7 +18,7 @@ #include "benchmark/benchmark.h" -#include "TestHelpers.h" +#include "BenchmarkHelpers.h" int main(int argc, char** argv) { ::benchmark::Initialize(&argc, argv); diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp index 3619b7ee83ab..7149beef797f 100644 --- a/libs/androidfw/tests/BenchmarkHelpers.cpp +++ b/libs/androidfw/tests/BenchmarkHelpers.cpp @@ -18,6 +18,7 @@ #include "android-base/stringprintf.h" #include "androidfw/AssetManager.h" +#include "androidfw/AssetManager2.h" namespace android { @@ -48,4 +49,34 @@ void GetResourceBenchmarkOld(const std::vector<std::string>& paths, const ResTab } } +void GetResourceBenchmark(const std::vector<std::string>& paths, const ResTable_config* config, + uint32_t resid, benchmark::State& state) { + std::vector<std::unique_ptr<const ApkAssets>> apk_assets; + std::vector<const ApkAssets*> apk_assets_ptrs; + for (const std::string& path : paths) { + std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); + if (apk == nullptr) { + state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str()); + return; + } + apk_assets_ptrs.push_back(apk.get()); + apk_assets.push_back(std::move(apk)); + } + + AssetManager2 assetmanager; + assetmanager.SetApkAssets(apk_assets_ptrs); + if (config != nullptr) { + assetmanager.SetConfiguration(*config); + } + + Res_value value; + ResTable_config selected_config; + uint32_t flags; + + while (state.KeepRunning()) { + assetmanager.GetResource(resid, false /* may_be_bag */, 0u /* density_override */, &value, + &selected_config, &flags); + } +} + } // namespace android diff --git a/libs/androidfw/tests/BenchmarkHelpers.h b/libs/androidfw/tests/BenchmarkHelpers.h index fc366642ca36..eb0939d0e23b 100644 --- a/libs/androidfw/tests/BenchmarkHelpers.h +++ b/libs/androidfw/tests/BenchmarkHelpers.h @@ -14,21 +14,25 @@ * limitations under the License. */ -#ifndef TESTS_BENCHMARKHELPERS_H_ -#define TESTS_BENCHMARKHELPERS_H_ +#ifndef ANDROIDFW_TESTS_BENCHMARKHELPERS_H +#define ANDROIDFW_TESTS_BENCHMARKHELPERS_H #include <string> #include <vector> +#include "androidfw/ResourceTypes.h" #include "benchmark/benchmark.h" -#include "androidfw/ResourceTypes.h" +#include "CommonHelpers.h" namespace android { void GetResourceBenchmarkOld(const std::vector<std::string>& paths, const ResTable_config* config, - uint32_t resid, benchmark::State& state); + uint32_t resid, ::benchmark::State& state); + +void GetResourceBenchmark(const std::vector<std::string>& paths, const ResTable_config* config, + uint32_t resid, benchmark::State& state); } // namespace android -#endif /* TESTS_BENCHMARKHELPERS_H_ */ +#endif // ANDROIDFW_TESTS_BENCHMARKHELPERS_H diff --git a/libs/androidfw/tests/CommonHelpers.cpp b/libs/androidfw/tests/CommonHelpers.cpp new file mode 100644 index 000000000000..faa5350f9ecc --- /dev/null +++ b/libs/androidfw/tests/CommonHelpers.cpp @@ -0,0 +1,65 @@ +/* + * 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 "CommonHelpers.h" + +#include <iostream> + +#include "android-base/file.h" +#include "android-base/logging.h" +#include "android-base/strings.h" + +namespace android { + +static std::string sTestDataPath; + +void InitializeTest(int* argc, char** argv) { + // Set the default test data path to be the executable path directory + data. + SetTestDataPath(base::GetExecutableDirectory() + "/tests/data"); + + for (int i = 1; i < *argc; i++) { + const std::string arg = argv[i]; + if (base::StartsWith(arg, "--testdata=")) { + SetTestDataPath(arg.substr(strlen("--testdata="))); + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + --(*argc); + --i; + } else if (arg == "-h" || arg == "--help") { + std::cerr << "\nAdditional options specific to this test:\n" + " --testdata=[PATH]\n" + " Specify the location of test data used within the tests.\n"; + exit(1); + } + } +} + +void SetTestDataPath(const std::string& path) { + sTestDataPath = path; +} + +const std::string& GetTestDataPath() { + CHECK(!sTestDataPath.empty()) << "no test data path set."; + return sTestDataPath; +} + +std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) { + String8 str = pool->string8ObjectAt(idx); + return std::string(str.string(), str.length()); +} + +} // namespace android diff --git a/libs/androidfw/tests/CommonHelpers.h b/libs/androidfw/tests/CommonHelpers.h new file mode 100644 index 000000000000..c160fbba4c01 --- /dev/null +++ b/libs/androidfw/tests/CommonHelpers.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#ifndef ANDROIDFW_TEST_COMMON_HELPERS_H +#define ANDROIDFW_TEST_COMMON_HELPERS_H + +#include <ostream> +#include <string> + +#include "androidfw/ResourceTypes.h" +#include "utils/String16.h" +#include "utils/String8.h" + +namespace android { + +void InitializeTest(int* argc, char** argv); + +enum { MAY_NOT_BE_BAG = false }; + +void SetTestDataPath(const std::string& path); + +const std::string& GetTestDataPath(); + +std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx); + +static inline bool operator==(const ResTable_config& a, const ResTable_config& b) { + return a.compare(b) == 0; +} + +static inline ::std::ostream& operator<<(::std::ostream& out, const String8& str) { + return out << str.string(); +} + +static inline ::std::ostream& operator<<(::std::ostream& out, const String16& str) { + return out << String8(str).string(); +} + +static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) { + return out << c.toString(); +} + +} // namespace android + +#endif // ANDROIDFW_TEST_COMMON_HELPERS_H diff --git a/libs/androidfw/tests/ConfigLocale_test.cpp b/libs/androidfw/tests/ConfigLocale_test.cpp index 86a627e1485d..ac08c52772d1 100644 --- a/libs/androidfw/tests/ConfigLocale_test.cpp +++ b/libs/androidfw/tests/ConfigLocale_test.cpp @@ -173,6 +173,18 @@ TEST(ConfigLocaleTest, IsMoreSpecificThan) { fillIn("en", "US", NULL, "POSIX", &r); EXPECT_FALSE(l.isMoreSpecificThan(r)); EXPECT_TRUE(r.isMoreSpecificThan(l)); + + fillIn("ar", "EG", NULL, NULL, &l); + fillIn("ar", "EG", NULL, NULL, &r); + memcpy(&r.localeNumberingSystem, "latn", 4); + EXPECT_FALSE(l.isMoreSpecificThan(r)); + EXPECT_TRUE(r.isMoreSpecificThan(l)); + + fillIn("en", "US", NULL, NULL, &l); + fillIn("es", "ES", NULL, NULL, &r); + + EXPECT_FALSE(l.isMoreSpecificThan(r)); + EXPECT_FALSE(r.isMoreSpecificThan(l)); } TEST(ConfigLocaleTest, setLocale) { @@ -185,6 +197,7 @@ TEST(ConfigLocaleTest, setLocale) { EXPECT_TRUE(test.localeScriptWasComputed); EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); EXPECT_EQ(0, test.localeVariant[0]); + EXPECT_EQ(0, test.localeNumberingSystem[0]); test.setBcp47Locale("eng-419"); char out[4] = {1, 1, 1, 1}; @@ -198,6 +211,7 @@ TEST(ConfigLocaleTest, setLocale) { EXPECT_EQ('4', out[0]); EXPECT_EQ('1', out[1]); EXPECT_EQ('9', out[2]); + EXPECT_EQ(0, test.localeNumberingSystem[0]); test.setBcp47Locale("en-Latn-419"); EXPECT_EQ('e', test.language[0]); @@ -209,6 +223,7 @@ TEST(ConfigLocaleTest, setLocale) { EXPECT_EQ('4', out[0]); EXPECT_EQ('1', out[1]); EXPECT_EQ('9', out[2]); + EXPECT_EQ(0, test.localeNumberingSystem[0]); test.setBcp47Locale("de-1901"); memset(out, 1, 4); @@ -222,6 +237,7 @@ TEST(ConfigLocaleTest, setLocale) { test.unpackRegion(out); EXPECT_EQ('\0', out[0]); EXPECT_EQ(0, strcmp("1901", test.localeVariant)); + EXPECT_EQ(0, test.localeNumberingSystem[0]); test.setBcp47Locale("de-Latn-1901"); memset(out, 1, 4); @@ -235,6 +251,44 @@ TEST(ConfigLocaleTest, setLocale) { test.unpackRegion(out); EXPECT_EQ('\0', out[0]); EXPECT_EQ(0, strcmp("1901", test.localeVariant)); + EXPECT_EQ(0, test.localeNumberingSystem[0]); + + test.setBcp47Locale("ar-EG-u-nu-latn"); + EXPECT_EQ('a', test.language[0]); + EXPECT_EQ('r', test.language[1]); + EXPECT_EQ('E', test.country[0]); + EXPECT_EQ('G', test.country[1]); + EXPECT_TRUE(test.localeScriptWasComputed); + EXPECT_EQ(0, memcmp("Arab", test.localeScript, 4)); + EXPECT_EQ(0, test.localeVariant[0]); + EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4)); + + test.setBcp47Locale("ar-EG-u"); + EXPECT_EQ(0, test.localeNumberingSystem[0]); + + test.setBcp47Locale("ar-EG-u-nu"); + EXPECT_EQ(0, test.localeNumberingSystem[0]); + + test.setBcp47Locale("ar-EG-u-attr-nu-latn"); + EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4)); + + test.setBcp47Locale("ar-EG-u-ca-gregory-nu-latn"); + EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4)); + + test.setBcp47Locale("ar-EG-u-nu-latn-ca-gregory"); + EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4)); + + test.setBcp47Locale("ar-EG-u-nu-toolongnumsys"); + EXPECT_EQ(0, test.localeNumberingSystem[0]); + + test.setBcp47Locale("ar-EG-u-nu-latn-nu-arab"); + EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4)); + + test.setBcp47Locale("ar-EG-u-co-nu-latn"); + EXPECT_EQ(0, test.localeNumberingSystem[0]); + + test.setBcp47Locale("ar-u-co-abcd-attr-nu-latn"); + EXPECT_EQ(0, test.localeNumberingSystem[0]); } TEST(ConfigLocaleTest, computeScript) { @@ -279,6 +333,22 @@ TEST(ConfigLocaleTest, getBcp47Locale_script) { EXPECT_EQ(0, strcmp("en", out)); } +TEST(ConfigLocaleTest, getBcp47Locale_numberingSystem) { + ResTable_config config; + fillIn("en", NULL, NULL, NULL, &config); + + char out[RESTABLE_MAX_LOCALE_LEN]; + + memcpy(&config.localeNumberingSystem, "latn", 4); + config.getBcp47Locale(out); + EXPECT_EQ(0, strcmp("en-u-nu-latn", out)); + + fillIn("sr", "SR", "Latn", NULL, &config); + memcpy(&config.localeNumberingSystem, "latn", 4); + config.getBcp47Locale(out); + EXPECT_EQ(0, strcmp("sr-Latn-SR-u-nu-latn", out)); +} + TEST(ConfigLocaleTest, getBcp47Locale_canonicalize) { ResTable_config config; char out[RESTABLE_MAX_LOCALE_LEN]; @@ -391,6 +461,11 @@ TEST(ConfigLocaleTest, match) { fillIn("ar", "XB", NULL, NULL, &requested); // Even if they are pseudo-locales, exactly equal locales match. EXPECT_TRUE(supported.match(requested)); + + fillIn("ar", "EG", NULL, NULL, &supported); + fillIn("ar", "TN", NULL, NULL, &requested); + memcpy(&supported.localeNumberingSystem, "latn", 4); + EXPECT_TRUE(supported.match(requested)); } TEST(ConfigLocaleTest, match_emptyScript) { @@ -716,6 +791,26 @@ TEST(ConfigLocaleTest, isLocaleBetterThan_regionComparison) { EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); } +TEST(ConfigLocaleTest, isLocaleBetterThan_numberingSystem) { + ResTable_config config1, config2, request; + + fillIn("ar", "EG", NULL, NULL, &request); + memcpy(&request.localeNumberingSystem, "latn", 4); + fillIn("ar", NULL, NULL, NULL, &config1); + memcpy(&config1.localeNumberingSystem, "latn", 4); + fillIn("ar", NULL, NULL, NULL, &config2); + EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); + EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); + + fillIn("ar", "EG", NULL, NULL, &request); + memcpy(&request.localeNumberingSystem, "latn", 4); + fillIn("ar", "TN", NULL, NULL, &config1); + memcpy(&config1.localeNumberingSystem, "latn", 4); + fillIn("ar", NULL, NULL, NULL, &config2); + EXPECT_TRUE(config2.isLocaleBetterThan(config1, &request)); + EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); +} + // Default resources are considered better matches for US English // and US-like English locales than International English locales TEST(ConfigLocaleTest, isLocaleBetterThan_UsEnglishIsSpecial) { diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp index d12be184745c..9eb4a13f34d1 100644 --- a/libs/androidfw/tests/Idmap_test.cpp +++ b/libs/androidfw/tests/Idmap_test.cpp @@ -22,7 +22,7 @@ #include "TestHelpers.h" #include "data/basic/R.h" -using com::android::basic::R; +using ::com::android::basic::R; namespace android { diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp index 756869f6377d..37ddafb14fd3 100644 --- a/libs/androidfw/tests/LoadedArsc_test.cpp +++ b/libs/androidfw/tests/LoadedArsc_test.cpp @@ -19,11 +19,13 @@ #include "TestHelpers.h" #include "data/basic/R.h" #include "data/libclient/R.h" +#include "data/sparse/R.h" #include "data/styles/R.h" namespace app = com::android::app; namespace basic = com::android::basic; namespace libclient = com::android::libclient; +namespace sparse = com::android::sparse; namespace android { @@ -32,8 +34,7 @@ TEST(LoadedArscTest, LoadSinglePackageArsc) { ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = - LoadedArsc::Load(contents.data(), contents.size()); + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); ASSERT_NE(nullptr, loaded_arsc); const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages(); @@ -45,12 +46,9 @@ TEST(LoadedArscTest, LoadSinglePackageArsc) { memset(&config, 0, sizeof(config)); config.sdkVersion = 24; - LoadedArscEntry entry; - ResTable_config selected_config; - uint32_t flags; + FindEntryResult entry; - ASSERT_TRUE( - loaded_arsc->FindEntry(app::R::string::string_one, config, &entry, &selected_config, &flags)); + ASSERT_TRUE(loaded_arsc->FindEntry(app::R::string::string_one, config, &entry)); ASSERT_NE(nullptr, entry.entry); } @@ -59,8 +57,7 @@ TEST(LoadedArscTest, FindDefaultEntry) { ASSERT_TRUE( ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = - LoadedArsc::Load(contents.data(), contents.size()); + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); ASSERT_NE(nullptr, loaded_arsc); ResTable_config desired_config; @@ -68,12 +65,25 @@ TEST(LoadedArscTest, FindDefaultEntry) { desired_config.language[0] = 'd'; desired_config.language[1] = 'e'; - LoadedArscEntry entry; - ResTable_config selected_config; - uint32_t flags; + FindEntryResult entry; + ASSERT_TRUE(loaded_arsc->FindEntry(basic::R::string::test1, desired_config, &entry)); + ASSERT_NE(nullptr, entry.entry); +} + +TEST(LoadedArscTest, LoadSparseEntryApp) { + std::string contents; + ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc", + &contents)); + + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); + ASSERT_NE(nullptr, loaded_arsc); + + ResTable_config config; + memset(&config, 0, sizeof(config)); + config.sdkVersion = 26; - ASSERT_TRUE(loaded_arsc->FindEntry(basic::R::string::test1, desired_config, &entry, - &selected_config, &flags)); + FindEntryResult entry; + ASSERT_TRUE(loaded_arsc->FindEntry(sparse::R::integer::foo_9, config, &entry)); ASSERT_NE(nullptr, entry.entry); } @@ -82,8 +92,7 @@ TEST(LoadedArscTest, LoadSharedLibrary) { ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = - LoadedArsc::Load(contents.data(), contents.size()); + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); ASSERT_NE(nullptr, loaded_arsc); const auto& packages = loaded_arsc->GetPackages(); @@ -104,8 +113,7 @@ TEST(LoadedArscTest, LoadAppLinkedAgainstSharedLibrary) { ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/libclient/libclient.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = - LoadedArsc::Load(contents.data(), contents.size()); + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); ASSERT_NE(nullptr, loaded_arsc); const auto& packages = loaded_arsc->GetPackages(); @@ -132,8 +140,9 @@ TEST(LoadedArscTest, LoadAppAsSharedLibrary) { ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/appaslib/appaslib.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load( - contents.data(), contents.size(), false /*system*/, true /*load_as_shared_library*/); + std::unique_ptr<const LoadedArsc> loaded_arsc = + LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/, + true /*load_as_shared_library*/); ASSERT_NE(nullptr, loaded_arsc); const auto& packages = loaded_arsc->GetPackages(); @@ -147,33 +156,68 @@ TEST(LoadedArscTest, LoadFeatureSplit) { std::string contents; ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", "resources.arsc", &contents)); - std::unique_ptr<const LoadedArsc> loaded_arsc = - LoadedArsc::Load(contents.data(), contents.size()); + std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents)); ASSERT_NE(nullptr, loaded_arsc); ResTable_config desired_config; memset(&desired_config, 0, sizeof(desired_config)); - LoadedArscEntry entry; - ResTable_config selected_config; - uint32_t flags; - - ASSERT_TRUE(loaded_arsc->FindEntry(basic::R::string::test3, desired_config, &entry, - &selected_config, &flags)); + FindEntryResult entry; + ASSERT_TRUE(loaded_arsc->FindEntry(basic::R::string::test3, desired_config, &entry)); size_t len; const char16_t* type_name16 = entry.type_string_ref.string16(&len); ASSERT_NE(nullptr, type_name16); ASSERT_NE(0u, len); - size_t utf8_len = utf16_to_utf8_length(type_name16, len); - std::string type_name; - type_name.resize(utf8_len); - utf16_to_utf8(type_name16, len, &*type_name.begin(), utf8_len + 1); - + std::string type_name = util::Utf16ToUtf8(StringPiece16(type_name16, len)); EXPECT_EQ(std::string("string"), type_name); } +class MockLoadedIdmap : public LoadedIdmap { + public: + MockLoadedIdmap() : LoadedIdmap() { + local_header_.magic = kIdmapMagic; + local_header_.version = kIdmapCurrentVersion; + local_header_.target_package_id = 0x08; + local_header_.type_count = 1; + header_ = &local_header_; + + entry_header = util::unique_cptr<IdmapEntry_header>( + (IdmapEntry_header*)::malloc(sizeof(IdmapEntry_header) + sizeof(uint32_t))); + entry_header->target_type_id = 0x03; + entry_header->overlay_type_id = 0x02; + entry_header->entry_id_offset = 1; + entry_header->entry_count = 1; + entry_header->entries[0] = 0x00000000u; + type_map_[entry_header->overlay_type_id] = entry_header.get(); + } + + private: + Idmap_header local_header_; + util::unique_cptr<IdmapEntry_header> entry_header; +}; + +TEST(LoadedArscTest, LoadOverlay) { + std::string contents, overlay_contents; + ASSERT_TRUE( + ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents)); + ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk", "resources.arsc", + &overlay_contents)); + + MockLoadedIdmap loaded_idmap; + + std::unique_ptr<const LoadedArsc> loaded_arsc = + LoadedArsc::Load(StringPiece(overlay_contents), &loaded_idmap); + ASSERT_NE(nullptr, loaded_arsc); + + ResTable_config desired_config; + memset(&desired_config, 0, sizeof(desired_config)); + + FindEntryResult entry; + ASSERT_TRUE(loaded_arsc->FindEntry(0x08030001u, desired_config, &entry)); +} + // structs with size fields (like Res_value, ResTable_entry) should be // backwards and forwards compatible (aka checking the size field against // sizeof(Res_value) might not be backwards compatible. diff --git a/libs/androidfw/tests/SparseEntry_bench.cpp b/libs/androidfw/tests/SparseEntry_bench.cpp index 1ebf7ce623bd..c9b4ad8af278 100644 --- a/libs/androidfw/tests/SparseEntry_bench.cpp +++ b/libs/androidfw/tests/SparseEntry_bench.cpp @@ -18,47 +18,46 @@ #include "androidfw/ResourceTypes.h" #include "BenchmarkHelpers.h" -#include "TestHelpers.h" #include "data/sparse/R.h" namespace sparse = com::android::sparse; namespace android { -static void BM_SparseEntryGetResourceSparseSmall(benchmark::State& state) { +static void BM_SparseEntryGetResourceOldSparse(benchmark::State& state, uint32_t resid) { ResTable_config config; memset(&config, 0, sizeof(config)); config.sdkVersion = 26; - GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/sparse.apk"}, &config, - sparse::R::integer::foo_9, state); + GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/sparse.apk"}, &config, resid, state); } -BENCHMARK(BM_SparseEntryGetResourceSparseSmall); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparse, Small, sparse::R::integer::foo_9); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparse, Large, sparse::R::string::foo_999); -static void BM_SparseEntryGetResourceNotSparseSmall(benchmark::State& state) { +static void BM_SparseEntryGetResourceOldNotSparse(benchmark::State& state, uint32_t resid) { ResTable_config config; memset(&config, 0, sizeof(config)); config.sdkVersion = 26; - GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, - sparse::R::integer::foo_9, state); + GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, resid, state); } -BENCHMARK(BM_SparseEntryGetResourceNotSparseSmall); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparse, Small, sparse::R::integer::foo_9); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparse, Large, sparse::R::string::foo_999); -static void BM_SparseEntryGetResourceSparseLarge(benchmark::State& state) { +static void BM_SparseEntryGetResourceSparse(benchmark::State& state, uint32_t resid) { ResTable_config config; memset(&config, 0, sizeof(config)); config.sdkVersion = 26; - GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/sparse.apk"}, &config, - sparse::R::string::foo_999, state); + GetResourceBenchmark({GetTestDataPath() + "/sparse/sparse.apk"}, &config, resid, state); } -BENCHMARK(BM_SparseEntryGetResourceSparseLarge); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparse, Small, sparse::R::integer::foo_9); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparse, Large, sparse::R::string::foo_999); -static void BM_SparseEntryGetResourceNotSparseLarge(benchmark::State& state) { +static void BM_SparseEntryGetResourceNotSparse(benchmark::State& state, uint32_t resid) { ResTable_config config; memset(&config, 0, sizeof(config)); config.sdkVersion = 26; - GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, - sparse::R::string::foo_999, state); + GetResourceBenchmark({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, resid, state); } -BENCHMARK(BM_SparseEntryGetResourceNotSparseLarge); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparse, Small, sparse::R::integer::foo_9); +BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparse, Large, sparse::R::string::foo_999); } // namespace android diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp index 1e763a5e53a8..9e320a21b534 100644 --- a/libs/androidfw/tests/TestHelpers.cpp +++ b/libs/androidfw/tests/TestHelpers.cpp @@ -16,67 +16,22 @@ #include "TestHelpers.h" -#include <libgen.h> -#include <unistd.h> - -#include <memory> -#include <string> - -#include "android-base/file.h" -#include "android-base/logging.h" -#include "android-base/strings.h" #include "ziparchive/zip_archive.h" -namespace android { - -static std::string sTestDataPath; +using ::testing::AssertionFailure; +using ::testing::AssertionResult; +using ::testing::AssertionSuccess; -// Extract the directory of the current executable path. -static std::string GetExecutableDir() { - const std::string path = base::GetExecutablePath(); - std::unique_ptr<char, decltype(&std::free)> mutable_path = {strdup(path.c_str()), std::free}; - std::string executable_dir = dirname(mutable_path.get()); - return executable_dir; -} - -void InitializeTest(int* argc, char** argv) { - // Set the default test data path to be the executable path directory. - SetTestDataPath(GetExecutableDir()); - - for (int i = 1; i < *argc; i++) { - const std::string arg = argv[i]; - if (base::StartsWith(arg, "--testdata=")) { - SetTestDataPath(arg.substr(strlen("--testdata="))); - for (int j = i; j != *argc; j++) { - argv[j] = argv[j + 1]; - } - --(*argc); - --i; - } else if (arg == "-h" || arg == "--help") { - std::cerr << "\nAdditional options specific to this test:\n" - " --testdata=[PATH]\n" - " Specify the location of test data used within the tests.\n"; - exit(1); - } - } -} - -void SetTestDataPath(const std::string& path) { sTestDataPath = path; } - -const std::string& GetTestDataPath() { - CHECK(!sTestDataPath.empty()) << "no test data path set."; - return sTestDataPath; -} +namespace android { -::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path, - const std::string& file, - std::string* out_contents) { +AssertionResult ReadFileFromZipToString(const std::string& zip_path, const std::string& file, + std::string* out_contents) { out_contents->clear(); ::ZipArchiveHandle handle; int32_t result = OpenArchive(zip_path.c_str(), &handle); if (result != 0) { - return ::testing::AssertionFailure() << "Failed to open zip '" << zip_path - << "': " << ::ErrorCodeString(result); + return AssertionFailure() << "Failed to open zip '" << zip_path + << "': " << ::ErrorCodeString(result); } ::ZipString name(file.c_str()); @@ -84,8 +39,8 @@ const std::string& GetTestDataPath() { result = ::FindEntry(handle, name, &entry); if (result != 0) { ::CloseArchive(handle); - return ::testing::AssertionFailure() << "Could not find file '" << file << "' in zip '" - << zip_path << "' : " << ::ErrorCodeString(result); + return AssertionFailure() << "Could not find file '" << file << "' in zip '" << zip_path + << "' : " << ::ErrorCodeString(result); } out_contents->resize(entry.uncompressed_length); @@ -94,41 +49,36 @@ const std::string& GetTestDataPath() { out_contents->size()); if (result != 0) { ::CloseArchive(handle); - return ::testing::AssertionFailure() << "Failed to extract file '" << file << "' from zip '" - << zip_path << "': " << ::ErrorCodeString(result); + return AssertionFailure() << "Failed to extract file '" << file << "' from zip '" << zip_path + << "': " << ::ErrorCodeString(result); } ::CloseArchive(handle); - return ::testing::AssertionSuccess(); + return AssertionSuccess(); } -::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id, - const char* expected_str) { +AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id, + const char* expected_str) { Res_value val; ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG); if (block < 0) { - return ::testing::AssertionFailure() << "could not find resource"; + return AssertionFailure() << "could not find resource"; } if (val.dataType != Res_value::TYPE_STRING) { - return ::testing::AssertionFailure() << "resource is not a string"; + return AssertionFailure() << "resource is not a string"; } const ResStringPool* pool = table.getTableStringBlock(block); if (pool == NULL) { - return ::testing::AssertionFailure() << "table has no string pool for block " << block; + return AssertionFailure() << "table has no string pool for block " << block; } const String8 actual_str = pool->string8ObjectAt(val.data); if (String8(expected_str) != actual_str) { - return ::testing::AssertionFailure() << actual_str.string(); + return AssertionFailure() << actual_str.string(); } - return ::testing::AssertionSuccess() << actual_str.string(); -} - -std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) { - String8 str = pool->string8ObjectAt(idx); - return std::string(str.string(), str.length()); + return AssertionSuccess() << actual_str.string(); } } // namespace android diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h index ec78b2ae5efc..43a995536d89 100644 --- a/libs/androidfw/tests/TestHelpers.h +++ b/libs/androidfw/tests/TestHelpers.h @@ -14,53 +14,25 @@ * limitations under the License. */ -#ifndef TEST_HELPERS_H_ -#define TEST_HELPERS_H_ +#ifndef ANDROIDFW_TEST_TESTHELPERS_H +#define ANDROIDFW_TEST_TESTHELPERS_H -#include <ostream> #include <string> -#include <vector> #include "androidfw/ResourceTypes.h" #include "gtest/gtest.h" -#include "utils/String16.h" -#include "utils/String8.h" -static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) { - return out << str.string(); -} - -static inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) { - return out << android::String8(str).string(); -} +#include "CommonHelpers.h" namespace android { -void InitializeTest(int* argc, char** argv); - -enum { MAY_NOT_BE_BAG = false }; - -void SetTestDataPath(const std::string& path); - -const std::string& GetTestDataPath(); - ::testing::AssertionResult ReadFileFromZipToString(const std::string& zip_path, const std::string& file, std::string* out_contents); -static inline bool operator==(const ResTable_config& a, const ResTable_config& b) { - return a.compare(b) == 0; -} - -static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) { - return out << c.toString().string(); -} - ::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id, const char* expected_str); -std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx); - } // namespace android -#endif // TEST_HELPERS_H_ +#endif // ANDROIDFW_TEST_TESTHELPERS_H diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp index dfff9c00922c..55d53edf6a2b 100644 --- a/libs/androidfw/tests/Theme_test.cpp +++ b/libs/androidfw/tests/Theme_test.cpp @@ -23,6 +23,7 @@ #include "data/lib_one/R.h" #include "data/libclient/R.h" #include "data/styles/R.h" +#include "data/system/R.h" namespace app = com::android::app; namespace lib_one = com::android::lib_one; @@ -33,6 +34,9 @@ namespace android { class ThemeTest : public ::testing::Test { public: void SetUp() override { + system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/); + ASSERT_NE(nullptr, system_assets_); + style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); ASSERT_NE(nullptr, style_assets_); @@ -47,6 +51,7 @@ class ThemeTest : public ::testing::Test { } protected: + std::unique_ptr<const ApkAssets> system_assets_; std::unique_ptr<const ApkAssets> style_assets_; std::unique_ptr<const ApkAssets> libclient_assets_; std::unique_ptr<const ApkAssets> lib_one_assets_; @@ -123,6 +128,18 @@ TEST_F(ThemeTest, SingleThemeWithParent) { EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); } +TEST_F(ThemeTest, TryToUseBadResourceId) { + AssetManager2 assetmanager; + assetmanager.SetApkAssets({style_assets_.get()}); + + std::unique_ptr<Theme> theme = assetmanager.NewTheme(); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); + + Res_value value; + uint32_t flags; + ASSERT_EQ(kInvalidCookie, theme->GetAttribute(0x7f000001, &value, &flags)); +} + TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { AssetManager2 assetmanager; assetmanager.SetApkAssets({style_assets_.get()}); @@ -262,20 +279,30 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); } -TEST_F(ThemeTest, FailToCopyThemeWithDifferentAssetManager) { +TEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) { AssetManager2 assetmanager_one; - assetmanager_one.SetApkAssets({style_assets_.get()}); + assetmanager_one.SetApkAssets({system_assets_.get(), style_assets_.get()}); AssetManager2 assetmanager_two; - assetmanager_two.SetApkAssets({style_assets_.get()}); + assetmanager_two.SetApkAssets({system_assets_.get(), style_assets_.get()}); auto theme_one = assetmanager_one.NewTheme(); ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); auto theme_two = assetmanager_two.NewTheme(); + ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One)); ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo)); - EXPECT_FALSE(theme_one->SetTo(*theme_two)); + EXPECT_TRUE(theme_one->SetTo(*theme_two)); + + Res_value value; + uint32_t flags; + + // No app resources. + EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags)); + + // Only system. + EXPECT_NE(kInvalidCookie, theme_one->GetAttribute(R::attr::foreground, &value, &flags)); } } // namespace android diff --git a/libs/androidfw/tests/data/basic/basic.apk b/libs/androidfw/tests/data/basic/basic.apk Binary files differindex 0c17328e86b2..18ef75e91ded 100644 --- a/libs/androidfw/tests/data/basic/basic.apk +++ b/libs/androidfw/tests/data/basic/basic.apk diff --git a/libs/androidfw/tests/data/basic/basic_de_fr.apk b/libs/androidfw/tests/data/basic/basic_de_fr.apk Binary files differindex e45258c6a005..767dff6fcfa5 100644 --- a/libs/androidfw/tests/data/basic/basic_de_fr.apk +++ b/libs/androidfw/tests/data/basic/basic_de_fr.apk diff --git a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk Binary files differindex 4ae1a7c87a70..58953f56d736 100644 --- a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk +++ b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk diff --git a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk Binary files differindex a240d4c06c1d..103f6565bb06 100644 --- a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk +++ b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk diff --git a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk Binary files differindex fd3d9b233084..61369d506786 100644 --- a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk +++ b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk diff --git a/libs/androidfw/tests/data/basic/build b/libs/androidfw/tests/data/basic/build index d619800d6fc5..5682ed4d3041 100755 --- a/libs/androidfw/tests/data/basic/build +++ b/libs/androidfw/tests/data/basic/build @@ -19,11 +19,15 @@ set -e PATH_TO_FRAMEWORK_RES=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/android.jar -aapt package \ - -M AndroidManifest.xml \ - -S res \ - -A assets \ +aapt2 compile --dir res -o compiled.flata +aapt2 link \ -I $PATH_TO_FRAMEWORK_RES \ - --split hdpi --split xhdpi --split xxhdpi --split fr,de \ - -F basic.apk \ - -f + --manifest AndroidManifest.xml \ + -A assets \ + --split basic_hdpi-v4.apk:hdpi \ + --split basic_xhdpi-v4.apk:xhdpi \ + --split basic_xxhdpi-v4.apk:xxhdpi \ + --split basic_de_fr.apk:de,fr \ + -o basic.apk \ + compiled.flata +rm compiled.flata diff --git a/libs/androidfw/tests/data/basic/res/values/values.xml b/libs/androidfw/tests/data/basic/res/values/values.xml index 638c9832ab4c..6c474596b5cd 100644 --- a/libs/androidfw/tests/data/basic/res/values/values.xml +++ b/libs/androidfw/tests/data/basic/res/values/values.xml @@ -60,4 +60,9 @@ <item>2</item> <item>3</item> </integer-array> + + <overlayable> + <item type="string" name="test2" /> + <item type="array" name="integerArray1" /> + </overlayable> </resources> diff --git a/libs/androidfw/tests/data/overlay/build b/libs/androidfw/tests/data/overlay/build index 112f373ead30..716b1bd9db64 100755 --- a/libs/androidfw/tests/data/overlay/build +++ b/libs/androidfw/tests/data/overlay/build @@ -17,4 +17,6 @@ set -e -aapt package -M AndroidManifest.xml -S res -F overlay.apk -f +aapt2 compile --dir res -o compiled.flata +aapt2 link --manifest AndroidManifest.xml -o overlay.apk compiled.flata +rm compiled.flata diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk Binary files differindex 40bf17c5951a..33f961117c44 100644 --- a/libs/androidfw/tests/data/overlay/overlay.apk +++ b/libs/androidfw/tests/data/overlay/overlay.apk |