Home | History | Annotate | Download | only in unit
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stddef.h>
     18 #include <stdio.h>
     19 
     20 #include <functional>
     21 #include <map>
     22 #include <memory>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <android-base/file.h>
     27 #include <android-base/logging.h>
     28 #include <android-base/stringprintf.h>
     29 #include <gtest/gtest.h>
     30 #include <gtest/gtest_prod.h>
     31 
     32 #include "common/test_constants.h"
     33 #include "minui/minui.h"
     34 #include "otautil/paths.h"
     35 #include "private/resources.h"
     36 #include "recovery_ui/device.h"
     37 #include "recovery_ui/screen_ui.h"
     38 
     39 static const std::vector<std::string> HEADERS{ "header" };
     40 static const std::vector<std::string> ITEMS{ "item1", "item2", "item3", "item4", "1234567890" };
     41 
     42 // TODO(xunchang) check if some draw functions are called when drawing menus.
     43 class MockDrawFunctions : public DrawInterface {
     44   void SetColor(UIElement /* element */) const override {}
     45   void DrawHighlightBar(int /* x */, int /* y */, int /* width */,
     46                         int /* height */) const override {}
     47   int DrawHorizontalRule(int /* y */) const override {
     48     return 0;
     49   }
     50   int DrawTextLine(int /* x */, int /* y */, const std::string& /* line */,
     51                    bool /* bold */) const override {
     52     return 0;
     53   }
     54   void DrawSurface(const GRSurface* /* surface */, int /* sx */, int /* sy */, int /* w */,
     55                    int /* h */, int /* dx */, int /* dy */) const override {}
     56   void DrawFill(int /* x */, int /* y */, int /* w */, int /* h */) const override {}
     57   void DrawTextIcon(int /* x */, int /* y */, const GRSurface* /* surface */) const override {}
     58   int DrawTextLines(int /* x */, int /* y */,
     59                     const std::vector<std::string>& /* lines */) const override {
     60     return 0;
     61   }
     62   int DrawWrappedTextLines(int /* x */, int /* y */,
     63                            const std::vector<std::string>& /* lines */) const override {
     64     return 0;
     65   }
     66 };
     67 
     68 class ScreenUITest : public testing::Test {
     69  protected:
     70   MockDrawFunctions draw_funcs_;
     71 };
     72 
     73 TEST_F(ScreenUITest, StartPhoneMenuSmoke) {
     74   TextMenu menu(false, 10, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
     75   ASSERT_FALSE(menu.scrollable());
     76   ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
     77   ASSERT_EQ(5u, menu.ItemsCount());
     78 
     79   std::string message;
     80   ASSERT_FALSE(menu.ItemsOverflow(&message));
     81   for (size_t i = 0; i < menu.ItemsCount(); i++) {
     82     ASSERT_EQ(ITEMS[i], menu.TextItem(i));
     83   }
     84 
     85   ASSERT_EQ(0, menu.selection());
     86 }
     87 
     88 TEST_F(ScreenUITest, StartWearMenuSmoke) {
     89   TextMenu menu(true, 10, 8, HEADERS, ITEMS, 1, 20, draw_funcs_);
     90   ASSERT_TRUE(menu.scrollable());
     91   ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
     92   ASSERT_EQ(5u, menu.ItemsCount());
     93 
     94   std::string message;
     95   ASSERT_FALSE(menu.ItemsOverflow(&message));
     96   for (size_t i = 0; i < menu.ItemsCount() - 1; i++) {
     97     ASSERT_EQ(ITEMS[i], menu.TextItem(i));
     98   }
     99   // Test of the last item is truncated
    100   ASSERT_EQ("12345678", menu.TextItem(4));
    101   ASSERT_EQ(1, menu.selection());
    102 }
    103 
    104 TEST_F(ScreenUITest, StartPhoneMenuItemsOverflow) {
    105   TextMenu menu(false, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
    106   ASSERT_FALSE(menu.scrollable());
    107   ASSERT_EQ(1u, menu.ItemsCount());
    108 
    109   std::string message;
    110   ASSERT_FALSE(menu.ItemsOverflow(&message));
    111   for (size_t i = 0; i < menu.ItemsCount(); i++) {
    112     ASSERT_EQ(ITEMS[i], menu.TextItem(i));
    113   }
    114 
    115   ASSERT_EQ(0u, menu.MenuStart());
    116   ASSERT_EQ(1u, menu.MenuEnd());
    117 }
    118 
    119 TEST_F(ScreenUITest, StartWearMenuItemsOverflow) {
    120   TextMenu menu(true, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
    121   ASSERT_TRUE(menu.scrollable());
    122   ASSERT_EQ(5u, menu.ItemsCount());
    123 
    124   std::string message;
    125   ASSERT_TRUE(menu.ItemsOverflow(&message));
    126   ASSERT_EQ("Current item: 1/5", message);
    127 
    128   for (size_t i = 0; i < menu.ItemsCount(); i++) {
    129     ASSERT_EQ(ITEMS[i], menu.TextItem(i));
    130   }
    131 
    132   ASSERT_EQ(0u, menu.MenuStart());
    133   ASSERT_EQ(1u, menu.MenuEnd());
    134 }
    135 
    136 TEST_F(ScreenUITest, PhoneMenuSelectSmoke) {
    137   int sel = 0;
    138   TextMenu menu(false, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
    139   // Mimic down button 10 times (2 * items size)
    140   for (int i = 0; i < 10; i++) {
    141     sel = menu.Select(++sel);
    142     ASSERT_EQ(sel, menu.selection());
    143 
    144     // Wraps the selection for unscrollable menu when it reaches the boundary.
    145     int expected = (i + 1) % 5;
    146     ASSERT_EQ(expected, menu.selection());
    147 
    148     ASSERT_EQ(0u, menu.MenuStart());
    149     ASSERT_EQ(5u, menu.MenuEnd());
    150   }
    151 
    152   // Mimic up button 10 times
    153   for (int i = 0; i < 10; i++) {
    154     sel = menu.Select(--sel);
    155     ASSERT_EQ(sel, menu.selection());
    156 
    157     int expected = (9 - i) % 5;
    158     ASSERT_EQ(expected, menu.selection());
    159 
    160     ASSERT_EQ(0u, menu.MenuStart());
    161     ASSERT_EQ(5u, menu.MenuEnd());
    162   }
    163 }
    164 
    165 TEST_F(ScreenUITest, WearMenuSelectSmoke) {
    166   int sel = 0;
    167   TextMenu menu(true, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
    168   // Mimic pressing down button 10 times (2 * items size)
    169   for (int i = 0; i < 10; i++) {
    170     sel = menu.Select(++sel);
    171     ASSERT_EQ(sel, menu.selection());
    172 
    173     // Stops the selection at the boundary if the menu is scrollable.
    174     int expected = std::min(i + 1, 4);
    175     ASSERT_EQ(expected, menu.selection());
    176 
    177     ASSERT_EQ(0u, menu.MenuStart());
    178     ASSERT_EQ(5u, menu.MenuEnd());
    179   }
    180 
    181   // Mimic pressing up button 10 times
    182   for (int i = 0; i < 10; i++) {
    183     sel = menu.Select(--sel);
    184     ASSERT_EQ(sel, menu.selection());
    185 
    186     int expected = std::max(3 - i, 0);
    187     ASSERT_EQ(expected, menu.selection());
    188 
    189     ASSERT_EQ(0u, menu.MenuStart());
    190     ASSERT_EQ(5u, menu.MenuEnd());
    191   }
    192 }
    193 
    194 TEST_F(ScreenUITest, WearMenuSelectItemsOverflow) {
    195   int sel = 1;
    196   TextMenu menu(true, 3, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
    197   ASSERT_EQ(5u, menu.ItemsCount());
    198 
    199   // Scroll the menu to the end, and check the start & end of menu.
    200   for (int i = 0; i < 3; i++) {
    201     sel = menu.Select(++sel);
    202     ASSERT_EQ(i + 2, sel);
    203     ASSERT_EQ(static_cast<size_t>(i), menu.MenuStart());
    204     ASSERT_EQ(static_cast<size_t>(i + 3), menu.MenuEnd());
    205   }
    206 
    207   // Press down button one more time won't change the MenuStart() and MenuEnd().
    208   sel = menu.Select(++sel);
    209   ASSERT_EQ(4, sel);
    210   ASSERT_EQ(2u, menu.MenuStart());
    211   ASSERT_EQ(5u, menu.MenuEnd());
    212 
    213   // Scroll the menu to the top.
    214   // The expected menu sel, start & ends are:
    215   // sel 3, start 2, end 5
    216   // sel 2, start 2, end 5
    217   // sel 1, start 1, end 4
    218   // sel 0, start 0, end 3
    219   for (int i = 0; i < 4; i++) {
    220     sel = menu.Select(--sel);
    221     ASSERT_EQ(3 - i, sel);
    222     ASSERT_EQ(static_cast<size_t>(std::min(3 - i, 2)), menu.MenuStart());
    223     ASSERT_EQ(static_cast<size_t>(std::min(6 - i, 5)), menu.MenuEnd());
    224   }
    225 
    226   // Press up button one more time won't change the MenuStart() and MenuEnd().
    227   sel = menu.Select(--sel);
    228   ASSERT_EQ(0, sel);
    229   ASSERT_EQ(0u, menu.MenuStart());
    230   ASSERT_EQ(3u, menu.MenuEnd());
    231 }
    232 
    233 TEST_F(ScreenUITest, GraphicMenuSelection) {
    234   auto image = GRSurface::Create(50, 50, 50, 1);
    235   auto header = image->Clone();
    236   std::vector<const GRSurface*> items = {
    237     image.get(),
    238     image.get(),
    239     image.get(),
    240   };
    241   GraphicMenu menu(header.get(), items, 0, draw_funcs_);
    242 
    243   ASSERT_EQ(0, menu.selection());
    244 
    245   int sel = 0;
    246   for (int i = 0; i < 3; i++) {
    247     sel = menu.Select(++sel);
    248     ASSERT_EQ((i + 1) % 3, sel);
    249     ASSERT_EQ(sel, menu.selection());
    250   }
    251 
    252   sel = 0;
    253   for (int i = 0; i < 3; i++) {
    254     sel = menu.Select(--sel);
    255     ASSERT_EQ(2 - i, sel);
    256     ASSERT_EQ(sel, menu.selection());
    257   }
    258 }
    259 
    260 TEST_F(ScreenUITest, GraphicMenuValidate) {
    261   auto image = GRSurface::Create(50, 50, 50, 1);
    262   auto header = image->Clone();
    263   std::vector<const GRSurface*> items = {
    264     image.get(),
    265     image.get(),
    266     image.get(),
    267   };
    268 
    269   ASSERT_TRUE(GraphicMenu::Validate(200, 200, header.get(), items));
    270 
    271   // Menu exceeds the horizontal boundary.
    272   auto wide_surface = GRSurface::Create(300, 50, 300, 1);
    273   ASSERT_FALSE(GraphicMenu::Validate(299, 200, wide_surface.get(), items));
    274 
    275   // Menu exceeds the vertical boundary.
    276   items.emplace_back(image.get());
    277   ASSERT_FALSE(GraphicMenu::Validate(200, 249, header.get(), items));
    278 }
    279 
    280 static constexpr int kMagicAction = 101;
    281 
    282 enum class KeyCode : int {
    283   TIMEOUT = -1,
    284   NO_OP = 0,
    285   UP = 1,
    286   DOWN = 2,
    287   ENTER = 3,
    288   MAGIC = 1001,
    289   LAST,
    290 };
    291 
    292 static const std::map<KeyCode, int> kKeyMapping{
    293   // clang-format off
    294   { KeyCode::NO_OP, Device::kNoAction },
    295   { KeyCode::UP, Device::kHighlightUp },
    296   { KeyCode::DOWN, Device::kHighlightDown },
    297   { KeyCode::ENTER, Device::kInvokeItem },
    298   { KeyCode::MAGIC, kMagicAction },
    299   // clang-format on
    300 };
    301 
    302 class TestableScreenRecoveryUI : public ScreenRecoveryUI {
    303  public:
    304   int WaitKey() override;
    305 
    306   void SetKeyBuffer(const std::vector<KeyCode>& buffer);
    307 
    308   int KeyHandler(int key, bool visible) const;
    309 
    310  private:
    311   FRIEND_TEST(DISABLED_ScreenRecoveryUITest, Init);
    312   FRIEND_TEST(DISABLED_ScreenRecoveryUITest, RtlLocale);
    313   FRIEND_TEST(DISABLED_ScreenRecoveryUITest, RtlLocaleWithSuffix);
    314   FRIEND_TEST(DISABLED_ScreenRecoveryUITest, LoadAnimation);
    315   FRIEND_TEST(DISABLED_ScreenRecoveryUITest, LoadAnimation_MissingAnimation);
    316 
    317   std::vector<KeyCode> key_buffer_;
    318   size_t key_buffer_index_;
    319 };
    320 
    321 void TestableScreenRecoveryUI::SetKeyBuffer(const std::vector<KeyCode>& buffer) {
    322   key_buffer_ = buffer;
    323   key_buffer_index_ = 0;
    324 }
    325 
    326 int TestableScreenRecoveryUI::KeyHandler(int key, bool) const {
    327   KeyCode key_code = static_cast<KeyCode>(key);
    328   if (kKeyMapping.find(key_code) != kKeyMapping.end()) {
    329     return kKeyMapping.at(key_code);
    330   }
    331   return Device::kNoAction;
    332 }
    333 
    334 int TestableScreenRecoveryUI::WaitKey() {
    335   if (IsKeyInterrupted()) {
    336     return static_cast<int>(RecoveryUI::KeyError::INTERRUPTED);
    337   }
    338 
    339   CHECK_LT(key_buffer_index_, key_buffer_.size());
    340   return static_cast<int>(key_buffer_[key_buffer_index_++]);
    341 }
    342 
    343 class DISABLED_ScreenRecoveryUITest : public ::testing::Test {
    344  protected:
    345   const std::string kTestLocale = "en-US";
    346   const std::string kTestRtlLocale = "ar";
    347   const std::string kTestRtlLocaleWithSuffix = "ar-EG";
    348 
    349   void SetUp() override {
    350     has_graphics_ = gr_init() == 0;
    351     gr_exit();
    352 
    353     if (has_graphics_) {
    354       ui_ = std::make_unique<TestableScreenRecoveryUI>();
    355     }
    356 
    357     testdata_dir_ = from_testdata_base("");
    358     Paths::Get().set_resource_dir(testdata_dir_);
    359     res_set_resource_dir(testdata_dir_);
    360   }
    361 
    362   bool has_graphics_;
    363   std::unique_ptr<TestableScreenRecoveryUI> ui_;
    364   std::string testdata_dir_;
    365 };
    366 
    367 #define RETURN_IF_NO_GRAPHICS                                                 \
    368   do {                                                                        \
    369     if (!has_graphics_) {                                                     \
    370       GTEST_LOG_(INFO) << "Test skipped due to no available graphics device"; \
    371       return;                                                                 \
    372     }                                                                         \
    373   } while (false)
    374 
    375 TEST_F(DISABLED_ScreenRecoveryUITest, Init) {
    376   RETURN_IF_NO_GRAPHICS;
    377 
    378   ASSERT_TRUE(ui_->Init(kTestLocale));
    379   ASSERT_EQ(kTestLocale, ui_->GetLocale());
    380   ASSERT_FALSE(ui_->rtl_locale_);
    381   ASSERT_FALSE(ui_->IsTextVisible());
    382   ASSERT_FALSE(ui_->WasTextEverVisible());
    383 }
    384 
    385 TEST_F(DISABLED_ScreenRecoveryUITest, dtor_NotCallingInit) {
    386   ui_.reset();
    387   ASSERT_FALSE(ui_);
    388 }
    389 
    390 TEST_F(DISABLED_ScreenRecoveryUITest, ShowText) {
    391   RETURN_IF_NO_GRAPHICS;
    392 
    393   ASSERT_TRUE(ui_->Init(kTestLocale));
    394   ASSERT_FALSE(ui_->IsTextVisible());
    395   ui_->ShowText(true);
    396   ASSERT_TRUE(ui_->IsTextVisible());
    397   ASSERT_TRUE(ui_->WasTextEverVisible());
    398 
    399   ui_->ShowText(false);
    400   ASSERT_FALSE(ui_->IsTextVisible());
    401   ASSERT_TRUE(ui_->WasTextEverVisible());
    402 }
    403 
    404 TEST_F(DISABLED_ScreenRecoveryUITest, RtlLocale) {
    405   RETURN_IF_NO_GRAPHICS;
    406 
    407   ASSERT_TRUE(ui_->Init(kTestRtlLocale));
    408   ASSERT_TRUE(ui_->rtl_locale_);
    409 }
    410 
    411 TEST_F(DISABLED_ScreenRecoveryUITest, RtlLocaleWithSuffix) {
    412   RETURN_IF_NO_GRAPHICS;
    413 
    414   ASSERT_TRUE(ui_->Init(kTestRtlLocaleWithSuffix));
    415   ASSERT_TRUE(ui_->rtl_locale_);
    416 }
    417 
    418 TEST_F(DISABLED_ScreenRecoveryUITest, ShowMenu) {
    419   RETURN_IF_NO_GRAPHICS;
    420 
    421   ASSERT_TRUE(ui_->Init(kTestLocale));
    422   ui_->SetKeyBuffer({
    423       KeyCode::UP,
    424       KeyCode::DOWN,
    425       KeyCode::UP,
    426       KeyCode::DOWN,
    427       KeyCode::ENTER,
    428   });
    429   ASSERT_EQ(3u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
    430                               std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    431                                         std::placeholders::_1, std::placeholders::_2)));
    432 
    433   ui_->SetKeyBuffer({
    434       KeyCode::UP,
    435       KeyCode::UP,
    436       KeyCode::NO_OP,
    437       KeyCode::NO_OP,
    438       KeyCode::UP,
    439       KeyCode::ENTER,
    440   });
    441   ASSERT_EQ(2u, ui_->ShowMenu(HEADERS, ITEMS, 0, true,
    442                               std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    443                                         std::placeholders::_1, std::placeholders::_2)));
    444 }
    445 
    446 TEST_F(DISABLED_ScreenRecoveryUITest, ShowMenu_NotMenuOnly) {
    447   RETURN_IF_NO_GRAPHICS;
    448 
    449   ASSERT_TRUE(ui_->Init(kTestLocale));
    450   ui_->SetKeyBuffer({
    451       KeyCode::MAGIC,
    452   });
    453   ASSERT_EQ(static_cast<size_t>(kMagicAction),
    454             ui_->ShowMenu(HEADERS, ITEMS, 3, false,
    455                           std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    456                                     std::placeholders::_1, std::placeholders::_2)));
    457 }
    458 
    459 TEST_F(DISABLED_ScreenRecoveryUITest, ShowMenu_TimedOut) {
    460   RETURN_IF_NO_GRAPHICS;
    461 
    462   ASSERT_TRUE(ui_->Init(kTestLocale));
    463   ui_->SetKeyBuffer({
    464       KeyCode::TIMEOUT,
    465   });
    466   ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT),
    467             ui_->ShowMenu(HEADERS, ITEMS, 3, true, nullptr));
    468 }
    469 
    470 TEST_F(DISABLED_ScreenRecoveryUITest, ShowMenu_TimedOut_TextWasEverVisible) {
    471   RETURN_IF_NO_GRAPHICS;
    472 
    473   ASSERT_TRUE(ui_->Init(kTestLocale));
    474   ui_->ShowText(true);
    475   ui_->ShowText(false);
    476   ASSERT_TRUE(ui_->WasTextEverVisible());
    477 
    478   ui_->SetKeyBuffer({
    479       KeyCode::TIMEOUT,
    480       KeyCode::DOWN,
    481       KeyCode::ENTER,
    482   });
    483   ASSERT_EQ(4u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
    484                               std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    485                                         std::placeholders::_1, std::placeholders::_2)));
    486 }
    487 
    488 TEST_F(DISABLED_ScreenRecoveryUITest, ShowMenuWithInterrupt) {
    489   RETURN_IF_NO_GRAPHICS;
    490 
    491   ASSERT_TRUE(ui_->Init(kTestLocale));
    492   ui_->SetKeyBuffer({
    493       KeyCode::UP,
    494       KeyCode::DOWN,
    495       KeyCode::UP,
    496       KeyCode::DOWN,
    497       KeyCode::ENTER,
    498   });
    499 
    500   ui_->InterruptKey();
    501   ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
    502             ui_->ShowMenu(HEADERS, ITEMS, 3, true,
    503                           std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    504                                     std::placeholders::_1, std::placeholders::_2)));
    505 
    506   ui_->SetKeyBuffer({
    507       KeyCode::UP,
    508       KeyCode::UP,
    509       KeyCode::NO_OP,
    510       KeyCode::NO_OP,
    511       KeyCode::UP,
    512       KeyCode::ENTER,
    513   });
    514   ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
    515             ui_->ShowMenu(HEADERS, ITEMS, 0, true,
    516                           std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
    517                                     std::placeholders::_1, std::placeholders::_2)));
    518 }
    519 
    520 TEST_F(DISABLED_ScreenRecoveryUITest, LoadAnimation) {
    521   RETURN_IF_NO_GRAPHICS;
    522 
    523   ASSERT_TRUE(ui_->Init(kTestLocale));
    524   // Make a few copies of loop00000.png from testdata.
    525   std::string image_data;
    526   ASSERT_TRUE(android::base::ReadFileToString(testdata_dir_ + "/loop00000.png", &image_data));
    527 
    528   std::vector<std::string> tempfiles;
    529   TemporaryDir resource_dir;
    530   for (const auto& name : { "00002", "00100", "00050" }) {
    531     tempfiles.push_back(android::base::StringPrintf("%s/loop%s.png", resource_dir.path, name));
    532     ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
    533   }
    534   for (const auto& name : { "00", "01" }) {
    535     tempfiles.push_back(android::base::StringPrintf("%s/intro%s.png", resource_dir.path, name));
    536     ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
    537   }
    538   Paths::Get().set_resource_dir(resource_dir.path);
    539 
    540   ui_->LoadAnimation();
    541 
    542   ASSERT_EQ(2u, ui_->intro_frames_.size());
    543   ASSERT_EQ(3u, ui_->loop_frames_.size());
    544 
    545   for (const auto& name : tempfiles) {
    546     ASSERT_EQ(0, unlink(name.c_str()));
    547   }
    548 }
    549 
    550 TEST_F(DISABLED_ScreenRecoveryUITest, LoadAnimation_MissingAnimation) {
    551   RETURN_IF_NO_GRAPHICS;
    552 
    553   ASSERT_TRUE(ui_->Init(kTestLocale));
    554   // We need a dir that doesn't contain any animation. However, using TemporaryDir will give
    555   // leftovers since this is a death test where TemporaryDir::~TemporaryDir() won't be called.
    556   Paths::Get().set_resource_dir("/proc/self");
    557 
    558   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    559   ASSERT_EXIT(ui_->LoadAnimation(), ::testing::KilledBySignal(SIGABRT), "");
    560 }
    561 
    562 #undef RETURN_IF_NO_GRAPHICS
    563