diff options
Diffstat (limited to 'wear_ui.cpp')
-rw-r--r-- | wear_ui.cpp | 507 |
1 files changed, 246 insertions, 261 deletions
diff --git a/wear_ui.cpp b/wear_ui.cpp index 6c0286558..624116c0c 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -45,167 +45,164 @@ static WearRecoveryUI* self = NULL; // Return the current time as a double (including fractions of a second). static double now() { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; } -WearRecoveryUI::WearRecoveryUI() : - progress_bar_y(259), - outer_height(0), - outer_width(0), - menu_unusable_rows(0) { - intro_frames = 22; - loop_frames = 60; - animation_fps = 30; +WearRecoveryUI::WearRecoveryUI() + : kProgressBarBaseline(RECOVERY_UI_PROGRESS_BAR_BASELINE), + kMenuUnusableRows(RECOVERY_UI_MENU_UNUSABLE_ROWS) { + // TODO: kMenuUnusableRows should be computed based on the lines in draw_screen_locked(). - for (size_t i = 0; i < 5; i++) - backgroundIcon[i] = NULL; + // TODO: The following three variables are likely not needed. The first two are detected + // automatically in ScreenRecoveryUI::LoadAnimation(), based on the actual files seen on device. + intro_frames = 22; + loop_frames = 60; - self = this; + touch_screen_allowed_ = true; + + for (size_t i = 0; i < 5; i++) backgroundIcon[i] = NULL; + + self = this; } -int WearRecoveryUI::GetProgressBaseline() { - return progress_bar_y; +int WearRecoveryUI::GetProgressBaseline() const { + return kProgressBarBaseline; } // Draw background frame on the screen. Does not flip pages. // Should only be called with updateMutex locked. // 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 (currentIcon != NONE) { - GRSurface* surface; - if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { - if (!intro_done) { - surface = introFrames[current_frame]; - } else { - surface = loopFrames[current_frame]; - } - } - else { - surface = backgroundIcon[currentIcon]; - } +void WearRecoveryUI::draw_background_locked() { + pagesIdentical = false; + gr_color(0, 0, 0, 255); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + + if (currentIcon != NONE) { + GRSurface* surface; + if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { + if (!intro_done) { + surface = introFrames[current_frame]; + } else { + surface = loopFrames[current_frame]; + } + } else { + surface = backgroundIcon[currentIcon]; + } - int width = gr_get_width(surface); - int height = gr_get_height(surface); + int width = gr_get_width(surface); + int height = gr_get_height(surface); - int x = (gr_fb_width() - width) / 2; - int y = (gr_fb_height() - height) / 2; + int x = (gr_fb_width() - width) / 2; + int y = (gr_fb_height() - height) / 2; - gr_blit(surface, 0, 0, width, height, x, y); - } + gr_blit(surface, 0, 0, width, height, x, y); + } } -static const char* HEADERS[] = { - "Swipe up/down to move.", - "Swipe left/right to select.", - "", - NULL +static const char* SWIPE_HELP[] = { + "Swipe up/down to move.", + "Swipe left/right to select.", + "", + NULL }; // TODO merge drawing routines with screen_ui -void WearRecoveryUI::draw_screen_locked() -{ - char cur_selection_str[50]; +void WearRecoveryUI::draw_screen_locked() { + char cur_selection_str[50]; + + draw_background_locked(); + if (!show_text) { + draw_foreground_locked(); + } else { + SetColor(TEXT_FILL); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); - draw_background_locked(); - if (!show_text) { - draw_foreground_locked(); - } else { - SetColor(TEXT_FILL); - gr_fill(0, 0, gr_fb_width(), gr_fb_height()); - - int y = outer_height; - int x = outer_width; - if (show_menu) { - std::string recovery_fingerprint = - android::base::GetProperty("ro.bootimage.build.fingerprint", ""); - SetColor(HEADER); - DrawTextLine(x + 4, &y, "Android Recovery", true); - for (auto& chunk: android::base::Split(recovery_fingerprint, ":")) { - DrawTextLine(x +4, &y, chunk.c_str(), false); - } - - // This is actually the help strings. - DrawTextLines(x + 4, &y, HEADERS); - SetColor(HEADER); - DrawTextLines(x + 4, &y, menu_headers_); - - // Show the current menu item number in relation to total number if - // items don't fit on the screen. - if (menu_items > menu_end - menu_start) { - sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items); - gr_text(gr_sys_font(), x+4, y, cur_selection_str, 1); - y += char_height_+4; - } - - // Menu begins here - SetColor(MENU); - - for (int i = menu_start; i < menu_end; ++i) { - - if (i == menu_sel) { - // draw the highlight bar - SetColor(MENU_SEL_BG); - 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); - } - SetColor(MENU); - } else if (menu_[i][0]) { - gr_text(gr_sys_font(), x + 4, y, menu_[i], 0); - } - y += char_height_+4; - } - SetColor(MENU); - y += 4; - gr_fill(0, y, gr_fb_width(), y+2); - y += 4; - } + int y = kMarginHeight; + int x = kMarginWidth; + if (show_menu) { + std::string recovery_fingerprint = + android::base::GetProperty("ro.bootimage.build.fingerprint", ""); + SetColor(HEADER); + y += DrawTextLine(x + 4, y, "Android Recovery", true); + for (auto& chunk : android::base::Split(recovery_fingerprint, ":")) { + y += DrawTextLine(x + 4, y, chunk.c_str(), false); + } + + // This is actually the help strings. + y += DrawTextLines(x + 4, y, SWIPE_HELP); + SetColor(HEADER); + y += DrawTextLines(x + 4, y, menu_headers_); + + // Show the current menu item number in relation to total number if + // items don't fit on the screen. + if (menu_items > menu_end - menu_start) { + sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items); + gr_text(gr_sys_font(), x + 4, y, cur_selection_str, 1); + y += char_height_ + 4; + } - SetColor(LOG); - - // display from the bottom up, until we hit the top of the - // 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_; - size_t count = 0; - for (int ty = gr_fb_height() - char_height_ - outer_height; - ty > y + 2 && count < text_rows_; - ty -= char_height_, ++count) { - gr_text(gr_sys_font(), x+4, ty, text_[row], 0); - --row; - if (row < 0) row = text_rows_ - 1; + // Menu begins here + SetColor(MENU); + + for (int i = menu_start; i < menu_end; ++i) { + if (i == menu_sel) { + // draw the highlight bar + SetColor(MENU_SEL_BG); + 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].c_str(), 1); + } + SetColor(MENU); + } else if (menu_[i][0]) { + gr_text(gr_sys_font(), x + 4, y, menu_[i].c_str(), 0); } + y += char_height_ + 4; + } + SetColor(MENU); + y += 4; + gr_fill(0, y, gr_fb_width(), y + 2); + y += 4; } + + SetColor(LOG); + + // display from the bottom up, until we hit the top of the + // 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_; + size_t count = 0; + for (int ty = gr_fb_height() - char_height_ - kMarginHeight; ty > y + 2 && count < text_rows_; + ty -= char_height_, ++count) { + gr_text(gr_sys_font(), x + 4, ty, text_[row], 0); + --row; + if (row < 0) row = text_rows_ - 1; + } + } } // TODO merge drawing routines with screen_ui void WearRecoveryUI::update_progress_locked() { - draw_screen_locked(); - gr_flip(); + draw_screen_locked(); + gr_flip(); } bool WearRecoveryUI::InitTextParams() { - if (!ScreenRecoveryUI::InitTextParams()) { - return false; - } + if (!ScreenRecoveryUI::InitTextParams()) { + return false; + } - text_cols_ = (gr_fb_width() - (outer_width * 2)) / char_width_; + text_cols_ = (gr_fb_width() - (kMarginWidth * 2)) / char_width_; - if (text_rows_ > kMaxRows) text_rows_ = kMaxRows; - if (text_cols_ > kMaxCols) text_cols_ = kMaxCols; + if (text_rows_ > kMaxRows) text_rows_ = kMaxRows; + if (text_cols_ > kMaxCols) text_cols_ = kMaxCols; - visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_; - return true; + visible_text_rows = (gr_fb_height() - (kMarginHeight * 2)) / char_height_; + return true; } bool WearRecoveryUI::Init(const std::string& locale) { @@ -222,7 +219,8 @@ bool WearRecoveryUI::Init(const std::string& locale) { return true; } -void WearRecoveryUI::SetStage(int current, int max) {} +void WearRecoveryUI::SetStage(int current, int max) { +} void WearRecoveryUI::Print(const char* fmt, ...) { char buf[256]; @@ -252,165 +250,152 @@ void WearRecoveryUI::Print(const char* fmt, ...) { pthread_mutex_unlock(&updateMutex); } -void WearRecoveryUI::StartMenu(const char* const * headers, const char* const * items, +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) { - menu_headers_ = headers; - size_t i = 0; - // "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. - // Bug: 23752519 - for (; items[i] != nullptr; i++) { - strncpy(menu_[i], items[i], text_cols_ - 1); - menu_[i][text_cols_ - 1] = '\0'; - } - menu_items = i; - show_menu = true; - menu_sel = initial_selection; - menu_start = 0; - menu_end = visible_text_rows - 1 - menu_unusable_rows; - if (menu_items <= menu_end) - menu_end = menu_items; - update_screen_locked(); + pthread_mutex_lock(&updateMutex); + if (text_rows_ > 0 && text_cols_ > 0) { + menu_headers_ = headers; + menu_.clear(); + // "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. + // Bug: 23752519 + for (size_t i = 0; items[i] != nullptr; i++) { + menu_.emplace_back(std::string(items[i], strnlen(items[i], text_cols_ - 1))); } - pthread_mutex_unlock(&updateMutex); + menu_items = static_cast<int>(menu_.size()); + show_menu = true; + menu_sel = initial_selection; + menu_start = 0; + menu_end = visible_text_rows - 1 - kMenuUnusableRows; + if (menu_items <= menu_end) menu_end = menu_items; + update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); } int WearRecoveryUI::SelectMenu(int sel) { - int old_sel; - pthread_mutex_lock(&updateMutex); - if (show_menu) { - old_sel = menu_sel; - menu_sel = sel; - if (menu_sel < 0) menu_sel = 0; - if (menu_sel >= menu_items) menu_sel = menu_items-1; - if (menu_sel < menu_start) { - menu_start--; - menu_end--; - } else if (menu_sel >= menu_end && menu_sel < menu_items) { - menu_end++; - menu_start++; - } - sel = menu_sel; - if (menu_sel != old_sel) update_screen_locked(); + int old_sel; + pthread_mutex_lock(&updateMutex); + if (show_menu) { + old_sel = menu_sel; + menu_sel = sel; + if (menu_sel < 0) menu_sel = 0; + if (menu_sel >= menu_items) menu_sel = menu_items - 1; + if (menu_sel < menu_start) { + menu_start--; + menu_end--; + } else if (menu_sel >= menu_end && menu_sel < menu_items) { + menu_end++; + menu_start++; } - pthread_mutex_unlock(&updateMutex); - return sel; + sel = menu_sel; + if (menu_sel != old_sel) update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); + return sel; } void WearRecoveryUI::ShowFile(FILE* fp) { - std::vector<off_t> offsets; - offsets.push_back(ftello(fp)); - ClearText(); - - struct stat sb; - fstat(fileno(fp), &sb); - - bool show_prompt = false; - while (true) { - if (show_prompt) { - Print("--(%d%% of %d bytes)--", - static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))), - static_cast<int>(sb.st_size)); - Redraw(); - while (show_prompt) { - show_prompt = false; - int key = WaitKey(); - if (key == KEY_POWER || key == KEY_ENTER) { - return; - } else if (key == KEY_UP || key == KEY_VOLUMEUP) { - if (offsets.size() <= 1) { - show_prompt = true; - } else { - offsets.pop_back(); - fseek(fp, offsets.back(), SEEK_SET); - } - } else { - if (feof(fp)) { - return; - } - offsets.push_back(ftello(fp)); - } - } - ClearText(); - } - - int ch = getc(fp); - if (ch == EOF) { - text_row_ = text_top_ = text_rows_ - 2; + std::vector<off_t> offsets; + offsets.push_back(ftello(fp)); + ClearText(); + + struct stat sb; + fstat(fileno(fp), &sb); + + bool show_prompt = false; + while (true) { + if (show_prompt) { + Print("--(%d%% of %d bytes)--", + static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))), + static_cast<int>(sb.st_size)); + Redraw(); + while (show_prompt) { + show_prompt = false; + int key = WaitKey(); + if (key == KEY_POWER || key == KEY_ENTER) { + return; + } else if (key == KEY_UP || key == KEY_VOLUMEUP) { + if (offsets.size() <= 1) { show_prompt = true; + } else { + offsets.pop_back(); + fseek(fp, offsets.back(), SEEK_SET); + } } else { - PutChar(ch); - if (text_col_ == 0 && text_row_ >= text_rows_ - 2) { - text_top_ = text_row_; - show_prompt = true; - } + if (feof(fp)) { + return; + } + offsets.push_back(ftello(fp)); } + } + ClearText(); } -} -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_; + int ch = getc(fp); + if (ch == EOF) { + 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_; + show_prompt = true; + } } - pthread_mutex_unlock(&updateMutex); + } } -void WearRecoveryUI::ShowFile(const char* filename) { - FILE* fp = fopen_path(filename, "re"); - if (fp == nullptr) { - Print(" Unable to open %s: %s\n", filename, strerror(errno)); - return; - } - ShowFile(fp); - fclose(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_; + } + pthread_mutex_unlock(&updateMutex); } -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); - } - pthread_mutex_unlock(&updateMutex); +void WearRecoveryUI::ShowFile(const char* filename) { + FILE* fp = fopen_path(filename, "re"); + if (fp == nullptr) { + Print(" Unable to open %s: %s\n", filename, strerror(errno)); + return; + } + ShowFile(fp); + fclose(fp); } void WearRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - PrintV(fmt, false, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + PrintV(fmt, false, ap); + va_end(ap); } void WearRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) { - std::string str; - android::base::StringAppendV(&str, fmt, ap); + std::string str; + android::base::StringAppendV(&str, fmt, ap); - if (copy_to_stdout) { - fputs(str.c_str(), stdout); - } + if (copy_to_stdout) { + fputs(str.c_str(), stdout); + } - pthread_mutex_lock(&updateMutex); - 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_[text_row_][text_col_++] = *ptr; - } + pthread_mutex_lock(&updateMutex); + 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'; - update_screen_locked(); + 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; } - pthread_mutex_unlock(&updateMutex); + text_[text_row_][text_col_] = '\0'; + update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); } |