Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18a5d529 authored by Tao Bao's avatar Tao Bao Committed by android-build-merger
Browse files

Merge "ui: Manage loaded resources with smart pointers."

am: 06aea3a8

Change-Id: I2ca8a20ee76d743bbf5cb7f2956de1497b343de2
parents 2a4e64a3 06aea3a8
Loading
Loading
Loading
Loading
+106 −101
Original line number Diff line number Diff line
@@ -197,11 +197,16 @@ int TextMenu::DrawItems(int x, int y, int screen_width, bool long_press) const {
  return offset;
}

GraphicMenu::GraphicMenu(GRSurface* graphic_headers, const std::vector<GRSurface*>& graphic_items,
GraphicMenu::GraphicMenu(const GRSurface* graphic_headers,
                         const std::vector<const GRSurface*>& graphic_items,
                         size_t initial_selection, const DrawInterface& draw_funcs)
    : Menu(initial_selection, draw_funcs),
      graphic_headers_(graphic_headers),
      graphic_items_(graphic_items) {}
    : Menu(initial_selection, draw_funcs) {
  graphic_headers_ = graphic_headers->Clone();
  graphic_items_.reserve(graphic_items.size());
  for (const auto& item : graphic_items) {
    graphic_items_.emplace_back(item->Clone());
  }
}

int GraphicMenu::Select(int sel) {
  CHECK_LE(graphic_items_.size(), static_cast<size_t>(std::numeric_limits<int>::max()));
@@ -221,7 +226,7 @@ int GraphicMenu::Select(int sel) {

int GraphicMenu::DrawHeader(int x, int y) const {
  draw_funcs_.SetColor(UIElement::HEADER);
  draw_funcs_.DrawTextIcon(x, y, graphic_headers_);
  draw_funcs_.DrawTextIcon(x, y, graphic_headers_.get());
  return graphic_headers_->height;
}

@@ -242,7 +247,7 @@ int GraphicMenu::DrawItems(int x, int y, int screen_width, bool long_press) cons
      // Bold white text for the selected item.
      draw_funcs_.SetColor(UIElement::MENU_SEL_FG);
    }
    draw_funcs_.DrawTextIcon(x, y + offset, item);
    draw_funcs_.DrawTextIcon(x, y + offset, item.get());
    offset += item->height;

    draw_funcs_.SetColor(UIElement::MENU);
@@ -251,8 +256,8 @@ int GraphicMenu::DrawItems(int x, int y, int screen_width, bool long_press) cons
  return offset;
}

bool GraphicMenu::Validate(size_t max_width, size_t max_height, GRSurface* graphic_headers,
                           const std::vector<GRSurface*>& graphic_items) {
bool GraphicMenu::Validate(size_t max_width, size_t max_height, const GRSurface* graphic_headers,
                           const std::vector<const GRSurface*>& graphic_items) {
  int offset = 0;
  if (!ValidateGraphicSurface(max_width, max_height, offset, graphic_headers)) {
    return false;
@@ -307,7 +312,9 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
      animation_fps_(
          android::base::GetIntProperty("ro.recovery.ui.animation_fps", kDefaultAnimationFps)),
      density_(static_cast<float>(android::base::GetIntProperty("ro.sf.lcd_density", 160)) / 160.f),
      currentIcon(NONE),
      current_icon_(NONE),
      current_frame_(0),
      intro_done_(false),
      progressBarType(EMPTY),
      progressScopeStart(0),
      progressScopeSize(0),
@@ -322,10 +329,6 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
      show_text_ever(false),
      scrollable_menu_(scrollable_menu),
      file_viewer_text_(nullptr),
      intro_frames(0),
      loop_frames(0),
      current_frame(0),
      intro_done(false),
      stage(-1),
      max_stage(-1),
      locale_(""),
@@ -340,23 +343,23 @@ ScreenRecoveryUI::~ScreenRecoveryUI() {
  gr_exit();
}

GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
  if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
    return intro_done ? loopFrames[current_frame] : introFrames[current_frame];
const GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
  if (current_icon_ == INSTALLING_UPDATE || current_icon_ == ERASING) {
    return intro_done_ ? loop_frames_[current_frame_].get() : intro_frames_[current_frame_].get();
  }
  return error_icon;
  return error_icon_.get();
}

GRSurface* ScreenRecoveryUI::GetCurrentText() const {
  switch (currentIcon) {
const GRSurface* ScreenRecoveryUI::GetCurrentText() const {
  switch (current_icon_) {
    case ERASING:
      return erasing_text;
      return erasing_text_.get();
    case ERROR:
      return error_text;
      return error_text_.get();
    case INSTALLING_UPDATE:
      return installing_text;
      return installing_text_.get();
    case NO_COMMAND:
      return no_command_text;
      return no_command_text_.get();
    case NONE:
      abort();
  }
@@ -391,20 +394,21 @@ static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
};

int ScreenRecoveryUI::GetAnimationBaseline() const {
  return GetTextBaseline() - PixelsFromDp(kLayouts[layout_][ICON]) - gr_get_height(loopFrames[0]);
  return GetTextBaseline() - PixelsFromDp(kLayouts[layout_][ICON]) -
         gr_get_height(loop_frames_[0].get());
}

int ScreenRecoveryUI::GetTextBaseline() const {
  return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) -
         gr_get_height(installing_text);
         gr_get_height(installing_text_.get());
}

int ScreenRecoveryUI::GetProgressBaseline() const {
  int elements_sum = gr_get_height(loopFrames[0]) + PixelsFromDp(kLayouts[layout_][ICON]) +
                     gr_get_height(installing_text) + PixelsFromDp(kLayouts[layout_][TEXT]) +
                     gr_get_height(progressBarFill);
  int elements_sum = gr_get_height(loop_frames_[0].get()) + PixelsFromDp(kLayouts[layout_][ICON]) +
                     gr_get_height(installing_text_.get()) + PixelsFromDp(kLayouts[layout_][TEXT]) +
                     gr_get_height(progress_bar_fill_.get());
  int bottom_gap = (ScreenHeight() - elements_sum) / 2;
  return ScreenHeight() - bottom_gap - gr_get_height(progressBarFill);
  return ScreenHeight() - bottom_gap - gr_get_height(progress_bar_fill_.get());
}

// Clear the screen and draw the currently selected background icon (if any).
@@ -413,20 +417,20 @@ void ScreenRecoveryUI::draw_background_locked() {
  pagesIdentical = false;
  gr_color(0, 0, 0, 255);
  gr_clear();
  if (currentIcon != NONE) {
  if (current_icon_ != NONE) {
    if (max_stage != -1) {
      int stage_height = gr_get_height(stageMarkerEmpty);
      int stage_width = gr_get_width(stageMarkerEmpty);
      int x = (ScreenWidth() - max_stage * gr_get_width(stageMarkerEmpty)) / 2;
      int stage_height = gr_get_height(stage_marker_empty_.get());
      int stage_width = gr_get_width(stage_marker_empty_.get());
      int x = (ScreenWidth() - max_stage * gr_get_width(stage_marker_empty_.get())) / 2;
      int y = ScreenHeight() - stage_height - margin_height_;
      for (int i = 0; i < max_stage; ++i) {
        GRSurface* stage_surface = (i < stage) ? stageMarkerFill : stageMarkerEmpty;
        DrawSurface(stage_surface, 0, 0, stage_width, stage_height, x, y);
        const auto& stage_surface = (i < stage) ? stage_marker_fill_ : stage_marker_empty_;
        DrawSurface(stage_surface.get(), 0, 0, stage_width, stage_height, x, y);
        x += stage_width;
      }
    }

    GRSurface* text_surface = GetCurrentText();
    const auto& text_surface = GetCurrentText();
    int text_x = (ScreenWidth() - gr_get_width(text_surface)) / 2;
    int text_y = GetTextBaseline();
    gr_color(255, 255, 255, 255);
@@ -437,8 +441,8 @@ void ScreenRecoveryUI::draw_background_locked() {
// Draws the animation and progress bar (if any) on the screen. Does not flip pages. Should only be
// called with updateMutex locked.
void ScreenRecoveryUI::draw_foreground_locked() {
  if (currentIcon != NONE) {
    GRSurface* frame = GetCurrentFrame();
  if (current_icon_ != NONE) {
    const auto& frame = GetCurrentFrame();
    int frame_width = gr_get_width(frame);
    int frame_height = gr_get_height(frame);
    int frame_x = (ScreenWidth() - frame_width) / 2;
@@ -447,8 +451,8 @@ void ScreenRecoveryUI::draw_foreground_locked() {
  }

  if (progressBarType != EMPTY) {
    int width = gr_get_width(progressBarEmpty);
    int height = gr_get_height(progressBarEmpty);
    int width = gr_get_width(progress_bar_empty_.get());
    int height = gr_get_height(progress_bar_empty_.get());

    int progress_x = (ScreenWidth() - width) / 2;
    int progress_y = GetProgressBaseline();
@@ -464,19 +468,20 @@ void ScreenRecoveryUI::draw_foreground_locked() {
      if (rtl_locale_) {
        // Fill the progress bar from right to left.
        if (pos > 0) {
          DrawSurface(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos,
                      progress_y);
          DrawSurface(progress_bar_fill_.get(), width - pos, 0, pos, height,
                      progress_x + width - pos, progress_y);
        }
        if (pos < width - 1) {
          DrawSurface(progressBarEmpty, 0, 0, width - pos, height, progress_x, progress_y);
          DrawSurface(progress_bar_empty_.get(), 0, 0, width - pos, height, progress_x, progress_y);
        }
      } else {
        // Fill the progress bar from left to right.
        if (pos > 0) {
          DrawSurface(progressBarFill, 0, 0, pos, height, progress_x, progress_y);
          DrawSurface(progress_bar_fill_.get(), 0, 0, pos, height, progress_x, progress_y);
        }
        if (pos < width - 1) {
          DrawSurface(progressBarEmpty, pos, 0, width - pos, height, progress_x + pos, progress_y);
          DrawSurface(progress_bar_empty_.get(), pos, 0, width - pos, height, progress_x + pos,
                      progress_y);
        }
      }
    }
@@ -518,15 +523,14 @@ void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector<std::string
  SetLocale(locales_entries[sel]);
  std::vector<std::string> text_name = { "erasing_text", "error_text", "installing_text",
                                         "installing_security_text", "no_command_text" };
  std::unordered_map<std::string, std::unique_ptr<GRSurface, decltype(&free)>> surfaces;
  std::unordered_map<std::string, std::unique_ptr<GRSurface>> surfaces;
  for (const auto& name : text_name) {
    GRSurface* text_image = nullptr;
    LoadLocalizedBitmap(name.c_str(), &text_image);
    auto text_image = LoadLocalizedBitmap(name);
    if (!text_image) {
      Print("Failed to load %s\n", name.c_str());
      return;
    }
    surfaces.emplace(name, std::unique_ptr<GRSurface, decltype(&free)>(text_image, &free));
    surfaces.emplace(name, std::move(text_image));
  }

  std::lock_guard<std::mutex> lg(updateMutex);
@@ -753,16 +757,16 @@ void ScreenRecoveryUI::ProgressThreadLoop() {

      // update the installation animation, if active
      // skip this if we have a text overlay (too expensive to update)
      if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) {
        if (!intro_done) {
          if (current_frame == intro_frames - 1) {
            intro_done = true;
            current_frame = 0;
      if ((current_icon_ == INSTALLING_UPDATE || current_icon_ == ERASING) && !show_text) {
        if (!intro_done_) {
          if (current_frame_ == intro_frames_.size() - 1) {
            intro_done_ = true;
            current_frame_ = 0;
          } else {
            ++current_frame;
            ++current_frame_;
          }
        } else {
          current_frame = (current_frame + 1) % loop_frames;
          current_frame_ = (current_frame_ + 1) % loop_frames_.size();
        }

        redraw = true;
@@ -791,18 +795,23 @@ void ScreenRecoveryUI::ProgressThreadLoop() {
  }
}

void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) {
  int result = res_create_display_surface(filename, surface);
  if (result < 0) {
    LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")";
std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadBitmap(const std::string& filename) {
  GRSurface* surface;
  if (auto result = res_create_display_surface(filename.c_str(), &surface); result < 0) {
    LOG(ERROR) << "Failed to load bitmap " << filename << " (error " << result << ")";
    return nullptr;
  }
  return std::unique_ptr<GRSurface>(surface);
}

void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) {
  int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface);
  if (result < 0) {
    LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")";
std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadLocalizedBitmap(const std::string& filename) {
  GRSurface* surface;
  if (auto result = res_create_localized_alpha_surface(filename.c_str(), locale_.c_str(), &surface);
      result < 0) {
    LOG(ERROR) << "Failed to load bitmap " << filename << " (error " << result << ")";
    return nullptr;
  }
  return std::unique_ptr<GRSurface>(surface);
}

static char** Alloc2d(size_t rows, size_t cols) {
@@ -817,9 +826,9 @@ static char** Alloc2d(size_t rows, size_t cols) {
// Choose the right background string to display during update.
void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
  if (security_update) {
    LoadLocalizedBitmap("installing_security_text", &installing_text);
    installing_text_ = LoadLocalizedBitmap("installing_security_text");
  } else {
    LoadLocalizedBitmap("installing_text", &installing_text);
    installing_text_ = LoadLocalizedBitmap("installing_text");
  }
  Redraw();
}
@@ -838,10 +847,6 @@ bool ScreenRecoveryUI::InitTextParams() {
// TODO(xunchang) load localized text icons for the menu. (Init for screenRecoveryUI but
// not wearRecoveryUI).
bool ScreenRecoveryUI::LoadWipeDataMenuText() {
  wipe_data_menu_header_text_ = nullptr;
  factory_data_reset_text_ = nullptr;
  try_again_text_ = nullptr;

  return true;
}

@@ -869,21 +874,20 @@ bool ScreenRecoveryUI::Init(const std::string& locale) {
  // Set up the locale info.
  SetLocale(locale);

  LoadBitmap("icon_error", &error_icon);
  error_icon_ = LoadBitmap("icon_error");

  LoadBitmap("progress_empty", &progressBarEmpty);
  LoadBitmap("progress_fill", &progressBarFill);
  progress_bar_empty_ = LoadBitmap("progress_empty");
  progress_bar_fill_ = LoadBitmap("progress_fill");
  stage_marker_empty_ = LoadBitmap("stage_empty");
  stage_marker_fill_ = LoadBitmap("stage_fill");

  LoadBitmap("stage_empty", &stageMarkerEmpty);
  LoadBitmap("stage_fill", &stageMarkerFill);
  erasing_text_ = LoadLocalizedBitmap("erasing_text");
  no_command_text_ = LoadLocalizedBitmap("no_command_text");
  error_text_ = LoadLocalizedBitmap("error_text");

  // Background text for "installing_update" could be "installing update"
  // or "installing security update". It will be set after UI init according
  // to commands in BCB.
  installing_text = nullptr;
  LoadLocalizedBitmap("erasing_text", &erasing_text);
  LoadLocalizedBitmap("no_command_text", &no_command_text);
  LoadLocalizedBitmap("error_text", &error_text);
  // Background text for "installing_update" could be "installing update" or
  // "installing security update". It will be set after Init() according to the commands in BCB.
  installing_text_.reset();

  LoadWipeDataMenuText();

@@ -915,32 +919,34 @@ void ScreenRecoveryUI::LoadAnimation() {
    }
  }

  intro_frames = intro_frame_names.size();
  loop_frames = loop_frame_names.size();
  size_t intro_frames = intro_frame_names.size();
  size_t loop_frames = loop_frame_names.size();

  // It's okay to not have an intro.
  if (intro_frames == 0) intro_done = true;
  if (intro_frames == 0) intro_done_ = true;
  // But you must have an animation.
  if (loop_frames == 0) abort();

  std::sort(intro_frame_names.begin(), intro_frame_names.end());
  std::sort(loop_frame_names.begin(), loop_frame_names.end());

  introFrames = new GRSurface*[intro_frames];
  for (size_t i = 0; i < intro_frames; i++) {
    LoadBitmap(intro_frame_names.at(i).c_str(), &introFrames[i]);
  intro_frames_.clear();
  intro_frames_.reserve(intro_frames);
  for (const auto& frame_name : intro_frame_names) {
    intro_frames_.emplace_back(LoadBitmap(frame_name));
  }

  loopFrames = new GRSurface*[loop_frames];
  for (size_t i = 0; i < loop_frames; i++) {
    LoadBitmap(loop_frame_names.at(i).c_str(), &loopFrames[i]);
  loop_frames_.clear();
  loop_frames_.reserve(loop_frames);
  for (const auto& frame_name : loop_frame_names) {
    loop_frames_.emplace_back(LoadBitmap(frame_name));
  }
}

void ScreenRecoveryUI::SetBackground(Icon icon) {
  std::lock_guard<std::mutex> lg(updateMutex);

  currentIcon = icon;
  current_icon_ = icon;
  update_screen_locked();
}

@@ -972,7 +978,7 @@ void ScreenRecoveryUI::SetProgress(float fraction) {
  if (fraction > 1.0) fraction = 1.0;
  if (progressBarType == DETERMINATE && fraction > progress) {
    // Skip updates that aren't visibly different.
    int width = gr_get_width(progressBarEmpty);
    int width = gr_get_width(progress_bar_empty_.get());
    float scale = width * progressScopeSize;
    if ((int)(progress * scale) != (int)(fraction * scale)) {
      progress = fraction;
@@ -1115,10 +1121,9 @@ void ScreenRecoveryUI::ShowFile(const std::string& filename) {
  text_row_ = old_text_row;
}

std::unique_ptr<Menu> ScreenRecoveryUI::CreateMenu(GRSurface* graphic_header,
                                                   const std::vector<GRSurface*>& graphic_items,
                                                   const std::vector<std::string>& text_headers,
                                                   const std::vector<std::string>& text_items,
std::unique_ptr<Menu> ScreenRecoveryUI::CreateMenu(
    const GRSurface* graphic_header, const std::vector<const GRSurface*>& graphic_items,
    const std::vector<std::string>& text_headers, const std::vector<std::string>& text_items,
    size_t initial_selection) const {
  // horizontal unusable area: margin width + menu indent
  size_t max_width = ScreenWidth() - margin_width_ - kMenuIndent;
@@ -1235,8 +1240,8 @@ size_t ScreenRecoveryUI::ShowMenu(const std::vector<std::string>& headers,
size_t ScreenRecoveryUI::ShowPromptWipeDataMenu(const std::vector<std::string>& backup_headers,
                                                const std::vector<std::string>& backup_items,
                                                const std::function<int(int, bool)>& key_handler) {
  auto wipe_data_menu =
      CreateMenu(wipe_data_menu_header_text_, { try_again_text_, factory_data_reset_text_ },
  auto wipe_data_menu = CreateMenu(wipe_data_menu_header_text_.get(),
                                   { try_again_text_.get(), factory_data_reset_text_.get() },
                                   backup_headers, backup_items, 0);
  if (wipe_data_menu == nullptr) {
    return 0;
+41 −44
Original line number Diff line number Diff line
@@ -162,32 +162,31 @@ class TextMenu : public Menu {
  int char_height_;
};

// This class uses GRSurfaces* as the menu header and items.
// This class uses GRSurface's as the menu header and items.
class GraphicMenu : public Menu {
 public:
  // Constructs a Menu instance with the given |headers|, |items| and properties. Sets the initial
  // selection to |initial_selection|.
  GraphicMenu(GRSurface* graphic_headers, const std::vector<GRSurface*>& graphic_items,
  // selection to |initial_selection|. |headers| and |items| will be made local copies.
  GraphicMenu(const GRSurface* graphic_headers, const std::vector<const GRSurface*>& graphic_items,
              size_t initial_selection, const DrawInterface& draw_funcs);

  int Select(int sel) override;
  int DrawHeader(int x, int y) const override;
  int DrawItems(int x, int y, int screen_width, bool long_press) const override;

  // Checks if all the header and items are valid GRSurfaces; and that they can fit in the area
  // Checks if all the header and items are valid GRSurface's; and that they can fit in the area
  // defined by |max_width| and |max_height|.
  static bool Validate(size_t max_width, size_t max_height, GRSurface* graphic_headers,
                       const std::vector<GRSurface*>& graphic_items);
  static bool Validate(size_t max_width, size_t max_height, const GRSurface* graphic_headers,
                       const std::vector<const GRSurface*>& graphic_items);

  // Returns true if |surface| fits on the screen with a vertical offset |y|.
  static bool ValidateGraphicSurface(size_t max_width, size_t max_height, int y,
                                     const GRSurface* surface);

 private:
  // Pointers to the menu headers and items in graphic icons. This class does not have the ownership
  // of the these objects.
  GRSurface* graphic_headers_;
  std::vector<GRSurface*> graphic_items_;
  // Menu headers and items in graphic icons. These are the copies owned by the class instance.
  std::unique_ptr<GRSurface> graphic_headers_;
  std::vector<std::unique_ptr<GRSurface>> graphic_items_;
};

// Implementation of RecoveryUI appropriate for devices with a screen
@@ -243,6 +242,7 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {

 protected:
  static constexpr int kMenuIndent = 4;

  // The margin that we don't want to use for showing texts (e.g. round screen, or screen with
  // rounded corners).
  const int margin_width_;
@@ -261,8 +261,8 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
  // Creates a GraphicMenu with |graphic_header| and |graphic_items|. If the GraphicMenu isn't
  // valid or it doesn't fit on the screen; falls back to create a TextMenu instead. If succeeds,
  // returns a unique pointer to the created menu; otherwise returns nullptr.
  virtual std::unique_ptr<Menu> CreateMenu(GRSurface* graphic_header,
                                           const std::vector<GRSurface*>& graphic_items,
  virtual std::unique_ptr<Menu> CreateMenu(const GRSurface* graphic_header,
                                           const std::vector<const GRSurface*>& graphic_items,
                                           const std::vector<std::string>& text_headers,
                                           const std::vector<std::string>& text_items,
                                           size_t initial_selection) const;
@@ -288,8 +288,8 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
  virtual void update_screen_locked();
  virtual void update_progress_locked();

  GRSurface* GetCurrentFrame() const;
  GRSurface* GetCurrentText() const;
  const GRSurface* GetCurrentFrame() const;
  const GRSurface* GetCurrentText() const;

  void ProgressThreadLoop();

@@ -299,8 +299,8 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
  void ClearText();

  void LoadAnimation();
  void LoadBitmap(const char* filename, GRSurface** surface);
  void LoadLocalizedBitmap(const char* filename, GRSurface** surface);
  std::unique_ptr<GRSurface> LoadBitmap(const std::string& filename);
  std::unique_ptr<GRSurface> LoadLocalizedBitmap(const std::string& filename);

  int PixelsFromDp(int dp) const;
  virtual int GetAnimationBaseline() const;
@@ -324,30 +324,34 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
  int DrawTextLines(int x, int y, const std::vector<std::string>& lines) const override;
  int DrawWrappedTextLines(int x, int y, const std::vector<std::string>& lines) const override;

  Icon currentIcon;

  // The layout to use.
  int layout_;

  GRSurface* error_icon;

  GRSurface* erasing_text;
  GRSurface* error_text;
  GRSurface* installing_text;
  GRSurface* no_command_text;

  // Graphs for the wipe data menu
  GRSurface* wipe_data_menu_header_text_;
  GRSurface* try_again_text_;
  GRSurface* factory_data_reset_text_;

  GRSurface** introFrames;
  GRSurface** loopFrames;

  GRSurface* progressBarEmpty;
  GRSurface* progressBarFill;
  GRSurface* stageMarkerEmpty;
  GRSurface* stageMarkerFill;
  // The images that contain localized texts.
  std::unique_ptr<GRSurface> erasing_text_;
  std::unique_ptr<GRSurface> error_text_;
  std::unique_ptr<GRSurface> installing_text_;
  std::unique_ptr<GRSurface> no_command_text_;

  // Localized text images for the wipe data menu.
  std::unique_ptr<GRSurface> wipe_data_menu_header_text_;
  std::unique_ptr<GRSurface> try_again_text_;
  std::unique_ptr<GRSurface> factory_data_reset_text_;

  // current_icon_ points to one of the frames in intro_frames_ or loop_frames_, indexed by
  // current_frame_, or error_icon_.
  Icon current_icon_;
  std::unique_ptr<GRSurface> error_icon_;
  std::vector<std::unique_ptr<GRSurface>> intro_frames_;
  std::vector<std::unique_ptr<GRSurface>> loop_frames_;
  size_t current_frame_;
  bool intro_done_;

  // progress_bar and stage_marker images.
  std::unique_ptr<GRSurface> progress_bar_empty_;
  std::unique_ptr<GRSurface> progress_bar_fill_;
  std::unique_ptr<GRSurface> stage_marker_empty_;
  std::unique_ptr<GRSurface> stage_marker_fill_;

  ProgressType progressBarType;

@@ -377,13 +381,6 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
  std::thread progress_thread_;
  std::atomic<bool> progress_thread_stopped_{ false };

  // Number of intro frames and loop frames in the animation.
  size_t intro_frames;
  size_t loop_frames;

  size_t current_frame;
  bool intro_done;

  int stage, max_stage;

  int char_width_;
+15 −15
Original line number Diff line number Diff line
@@ -231,12 +231,12 @@ TEST_F(ScreenUITest, WearMenuSelectItemsOverflow) {
}

TEST_F(ScreenUITest, GraphicMenuSelection) {
  auto header = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  auto item = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  std::vector<GRSurface*> items = {
    item.get(),
    item.get(),
    item.get(),
  auto image = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  auto header = image->Clone();
  std::vector<const GRSurface*> items = {
    image.get(),
    image.get(),
    image.get(),
  };
  GraphicMenu menu(header.get(), items, 0, draw_funcs_);

@@ -258,12 +258,12 @@ TEST_F(ScreenUITest, GraphicMenuSelection) {
}

TEST_F(ScreenUITest, GraphicMenuValidate) {
  auto header = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  auto item = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  std::vector<GRSurface*> items = {
    item.get(),
    item.get(),
    item.get(),
  auto image = GRSurface::Create(50, 50, 50, 1, 50 * 50);
  auto header = image->Clone();
  std::vector<const GRSurface*> items = {
    image.get(),
    image.get(),
    image.get(),
  };

  ASSERT_TRUE(GraphicMenu::Validate(200, 200, header.get(), items));
@@ -273,7 +273,7 @@ TEST_F(ScreenUITest, GraphicMenuValidate) {
  ASSERT_FALSE(GraphicMenu::Validate(299, 200, wide_surface.get(), items));

  // Menu exceeds the vertical boundary.
  items.push_back(item.get());
  items.emplace_back(image.get());
  ASSERT_FALSE(GraphicMenu::Validate(200, 249, header.get(), items));
}

@@ -539,8 +539,8 @@ TEST_F(ScreenRecoveryUITest, LoadAnimation) {

  ui_->LoadAnimation();

  ASSERT_EQ(2u, ui_->intro_frames);
  ASSERT_EQ(3u, ui_->loop_frames);
  ASSERT_EQ(2u, ui_->intro_frames_.size());
  ASSERT_EQ(3u, ui_->loop_frames_.size());

  for (const auto& name : tempfiles) {
    ASSERT_EQ(0, unlink(name.c_str()));
+3 −3
Original line number Diff line number Diff line
@@ -51,8 +51,8 @@ void WearRecoveryUI::draw_background_locked() {
  gr_color(0, 0, 0, 255);
  gr_fill(0, 0, gr_fb_width(), gr_fb_height());

  if (currentIcon != NONE) {
    GRSurface* frame = GetCurrentFrame();
  if (current_icon_ != NONE) {
    const auto& frame = GetCurrentFrame();
    int frame_width = gr_get_width(frame);
    int frame_height = gr_get_height(frame);
    int frame_x = (gr_fb_width() - frame_width) / 2;
@@ -60,7 +60,7 @@ void WearRecoveryUI::draw_background_locked() {
    gr_blit(frame, 0, 0, frame_width, frame_height, frame_x, frame_y);

    // Draw recovery text on screen above progress bar.
    GRSurface* text = GetCurrentText();
    const auto& text = GetCurrentText();
    int text_x = (ScreenWidth() - gr_get_width(text)) / 2;
    int text_y = GetProgressBaseline() - gr_get_height(text) - 10;
    gr_color(255, 255, 255, 255);