summaryrefslogtreecommitdiff
path: root/libs/androidfw/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libs/androidfw/tests')
-rw-r--r--libs/androidfw/tests/Android.mk126
-rw-r--r--libs/androidfw/tests/ApkAssets_test.cpp64
-rw-r--r--libs/androidfw/tests/AssetManager2_bench.cpp32
-rw-r--r--libs/androidfw/tests/AssetManager2_test.cpp23
-rw-r--r--libs/androidfw/tests/BenchMain.cpp2
-rw-r--r--libs/androidfw/tests/BenchmarkHelpers.cpp31
-rw-r--r--libs/androidfw/tests/BenchmarkHelpers.h14
-rw-r--r--libs/androidfw/tests/CommonHelpers.cpp65
-rw-r--r--libs/androidfw/tests/CommonHelpers.h57
-rw-r--r--libs/androidfw/tests/ConfigLocale_test.cpp95
-rw-r--r--libs/androidfw/tests/Idmap_test.cpp2
-rw-r--r--libs/androidfw/tests/LoadedArsc_test.cpp110
-rw-r--r--libs/androidfw/tests/SparseEntry_bench.cpp33
-rw-r--r--libs/androidfw/tests/TestHelpers.cpp90
-rw-r--r--libs/androidfw/tests/TestHelpers.h36
-rw-r--r--libs/androidfw/tests/Theme_test.cpp35
-rw-r--r--libs/androidfw/tests/data/basic/basic.apkbin3207 -> 3124 bytes
-rw-r--r--libs/androidfw/tests/data/basic/basic_de_fr.apkbin1524 -> 1327 bytes
-rw-r--r--libs/androidfw/tests/data/basic/basic_hdpi-v4.apkbin1306 -> 1151 bytes
-rw-r--r--libs/androidfw/tests/data/basic/basic_xhdpi-v4.apkbin1312 -> 1155 bytes
-rw-r--r--libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apkbin1310 -> 1155 bytes
-rwxr-xr-xlibs/androidfw/tests/data/basic/build18
-rw-r--r--libs/androidfw/tests/data/basic/res/values/values.xml5
-rwxr-xr-xlibs/androidfw/tests/data/overlay/build4
-rw-r--r--libs/androidfw/tests/data/overlay/overlay.apkbin2442 -> 5211 bytes
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
index 0c17328e86b2..18ef75e91ded 100644
--- a/libs/androidfw/tests/data/basic/basic.apk
+++ b/libs/androidfw/tests/data/basic/basic.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_de_fr.apk b/libs/androidfw/tests/data/basic/basic_de_fr.apk
index e45258c6a005..767dff6fcfa5 100644
--- a/libs/androidfw/tests/data/basic/basic_de_fr.apk
+++ b/libs/androidfw/tests/data/basic/basic_de_fr.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
index 4ae1a7c87a70..58953f56d736 100644
--- a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
index a240d4c06c1d..103f6565bb06 100644
--- a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
index fd3d9b233084..61369d506786 100644
--- a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
Binary files differ
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
index 40bf17c5951a..33f961117c44 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ