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

Commit 5e7cfb9a authored by Damien Bargiacchi's avatar Damien Bargiacchi
Browse files

Remove duplicate methods and variables from WearRecoveryUI

Copy pasta is never as delicious as ones hopes.

Also fix the Pike not rendering recovery bug.

Change-Id: I903da7da436e3347a22ff51633e8a0f28fea2c46
parent 929ffefd
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@ static double now() {
ScreenRecoveryUI::ScreenRecoveryUI() :
    currentIcon(NONE),
    locale(nullptr),
    intro_done(false),
    current_frame(0),
    progressBarType(EMPTY),
    progressScopeStart(0),
    progressScopeSize(0),
@@ -75,6 +73,8 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
    file_viewer_text_(nullptr),
    intro_frames(0),
    loop_frames(0),
    current_frame(0),
    intro_done(false),
    animation_fps(30), // TODO: there's currently no way to infer this.
    stage(-1),
    max_stage(-1),
@@ -447,9 +447,18 @@ void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
    Redraw();
}

void ScreenRecoveryUI::Init() {
void ScreenRecoveryUI::InitTextParams() {
    gr_init();

    gr_font_size(gr_sys_font(), &char_width_, &char_height_);
    text_rows_ = gr_fb_height() / char_height_;
    text_cols_ = gr_fb_width() / char_width_;
}

void ScreenRecoveryUI::Init() {
    RecoveryUI::Init();
    InitTextParams();

    density_ = static_cast<float>(property_get_int32("ro.sf.lcd_density", 160)) / 160.f;

    // Are we portrait or landscape?
@@ -457,10 +466,6 @@ void ScreenRecoveryUI::Init() {
    // Are we the large variant of our base layout?
    if (gr_fb_height() > PixelsFromDp(800)) ++layout_;

    gr_font_size(gr_sys_font(), &char_width_, &char_height_);
    text_rows_ = gr_fb_height() / char_height_;
    text_cols_ = gr_fb_width() / char_width_;

    text_ = Alloc2d(text_rows_, text_cols_ + 1);
    file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
    menu_ = Alloc2d(text_rows_, text_cols_ + 1);
@@ -487,37 +492,44 @@ void ScreenRecoveryUI::Init() {
    LoadAnimation();

    pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);

    RecoveryUI::Init();
}

void ScreenRecoveryUI::LoadAnimation() {
    // How many frames of intro and loop do we have?
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/res/images"), closedir);
    dirent* de;
    std::vector<std::string> intro_frame_names;
    std::vector<std::string> loop_frame_names;

    while ((de = readdir(dir.get())) != nullptr) {
        int value;
        if (sscanf(de->d_name, "intro%d", &value) == 1 && intro_frames < (value + 1)) {
            intro_frames = value + 1;
        } else if (sscanf(de->d_name, "loop%d", &value) == 1 && loop_frames < (value + 1)) {
            loop_frames = value + 1;
        int value, num_chars;
        if (sscanf(de->d_name, "intro%d%n.png", &value, &num_chars) == 1) {
            intro_frame_names.emplace_back(de->d_name, num_chars);
        } else if (sscanf(de->d_name, "loop%d%n.png", &value, &num_chars) == 1) {
            loop_frame_names.emplace_back(de->d_name, num_chars);
        }
    }

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

    LOGD("Recovery animation intro_frames: %d, loop_frames: %d\n", intro_frames, loop_frames);

    // It's okay to not have an intro.
    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 (int i = 0; i < intro_frames; ++i) {
        // TODO: remember the names above, so we don't have to hard-code the number of 0s.
        LoadBitmap(android::base::StringPrintf("intro%05d", i).c_str(), &introFrames[i]);
    for (size_t i = 0; i < intro_frames; i++) {
        LoadBitmap(intro_frame_names.at(i).c_str(), &introFrames[i]);
    }

    loopFrames = new GRSurface*[loop_frames];
    for (int i = 0; i < loop_frames; ++i) {
        LoadBitmap(android::base::StringPrintf("loop%05d", i).c_str(), &loopFrames[i]);
    for (size_t i = 0; i < loop_frames; i++) {
        LoadBitmap(loop_frame_names.at(i).c_str(), &loopFrames[i]);
    }
}

+24 −21
Original line number Diff line number Diff line
@@ -37,16 +37,16 @@ class ScreenRecoveryUI : public RecoveryUI {
    void SetSystemUpdateText(bool security_update);

    // progress indicator
    void SetProgressType(ProgressType type);
    void ShowProgress(float portion, float seconds);
    void SetProgress(float fraction);
    void SetProgressType(ProgressType type) override;
    void ShowProgress(float portion, float seconds) override;
    void SetProgress(float fraction) override;

    void SetStage(int current, int max);
    void SetStage(int current, int max) override;

    // text log
    void ShowText(bool visible);
    bool IsTextVisible();
    bool WasTextEverVisible();
    void ShowText(bool visible) override;
    bool IsTextVisible() override;
    bool WasTextEverVisible() override;

    // printing messages
    void Print(const char* fmt, ...) __printflike(2, 3);
@@ -72,8 +72,6 @@ class ScreenRecoveryUI : public RecoveryUI {
    Icon currentIcon;

    const char* locale;
    bool intro_done;
    int current_frame;

    // The scale factor from dp to pixels. 1.0 for mdpi, 4.0 for xxxhdpi.
    float density_;
@@ -123,8 +121,11 @@ class ScreenRecoveryUI : public RecoveryUI {
    pthread_t progress_thread_;

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

    size_t current_frame;
    bool intro_done;

    // Number of frames per sec (default: 30) for both parts of the animation.
    int animation_fps;
@@ -136,11 +137,13 @@ class ScreenRecoveryUI : public RecoveryUI {
    pthread_mutex_t updateMutex;
    bool rtl_locale;

    void draw_background_locked();
    void draw_foreground_locked();
    void draw_screen_locked();
    void update_screen_locked();
    void update_progress_locked();
    virtual void InitTextParams();

    virtual void draw_background_locked();
    virtual void draw_foreground_locked();
    virtual void draw_screen_locked();
    virtual void update_screen_locked();
    virtual void update_progress_locked();

    GRSurface* GetCurrentFrame();
    GRSurface* GetCurrentText();
@@ -148,8 +151,8 @@ class ScreenRecoveryUI : public RecoveryUI {
    static void* ProgressThreadStartRoutine(void* data);
    void ProgressThreadLoop();

    void ShowFile(FILE*);
    void PrintV(const char*, bool, va_list);
    virtual void ShowFile(FILE*);
    virtual void PrintV(const char*, bool, va_list);
    void PutChar(char);
    void ClearText();

@@ -158,9 +161,9 @@ class ScreenRecoveryUI : public RecoveryUI {
    void LoadLocalizedBitmap(const char* filename, GRSurface** surface);

    int PixelsFromDp(int dp);
    int GetAnimationBaseline();
    int GetProgressBaseline();
    int GetTextBaseline();
    virtual int GetAnimationBaseline();
    virtual int GetProgressBaseline();
    virtual int GetTextBaseline();

    void DrawHorizontalRule(int* y);
    void DrawTextLine(int x, int* y, const char* line, bool bold);
+77 −236
Original line number Diff line number Diff line
@@ -47,32 +47,13 @@ static double now() {
}

WearRecoveryUI::WearRecoveryUI() :
    progress_bar_height(3),
    progress_bar_width(200),
    progress_bar_y(259),
    outer_height(0),
    outer_width(0),
    menu_unusable_rows(0),
    intro_frames(22),
    loop_frames(60),
    animation_fps(30),
    currentIcon(NONE),
    intro_done(false),
    current_frame(0),
    progressBarType(EMPTY),
    progressScopeStart(0),
    progressScopeSize(0),
    progress(0),
    text_cols(0),
    text_rows(0),
    text_col(0),
    text_row(0),
    text_top(0),
    show_text(false),
    show_text_ever(false),
    show_menu(false),
    menu_items(0),
    menu_sel(0) {
    menu_unusable_rows(0) {
    intro_frames = 22;
    loop_frames = 60;
    animation_fps = 30;

    for (size_t i = 0; i < 5; i++)
        backgroundIcon[i] = NULL;
@@ -80,16 +61,22 @@ WearRecoveryUI::WearRecoveryUI() :
    self = this;
}

int WearRecoveryUI::GetProgressBaseline() {
    return progress_bar_y;
}

// Draw background frame on the screen.  Does not flip pages.
// Should only be called with updateMutex locked.
void WearRecoveryUI::draw_background_locked(Icon icon)
// TODO merge drawing routines with screen_ui
void WearRecoveryUI::draw_background_locked()
{
    pagesIdentical = false;
    gr_color(0, 0, 0, 255);
    gr_fill(0, 0, gr_fb_width(), gr_fb_height());

    if (icon) {
    if (currentIcon != NONE) {
        GRSurface* surface;
        if (icon == INSTALLING_UPDATE || icon == ERASING) {
        if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
            if (!intro_done) {
                surface = introFrames[current_frame];
            } else {
@@ -97,7 +84,7 @@ void WearRecoveryUI::draw_background_locked(Icon icon)
            }
        }
        else {
            surface = backgroundIcon[icon];
            surface = backgroundIcon[currentIcon];
        }

        int width = gr_get_width(surface);
@@ -110,36 +97,6 @@ void WearRecoveryUI::draw_background_locked(Icon icon)
    }
}

// Draw the progress bar (if any) on the screen.  Does not flip pages.
// Should only be called with updateMutex locked.
void WearRecoveryUI::draw_progress_locked()
{
    if (currentIcon == ERROR) return;
    if (progressBarType != DETERMINATE) return;

    int width = progress_bar_width;
    int height = progress_bar_height;
    int dx = (gr_fb_width() - width)/2;
    int dy = progress_bar_y;

    float p = progressScopeStart + progress * progressScopeSize;
    int pos = (int) (p * width);

    gr_color(0x43, 0x43, 0x43, 0xff);
    gr_fill(dx, dy, dx + width, dy + height);

    if (pos > 0) {
        gr_color(0x02, 0xa8, 0xf3, 255);
        if (rtl_locale) {
            // Fill the progress bar from right to left.
            gr_fill(dx + width - pos, dy, dx + width, dy + height);
        } else {
            // Fill the progress bar from left to right.
            gr_fill(dx, dy, dx + pos, dy + height);
        }
    }
}

static const char* HEADERS[] = {
    "Swipe up/down to move.",
    "Swipe left/right to select.",
@@ -147,13 +104,15 @@ static const char* HEADERS[] = {
    NULL
};

// TODO merge drawing routines with screen_ui
void WearRecoveryUI::draw_screen_locked()
{
    draw_background_locked(currentIcon);
    draw_progress_locked();
    char cur_selection_str[50];

    if (show_text) {
    draw_background_locked();
    if (!show_text) {
        draw_foreground_locked();
    } else {
        SetColor(TEXT_FILL);
        gr_fill(0, 0, gr_fb_width(), gr_fb_height());

@@ -192,10 +151,12 @@ void WearRecoveryUI::draw_screen_locked()
                    gr_fill(x, y-2, gr_fb_width()-x, y+char_height_+2);
                    // white text of selected item
                    SetColor(MENU_SEL_FG);
                    if (menu[i][0]) gr_text(gr_sys_font(), x+4, y, menu[i], 1);
                    if (menu_[i][0]) {
                        gr_text(gr_sys_font(), x + 4, y, menu_[i], 1);
                    }
                    SetColor(MENU);
                } else if (menu[i][0]) {
                    gr_text(gr_sys_font(), x+4, y, menu[i], 0);
                } else if (menu_[i][0]) {
                    gr_text(gr_sys_font(), x + 4, y, menu_[i], 0);
                }
                y += char_height_+4;
            }
@@ -211,24 +172,18 @@ void WearRecoveryUI::draw_screen_locked()
        // screen, the bottom of the menu, or we've displayed the
        // entire text buffer.
        int ty;
        int row = (text_top+text_rows-1) % text_rows;
        int row = (text_top_ + text_rows_ - 1) % text_rows_;
        size_t count = 0;
        for (int ty = gr_fb_height() - char_height_ - outer_height;
             ty > y+2 && count < text_rows;
             ty > y + 2 && count < text_rows_;
             ty -= char_height_, ++count) {
            gr_text(gr_sys_font(), x+4, ty, text[row], 0);
            gr_text(gr_sys_font(), x+4, ty, text_[row], 0);
            --row;
            if (row < 0) row = text_rows-1;
            if (row < 0) row = text_rows_ - 1;
        }
    }
}

void WearRecoveryUI::update_screen_locked()
{
    draw_screen_locked();
    gr_flip();
}

// Keeps the progress bar updated, even when the process is otherwise busy.
void* WearRecoveryUI::progress_thread(void *cookie) {
    self->progress_loop();
@@ -240,7 +195,7 @@ void WearRecoveryUI::progress_loop() {
    for (;;) {
        double start = now();
        pthread_mutex_lock(&updateMutex);
        int redraw = 0;
        bool redraw = false;

        if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING)
                                                            && !show_text) {
@@ -254,7 +209,7 @@ void WearRecoveryUI::progress_loop() {
            } else {
                current_frame = (current_frame + 1) % loop_frames;
            }
            redraw = 1;
            redraw = true;
        }

        // move the progress bar forward on timed intervals, if configured
@@ -265,12 +220,11 @@ void WearRecoveryUI::progress_loop() {
            if (p > 1.0) p = 1.0;
            if (p > progress) {
                progress = p;
                redraw = 1;
                redraw = true;
            }
        }

        if (redraw)
            update_screen_locked();
        if (redraw) update_screen_locked();

        pthread_mutex_unlock(&updateMutex);
        double end = now();
@@ -281,93 +235,27 @@ void WearRecoveryUI::progress_loop() {
    }
}

void WearRecoveryUI::Init()
{
    gr_init();
void WearRecoveryUI::InitTextParams() {
    ScreenRecoveryUI::InitTextParams();

    text_cols_ = (gr_fb_width() - (outer_width * 2)) / char_width_;

    gr_font_size(gr_sys_font(), &char_width_, &char_height_);
    if (text_rows_ > kMaxRows) text_rows_ = kMaxRows;
    if (text_cols_ > kMaxCols) text_cols_ = kMaxCols;

    text_col = text_row = 0;
    text_rows = (gr_fb_height()) / char_height_;
    visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_;
    if (text_rows > kMaxRows) text_rows = kMaxRows;
    text_top = 1;
}

    text_cols = (gr_fb_width() - (outer_width * 2)) / char_width_;
    if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
void WearRecoveryUI::Init() {
    ScreenRecoveryUI::Init();

    LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]);
    backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
    LoadBitmap("icon_error", &backgroundIcon[ERROR]);
    backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];

    introFrames = (GRSurface**)malloc(intro_frames * sizeof(GRSurface*));
    for (int i = 0; i < intro_frames; ++i) {
        char filename[40];
        sprintf(filename, "intro%02d", i);
        LoadBitmap(filename, introFrames + i);
    }

    loopFrames = (GRSurface**)malloc(loop_frames * sizeof(GRSurface*));
    for (int i = 0; i < loop_frames; ++i) {
        char filename[40];
        sprintf(filename, "loop%02d", i);
        LoadBitmap(filename, loopFrames + i);
    }

    pthread_create(&progress_t, NULL, progress_thread, NULL);
    RecoveryUI::Init();
}

void WearRecoveryUI::SetBackground(Icon icon)
{
    pthread_mutex_lock(&updateMutex);
    currentIcon = icon;
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::SetProgressType(ProgressType type)
{
    pthread_mutex_lock(&updateMutex);
    if (progressBarType != type) {
        progressBarType = type;
    }
    progressScopeStart = 0;
    progressScopeSize = 0;
    progress = 0;
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::ShowProgress(float portion, float seconds)
{
    pthread_mutex_lock(&updateMutex);
    progressBarType = DETERMINATE;
    progressScopeStart += progressScopeSize;
    progressScopeSize = portion;
    progressScopeTime = now();
    progressScopeDuration = seconds;
    progress = 0;
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::SetProgress(float fraction)
{
    pthread_mutex_lock(&updateMutex);
    if (fraction < 0.0) fraction = 0.0;
    if (fraction > 1.0) fraction = 1.0;
    if (progressBarType == DETERMINATE && fraction > progress) {
        // Skip updates that aren't visibly different.
        int width = progress_bar_width;
        float scale = width * progressScopeSize;
        if ((int) (progress * scale) != (int) (fraction * scale)) {
            progress = fraction;
            update_screen_locked();
        }
    }
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::SetStage(int current, int max)
@@ -386,18 +274,18 @@ void WearRecoveryUI::Print(const char *fmt, ...)

    // This can get called before ui_init(), so be careful.
    pthread_mutex_lock(&updateMutex);
    if (text_rows > 0 && text_cols > 0) {
    if (text_rows_ > 0 && text_cols_ > 0) {
        char *ptr;
        for (ptr = buf; *ptr != '\0'; ++ptr) {
            if (*ptr == '\n' || text_col >= text_cols) {
                text[text_row][text_col] = '\0';
                text_col = 0;
                text_row = (text_row + 1) % text_rows;
                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
            if (*ptr == '\n' || text_col_ >= text_cols_) {
                text_[text_row_][text_col_] = '\0';
                text_col_ = 0;
                text_row_ = (text_row_ + 1) % text_rows_;
                if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
            }
            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
            if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
        }
        text[text_row][text_col] = '\0';
        text_[text_row_][text_col_] = '\0';
        update_screen_locked();
    }
    pthread_mutex_unlock(&updateMutex);
@@ -406,20 +294,20 @@ void WearRecoveryUI::Print(const char *fmt, ...)
void WearRecoveryUI::StartMenu(const char* const * headers, const char* const * items,
                               int initial_selection) {
    pthread_mutex_lock(&updateMutex);
    if (text_rows > 0 && text_cols > 0) {
    if (text_rows_ > 0 && text_cols_ > 0) {
        menu_headers_ = headers;
        size_t i = 0;
        // "i < text_rows" is removed from the loop termination condition,
        // "i < text_rows_" is removed from the loop termination condition,
        // which is different from the one in ScreenRecoveryUI::StartMenu().
        // Because WearRecoveryUI supports scrollable menu, it's fine to have
        // more entries than text_rows. The menu may be truncated otherwise.
        // more entries than text_rows_. The menu may be truncated otherwise.
        // Bug: 23752519
        for (; items[i] != nullptr; i++) {
            strncpy(menu[i], items[i], text_cols - 1);
            menu[i][text_cols - 1] = '\0';
            strncpy(menu_[i], items[i], text_cols_ - 1);
            menu_[i][text_cols_ - 1] = '\0';
        }
        menu_items = i;
        show_menu = 1;
        show_menu = true;
        menu_sel = initial_selection;
        menu_start = 0;
        menu_end = visible_text_rows - 1 - menu_unusable_rows;
@@ -433,7 +321,7 @@ void WearRecoveryUI::StartMenu(const char* const * headers, const char* const *
int WearRecoveryUI::SelectMenu(int sel) {
    int old_sel;
    pthread_mutex_lock(&updateMutex);
    if (show_menu > 0) {
    if (show_menu) {
        old_sel = menu_sel;
        menu_sel = sel;
        if (menu_sel < 0) menu_sel = 0;
@@ -452,53 +340,6 @@ int WearRecoveryUI::SelectMenu(int sel) {
    return sel;
}

void WearRecoveryUI::EndMenu() {
    int i;
    pthread_mutex_lock(&updateMutex);
    if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
        show_menu = 0;
        update_screen_locked();
    }
    pthread_mutex_unlock(&updateMutex);
}

bool WearRecoveryUI::IsTextVisible()
{
    pthread_mutex_lock(&updateMutex);
    int visible = show_text;
    pthread_mutex_unlock(&updateMutex);
    return visible;
}

bool WearRecoveryUI::WasTextEverVisible()
{
    pthread_mutex_lock(&updateMutex);
    int ever_visible = show_text_ever;
    pthread_mutex_unlock(&updateMutex);
    return ever_visible;
}

void WearRecoveryUI::ShowText(bool visible)
{
    pthread_mutex_lock(&updateMutex);
    // Don't show text during ota install or factory reset
    if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
        pthread_mutex_unlock(&updateMutex);
        return;
    }
    show_text = visible;
    if (show_text) show_text_ever = 1;
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::Redraw()
{
    pthread_mutex_lock(&updateMutex);
    update_screen_locked();
    pthread_mutex_unlock(&updateMutex);
}

void WearRecoveryUI::ShowFile(FILE* fp) {
    std::vector<long> offsets;
    offsets.push_back(ftell(fp));
@@ -538,12 +379,12 @@ void WearRecoveryUI::ShowFile(FILE* fp) {

        int ch = getc(fp);
        if (ch == EOF) {
            text_row = text_top = text_rows - 2;
            text_row_ = text_top_ = text_rows_ - 2;
            show_prompt = true;
        } else {
            PutChar(ch);
            if (text_col == 0 && text_row >= text_rows - 2) {
                text_top = text_row;
            if (text_col_ == 0 && text_row_ >= text_rows_ - 2) {
                text_top_ = text_row_;
                show_prompt = true;
            }
        }
@@ -552,10 +393,10 @@ void WearRecoveryUI::ShowFile(FILE* fp) {

void WearRecoveryUI::PutChar(char ch) {
    pthread_mutex_lock(&updateMutex);
    if (ch != '\n') text[text_row][text_col++] = ch;
    if (ch == '\n' || text_col >= text_cols) {
        text_col = 0;
        ++text_row;
    if (ch != '\n') text_[text_row_][text_col_++] = ch;
    if (ch == '\n' || text_col_ >= text_cols_) {
        text_col_ = 0;
        ++text_row_;
    }
    pthread_mutex_unlock(&updateMutex);
}
@@ -572,11 +413,11 @@ void WearRecoveryUI::ShowFile(const char* filename) {

void WearRecoveryUI::ClearText() {
    pthread_mutex_lock(&updateMutex);
    text_col = 0;
    text_row = 0;
    text_top = 1;
    for (size_t i = 0; i < text_rows; ++i) {
        memset(text[i], 0, text_cols + 1);
    text_col_ = 0;
    text_row_ = 0;
    text_top_ = 1;
    for (size_t i = 0; i < text_rows_; ++i) {
        memset(text_[i], 0, text_cols_ + 1);
    }
    pthread_mutex_unlock(&updateMutex);
}
@@ -597,17 +438,17 @@ void WearRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
    }

    pthread_mutex_lock(&updateMutex);
    if (text_rows > 0 && text_cols > 0) {
    if (text_rows_ > 0 && text_cols_ > 0) {
        for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
            if (*ptr == '\n' || text_col >= text_cols) {
                text[text_row][text_col] = '\0';
                text_col = 0;
                text_row = (text_row + 1) % text_rows;
                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
            if (*ptr == '\n' || text_col_ >= text_cols_) {
                text_[text_row_][text_col_] = '\0';
                text_col_ = 0;
                text_row_ = (text_row_ + 1) % text_rows_;
                if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
            }
            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
            if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
        }
        text[text_row][text_col] = '\0';
        text_[text_row_][text_col_] = '\0';
        update_screen_locked();
    }
    pthread_mutex_unlock(&updateMutex);
+15 −57
Original line number Diff line number Diff line
@@ -23,39 +23,22 @@ class WearRecoveryUI : public ScreenRecoveryUI {
  public:
    WearRecoveryUI();

    void Init();
    // overall recovery state ("background image")
    void SetBackground(Icon icon);
    void Init() override;

    // progress indicator
    void SetProgressType(ProgressType type);
    void ShowProgress(float portion, float seconds);
    void SetProgress(float fraction);

    void SetStage(int current, int max);

    // text log
    void ShowText(bool visible);
    bool IsTextVisible();
    bool WasTextEverVisible();
    void SetStage(int current, int max) override;

    // printing messages
    void Print(const char* fmt, ...);
    void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3);
    void ShowFile(const char* filename);
    void ShowFile(FILE* fp);
    void Print(const char* fmt, ...) override;
    void PrintOnScreenOnly(const char* fmt, ...) override __printflike(2, 3);
    void ShowFile(const char* filename) override;
    void ShowFile(FILE* fp) override;

    // menu display
    void StartMenu(const char* const * headers, const char* const * items,
                           int initial_selection);
    int SelectMenu(int sel);
    void EndMenu();

    void Redraw();
                   int initial_selection) override;
    int SelectMenu(int sel) override;

  protected:
    int progress_bar_height, progress_bar_width;

    // progress bar vertical position, it's centered horizontally
    int progress_bar_y;

@@ -67,59 +50,34 @@ class WearRecoveryUI : public ScreenRecoveryUI {
    // that may otherwise go out of the screen.
    int menu_unusable_rows;

    // number of intro frames (default: 22) and loop frames (default: 60)
    int intro_frames;
    int loop_frames;

    // Number of frames per sec (default: 30) for both of intro and loop.
    int animation_fps;

  private:
    Icon currentIcon;
    int GetProgressBaseline() override;

    bool intro_done;
    void InitTextParams() override;

    int current_frame;
    void PrintV(const char*, bool, va_list) override;

  private:
    GRSurface* backgroundIcon[5];
    GRSurface* *introFrames;
    GRSurface* *loopFrames;

    ProgressType progressBarType;

    float progressScopeStart, progressScopeSize, progress;
    double progressScopeTime, progressScopeDuration;

    static const int kMaxCols = 96;
    static const int kMaxRows = 96;

    // Log text overlay, displayed when a magic key is pressed
    char text[kMaxRows][kMaxCols];
    size_t text_cols, text_rows;
    // Number of text rows seen on screen
    int visible_text_rows;
    size_t text_col, text_row, text_top;
    bool show_text;
    bool show_text_ever;   // has show_text ever been true?

    char menu[kMaxRows][kMaxCols];
    bool show_menu;
    const char* const* menu_headers_;
    int menu_items, menu_sel;
    int menu_start, menu_end;

    pthread_t progress_t;

  private:
    void draw_background_locked(Icon icon);
    void draw_background_locked() override;
    void draw_screen_locked() override;
    void draw_progress_locked();
    void draw_screen_locked();
    void update_screen_locked();

    static void* progress_thread(void* cookie);
    void progress_loop();
    void PutChar(char);
    void ClearText();
    void PrintV(const char*, bool, va_list);
};

#endif  // RECOVERY_WEAR_UI_H