Add a function in screenUI to display the pre-generated graphs for rescue party. If these graphs are not valid, falls back to display the old text strings. Right now we haven't generated the localized graphs yet, so the UI always shows the TextMenu. Bug: 116655889 Test: check rescue party under recovery Change-Id: I0558cb536b659cdc25c8b7946d3a39820935b003
563 lines
17 KiB
C++
563 lines
17 KiB
C++
/*
|
|
* Copyright (C) 2018 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 <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
#include <functional>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android-base/stringprintf.h>
|
|
#include <android-base/test_utils.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "common/test_constants.h"
|
|
#include "device.h"
|
|
#include "minui/minui.h"
|
|
#include "otautil/paths.h"
|
|
#include "private/resources.h"
|
|
#include "screen_ui.h"
|
|
|
|
static const std::vector<std::string> HEADERS{ "header" };
|
|
static const std::vector<std::string> ITEMS{ "item1", "item2", "item3", "item4", "1234567890" };
|
|
|
|
// TODO(xunchang) check if some draw functions are called when drawing menus.
|
|
class MockDrawFunctions : public DrawInterface {
|
|
void SetColor(UIElement /* element */) const override {}
|
|
void DrawHighlightBar(int /* x */, int /* y */, int /* width */,
|
|
int /* height */) const override {};
|
|
int DrawHorizontalRule(int /* y */) const override {
|
|
return 0;
|
|
};
|
|
int DrawTextLine(int /* x */, int /* y */, const std::string& /* line */,
|
|
bool /* bold */) const override {
|
|
return 0;
|
|
};
|
|
void DrawSurface(GRSurface* /* surface */, int /* sx */, int /* sy */, int /* w */, int /* h */,
|
|
int /* dx */, int /* dy */) const override {};
|
|
void DrawFill(int /* x */, int /* y */, int /* w */, int /* h */) const override {};
|
|
void DrawTextIcon(int /* x */, int /* y */, GRSurface* /* surface */) const override {};
|
|
int DrawTextLines(int /* x */, int /* y */,
|
|
const std::vector<std::string>& /* lines */) const override {
|
|
return 0;
|
|
};
|
|
int DrawWrappedTextLines(int /* x */, int /* y */,
|
|
const std::vector<std::string>& /* lines */) const override {
|
|
return 0;
|
|
};
|
|
};
|
|
|
|
class ScreenUITest : public testing::Test {
|
|
protected:
|
|
MockDrawFunctions draw_funcs_;
|
|
};
|
|
|
|
TEST_F(ScreenUITest, StartPhoneMenuSmoke) {
|
|
TextMenu menu(false, 10, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
|
|
ASSERT_FALSE(menu.scrollable());
|
|
ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
|
|
ASSERT_EQ(5u, menu.ItemsCount());
|
|
|
|
std::string message;
|
|
ASSERT_FALSE(menu.ItemsOverflow(&message));
|
|
for (size_t i = 0; i < menu.ItemsCount(); i++) {
|
|
ASSERT_EQ(ITEMS[i], menu.TextItem(i));
|
|
}
|
|
|
|
ASSERT_EQ(0, menu.selection());
|
|
}
|
|
|
|
TEST_F(ScreenUITest, StartWearMenuSmoke) {
|
|
TextMenu menu(true, 10, 8, HEADERS, ITEMS, 1, 20, draw_funcs_);
|
|
ASSERT_TRUE(menu.scrollable());
|
|
ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
|
|
ASSERT_EQ(5u, menu.ItemsCount());
|
|
|
|
std::string message;
|
|
ASSERT_FALSE(menu.ItemsOverflow(&message));
|
|
for (size_t i = 0; i < menu.ItemsCount() - 1; i++) {
|
|
ASSERT_EQ(ITEMS[i], menu.TextItem(i));
|
|
}
|
|
// Test of the last item is truncated
|
|
ASSERT_EQ("12345678", menu.TextItem(4));
|
|
ASSERT_EQ(1, menu.selection());
|
|
}
|
|
|
|
TEST_F(ScreenUITest, StartPhoneMenuItemsOverflow) {
|
|
TextMenu menu(false, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
|
|
ASSERT_FALSE(menu.scrollable());
|
|
ASSERT_EQ(1u, menu.ItemsCount());
|
|
|
|
std::string message;
|
|
ASSERT_FALSE(menu.ItemsOverflow(&message));
|
|
for (size_t i = 0; i < menu.ItemsCount(); i++) {
|
|
ASSERT_EQ(ITEMS[i], menu.TextItem(i));
|
|
}
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(1u, menu.MenuEnd());
|
|
}
|
|
|
|
TEST_F(ScreenUITest, StartWearMenuItemsOverflow) {
|
|
TextMenu menu(true, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
|
|
ASSERT_TRUE(menu.scrollable());
|
|
ASSERT_EQ(5u, menu.ItemsCount());
|
|
|
|
std::string message;
|
|
ASSERT_TRUE(menu.ItemsOverflow(&message));
|
|
ASSERT_EQ("Current item: 1/5", message);
|
|
|
|
for (size_t i = 0; i < menu.ItemsCount(); i++) {
|
|
ASSERT_EQ(ITEMS[i], menu.TextItem(i));
|
|
}
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(1u, menu.MenuEnd());
|
|
}
|
|
|
|
TEST_F(ScreenUITest, PhoneMenuSelectSmoke) {
|
|
int sel = 0;
|
|
TextMenu menu(false, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
|
|
// Mimic down button 10 times (2 * items size)
|
|
for (int i = 0; i < 10; i++) {
|
|
sel = menu.Select(++sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
|
|
// Wraps the selection for unscrollable menu when it reaches the boundary.
|
|
int expected = (i + 1) % 5;
|
|
ASSERT_EQ(expected, menu.selection());
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(5u, menu.MenuEnd());
|
|
}
|
|
|
|
// Mimic up button 10 times
|
|
for (int i = 0; i < 10; i++) {
|
|
sel = menu.Select(--sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
|
|
int expected = (9 - i) % 5;
|
|
ASSERT_EQ(expected, menu.selection());
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(5u, menu.MenuEnd());
|
|
}
|
|
}
|
|
|
|
TEST_F(ScreenUITest, WearMenuSelectSmoke) {
|
|
int sel = 0;
|
|
TextMenu menu(true, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
|
|
// Mimic pressing down button 10 times (2 * items size)
|
|
for (int i = 0; i < 10; i++) {
|
|
sel = menu.Select(++sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
|
|
// Stops the selection at the boundary if the menu is scrollable.
|
|
int expected = std::min(i + 1, 4);
|
|
ASSERT_EQ(expected, menu.selection());
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(5u, menu.MenuEnd());
|
|
}
|
|
|
|
// Mimic pressing up button 10 times
|
|
for (int i = 0; i < 10; i++) {
|
|
sel = menu.Select(--sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
|
|
int expected = std::max(3 - i, 0);
|
|
ASSERT_EQ(expected, menu.selection());
|
|
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(5u, menu.MenuEnd());
|
|
}
|
|
}
|
|
|
|
TEST_F(ScreenUITest, WearMenuSelectItemsOverflow) {
|
|
int sel = 1;
|
|
TextMenu menu(true, 3, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
|
|
ASSERT_EQ(5u, menu.ItemsCount());
|
|
|
|
// Scroll the menu to the end, and check the start & end of menu.
|
|
for (int i = 0; i < 3; i++) {
|
|
sel = menu.Select(++sel);
|
|
ASSERT_EQ(i + 2, sel);
|
|
ASSERT_EQ(static_cast<size_t>(i), menu.MenuStart());
|
|
ASSERT_EQ(static_cast<size_t>(i + 3), menu.MenuEnd());
|
|
}
|
|
|
|
// Press down button one more time won't change the MenuStart() and MenuEnd().
|
|
sel = menu.Select(++sel);
|
|
ASSERT_EQ(4, sel);
|
|
ASSERT_EQ(2u, menu.MenuStart());
|
|
ASSERT_EQ(5u, menu.MenuEnd());
|
|
|
|
// Scroll the menu to the top.
|
|
// The expected menu sel, start & ends are:
|
|
// sel 3, start 2, end 5
|
|
// sel 2, start 2, end 5
|
|
// sel 1, start 1, end 4
|
|
// sel 0, start 0, end 3
|
|
for (int i = 0; i < 4; i++) {
|
|
sel = menu.Select(--sel);
|
|
ASSERT_EQ(3 - i, sel);
|
|
ASSERT_EQ(static_cast<size_t>(std::min(3 - i, 2)), menu.MenuStart());
|
|
ASSERT_EQ(static_cast<size_t>(std::min(6 - i, 5)), menu.MenuEnd());
|
|
}
|
|
|
|
// Press up button one more time won't change the MenuStart() and MenuEnd().
|
|
sel = menu.Select(--sel);
|
|
ASSERT_EQ(0, sel);
|
|
ASSERT_EQ(0u, menu.MenuStart());
|
|
ASSERT_EQ(3u, menu.MenuEnd());
|
|
}
|
|
|
|
TEST_F(ScreenUITest, GraphicMenuSelection) {
|
|
GRSurface fake_surface = GRSurface{ 50, 50, 50, 1, nullptr };
|
|
std::vector<GRSurface*> items = { &fake_surface, &fake_surface, &fake_surface };
|
|
GraphicMenu menu(&fake_surface, items, 0, draw_funcs_);
|
|
|
|
ASSERT_EQ(0, menu.selection());
|
|
|
|
int sel = 0;
|
|
for (int i = 0; i < 3; i++) {
|
|
sel = menu.Select(++sel);
|
|
ASSERT_EQ((i + 1) % 3, sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
}
|
|
|
|
sel = 0;
|
|
for (int i = 0; i < 3; i++) {
|
|
sel = menu.Select(--sel);
|
|
ASSERT_EQ(2 - i, sel);
|
|
ASSERT_EQ(sel, menu.selection());
|
|
}
|
|
}
|
|
|
|
TEST_F(ScreenUITest, GraphicMenuValidate) {
|
|
auto fake_surface = GRSurface{ 50, 50, 50, 1, nullptr };
|
|
std::vector<GRSurface*> items = { &fake_surface, &fake_surface, &fake_surface };
|
|
|
|
ASSERT_TRUE(GraphicMenu::Validate(200, 200, &fake_surface, items));
|
|
|
|
// Menu exceeds the horizontal boundary.
|
|
auto wide_surface = GRSurface{ 300, 50, 300, 1, nullptr };
|
|
ASSERT_FALSE(GraphicMenu::Validate(299, 200, &wide_surface, items));
|
|
|
|
// Menu exceeds the vertical boundary.
|
|
items.push_back(&fake_surface);
|
|
ASSERT_FALSE(GraphicMenu::Validate(200, 249, &fake_surface, items));
|
|
}
|
|
|
|
static constexpr int kMagicAction = 101;
|
|
|
|
enum class KeyCode : int {
|
|
TIMEOUT = -1,
|
|
NO_OP = 0,
|
|
UP = 1,
|
|
DOWN = 2,
|
|
ENTER = 3,
|
|
MAGIC = 1001,
|
|
LAST,
|
|
};
|
|
|
|
static const std::map<KeyCode, int> kKeyMapping{
|
|
// clang-format off
|
|
{ KeyCode::NO_OP, Device::kNoAction },
|
|
{ KeyCode::UP, Device::kHighlightUp },
|
|
{ KeyCode::DOWN, Device::kHighlightDown },
|
|
{ KeyCode::ENTER, Device::kInvokeItem },
|
|
{ KeyCode::MAGIC, kMagicAction },
|
|
// clang-format on
|
|
};
|
|
|
|
class TestableScreenRecoveryUI : public ScreenRecoveryUI {
|
|
public:
|
|
int WaitKey() override;
|
|
|
|
void SetKeyBuffer(const std::vector<KeyCode>& buffer);
|
|
|
|
int KeyHandler(int key, bool visible) const;
|
|
|
|
// The following functions expose the protected members for test purpose.
|
|
void RunLoadAnimation() {
|
|
LoadAnimation();
|
|
}
|
|
|
|
size_t GetLoopFrames() const {
|
|
return loop_frames;
|
|
}
|
|
|
|
size_t GetIntroFrames() const {
|
|
return intro_frames;
|
|
}
|
|
|
|
bool GetRtlLocale() const {
|
|
return rtl_locale_;
|
|
}
|
|
|
|
private:
|
|
std::vector<KeyCode> key_buffer_;
|
|
size_t key_buffer_index_;
|
|
};
|
|
|
|
void TestableScreenRecoveryUI::SetKeyBuffer(const std::vector<KeyCode>& buffer) {
|
|
key_buffer_ = buffer;
|
|
key_buffer_index_ = 0;
|
|
}
|
|
|
|
int TestableScreenRecoveryUI::KeyHandler(int key, bool) const {
|
|
KeyCode key_code = static_cast<KeyCode>(key);
|
|
if (kKeyMapping.find(key_code) != kKeyMapping.end()) {
|
|
return kKeyMapping.at(key_code);
|
|
}
|
|
return Device::kNoAction;
|
|
}
|
|
|
|
int TestableScreenRecoveryUI::WaitKey() {
|
|
if (IsKeyInterrupted()) {
|
|
return static_cast<int>(RecoveryUI::KeyError::INTERRUPTED);
|
|
}
|
|
|
|
CHECK_LT(key_buffer_index_, key_buffer_.size());
|
|
return static_cast<int>(key_buffer_[key_buffer_index_++]);
|
|
}
|
|
|
|
class ScreenRecoveryUITest : public ::testing::Test {
|
|
protected:
|
|
const std::string kTestLocale = "en-US";
|
|
const std::string kTestRtlLocale = "ar";
|
|
const std::string kTestRtlLocaleWithSuffix = "ar-EG";
|
|
|
|
void SetUp() override {
|
|
has_graphics_ = gr_init() == 0;
|
|
gr_exit();
|
|
|
|
if (has_graphics_) {
|
|
ui_ = std::make_unique<TestableScreenRecoveryUI>();
|
|
}
|
|
|
|
testdata_dir_ = from_testdata_base("");
|
|
Paths::Get().set_resource_dir(testdata_dir_);
|
|
res_set_resource_dir(testdata_dir_);
|
|
}
|
|
|
|
bool has_graphics_;
|
|
std::unique_ptr<TestableScreenRecoveryUI> ui_;
|
|
std::string testdata_dir_;
|
|
};
|
|
|
|
#define RETURN_IF_NO_GRAPHICS \
|
|
do { \
|
|
if (!has_graphics_) { \
|
|
GTEST_LOG_(INFO) << "Test skipped due to no available graphics device"; \
|
|
return; \
|
|
} \
|
|
} while (false)
|
|
|
|
TEST_F(ScreenRecoveryUITest, Init) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ASSERT_EQ(kTestLocale, ui_->GetLocale());
|
|
ASSERT_FALSE(ui_->GetRtlLocale());
|
|
ASSERT_FALSE(ui_->IsTextVisible());
|
|
ASSERT_FALSE(ui_->WasTextEverVisible());
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, dtor_NotCallingInit) {
|
|
ui_.reset();
|
|
ASSERT_FALSE(ui_);
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowText) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ASSERT_FALSE(ui_->IsTextVisible());
|
|
ui_->ShowText(true);
|
|
ASSERT_TRUE(ui_->IsTextVisible());
|
|
ASSERT_TRUE(ui_->WasTextEverVisible());
|
|
|
|
ui_->ShowText(false);
|
|
ASSERT_FALSE(ui_->IsTextVisible());
|
|
ASSERT_TRUE(ui_->WasTextEverVisible());
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, RtlLocale) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestRtlLocale));
|
|
ASSERT_TRUE(ui_->GetRtlLocale());
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, RtlLocaleWithSuffix) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestRtlLocaleWithSuffix));
|
|
ASSERT_TRUE(ui_->GetRtlLocale());
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowMenu) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::UP,
|
|
KeyCode::DOWN,
|
|
KeyCode::UP,
|
|
KeyCode::DOWN,
|
|
KeyCode::ENTER,
|
|
});
|
|
ASSERT_EQ(3u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::UP,
|
|
KeyCode::UP,
|
|
KeyCode::NO_OP,
|
|
KeyCode::NO_OP,
|
|
KeyCode::UP,
|
|
KeyCode::ENTER,
|
|
});
|
|
ASSERT_EQ(2u, ui_->ShowMenu(HEADERS, ITEMS, 0, true,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowMenu_NotMenuOnly) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::MAGIC,
|
|
});
|
|
ASSERT_EQ(static_cast<size_t>(kMagicAction),
|
|
ui_->ShowMenu(HEADERS, ITEMS, 3, false,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::TIMEOUT,
|
|
});
|
|
ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT),
|
|
ui_->ShowMenu(HEADERS, ITEMS, 3, true, nullptr));
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut_TextWasEverVisible) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ui_->ShowText(true);
|
|
ui_->ShowText(false);
|
|
ASSERT_TRUE(ui_->WasTextEverVisible());
|
|
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::TIMEOUT,
|
|
KeyCode::DOWN,
|
|
KeyCode::ENTER,
|
|
});
|
|
ASSERT_EQ(4u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, ShowMenuWithInterrupt) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::UP,
|
|
KeyCode::DOWN,
|
|
KeyCode::UP,
|
|
KeyCode::DOWN,
|
|
KeyCode::ENTER,
|
|
});
|
|
|
|
ui_->InterruptKey();
|
|
ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
|
|
ui_->ShowMenu(HEADERS, ITEMS, 3, true,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
|
|
ui_->SetKeyBuffer({
|
|
KeyCode::UP,
|
|
KeyCode::UP,
|
|
KeyCode::NO_OP,
|
|
KeyCode::NO_OP,
|
|
KeyCode::UP,
|
|
KeyCode::ENTER,
|
|
});
|
|
ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
|
|
ui_->ShowMenu(HEADERS, ITEMS, 0, true,
|
|
std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
|
|
std::placeholders::_1, std::placeholders::_2)));
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, LoadAnimation) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
// Make a few copies of loop00000.png from testdata.
|
|
std::string image_data;
|
|
ASSERT_TRUE(android::base::ReadFileToString(testdata_dir_ + "/loop00000.png", &image_data));
|
|
|
|
std::vector<std::string> tempfiles;
|
|
TemporaryDir resource_dir;
|
|
for (const auto& name : { "00002", "00100", "00050" }) {
|
|
tempfiles.push_back(android::base::StringPrintf("%s/loop%s.png", resource_dir.path, name));
|
|
ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
|
|
}
|
|
for (const auto& name : { "00", "01" }) {
|
|
tempfiles.push_back(android::base::StringPrintf("%s/intro%s.png", resource_dir.path, name));
|
|
ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
|
|
}
|
|
Paths::Get().set_resource_dir(resource_dir.path);
|
|
|
|
ui_->RunLoadAnimation();
|
|
|
|
ASSERT_EQ(2u, ui_->GetIntroFrames());
|
|
ASSERT_EQ(3u, ui_->GetLoopFrames());
|
|
|
|
for (const auto& name : tempfiles) {
|
|
ASSERT_EQ(0, unlink(name.c_str()));
|
|
}
|
|
}
|
|
|
|
TEST_F(ScreenRecoveryUITest, LoadAnimation_MissingAnimation) {
|
|
RETURN_IF_NO_GRAPHICS;
|
|
|
|
ASSERT_TRUE(ui_->Init(kTestLocale));
|
|
// We need a dir that doesn't contain any animation. However, using TemporaryDir will give
|
|
// leftovers since this is a death test where TemporaryDir::~TemporaryDir() won't be called.
|
|
Paths::Get().set_resource_dir("/proc/self");
|
|
|
|
::testing::FLAGS_gtest_death_test_style = "threadsafe";
|
|
ASSERT_EXIT(ui_->RunLoadAnimation(), ::testing::KilledBySignal(SIGABRT), "");
|
|
}
|
|
|
|
#undef RETURN_IF_NO_GRAPHICS
|