diff options
author | Tianjie Xu <xunchang@google.com> | 2017-01-19 20:20:36 +0100 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-01-19 20:20:36 +0100 |
commit | a38224eadb00ecb32fac0454b78f5a805259ebbf (patch) | |
tree | 8603c5d1df466bcec6dda5c88ad8cd3bc66cad6d | |
parent | Merge "minui: Export minui/minui.h." (diff) | |
parent | Merge "Add checkers and tests for empty locale in PNG file" (diff) | |
download | android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar.gz android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar.bz2 android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar.lz android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar.xz android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.tar.zst android_bootable_recovery-a38224eadb00ecb32fac0454b78f5a805259ebbf.zip |
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | minui/resources.cpp | 4 | ||||
-rw-r--r-- | tests/Android.mk | 28 | ||||
-rw-r--r-- | tests/manual/recovery_test.cpp | 138 | ||||
-rw-r--r-- | tests/unit/locale_test.cpp | 3 |
5 files changed, 177 insertions, 3 deletions
@@ -40,3 +40,10 @@ Running the manual tests - Reboot the device immediately and run the test again. The test should save the contents of pmsg buffer into /data/misc/recovery/inject.txt. Test will pass if this file has expected contents. + +`ResourceTest` validates whether the png files are qualified as background text +image under recovery. + + 1. `adb sync data` to make sure the test-dir has the images to test. + 2. The test will automatically pickup and verify all `_text.png` files in + the test dir. diff --git a/minui/resources.cpp b/minui/resources.cpp index e6909f269..726c627ed 100644 --- a/minui/resources.cpp +++ b/minui/resources.cpp @@ -374,7 +374,9 @@ int res_create_alpha_surface(const char* name, GRSurface** pSurface) { // This function tests if a locale string stored in PNG (prefix) matches // the locale string provided by the system (locale). bool matches_locale(const char* prefix, const char* locale) { - if (locale == NULL) return false; + if (locale == nullptr) { + return false; + } // Return true if the whole string of prefix matches the top part of // locale. For instance, prefix == "en" matches locale == "en_US"; diff --git a/tests/Android.mk b/tests/Android.mk index 1203817a2..1dbd2b614 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -49,10 +49,34 @@ LOCAL_CLANG := true LOCAL_CFLAGS := -Werror LOCAL_MODULE := recovery_manual_test LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -LOCAL_STATIC_LIBRARIES := libbase +LOCAL_STATIC_LIBRARIES := \ + libminui \ + libbase LOCAL_SRC_FILES := manual/recovery_test.cpp -LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libpng + +resource_files := $(call find-files-in-subdirs, bootable/recovery, \ + "*_text.png", \ + res-mdpi/images \ + res-hdpi/images \ + res-xhdpi/images \ + res-xxhdpi/images \ + res-xxxhdpi/images \ + ) + +# The resource image files that will go to $OUT/data/nativetest/recovery. +testimage_out_path := $(TARGET_OUT_DATA)/nativetest/recovery +GEN := $(addprefix $(testimage_out_path)/, $(resource_files)) + +$(GEN): PRIVATE_PATH := $(LOCAL_PATH) +$(GEN): PRIVATE_CUSTOM_TOOL = cp $< $@ +$(GEN): $(testimage_out_path)/% : bootable/recovery/% + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + include $(BUILD_NATIVE_TEST) # Component tests diff --git a/tests/manual/recovery_test.cpp b/tests/manual/recovery_test.cpp index e73cb1509..d36dd331e 100644 --- a/tests/manual/recovery_test.cpp +++ b/tests/manual/recovery_test.cpp @@ -14,19 +14,27 @@ * limitations under the License. */ +#include <dirent.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <string> +#include <vector> #include <android-base/file.h> +#include <android-base/strings.h> #include <android/log.h> #include <gtest/gtest.h> +#include <png.h> #include <private/android_logger.h> +#include "minui/minui.h" + static const std::string myFilename = "/data/misc/recovery/inject.txt"; static const std::string myContent = "Hello World\nWelcome to my recovery\n"; +static const std::string kLocale = "zu"; +static const std::string kResourceTestDir = "/data/nativetest/recovery/"; // Failure is expected on systems that do not deliver either the // recovery-persist or recovery-refresh executables. Tests also require @@ -84,3 +92,133 @@ TEST(recovery, persist) { } EXPECT_EQ(0, unlink(myFilename.c_str())); } + +std::vector<std::string> image_dir { + "res-mdpi/images/", + "res-hdpi/images/", + "res-xhdpi/images/", + "res-xxhdpi/images/", + "res-xxxhdpi/images/" +}; + +static int png_filter(const dirent* de) { + if (de->d_type != DT_REG || !android::base::EndsWith(de->d_name, "_text.png")) { + return 0; + } + return 1; +} + +// Find out all png files to test under /data/nativetest/recovery/. +static std::vector<std::string> add_files() { + std::vector<std::string> files; + for (const std::string& str : image_dir) { + std::string dir_path = kResourceTestDir + str; + dirent** namelist; + int n = scandir(dir_path.c_str(), &namelist, png_filter, alphasort); + if (n == -1) { + printf("Failed to scan dir %s: %s\n", kResourceTestDir.c_str(), strerror(errno)); + return files; + } + if (n == 0) { + printf("No file is added for test in %s\n", kResourceTestDir.c_str()); + } + + while (n--) { + std::string file_path = dir_path + namelist[n]->d_name; + files.push_back(file_path); + free(namelist[n]); + } + free(namelist); + } + return files; +} + +class ResourceTest : public testing::TestWithParam<std::string> { + public: + static std::vector<std::string> png_list; + + // Parse a png file and test if it's qualified for the background text image + // under recovery. + void SetUp() override { + std::string file_path = GetParam(); + fp = fopen(file_path.c_str(), "rb"); + ASSERT_NE(nullptr, fp); + + unsigned char header[8]; + size_t bytesRead = fread(header, 1, sizeof(header), fp); + ASSERT_EQ(sizeof(header), bytesRead); + ASSERT_EQ(0, png_sig_cmp(header, 0, sizeof(header))); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + ASSERT_NE(nullptr, png_ptr); + + info_ptr = png_create_info_struct(png_ptr); + ASSERT_NE(nullptr, info_ptr); + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, sizeof(header)); + png_read_info(png_ptr, info_ptr); + + int color_type, bit_depth; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, + nullptr); + ASSERT_EQ(PNG_COLOR_TYPE_GRAY, color_type) << "Recovery expects grayscale PNG file."; + ASSERT_LT(static_cast<png_uint_32>(5), width); + ASSERT_LT(static_cast<png_uint_32>(0), height); + if (bit_depth <= 8) { + // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray. + png_set_expand_gray_1_2_4_to_8(png_ptr); + } + + png_byte channels = png_get_channels(png_ptr, info_ptr); + ASSERT_EQ(1, channels) << "Recovery background text images expects 1-channel PNG file."; + } + + void TearDown() override { + if (png_ptr != nullptr && info_ptr != nullptr) { + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); + } + + if (fp != nullptr) { + fclose(fp); + } + } + + protected: + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + + FILE* fp; +}; + +std::vector<std::string> ResourceTest::png_list = add_files(); + +TEST_P(ResourceTest, ValidateLocale) { + std::vector<unsigned char> row(width); + for (png_uint_32 y = 0; y < height; ++y) { + png_read_row(png_ptr, row.data(), nullptr); + int w = (row[1] << 8) | row[0]; + int h = (row[3] << 8) | row[2]; + int len = row[4]; + EXPECT_LT(0, w); + EXPECT_LT(0, h); + EXPECT_LT(0, len) << "Locale string should be non-empty."; + EXPECT_NE(0, row[5]) << "Locale string is missing."; + + ASSERT_GT(height, y + 1 + h) << "Locale: " << kLocale << " is not found in the file."; + char* loc = reinterpret_cast<char*>(&row[5]); + if (matches_locale(loc, kLocale.c_str())) { + EXPECT_TRUE(android::base::StartsWith(loc, kLocale.c_str())); + break; + } else { + for (int i = 0; i < h; ++i, ++y) { + png_read_row(png_ptr, row.data(), nullptr); + } + } + } +} + +INSTANTIATE_TEST_CASE_P(BackgroundTextValidation, ResourceTest, + ::testing::ValuesIn(ResourceTest::png_list.cbegin(), + ResourceTest::png_list.cend())); diff --git a/tests/unit/locale_test.cpp b/tests/unit/locale_test.cpp index 0e515f8c1..f73235005 100644 --- a/tests/unit/locale_test.cpp +++ b/tests/unit/locale_test.cpp @@ -26,4 +26,7 @@ TEST(LocaleTest, Misc) { EXPECT_TRUE(matches_locale("en", "en_GB")); EXPECT_FALSE(matches_locale("en_GB", "en")); EXPECT_FALSE(matches_locale("en_GB", "en_US")); + EXPECT_FALSE(matches_locale("en_US", "")); + // Empty locale prefix in the PNG file will match the input locale. + EXPECT_TRUE(matches_locale("", "en_US")); } |