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

This commit is contained in:
Treehugger Robot
2018-11-06 01:37:37 +00:00
committed by Gerrit Code Review
4 changed files with 162 additions and 160 deletions
+106 -101
View File
@@ -197,11 +197,16 @@ int TextMenu::DrawItems(int x, int y, int screen_width, bool long_press) const {
return offset; 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) size_t initial_selection, const DrawInterface& draw_funcs)
: Menu(initial_selection, draw_funcs), : Menu(initial_selection, draw_funcs) {
graphic_headers_(graphic_headers), graphic_headers_ = graphic_headers->Clone();
graphic_items_(graphic_items) {} graphic_items_.reserve(graphic_items.size());
for (const auto& item : graphic_items) {
graphic_items_.emplace_back(item->Clone());
}
}
int GraphicMenu::Select(int sel) { int GraphicMenu::Select(int sel) {
CHECK_LE(graphic_items_.size(), static_cast<size_t>(std::numeric_limits<int>::max())); 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 { int GraphicMenu::DrawHeader(int x, int y) const {
draw_funcs_.SetColor(UIElement::HEADER); draw_funcs_.SetColor(UIElement::HEADER);
draw_funcs_.DrawTextIcon(x, y, graphic_headers_); draw_funcs_.DrawTextIcon(x, y, graphic_headers_.get());
return graphic_headers_->height; 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. // Bold white text for the selected item.
draw_funcs_.SetColor(UIElement::MENU_SEL_FG); 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; offset += item->height;
draw_funcs_.SetColor(UIElement::MENU); 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; return offset;
} }
bool GraphicMenu::Validate(size_t max_width, size_t max_height, GRSurface* graphic_headers, bool GraphicMenu::Validate(size_t max_width, size_t max_height, const GRSurface* graphic_headers,
const std::vector<GRSurface*>& graphic_items) { const std::vector<const GRSurface*>& graphic_items) {
int offset = 0; int offset = 0;
if (!ValidateGraphicSurface(max_width, max_height, offset, graphic_headers)) { if (!ValidateGraphicSurface(max_width, max_height, offset, graphic_headers)) {
return false; return false;
@@ -307,7 +312,9 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
animation_fps_( animation_fps_(
android::base::GetIntProperty("ro.recovery.ui.animation_fps", kDefaultAnimationFps)), android::base::GetIntProperty("ro.recovery.ui.animation_fps", kDefaultAnimationFps)),
density_(static_cast<float>(android::base::GetIntProperty("ro.sf.lcd_density", 160)) / 160.f), 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), progressBarType(EMPTY),
progressScopeStart(0), progressScopeStart(0),
progressScopeSize(0), progressScopeSize(0),
@@ -322,10 +329,6 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
show_text_ever(false), show_text_ever(false),
scrollable_menu_(scrollable_menu), scrollable_menu_(scrollable_menu),
file_viewer_text_(nullptr), file_viewer_text_(nullptr),
intro_frames(0),
loop_frames(0),
current_frame(0),
intro_done(false),
stage(-1), stage(-1),
max_stage(-1), max_stage(-1),
locale_(""), locale_(""),
@@ -340,23 +343,23 @@ ScreenRecoveryUI::~ScreenRecoveryUI() {
gr_exit(); gr_exit();
} }
GRSurface* ScreenRecoveryUI::GetCurrentFrame() const { const GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { if (current_icon_ == INSTALLING_UPDATE || current_icon_ == ERASING) {
return intro_done ? loopFrames[current_frame] : introFrames[current_frame]; return intro_done_ ? loop_frames_[current_frame_].get() : intro_frames_[current_frame_].get();
} }
return error_icon; return error_icon_.get();
} }
GRSurface* ScreenRecoveryUI::GetCurrentText() const { const GRSurface* ScreenRecoveryUI::GetCurrentText() const {
switch (currentIcon) { switch (current_icon_) {
case ERASING: case ERASING:
return erasing_text; return erasing_text_.get();
case ERROR: case ERROR:
return error_text; return error_text_.get();
case INSTALLING_UPDATE: case INSTALLING_UPDATE:
return installing_text; return installing_text_.get();
case NO_COMMAND: case NO_COMMAND:
return no_command_text; return no_command_text_.get();
case NONE: case NONE:
abort(); abort();
} }
@@ -391,20 +394,21 @@ static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
}; };
int ScreenRecoveryUI::GetAnimationBaseline() const { 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 { int ScreenRecoveryUI::GetTextBaseline() const {
return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) - return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) -
gr_get_height(installing_text); gr_get_height(installing_text_.get());
} }
int ScreenRecoveryUI::GetProgressBaseline() const { int ScreenRecoveryUI::GetProgressBaseline() const {
int elements_sum = gr_get_height(loopFrames[0]) + PixelsFromDp(kLayouts[layout_][ICON]) + int elements_sum = gr_get_height(loop_frames_[0].get()) + PixelsFromDp(kLayouts[layout_][ICON]) +
gr_get_height(installing_text) + PixelsFromDp(kLayouts[layout_][TEXT]) + gr_get_height(installing_text_.get()) + PixelsFromDp(kLayouts[layout_][TEXT]) +
gr_get_height(progressBarFill); gr_get_height(progress_bar_fill_.get());
int bottom_gap = (ScreenHeight() - elements_sum) / 2; 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). // Clear the screen and draw the currently selected background icon (if any).
@@ -413,20 +417,20 @@ void ScreenRecoveryUI::draw_background_locked() {
pagesIdentical = false; pagesIdentical = false;
gr_color(0, 0, 0, 255); gr_color(0, 0, 0, 255);
gr_clear(); gr_clear();
if (currentIcon != NONE) { if (current_icon_ != NONE) {
if (max_stage != -1) { if (max_stage != -1) {
int stage_height = gr_get_height(stageMarkerEmpty); int stage_height = gr_get_height(stage_marker_empty_.get());
int stage_width = gr_get_width(stageMarkerEmpty); int stage_width = gr_get_width(stage_marker_empty_.get());
int x = (ScreenWidth() - max_stage * gr_get_width(stageMarkerEmpty)) / 2; int x = (ScreenWidth() - max_stage * gr_get_width(stage_marker_empty_.get())) / 2;
int y = ScreenHeight() - stage_height - margin_height_; int y = ScreenHeight() - stage_height - margin_height_;
for (int i = 0; i < max_stage; ++i) { for (int i = 0; i < max_stage; ++i) {
GRSurface* stage_surface = (i < stage) ? stageMarkerFill : stageMarkerEmpty; const auto& stage_surface = (i < stage) ? stage_marker_fill_ : stage_marker_empty_;
DrawSurface(stage_surface, 0, 0, stage_width, stage_height, x, y); DrawSurface(stage_surface.get(), 0, 0, stage_width, stage_height, x, y);
x += stage_width; x += stage_width;
} }
} }
GRSurface* text_surface = GetCurrentText(); const auto& text_surface = GetCurrentText();
int text_x = (ScreenWidth() - gr_get_width(text_surface)) / 2; int text_x = (ScreenWidth() - gr_get_width(text_surface)) / 2;
int text_y = GetTextBaseline(); int text_y = GetTextBaseline();
gr_color(255, 255, 255, 255); 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 // Draws the animation and progress bar (if any) on the screen. Does not flip pages. Should only be
// called with updateMutex locked. // called with updateMutex locked.
void ScreenRecoveryUI::draw_foreground_locked() { void ScreenRecoveryUI::draw_foreground_locked() {
if (currentIcon != NONE) { if (current_icon_ != NONE) {
GRSurface* frame = GetCurrentFrame(); const auto& frame = GetCurrentFrame();
int frame_width = gr_get_width(frame); int frame_width = gr_get_width(frame);
int frame_height = gr_get_height(frame); int frame_height = gr_get_height(frame);
int frame_x = (ScreenWidth() - frame_width) / 2; int frame_x = (ScreenWidth() - frame_width) / 2;
@@ -447,8 +451,8 @@ void ScreenRecoveryUI::draw_foreground_locked() {
} }
if (progressBarType != EMPTY) { if (progressBarType != EMPTY) {
int width = gr_get_width(progressBarEmpty); int width = gr_get_width(progress_bar_empty_.get());
int height = gr_get_height(progressBarEmpty); int height = gr_get_height(progress_bar_empty_.get());
int progress_x = (ScreenWidth() - width) / 2; int progress_x = (ScreenWidth() - width) / 2;
int progress_y = GetProgressBaseline(); int progress_y = GetProgressBaseline();
@@ -464,19 +468,20 @@ void ScreenRecoveryUI::draw_foreground_locked() {
if (rtl_locale_) { if (rtl_locale_) {
// Fill the progress bar from right to left. // Fill the progress bar from right to left.
if (pos > 0) { if (pos > 0) {
DrawSurface(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos, DrawSurface(progress_bar_fill_.get(), width - pos, 0, pos, height,
progress_y); progress_x + width - pos, progress_y);
} }
if (pos < width - 1) { 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 { } else {
// Fill the progress bar from left to right. // Fill the progress bar from left to right.
if (pos > 0) { 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) { 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]); SetLocale(locales_entries[sel]);
std::vector<std::string> text_name = { "erasing_text", "error_text", "installing_text", std::vector<std::string> text_name = { "erasing_text", "error_text", "installing_text",
"installing_security_text", "no_command_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) { for (const auto& name : text_name) {
GRSurface* text_image = nullptr; auto text_image = LoadLocalizedBitmap(name);
LoadLocalizedBitmap(name.c_str(), &text_image);
if (!text_image) { if (!text_image) {
Print("Failed to load %s\n", name.c_str()); Print("Failed to load %s\n", name.c_str());
return; 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); std::lock_guard<std::mutex> lg(updateMutex);
@@ -753,16 +757,16 @@ void ScreenRecoveryUI::ProgressThreadLoop() {
// update the installation animation, if active // update the installation animation, if active
// skip this if we have a text overlay (too expensive to update) // skip this if we have a text overlay (too expensive to update)
if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) { if ((current_icon_ == INSTALLING_UPDATE || current_icon_ == ERASING) && !show_text) {
if (!intro_done) { if (!intro_done_) {
if (current_frame == intro_frames - 1) { if (current_frame_ == intro_frames_.size() - 1) {
intro_done = true; intro_done_ = true;
current_frame = 0; current_frame_ = 0;
} else { } else {
++current_frame; ++current_frame_;
} }
} else { } else {
current_frame = (current_frame + 1) % loop_frames; current_frame_ = (current_frame_ + 1) % loop_frames_.size();
} }
redraw = true; redraw = true;
@@ -791,18 +795,23 @@ void ScreenRecoveryUI::ProgressThreadLoop() {
} }
} }
void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadBitmap(const std::string& filename) {
int result = res_create_display_surface(filename, surface); GRSurface* surface;
if (result < 0) { if (auto result = res_create_display_surface(filename.c_str(), &surface); result < 0) {
LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")"; 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) { std::unique_ptr<GRSurface> ScreenRecoveryUI::LoadLocalizedBitmap(const std::string& filename) {
int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface); GRSurface* surface;
if (result < 0) { if (auto result = res_create_localized_alpha_surface(filename.c_str(), locale_.c_str(), &surface);
LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")"; 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) { 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. // Choose the right background string to display during update.
void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) { void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
if (security_update) { if (security_update) {
LoadLocalizedBitmap("installing_security_text", &installing_text); installing_text_ = LoadLocalizedBitmap("installing_security_text");
} else { } else {
LoadLocalizedBitmap("installing_text", &installing_text); installing_text_ = LoadLocalizedBitmap("installing_text");
} }
Redraw(); Redraw();
} }
@@ -838,10 +847,6 @@ bool ScreenRecoveryUI::InitTextParams() {
// TODO(xunchang) load localized text icons for the menu. (Init for screenRecoveryUI but // TODO(xunchang) load localized text icons for the menu. (Init for screenRecoveryUI but
// not wearRecoveryUI). // not wearRecoveryUI).
bool ScreenRecoveryUI::LoadWipeDataMenuText() { bool ScreenRecoveryUI::LoadWipeDataMenuText() {
wipe_data_menu_header_text_ = nullptr;
factory_data_reset_text_ = nullptr;
try_again_text_ = nullptr;
return true; return true;
} }
@@ -869,21 +874,20 @@ bool ScreenRecoveryUI::Init(const std::string& locale) {
// Set up the locale info. // Set up the locale info.
SetLocale(locale); SetLocale(locale);
LoadBitmap("icon_error", &error_icon); error_icon_ = LoadBitmap("icon_error");
LoadBitmap("progress_empty", &progressBarEmpty); progress_bar_empty_ = LoadBitmap("progress_empty");
LoadBitmap("progress_fill", &progressBarFill); progress_bar_fill_ = LoadBitmap("progress_fill");
stage_marker_empty_ = LoadBitmap("stage_empty");
stage_marker_fill_ = LoadBitmap("stage_fill");
LoadBitmap("stage_empty", &stageMarkerEmpty); erasing_text_ = LoadLocalizedBitmap("erasing_text");
LoadBitmap("stage_fill", &stageMarkerFill); no_command_text_ = LoadLocalizedBitmap("no_command_text");
error_text_ = LoadLocalizedBitmap("error_text");
// Background text for "installing_update" could be "installing update" // Background text for "installing_update" could be "installing update" or
// or "installing security update". It will be set after UI init according // "installing security update". It will be set after Init() according to the commands in BCB.
// to commands in BCB. installing_text_.reset();
installing_text = nullptr;
LoadLocalizedBitmap("erasing_text", &erasing_text);
LoadLocalizedBitmap("no_command_text", &no_command_text);
LoadLocalizedBitmap("error_text", &error_text);
LoadWipeDataMenuText(); LoadWipeDataMenuText();
@@ -915,32 +919,34 @@ void ScreenRecoveryUI::LoadAnimation() {
} }
} }
intro_frames = intro_frame_names.size(); size_t intro_frames = intro_frame_names.size();
loop_frames = loop_frame_names.size(); size_t loop_frames = loop_frame_names.size();
// It's okay to not have an intro. // 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. // But you must have an animation.
if (loop_frames == 0) abort(); if (loop_frames == 0) abort();
std::sort(intro_frame_names.begin(), intro_frame_names.end()); std::sort(intro_frame_names.begin(), intro_frame_names.end());
std::sort(loop_frame_names.begin(), loop_frame_names.end()); std::sort(loop_frame_names.begin(), loop_frame_names.end());
introFrames = new GRSurface*[intro_frames]; intro_frames_.clear();
for (size_t i = 0; i < intro_frames; i++) { intro_frames_.reserve(intro_frames);
LoadBitmap(intro_frame_names.at(i).c_str(), &introFrames[i]); for (const auto& frame_name : intro_frame_names) {
intro_frames_.emplace_back(LoadBitmap(frame_name));
} }
loopFrames = new GRSurface*[loop_frames]; loop_frames_.clear();
for (size_t i = 0; i < loop_frames; i++) { loop_frames_.reserve(loop_frames);
LoadBitmap(loop_frame_names.at(i).c_str(), &loopFrames[i]); for (const auto& frame_name : loop_frame_names) {
loop_frames_.emplace_back(LoadBitmap(frame_name));
} }
} }
void ScreenRecoveryUI::SetBackground(Icon icon) { void ScreenRecoveryUI::SetBackground(Icon icon) {
std::lock_guard<std::mutex> lg(updateMutex); std::lock_guard<std::mutex> lg(updateMutex);
currentIcon = icon; current_icon_ = icon;
update_screen_locked(); update_screen_locked();
} }
@@ -972,7 +978,7 @@ void ScreenRecoveryUI::SetProgress(float fraction) {
if (fraction > 1.0) fraction = 1.0; if (fraction > 1.0) fraction = 1.0;
if (progressBarType == DETERMINATE && fraction > progress) { if (progressBarType == DETERMINATE && fraction > progress) {
// Skip updates that aren't visibly different. // 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; float scale = width * progressScopeSize;
if ((int)(progress * scale) != (int)(fraction * scale)) { if ((int)(progress * scale) != (int)(fraction * scale)) {
progress = fraction; progress = fraction;
@@ -1115,11 +1121,10 @@ void ScreenRecoveryUI::ShowFile(const std::string& filename) {
text_row_ = old_text_row; text_row_ = old_text_row;
} }
std::unique_ptr<Menu> ScreenRecoveryUI::CreateMenu(GRSurface* graphic_header, std::unique_ptr<Menu> ScreenRecoveryUI::CreateMenu(
const std::vector<GRSurface*>& graphic_items, const GRSurface* graphic_header, const std::vector<const GRSurface*>& graphic_items,
const std::vector<std::string>& text_headers, const std::vector<std::string>& text_headers, const std::vector<std::string>& text_items,
const std::vector<std::string>& text_items, size_t initial_selection) const {
size_t initial_selection) const {
// horizontal unusable area: margin width + menu indent // horizontal unusable area: margin width + menu indent
size_t max_width = ScreenWidth() - margin_width_ - kMenuIndent; size_t max_width = ScreenWidth() - margin_width_ - kMenuIndent;
// vertical unusable area: margin height + title lines + helper message + high light bar. // vertical unusable area: margin height + title lines + helper message + high light bar.
@@ -1235,9 +1240,9 @@ size_t ScreenRecoveryUI::ShowMenu(const std::vector<std::string>& headers,
size_t ScreenRecoveryUI::ShowPromptWipeDataMenu(const std::vector<std::string>& backup_headers, size_t ScreenRecoveryUI::ShowPromptWipeDataMenu(const std::vector<std::string>& backup_headers,
const std::vector<std::string>& backup_items, const std::vector<std::string>& backup_items,
const std::function<int(int, bool)>& key_handler) { const std::function<int(int, bool)>& key_handler) {
auto wipe_data_menu = auto wipe_data_menu = CreateMenu(wipe_data_menu_header_text_.get(),
CreateMenu(wipe_data_menu_header_text_, { try_again_text_, factory_data_reset_text_ }, { try_again_text_.get(), factory_data_reset_text_.get() },
backup_headers, backup_items, 0); backup_headers, backup_items, 0);
if (wipe_data_menu == nullptr) { if (wipe_data_menu == nullptr) {
return 0; return 0;
} }
+38 -41
View File
@@ -162,32 +162,31 @@ class TextMenu : public Menu {
int char_height_; 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 { class GraphicMenu : public Menu {
public: public:
// Constructs a Menu instance with the given |headers|, |items| and properties. Sets the initial // Constructs a Menu instance with the given |headers|, |items| and properties. Sets the initial
// selection to |initial_selection|. // selection to |initial_selection|. |headers| and |items| will be made local copies.
GraphicMenu(GRSurface* graphic_headers, const std::vector<GRSurface*>& graphic_items, GraphicMenu(const GRSurface* graphic_headers, const std::vector<const GRSurface*>& graphic_items,
size_t initial_selection, const DrawInterface& draw_funcs); size_t initial_selection, const DrawInterface& draw_funcs);
int Select(int sel) override; int Select(int sel) override;
int DrawHeader(int x, int y) const override; int DrawHeader(int x, int y) const override;
int DrawItems(int x, int y, int screen_width, bool long_press) 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|. // defined by |max_width| and |max_height|.
static bool Validate(size_t max_width, size_t max_height, GRSurface* graphic_headers, static bool Validate(size_t max_width, size_t max_height, const GRSurface* graphic_headers,
const std::vector<GRSurface*>& graphic_items); const std::vector<const GRSurface*>& graphic_items);
// Returns true if |surface| fits on the screen with a vertical offset |y|. // 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, static bool ValidateGraphicSurface(size_t max_width, size_t max_height, int y,
const GRSurface* surface); const GRSurface* surface);
private: private:
// Pointers to the menu headers and items in graphic icons. This class does not have the ownership // Menu headers and items in graphic icons. These are the copies owned by the class instance.
// of the these objects. std::unique_ptr<GRSurface> graphic_headers_;
GRSurface* graphic_headers_; std::vector<std::unique_ptr<GRSurface>> graphic_items_;
std::vector<GRSurface*> graphic_items_;
}; };
// Implementation of RecoveryUI appropriate for devices with a screen // Implementation of RecoveryUI appropriate for devices with a screen
@@ -243,6 +242,7 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
protected: protected:
static constexpr int kMenuIndent = 4; static constexpr int kMenuIndent = 4;
// The margin that we don't want to use for showing texts (e.g. round screen, or screen with // The margin that we don't want to use for showing texts (e.g. round screen, or screen with
// rounded corners). // rounded corners).
const int margin_width_; 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 // 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, // 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. // returns a unique pointer to the created menu; otherwise returns nullptr.
virtual std::unique_ptr<Menu> CreateMenu(GRSurface* graphic_header, virtual std::unique_ptr<Menu> CreateMenu(const GRSurface* graphic_header,
const std::vector<GRSurface*>& graphic_items, const std::vector<const GRSurface*>& graphic_items,
const std::vector<std::string>& text_headers, const std::vector<std::string>& text_headers,
const std::vector<std::string>& text_items, const std::vector<std::string>& text_items,
size_t initial_selection) const; size_t initial_selection) const;
@@ -288,8 +288,8 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
virtual void update_screen_locked(); virtual void update_screen_locked();
virtual void update_progress_locked(); virtual void update_progress_locked();
GRSurface* GetCurrentFrame() const; const GRSurface* GetCurrentFrame() const;
GRSurface* GetCurrentText() const; const GRSurface* GetCurrentText() const;
void ProgressThreadLoop(); void ProgressThreadLoop();
@@ -299,8 +299,8 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
void ClearText(); void ClearText();
void LoadAnimation(); void LoadAnimation();
void LoadBitmap(const char* filename, GRSurface** surface); std::unique_ptr<GRSurface> LoadBitmap(const std::string& filename);
void LoadLocalizedBitmap(const char* filename, GRSurface** surface); std::unique_ptr<GRSurface> LoadLocalizedBitmap(const std::string& filename);
int PixelsFromDp(int dp) const; int PixelsFromDp(int dp) const;
virtual int GetAnimationBaseline() 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 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; int DrawWrappedTextLines(int x, int y, const std::vector<std::string>& lines) const override;
Icon currentIcon;
// The layout to use. // The layout to use.
int layout_; int layout_;
GRSurface* error_icon; // 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_;
GRSurface* erasing_text; // Localized text images for the wipe data menu.
GRSurface* error_text; std::unique_ptr<GRSurface> wipe_data_menu_header_text_;
GRSurface* installing_text; std::unique_ptr<GRSurface> try_again_text_;
GRSurface* no_command_text; std::unique_ptr<GRSurface> factory_data_reset_text_;
// Graphs for the wipe data menu // current_icon_ points to one of the frames in intro_frames_ or loop_frames_, indexed by
GRSurface* wipe_data_menu_header_text_; // current_frame_, or error_icon_.
GRSurface* try_again_text_; Icon current_icon_;
GRSurface* factory_data_reset_text_; 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_;
GRSurface** introFrames; // progress_bar and stage_marker images.
GRSurface** loopFrames; std::unique_ptr<GRSurface> progress_bar_empty_;
std::unique_ptr<GRSurface> progress_bar_fill_;
GRSurface* progressBarEmpty; std::unique_ptr<GRSurface> stage_marker_empty_;
GRSurface* progressBarFill; std::unique_ptr<GRSurface> stage_marker_fill_;
GRSurface* stageMarkerEmpty;
GRSurface* stageMarkerFill;
ProgressType progressBarType; ProgressType progressBarType;
@@ -377,13 +381,6 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface {
std::thread progress_thread_; std::thread progress_thread_;
std::atomic<bool> progress_thread_stopped_{ false }; 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 stage, max_stage;
int char_width_; int char_width_;
+15 -15
View File
@@ -231,12 +231,12 @@ TEST_F(ScreenUITest, WearMenuSelectItemsOverflow) {
} }
TEST_F(ScreenUITest, GraphicMenuSelection) { TEST_F(ScreenUITest, GraphicMenuSelection) {
auto header = GRSurface::Create(50, 50, 50, 1, 50 * 50); auto image = GRSurface::Create(50, 50, 50, 1, 50 * 50);
auto item = GRSurface::Create(50, 50, 50, 1, 50 * 50); auto header = image->Clone();
std::vector<GRSurface*> items = { std::vector<const GRSurface*> items = {
item.get(), image.get(),
item.get(), image.get(),
item.get(), image.get(),
}; };
GraphicMenu menu(header.get(), items, 0, draw_funcs_); GraphicMenu menu(header.get(), items, 0, draw_funcs_);
@@ -258,12 +258,12 @@ TEST_F(ScreenUITest, GraphicMenuSelection) {
} }
TEST_F(ScreenUITest, GraphicMenuValidate) { TEST_F(ScreenUITest, GraphicMenuValidate) {
auto header = GRSurface::Create(50, 50, 50, 1, 50 * 50); auto image = GRSurface::Create(50, 50, 50, 1, 50 * 50);
auto item = GRSurface::Create(50, 50, 50, 1, 50 * 50); auto header = image->Clone();
std::vector<GRSurface*> items = { std::vector<const GRSurface*> items = {
item.get(), image.get(),
item.get(), image.get(),
item.get(), image.get(),
}; };
ASSERT_TRUE(GraphicMenu::Validate(200, 200, header.get(), items)); 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)); ASSERT_FALSE(GraphicMenu::Validate(299, 200, wide_surface.get(), items));
// Menu exceeds the vertical boundary. // Menu exceeds the vertical boundary.
items.push_back(item.get()); items.emplace_back(image.get());
ASSERT_FALSE(GraphicMenu::Validate(200, 249, header.get(), items)); ASSERT_FALSE(GraphicMenu::Validate(200, 249, header.get(), items));
} }
@@ -539,8 +539,8 @@ TEST_F(ScreenRecoveryUITest, LoadAnimation) {
ui_->LoadAnimation(); ui_->LoadAnimation();
ASSERT_EQ(2u, ui_->intro_frames); ASSERT_EQ(2u, ui_->intro_frames_.size());
ASSERT_EQ(3u, ui_->loop_frames); ASSERT_EQ(3u, ui_->loop_frames_.size());
for (const auto& name : tempfiles) { for (const auto& name : tempfiles) {
ASSERT_EQ(0, unlink(name.c_str())); ASSERT_EQ(0, unlink(name.c_str()));
+3 -3
View File
@@ -51,8 +51,8 @@ void WearRecoveryUI::draw_background_locked() {
gr_color(0, 0, 0, 255); gr_color(0, 0, 0, 255);
gr_fill(0, 0, gr_fb_width(), gr_fb_height()); gr_fill(0, 0, gr_fb_width(), gr_fb_height());
if (currentIcon != NONE) { if (current_icon_ != NONE) {
GRSurface* frame = GetCurrentFrame(); const auto& frame = GetCurrentFrame();
int frame_width = gr_get_width(frame); int frame_width = gr_get_width(frame);
int frame_height = gr_get_height(frame); int frame_height = gr_get_height(frame);
int frame_x = (gr_fb_width() - frame_width) / 2; 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); gr_blit(frame, 0, 0, frame_width, frame_height, frame_x, frame_y);
// Draw recovery text on screen above progress bar. // 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_x = (ScreenWidth() - gr_get_width(text)) / 2;
int text_y = GetProgressBaseline() - gr_get_height(text) - 10; int text_y = GetProgressBaseline() - gr_get_height(text) - 10;
gr_color(255, 255, 255, 255); gr_color(255, 255, 255, 255);