From 337db14f274fc73dd540aa71d2c21c431fe686ec Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 20 Aug 2015 14:52:57 -0700 Subject: recovery: Factor out wear_ui.{cpp,h} into bootable/recovery. Every watch has a (mostly identical) copy of the wear_ui. Factor them out into a single copy for easier maintenance. Device-specific settings should be defined in recovery_ui.cpp that inherits WearRecoveryUI class. Bug: 22451422 Change-Id: Id07efca37d1b1d330e6327506c7b73ccf6ae9241 --- wear_ui.cpp | 650 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 650 insertions(+) create mode 100644 wear_ui.cpp (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp new file mode 100644 index 000000000..4ae42c467 --- /dev/null +++ b/wear_ui.cpp @@ -0,0 +1,650 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "device.h" +#include "minui/minui.h" +#include "wear_ui.h" +#include "ui.h" +#include "cutils/properties.h" +#include "base/strings.h" + +static int char_width; +static int char_height; + +// There's only (at most) one of these objects, and global callbacks +// (for pthread_create, and the input event system) need to find it, +// so use a global variable. +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; +} + +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), + currentIcon(NONE), + intro_done(false), + current_frame(0), + animation_fps(30), + rtl_locale(false), + 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) { + + for (size_t i = 0; i < 5; i++) + backgroundIcon[i] = NULL; + + pthread_mutex_init(&updateMutex, NULL); + self = this; +} + +// Draw background frame on the screen. Does not flip pages. +// Should only be called with updateMutex locked. +void WearRecoveryUI::draw_background_locked(Icon icon) +{ + gr_color(0, 0, 0, 255); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + + if (icon) { + GRSurface* surface; + if (icon == INSTALLING_UPDATE || icon == ERASING) { + if (!intro_done) { + surface = introFrames[current_frame]; + } else { + surface = loopFrames[current_frame]; + } + } + else { + surface = backgroundIcon[icon]; + } + + 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; + + gr_blit(surface, 0, 0, width, height, x, y); + } +} + +// 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); + } + } +} + +void WearRecoveryUI::SetColor(UIElement e) { + switch (e) { + case HEADER: + gr_color(247, 0, 6, 255); + break; + case MENU: + case MENU_SEL_BG: + gr_color(0, 106, 157, 255); + break; + case MENU_SEL_FG: + gr_color(255, 255, 255, 255); + break; + case LOG: + gr_color(249, 194, 0, 255); + break; + case TEXT_FILL: + gr_color(0, 0, 0, 160); + break; + default: + gr_color(255, 255, 255, 255); + break; + } +} + +void WearRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) { + gr_text(x, *y, line, bold); + *y += char_height + 4; +} + +void WearRecoveryUI::DrawTextLines(int x, int* y, const char* const* lines) { + for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) { + DrawTextLine(x, y, lines[i], false); + } +} + +static const char* HEADERS[] = { + "Swipe up/down to move.", + "Swipe left/right to select.", + "", + NULL +}; + +void WearRecoveryUI::draw_screen_locked() +{ + draw_background_locked(currentIcon); + draw_progress_locked(); + char cur_selection_str[50]; + + if (show_text) { + SetColor(TEXT_FILL); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + + int y = outer_height; + int x = outer_width; + if (show_menu) { + char recovery_fingerprint[PROPERTY_VALUE_MAX]; + property_get("ro.bootimage.build.fingerprint", recovery_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(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(x+4, y, menu[i], 1); + SetColor(MENU); + } else { + if (menu[i][0]) gr_text(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; + } + + 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(x+4, ty, text[row], 0); + --row; + 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(); + return NULL; +} + +void WearRecoveryUI::progress_loop() { + double interval = 1.0 / animation_fps; + for (;;) { + double start = now(); + pthread_mutex_lock(&updateMutex); + int redraw = 0; + + if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) + && !show_text) { + if (!intro_done) { + if (current_frame == intro_frames - 1) { + intro_done = true; + current_frame = 0; + } else { + current_frame++; + } + } else { + current_frame = (current_frame + 1) % loop_frames; + } + redraw = 1; + } + + // move the progress bar forward on timed intervals, if configured + int duration = progressScopeDuration; + if (progressBarType == DETERMINATE && duration > 0) { + double elapsed = now() - progressScopeTime; + float p = 1.0 * elapsed / duration; + if (p > 1.0) p = 1.0; + if (p > progress) { + progress = p; + redraw = 1; + } + } + + if (redraw) + update_screen_locked(); + + pthread_mutex_unlock(&updateMutex); + double end = now(); + // minimum of 20ms delay between frames + double delay = interval - (end-start); + if (delay < 0.02) delay = 0.02; + usleep((long)(delay * 1000000)); + } +} + +void WearRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { + int result = res_create_display_surface(filename, surface); + if (result < 0) { + LOGE("missing bitmap %s\n(Code %d)\n", filename, result); + } +} + +void WearRecoveryUI::Init() +{ + gr_init(); + + gr_font_size(&char_width, &char_height); + + 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; + + 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::SetLocale(const char* locale) { + if (locale) { + char* lang = strdup(locale); + for (char* p = lang; *p; ++p) { + if (*p == '_') { + *p = '\0'; + break; + } + } + + // A bit cheesy: keep an explicit list of supported languages + // that are RTL. + if (strcmp(lang, "ar") == 0 || // Arabic + strcmp(lang, "fa") == 0 || // Persian (Farsi) + strcmp(lang, "he") == 0 || // Hebrew (new language code) + strcmp(lang, "iw") == 0 || // Hebrew (old language code) + strcmp(lang, "ur") == 0) { // Urdu + rtl_locale = true; + } + free(lang); + } +} + +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) +{ +} + +void WearRecoveryUI::Print(const char *fmt, ...) +{ + char buf[256]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, 256, fmt, ap); + va_end(ap); + + fputs(buf, stdout); + + // This can get called before ui_init(), so be careful. + pthread_mutex_lock(&updateMutex); + 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[text_row][text_col++] = *ptr; + } + text[text_row][text_col] = '\0'; + update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); +} + +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; + for (; i < text_rows && items[i] != nullptr; i++) { + strncpy(menu[i], items[i], text_cols - 1); + menu[i][text_cols - 1] = '\0'; + } + menu_items = i; + show_menu = 1; + 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_unlock(&updateMutex); +} + +int WearRecoveryUI::SelectMenu(int sel) { + int old_sel; + pthread_mutex_lock(&updateMutex); + if (show_menu > 0) { + 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(); + } + pthread_mutex_unlock(&updateMutex); + 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 offsets; + offsets.push_back(ftell(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(100 * (double(ftell(fp)) / double(sb.st_size))), + static_cast(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(ftell(fp)); + } + } + ClearText(); + } + + 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; + } + } + } +} + +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::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::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); +} -- cgit v1.2.3 From 8e9c68019f9c284b89155c71922ad8ac84af6ab6 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Wed, 2 Sep 2015 11:20:30 -0700 Subject: recovery: Fix the bug that truncates menu entries. When there are 20 entries (like 10 last_log* and 10 last_kmg* in "view recovery logs"), there's no "Back" entry. Because the number of entries (21) exceeds text_rows (20) in WearRecoveryUI::StartMenu(). Since we have scrollable menu, having more entries than text_rows won't be an issue. Bug: 23752519 Change-Id: I12573d7a34852a1a3d130c9e88522cee737eb08f --- wear_ui.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 4ae42c467..55b7afc8f 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -482,7 +482,12 @@ void WearRecoveryUI::StartMenu(const char* const * headers, const char* const * if (text_rows > 0 && text_cols > 0) { menu_headers_ = headers; size_t i = 0; - for (; i < text_rows && items[i] != nullptr; i++) { + // "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'; } -- cgit v1.2.3 From 4b166f0e69d46858ff998414da2a01e0266fa339 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 4 Dec 2015 15:30:20 -0800 Subject: Track rename from base/ to android-base/. Change-Id: I354a8c424d340a9abe21fd716a4ee0d3b177d86f --- wear_ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 55b7afc8f..3ee38e8a4 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -35,7 +35,7 @@ #include "wear_ui.h" #include "ui.h" #include "cutils/properties.h" -#include "base/strings.h" +#include "android-base/strings.h" static int char_width; static int char_height; -- cgit v1.2.3 From b723f4f38f53a38502abb1a63165ac0749bc9cd9 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Fri, 11 Dec 2015 15:18:51 -0800 Subject: res: Embed FPS into icon_installing.png. We allow vendor-specific icon installing image but have defined private animation_fps that can't be overridden. This CL changes the image generator to optionally embed FPS (otherwise use the default value of 20) into the generated image. For wear devices, they are using individual images instead of the interlaced one. Change the animation_fps from private to protected so that it can be customized. Bug: 26009230 Change-Id: I9fbf64ec717029d4c54f72316f6cb079e8dbfb5e --- wear_ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 3ee38e8a4..50aeb3849 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -61,10 +61,10 @@ WearRecoveryUI::WearRecoveryUI() : menu_unusable_rows(0), intro_frames(22), loop_frames(60), + animation_fps(30), currentIcon(NONE), intro_done(false), current_frame(0), - animation_fps(30), rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), -- cgit v1.2.3 From 0eb41c3f370e89ff40cf1a3bd17e7b785b74641e Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Thu, 25 Feb 2016 18:27:03 -0800 Subject: Fixes to wear recovery for N Bug: 27336841 Change-Id: If4632e9791cce2c39590a4012687271f59a60af1 --- wear_ui.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 50aeb3849..8a57cfffa 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -36,6 +36,7 @@ #include "ui.h" #include "cutils/properties.h" #include "android-base/strings.h" +#include "android-base/stringprintf.h" static int char_width; static int char_height; @@ -653,3 +654,35 @@ void WearRecoveryUI::ClearText() { } pthread_mutex_unlock(&updateMutex); } + +void WearRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) { + 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); + + 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; + } + text[text_row][text_col] = '\0'; + update_screen_locked(); + } + pthread_mutex_unlock(&updateMutex); +} -- cgit v1.2.3 From 7d9fd96dc99a6008979811e36bb06f3afad18508 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Tue, 8 Mar 2016 13:18:45 -0800 Subject: recovery: Begin refactor of WearUI to use ScreenRecoveryUI This is the first of a series of changes which move WearUI to subclass ScreenRecoveryUI, to take advantage of several functions which are common between the two recovery UI implementations, and already defined in ScreenRecoveryUI. This patch changes the base class of WearUI, removes redundant header includes, and also removes a common function. Bug: 27407422 Change-Id: I8fd90826900f69272a82e23bd099790e8004d511 --- wear_ui.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 8a57cfffa..65bcd8494 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -16,9 +16,7 @@ #include #include -#include #include -#include #include #include #include @@ -31,9 +29,7 @@ #include "common.h" #include "device.h" -#include "minui/minui.h" #include "wear_ui.h" -#include "ui.h" #include "cutils/properties.h" #include "android-base/strings.h" #include "android-base/stringprintf.h" @@ -370,29 +366,6 @@ void WearRecoveryUI::Init() RecoveryUI::Init(); } -void WearRecoveryUI::SetLocale(const char* locale) { - if (locale) { - char* lang = strdup(locale); - for (char* p = lang; *p; ++p) { - if (*p == '_') { - *p = '\0'; - break; - } - } - - // A bit cheesy: keep an explicit list of supported languages - // that are RTL. - if (strcmp(lang, "ar") == 0 || // Arabic - strcmp(lang, "fa") == 0 || // Persian (Farsi) - strcmp(lang, "he") == 0 || // Hebrew (new language code) - strcmp(lang, "iw") == 0 || // Hebrew (old language code) - strcmp(lang, "ur") == 0) { // Urdu - rtl_locale = true; - } - free(lang); - } -} - void WearRecoveryUI::SetBackground(Icon icon) { pthread_mutex_lock(&updateMutex); -- cgit v1.2.3 From 1c7b2230d8aac9f064f68c48b6aa26aca000cc9d Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Tue, 8 Mar 2016 15:23:51 -0800 Subject: recovery: More refactoring of WearUI This patch performs the following modifications: - Remove setBackground function, and currentIcon member variable. - Remove common Progress*, Redraw and EndMenu functions. Bug: 27407422 Change-Id: Ic3c0e16b67941484c3bc1d04c9b61288e8896808 Signed-off-by: Prashant Malani --- wear_ui.cpp | 69 ------------------------------------------------------------- 1 file changed, 69 deletions(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 65bcd8494..ef48b788b 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -59,7 +59,6 @@ WearRecoveryUI::WearRecoveryUI() : intro_frames(22), loop_frames(60), animation_fps(30), - currentIcon(NONE), intro_done(false), current_frame(0), rtl_locale(false), @@ -366,57 +365,6 @@ void WearRecoveryUI::Init() 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) { } @@ -499,16 +447,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); @@ -539,13 +477,6 @@ void WearRecoveryUI::ShowText(bool visible) 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 offsets; offsets.push_back(ftell(fp)); -- cgit v1.2.3 From f7f9e50528761022989c4f0cac6a92716b54674f Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Thu, 10 Mar 2016 03:40:20 +0000 Subject: Revert "recovery: More refactoring of WearUI" This reverts commit 1c7b2230d8aac9f064f68c48b6aa26aca000cc9d. This change can lead to the derived class indirectly (and incorrectly) calling some functions from the base class, which can lead to unpredictable behavior. Bug: 27407422 Change-Id: I126a7489b0787dc195e942e2ceea6769de20d70c --- wear_ui.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index ef48b788b..65bcd8494 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -59,6 +59,7 @@ WearRecoveryUI::WearRecoveryUI() : intro_frames(22), loop_frames(60), animation_fps(30), + currentIcon(NONE), intro_done(false), current_frame(0), rtl_locale(false), @@ -365,6 +366,57 @@ void WearRecoveryUI::Init() 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) { } @@ -447,6 +499,16 @@ 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); @@ -477,6 +539,13 @@ void WearRecoveryUI::ShowText(bool visible) 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 offsets; offsets.push_back(ftell(fp)); -- cgit v1.2.3 From 0ba21cff07ceafeaa43e17aa26e341d961f6f29f Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Thu, 10 Mar 2016 14:51:25 -0800 Subject: recovery: Remove duplicate variables and functions The function that modifies rtl_locale exists only in the base class, and so the variable should not have a duplicate in the derived class, otherwise there may be incosistent values when it is read by the derived class (the thinking being that invoking the function will modify the base class version of the variable, and not the derived class version). Remove the updateMutex variable, and instead re-use the one in the base class. Also remove LoadBitmap from WearUI since it is identical to the one in ScreenRecoveryUI. Bug: 27407422 Change-Id: Idd823fa93dfa16d7b2c9c7160f8d0c2559d28731 --- wear_ui.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 65bcd8494..e76af8d6b 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -62,7 +62,6 @@ WearRecoveryUI::WearRecoveryUI() : currentIcon(NONE), intro_done(false), current_frame(0), - rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), @@ -81,7 +80,6 @@ WearRecoveryUI::WearRecoveryUI() : for (size_t i = 0; i < 5; i++) backgroundIcon[i] = NULL; - pthread_mutex_init(&updateMutex, NULL); self = this; } @@ -321,13 +319,6 @@ void WearRecoveryUI::progress_loop() { } } -void WearRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) { - int result = res_create_display_surface(filename, surface); - if (result < 0) { - LOGE("missing bitmap %s\n(Code %d)\n", filename, result); - } -} - void WearRecoveryUI::Init() { gr_init(); -- cgit v1.2.3 From 7a491225bbbb24593a4eda5dabe2fc1850d60dd1 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Fri, 11 Mar 2016 10:00:55 -0800 Subject: recovery: Remove SetColor, and other refactoring for WearUI The only difference from SetColor in ScreenRecoveryUI is the that the LOG messages have slightly different colors. That's not enough to warrant a duplicate function. So this patch removes SetColor and uses the parent class version. This patch also moves the DrawTextLine* functions into ScreenRecoveryUI since they're mostly the same. It also moves char_width and char_height into the class instead of keeping them as static variables. Bug: 27407422 Change-Id: I30428c9433baab8410cf710a01c9b1c44c217bf1 --- wear_ui.cpp | 56 +++++++++----------------------------------------------- 1 file changed, 9 insertions(+), 47 deletions(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index e76af8d6b..2502313ff 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -34,9 +34,6 @@ #include "android-base/strings.h" #include "android-base/stringprintf.h" -static int char_width; -static int char_height; - // There's only (at most) one of these objects, and global callbacks // (for pthread_create, and the input event system) need to find it, // so use a global variable. @@ -143,41 +140,6 @@ void WearRecoveryUI::draw_progress_locked() } } -void WearRecoveryUI::SetColor(UIElement e) { - switch (e) { - case HEADER: - gr_color(247, 0, 6, 255); - break; - case MENU: - case MENU_SEL_BG: - gr_color(0, 106, 157, 255); - break; - case MENU_SEL_FG: - gr_color(255, 255, 255, 255); - break; - case LOG: - gr_color(249, 194, 0, 255); - break; - case TEXT_FILL: - gr_color(0, 0, 0, 160); - break; - default: - gr_color(255, 255, 255, 255); - break; - } -} - -void WearRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) { - gr_text(x, *y, line, bold); - *y += char_height + 4; -} - -void WearRecoveryUI::DrawTextLines(int x, int* y, const char* const* lines) { - for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) { - DrawTextLine(x, y, lines[i], false); - } -} - static const char* HEADERS[] = { "Swipe up/down to move.", "Swipe left/right to select.", @@ -216,7 +178,7 @@ void WearRecoveryUI::draw_screen_locked() if (menu_items > menu_end - menu_start) { sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items); gr_text(x+4, y, cur_selection_str, 1); - y += char_height+4; + y += char_height_+4; } // Menu begins here @@ -227,7 +189,7 @@ void WearRecoveryUI::draw_screen_locked() 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); + 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(x+4, y, menu[i], 1); @@ -235,7 +197,7 @@ void WearRecoveryUI::draw_screen_locked() } else { if (menu[i][0]) gr_text(x+4, y, menu[i], 0); } - y += char_height+4; + y += char_height_+4; } SetColor(MENU); y += 4; @@ -251,9 +213,9 @@ void WearRecoveryUI::draw_screen_locked() 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; + for (int ty = gr_fb_height() - char_height_ - outer_height; ty > y+2 && count < text_rows; - ty -= char_height, ++count) { + ty -= char_height_, ++count) { gr_text(x+4, ty, text[row], 0); --row; if (row < 0) row = text_rows-1; @@ -323,15 +285,15 @@ void WearRecoveryUI::Init() { gr_init(); - gr_font_size(&char_width, &char_height); + gr_font_size(&char_width_, &char_height_); text_col = text_row = 0; - text_rows = (gr_fb_height()) / char_height; - visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height; + 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; + text_cols = (gr_fb_width() - (outer_width * 2)) / char_width_; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); -- cgit v1.2.3 From 5b00110e3d6c4af97cd7699a5c61fab2f973107e Mon Sep 17 00:00:00 2001 From: Alain Vongsouvanh Date: Tue, 7 Jun 2016 10:05:29 -0700 Subject: recovery: Make wear recovery more customizable. Making animation_fps protected and adding support for 0 frames intro. BUG: 29085786 Change-Id: I07b44570022bad89661973178d453592c01f3f10 --- wear_ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wear_ui.cpp') diff --git a/wear_ui.cpp b/wear_ui.cpp index 55b7afc8f..ebe0dfe37 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -288,7 +288,7 @@ void WearRecoveryUI::progress_loop() { if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) { if (!intro_done) { - if (current_frame == intro_frames - 1) { + if (current_frame >= intro_frames - 1) { intro_done = true; current_frame = 0; } else { -- cgit v1.2.3