1c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project/* 2211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker * Copyright (C) 2011 The Android Open Source Project 3c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 4c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * you may not use this file except in compliance with the License. 6c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * You may obtain a copy of the License at 7c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 8c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 10c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * See the License for the specific language governing permissions and 14c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * limitations under the License. 15c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project */ 16c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 176ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <errno.h> 186ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <fcntl.h> 19c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <linux/input.h> 20c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <pthread.h> 21c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdarg.h> 22c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdio.h> 23c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdlib.h> 24c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <string.h> 256ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <sys/stat.h> 26c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <sys/time.h> 276ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <sys/types.h> 28c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <time.h> 29c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <unistd.h> 30c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 31c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include "common.h" 3232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker#include "device.h" 33c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include "minui/minui.h" 34211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker#include "screen_ui.h" 3532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker#include "ui.h" 36c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 3755a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongkerstatic int char_width; 3855a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongkerstatic int char_height; 39c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 40211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// There's only (at most) one of these objects, and global callbacks 41211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// (for pthread_create, and the input event system) need to find it, 42211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// so use a global variable. 43211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerstatic ScreenRecoveryUI* self = NULL; 44c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 456809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// Return the current time as a double (including fractions of a second). 466809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongkerstatic double now() { 476809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker struct timeval tv; 486809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gettimeofday(&tv, NULL); 496809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker return tv.tv_sec + tv.tv_usec / 1000000.0; 506809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker} 516809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 52211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug ZongkerScreenRecoveryUI::ScreenRecoveryUI() : 53211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker currentIcon(NONE), 54211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker installingFrame(0), 55a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker locale(NULL), 565fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker rtl_locale(false), 57211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType(EMPTY), 58211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeStart(0), 59211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeSize(0), 60211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress(0), 61211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical(false), 62211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_cols(0), 63211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_rows(0), 64211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_col(0), 65211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_row(0), 66211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_top(0), 67211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_text(false), 68211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_text_ever(false), 69211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_menu(false), 70211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_top(0), 71211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_items(0), 72211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_sel(0), 7332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker animation_fps(20), 74eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker installing_frames(-1), 75c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker stage(-1), 76c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker max_stage(-1) { 775b468fc9305bf3adef681fa1e56364fc51761af8yetta_wu 785b468fc9305bf3adef681fa1e56364fc51761af8yetta_wu for (int i = 0; i < 5; i++) 795b468fc9305bf3adef681fa1e56364fc51761af8yetta_wu backgroundIcon[i] = NULL; 805b468fc9305bf3adef681fa1e56364fc51761af8yetta_wu 8180a7a4642be31db7ecd5eaa9e62b78deaa461146Bjorn Andersson memset(text, 0, sizeof(text)); 8280a7a4642be31db7ecd5eaa9e62b78deaa461146Bjorn Andersson 83211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_init(&updateMutex, NULL); 84211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker self = this; 85211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 86211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 87c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Clear the screen and draw the currently selected background icon (if any). 88211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 89211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_background_locked(Icon icon) 90c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 91211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = false; 925b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(0, 0, 0, 255); 9339cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker gr_clear(); 94c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 95c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (icon) { 96211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_surface surface = backgroundIcon[icon]; 97eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker if (icon == INSTALLING_UPDATE || icon == ERASING) { 98eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker surface = installation[installingFrame]; 99eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker } 10002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface text_surface = backgroundText[icon]; 10102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1026809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconWidth = gr_get_width(surface); 1036809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconHeight = gr_get_height(surface); 10402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textWidth = gr_get_width(text_surface); 10502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textHeight = gr_get_height(text_surface); 106c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int stageHeight = gr_get_height(stageMarkerEmpty); 107c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker 108c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int sh = (max_stage >= 0) ? stageHeight : 0; 10902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 110eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker iconX = (gr_fb_width() - iconWidth) / 2; 111eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker iconY = (gr_fb_height() - (iconHeight+textHeight+40+sh)) / 2; 11202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 11302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textX = (gr_fb_width() - textWidth) / 2; 114c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int textY = ((gr_fb_height() - (iconHeight+textHeight+40+sh)) / 2) + iconHeight + 40; 11502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1166809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); 117c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker if (stageHeight > 0) { 118c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int sw = gr_get_width(stageMarkerEmpty); 119c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int x = (gr_fb_width() - max_stage * gr_get_width(stageMarkerEmpty)) / 2; 120c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker int y = iconY + iconHeight + 20; 121c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker for (int i = 0; i < max_stage; ++i) { 122c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker gr_blit((i < stage) ? stageMarkerFill : stageMarkerEmpty, 123c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker 0, 0, sw, stageHeight, x, y); 124c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker x += sw; 125c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker } 126c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker } 127c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker 1285b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(255, 255, 255, 255); 12902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_texticon(textX, textY, text_surface); 130c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 131c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 132c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 133c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Draw the progress bar (if any) on the screen. Does not flip pages. 134211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 135211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_progress_locked() 136c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 13769f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (currentIcon == ERROR) return; 13869f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker 13902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { 140eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker gr_surface icon = installation[installingFrame]; 141eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker gr_blit(icon, 0, 0, gr_get_width(icon), gr_get_height(icon), iconX, iconY); 1426809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 143c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 144211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != EMPTY) { 14502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); 146211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int width = gr_get_width(progressBarEmpty); 147211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int height = gr_get_height(progressBarEmpty); 148c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1496809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dx = (gr_fb_width() - width)/2; 1506809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dy = (3*gr_fb_height() + iconHeight - 2*height)/4; 151c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1526809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // Erase behind the progress bar (in case this was a progress-only update) 1535b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(0, 0, 0, 255); 1546809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_fill(dx, dy, width, height); 155c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 156211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE) { 157211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float p = progressScopeStart + progress * progressScopeSize; 158211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int pos = (int) (p * width); 159c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1605fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (rtl_locale) { 1615fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from right to left. 1625fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1635fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); 1645fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1655fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1665fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); 1675fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1685fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } else { 1695fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from left to right. 1705fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1715fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); 1725fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1735fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1745fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); 1755fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1766809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 177c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 178c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 179c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 180c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 181c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongkervoid ScreenRecoveryUI::SetColor(UIElement e) { 182c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker switch (e) { 183c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker case HEADER: 1845b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(247, 0, 6, 255); 185c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker break; 186c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker case MENU: 187c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker case MENU_SEL_BG: 1885b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(0, 106, 157, 255); 189c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker break; 190c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker case MENU_SEL_FG: 191c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker gr_color(255, 255, 255, 255); 192c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker break; 193c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker case LOG: 1945b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(249, 194, 0, 255); 1955b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker break; 1965b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker case TEXT_FILL: 1975b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(0, 0, 0, 160); 198c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker break; 199c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker default: 200c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker gr_color(255, 255, 255, 255); 201c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker break; 202c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker } 203c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker} 204c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 205c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen. Does not flip pages. 206211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 207211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_screen_locked() 208c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 20939cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker if (!show_text) { 21039cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker draw_background_locked(currentIcon); 21139cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker draw_progress_locked(); 21239cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker } else { 2135b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_color(0, 0, 0, 255); 21439cf417e17011a72dd39acfe4cc8c90af26bdbafDoug Zongker gr_clear(); 215c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2166fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int y = 0; 217c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i = 0; 218c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu) { 219c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(HEADER); 220c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 221c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < menu_top + menu_items; ++i) { 222c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker if (i == menu_top) SetColor(MENU); 2236fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 224c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (i == menu_top + menu_sel) { 2256fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // draw the highlight bar 226c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(MENU_SEL_BG); 2275b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_fill(0, y-2, gr_fb_width(), y+char_height+2); 2286fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // white text of selected item 229c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(MENU_SEL_FG); 2305b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], 1); 231c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(MENU); 232c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2335b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top); 234c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 2356fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += char_height+4; 236c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 237c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(MENU); 2386fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 2396fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_fill(0, y, gr_fb_width(), y+2); 2406fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 241c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project ++i; 242c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 243c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 244c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker SetColor(LOG); 2456fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 2466fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // display from the bottom up, until we hit the top of the 2476fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // screen, the bottom of the menu, or we've displayed the 2486fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // entire text buffer. 2496fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int ty; 2506fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int row = (text_top+text_rows-1) % text_rows; 2516fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker for (int ty = gr_fb_height() - char_height, count = 0; 2526fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty > y+2 && count < text_rows; 2536fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty -= char_height, ++count) { 2545b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker gr_text(4, ty, text[row], 0); 2556fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker --row; 2566fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (row < 0) row = text_rows-1; 257c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 258c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 259c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 260c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 261c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen and flip the screen (make it visible). 262211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 263211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_screen_locked() 264c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 265c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); 266c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 267c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 268c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 269c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Updates only the progress bar, if possible, otherwise redraws the screen. 270211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 271211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_progress_locked() 272c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 273211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (show_text || !pagesIdentical) { 274c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); // Must redraw the whole screen 275211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = true; 276c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2776809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker draw_progress_locked(); // Draw only the progress bar and overlays 278c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 279c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 280c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 281c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 282c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Keeps the progress bar updated, even when the process is otherwise busy. 28332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid* ScreenRecoveryUI::progress_thread(void *cookie) { 28432a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker self->progress_loop(); 28532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker return NULL; 28632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker} 28732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 28832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid ScreenRecoveryUI::progress_loop() { 28932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double interval = 1.0 / animation_fps; 290c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (;;) { 2916809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double start = now(); 29232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_lock(&updateMutex); 293c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2946809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int redraw = 0; 2956809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 2966809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // update the installation animation, if active 2976809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // skip this if we have a text overlay (too expensive to update) 29802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && 29902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker installing_frames > 0 && !show_text) { 30032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker installingFrame = (installingFrame + 1) % installing_frames; 3016809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 3026809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 3036809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 304c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // move the progress bar forward on timed intervals, if configured 30532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker int duration = progressScopeDuration; 30632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (progressBarType == DETERMINATE && duration > 0) { 30732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double elapsed = now() - progressScopeTime; 30869f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker float p = 1.0 * elapsed / duration; 30969f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > 1.0) p = 1.0; 31069f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > progress) { 31169f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = p; 3126809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 313c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 314c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 315c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 31632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (redraw) update_progress_locked(); 3176809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 31832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_unlock(&updateMutex); 3196809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double end = now(); 3206809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // minimum of 20ms delay between frames 3216809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double delay = interval - (end-start); 3226809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker if (delay < 0.02) delay = 0.02; 3236809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker usleep((long)(delay * 1000000)); 324c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 325c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 326c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 327211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) { 328a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker int result = res_create_display_surface(filename, surface); 329211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (result < 0) { 330211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 331211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker } 332211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 333211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 334eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongkervoid ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, gr_surface** surface) { 335a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker int result = res_create_multi_display_surface(filename, frames, surface); 336eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker if (result < 0) { 337eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 338eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker } 339eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker} 340eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker 34102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongkervoid ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) { 342a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker int result = res_create_localized_alpha_surface(filename, locale, surface); 34302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (result < 0) { 34402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 34502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker } 34602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker} 34702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 348211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Init() 349c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 350c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_init(); 351c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 35255a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker gr_font_size(&char_width, &char_height); 35355a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker 354c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = text_row = 0; 3555b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker text_rows = gr_fb_height() / char_height; 356211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_rows > kMaxRows) text_rows = kMaxRows; 357c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_top = 1; 358c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 3595b5f6c2fd32839227d10ee3c97e662a415b80e2bDoug Zongker text_cols = gr_fb_width() / char_width; 360211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; 361211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 3629b8ae8038be65c2ec236bc04590716fbcd5363f6Alistair Strachan backgroundIcon[NONE] = NULL; 363eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker LoadBitmapArray("icon_installing", &installing_frames, &installation); 364eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : NULL; 36502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; 366211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("icon_error", &backgroundIcon[ERROR]); 36702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; 36802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 369211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_empty", &progressBarEmpty); 370211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_fill", &progressBarFill); 371c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker LoadBitmap("stage_empty", &stageMarkerEmpty); 372c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker LoadBitmap("stage_fill", &stageMarkerFill); 373c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 37402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); 37502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); 37602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); 37702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); 37802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 379211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_create(&progress_t, NULL, progress_thread, NULL); 38032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 38132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker RecoveryUI::Init(); 382c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 383c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 384a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongkervoid ScreenRecoveryUI::SetLocale(const char* new_locale) { 385a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker if (new_locale) { 386a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker this->locale = new_locale; 3875fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker char* lang = strdup(locale); 3885fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker for (char* p = lang; *p; ++p) { 3895fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (*p == '_') { 3905fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker *p = '\0'; 3915fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker break; 3925fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 3935fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 3945fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 3955fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // A bit cheesy: keep an explicit list of supported languages 3965fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // that are RTL. 3975fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (strcmp(lang, "ar") == 0 || // Arabic 3985fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "fa") == 0 || // Persian (Farsi) 3995fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "he") == 0 || // Hebrew (new language code) 400b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "iw") == 0 || // Hebrew (old language code) 401b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "ur") == 0) { // Urdu 4025fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker rtl_locale = true; 4035fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4045fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker free(lang); 405a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker } else { 406a418aa7dd5e94cbf1ab2a6fa1c63f60e5e087d42Doug Zongker new_locale = NULL; 4075fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4085fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker} 4095fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 410211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetBackground(Icon icon) 411c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 412211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 41302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 41452eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker currentIcon = icon; 41552eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker update_screen_locked(); 41652eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker 417211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 418c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 419c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 420211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgressType(ProgressType type) 421c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 422211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 423211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != type) { 424211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = type; 425c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 42669f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progressScopeStart = 0; 427239ac6abac4524be93fce710360c0512c6cc2ab3Doug Zongker progressScopeSize = 0; 42869f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = 0; 429239ac6abac4524be93fce710360c0512c6cc2ab3Doug Zongker update_progress_locked(); 430211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 431c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 432c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 433211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowProgress(float portion, float seconds) 434c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 435211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 436211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = DETERMINATE; 437211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeStart += progressScopeSize; 438211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeSize = portion; 439211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeTime = now(); 440211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeDuration = seconds; 441211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = 0; 442c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 443211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 444c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 445c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 446211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgress(float fraction) 447c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 448211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 449c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction < 0.0) fraction = 0.0; 450c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction > 1.0) fraction = 1.0; 451211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE && fraction > progress) { 452c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // Skip updates that aren't visibly different. 453eac881c952fc6be0beeb5f719e3a70e651f3610eDoug Zongker int width = gr_get_width(progressBarEmpty); 454211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float scale = width * progressScopeSize; 455211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if ((int) (progress * scale) != (int) (fraction * scale)) { 456211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = fraction; 457c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 458c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 459c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 460211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 461c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 462c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 463c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongkervoid ScreenRecoveryUI::SetStage(int current, int max) { 464c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker pthread_mutex_lock(&updateMutex); 465c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker stage = current; 466c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker max_stage = max; 467c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker pthread_mutex_unlock(&updateMutex); 468c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker} 469c87bab101893e8322b49d7c8600e3367b20ab50aDoug Zongker 470211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Print(const char *fmt, ...) 471c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 472c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char buf[256]; 473c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_list ap; 474c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_start(ap, fmt); 475c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project vsnprintf(buf, 256, fmt, ap); 476c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_end(ap); 477c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 4783d177d055c9cf3571e4b7c098818b454d1dbf9d7Doug Zongker fputs(buf, stdout); 479c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 480c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // This can get called before ui_init(), so be careful. 481211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 482c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 483c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char *ptr; 484c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (ptr = buf; *ptr != '\0'; ++ptr) { 485c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr == '\n' || text_col >= text_cols) { 486c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 487c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = 0; 488c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_row = (text_row + 1) % text_rows; 489c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_row == text_top) text_top = (text_top + 1) % text_rows; 490c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 491c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr != '\n') text[text_row][text_col++] = *ptr; 492c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 493c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 494c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 495c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 496211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 497c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 498c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 499211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::StartMenu(const char* const * headers, const char* const * items, 500211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int initial_selection) { 501c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 502211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 503c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 504c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (i = 0; i < text_rows; ++i) { 505c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (headers[i] == NULL) break; 506c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], headers[i], text_cols-1); 507c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 508c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 509c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_top = i; 510c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < text_rows; ++i) { 511c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (items[i-menu_top] == NULL) break; 512c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], items[i-menu_top], text_cols-1); 513c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 514c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 515c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_items = i - menu_top; 516c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 1; 517be598881d079511385a88b12b7a14b97e63dc85eDoug Zongker menu_sel = initial_selection; 518c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 519c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 520211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 521c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 522c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 523211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerint ScreenRecoveryUI::SelectMenu(int sel) { 524c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int old_sel; 525211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 526c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0) { 527c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project old_sel = menu_sel; 528c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_sel = sel; 529c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel < 0) menu_sel = 0; 530c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel >= menu_items) menu_sel = menu_items-1; 531c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project sel = menu_sel; 532c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel != old_sel) update_screen_locked(); 533c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 534211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 535c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return sel; 536c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 537c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 538211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::EndMenu() { 539c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 540211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 541c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0 && text_rows > 0 && text_cols > 0) { 542c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 0; 543c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 544c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 545211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 546c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 547c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 548211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::IsTextVisible() 549c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 550211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 551c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int visible = show_text; 552211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 553c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return visible; 554c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 555c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 556211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::WasTextEverVisible() 5575cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker{ 558211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5595cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker int ever_visible = show_text_ever; 560211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5615cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker return ever_visible; 5625cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker} 5635cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker 564211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowText(bool visible) 5654bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker{ 566211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5674bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker show_text = visible; 5685cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker if (show_text) show_text_ever = 1; 5694bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker update_screen_locked(); 570211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5714bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker} 572c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker 573c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongkervoid ScreenRecoveryUI::Redraw() 574c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker{ 575c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker pthread_mutex_lock(&updateMutex); 576c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker update_screen_locked(); 577c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker pthread_mutex_unlock(&updateMutex); 578c0441d171914e59941ec4f815ae0aabf56d6504fDoug Zongker} 579