Android recovery UI实现分析
从纯技术角度来讲, recovery和android本质上是两个独立的rootfs, 仅仅是recovery这个rootfs存在的意义就是为android这个rootfs服务,因此被解释为Android系统的一部分。
main(int argc, char **argv) {
......
Device* device = make_device();
ui = device->GetUI();
gCurrentUI = ui;
ui->Init();
ui->SetLocale(locale);
ui->SetBackground(RecoveryUI::NONE);
if (show_text) ui->ShowText(true);
......
if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
prompt_and_wait(device, status);
}
......
}
void ScreenRecoveryUI::Init()
{
gr_init(); gr_font_size(&char_width, &char_height); text_col = text_row = 0;
text_rows = gr_fb_height() / char_height;
if (text_rows > kMaxRows) text_rows = kMaxRows;
text_top = 1; text_cols = gr_fb_width() / 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]; LoadBitmap("progress_empty", &progressBarEmpty);
LoadBitmap("progress_fill", &progressBarFill); LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]);
LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]);
LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]);
LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); int i; progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames *
sizeof(gr_surface));
for (i = 0; i < indeterminate_frames; ++i) {
char filename[40];
// "indeterminate01.png", "indeterminate02.png", ...
sprintf(filename, "indeterminate%02d", i+1);
LoadBitmap(filename, progressBarIndeterminate+i);
} if (installing_frames > 0) {
installationOverlay = (gr_surface*)malloc(installing_frames *
sizeof(gr_surface));
for (i = 0; i < installing_frames; ++i) {
char filename[40];
// "icon_installing_overlay01.png",
// "icon_installing_overlay02.png", ...
sprintf(filename, "icon_installing_overlay%02d", i+1);
LoadBitmap(filename, installationOverlay+i);
}
} else {
installationOverlay = NULL;
} pthread_create(&progress_t, NULL, progress_thread, NULL); RecoveryUI::Init();
}
1、gr_init() 初始化图形设备,分配Pixelflinger库渲染的内存
2、gr_font_size() 将字体相应的surface长宽赋值给char_width和char_height
创建一个线程,该线程的任务是一个死循环,在该循环中不停
void ScreenRecoveryUI::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);
}
}
假设该文件也没有,则locale不会被赋值。就默认用English.
void ScreenRecoveryUI::SetBackground(Icon icon)
{
pthread_mutex_lock(&updateMutex); // Adjust the offset to account for the positioning of the
// base image on the screen.
if (backgroundIcon[icon] != NULL) {
gr_surface bg = backgroundIcon[icon];
gr_surface text = backgroundText[icon];
overlay_offset_x = install_overlay_offset_x + (gr_fb_width() - gr_get_width(bg)) / 2;
overlay_offset_y = install_overlay_offset_y +
(gr_fb_height() - (gr_get_height(bg) + gr_get_height(text) + 40)) / 2;
} currentIcon = icon;
update_screen_locked(); pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::update_screen_locked()
{
draw_screen_locked();
gr_flip();
}
void ScreenRecoveryUI::draw_screen_locked()
{
draw_background_locked(currentIcon);
draw_progress_locked(); if (show_text) {
SetColor(TEXT_FILL);
gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int y = 0;
int i = 0;
if (show_menu) {
SetColor(HEADER); for (; i < menu_top + menu_items; ++i) {
if (i == menu_top) SetColor(MENU); if (i == menu_top + menu_sel) {
// draw the highlight bar
SetColor(MENU_SEL_BG);
gr_fill(0, y-2, gr_fb_width(), y+char_height+2);
// white text of selected item
SetColor(MENU_SEL_FG);
if (menu[i][0]) gr_text(4, y, menu[i], 1);
SetColor(MENU);
} else {
if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top);
}
y += char_height+4;
}
SetColor(MENU);
y += 4;
gr_fill(0, y, gr_fb_width(), y+2);
y += 4;
++i;
} 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;
for (int ty = gr_fb_height() - char_height, count = 0;
ty > y+2 && count < text_rows;
ty -= char_height, ++count) {
gr_text(4, ty, text[row], 0);
--row;
if (row < 0) row = text_rows-1;
}
}
}
void ScreenRecoveryUI::draw_progress_locked()
{
if (currentIcon == ERROR) return; if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
draw_install_overlay_locked(installingFrame);
} if (progressBarType != EMPTY) {
int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]);
int width = gr_get_width(progressBarEmpty);
int height = gr_get_height(progressBarEmpty); int dx = (gr_fb_width() - width)/2;
int dy = (3*gr_fb_height() + iconHeight - 2*height)/4; // Erase behind the progress bar (in case this was a progress-only update)
gr_color(0, 0, 0, 255);
gr_fill(dx, dy, width, height); if (progressBarType == DETERMINATE) {
float p = progressScopeStart + progress * progressScopeSize;
int pos = (int) (p * width); if (rtl_locale) {
// Fill the progress bar from right to left.
if (pos > 0) {
gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy);
}
if (pos < width-1) {
gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy);
}
} else {
// Fill the progress bar from left to right.
if (pos > 0) {
gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
}
if (pos < width-1) {
gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
}
}
} if (progressBarType == INDETERMINATE) {
static int frame = 0;
gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
// in RTL locales, we run the animation backwards, which
// makes the spinner spin the other way.
if (rtl_locale) {
frame = (frame + indeterminate_frames - 1) % indeterminate_frames;
} else {
frame = (frame + 1) % indeterminate_frames;
}
}
}
}
int gr_init(void); /* 初始化图形显示,主要是打开设备、分配内存、初始化一些參数 */
void gr_exit(void); /* 注销图形显示,关闭设备并释放内存 */ int gr_fb_width(void); /* 获取屏幕的宽度 */
int gr_fb_height(void); /* 获取屏幕的高度 */
gr_pixel *gr_fb_data(void); /* 获取显示数据缓存的地址 */
void gr_flip(void); /* 刷新显示内容 */
void gr_fb_blank(bool blank); /* 清屏 */ void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a); /* 设置字体颜色 */
void gr_fill(int x, int y, int w, int h); /* 填充矩形区域,參数分别代表起始坐标、矩形区域大小 */
int gr_text(int x, int y, const char *s); /* 显示字符串 */
int gr_measure(const char *s); /* 获取字符串在默认字库中占用的像素长度 */
void gr_font_size(int *x, int *y); /* 获取当前字库一个字符所占的长宽 */ void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy); /* 填充由source指定的图片 */
unsigned int gr_get_width(gr_surface surface); /* 获取图片宽度 */
unsigned int gr_get_height(gr_surface surface); /* 获取图片高度 */
/* 依据图片创建显示资源数据,name为图片在mk文件指定的相对路径 */
int res_create_surface(const char* name, gr_surface* pSurface);
void res_free_surface(gr_surface surface); /* 释放资源数据 */
Android recovery UI实现分析的更多相关文章
- Android Recovery Ui 分析
Android recovery和android本质上是两个独立的rootfs, 仅仅是recovery这个rootfs存在的意义就是为android这个rootfs服务,因此被解释为Android ...
- android recovery 系统代码分析 -- 选择进入【转】
本文转载自:http://blog.csdn.net/andyhuabing/article/details/9226569 最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. An ...
- MTK Android 源码目录分析
Android 源码目录分析 Android 4.0 |-- abi (application binary interface:应用二进制接口)|-- art (average retrieval ...
- [Android]Volley源码分析(五)
前面几篇通过源码分析了Volley是怎样进行请求调度及请求是如何被实际执行的,这篇最后来看下请求结果是如何交付给请求者的(一般是Android的UI主线程). 类图:
- 从Android系统出发,分析Android控件构架
从Android系统出发,分析Android控件构架 Android中所有的控件追溯到根源,就是View 和ViewGroup,相信这个大家都知道,但是大家也许会不太清楚它们之间的具体关系是什么,在A ...
- Android优化——UI检视利器:Hierarchy Viewer
在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率.其中的一款叫 Hierachy Viewer的可视化调试工具,可以很方便地在 ...
- android recovery模式及ROM制作
转自android recovery模式及ROM制作 1.总述 为了方便客户日后的固件升级,本周研究了一下android的recovery模式.网上有不少这类的资料,但都比较繁杂,没有一个系统的介绍与 ...
- android recover 系统代码分析 -- 选择进入
最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级.而在进入Recover ...
- Android四个多线程分析:MessageQueue实现
Android四个多线程分析:MessageQueue的实现 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在前面两篇文章<Android多线 ...
随机推荐
- [.Net] DataTable添加列和行的三种方法
#region 方法一: DataTable tblDatas =new DataTable("Datas"); DataColumn dc =null; dc = tblData ...
- 二、SQL系列之~常见51道SQL查询语句
[写在前面~~] [PS1:建议SQL初学者一定要自己先做一遍题目,这样才有效果~~(做题时为验证查询结果是否正确,可更改表中数据)] [PS2:文末最后一条代码整合了全部51道题目及答案~~] [P ...
- 利用python开发的flappy bird 游戏
python 中 pygame模块能让我们很方便的编写游戏,16年我用python 仿制了flappy bird 游戏,下面是游戏的完整代码以及素材,分享给大家. 第一个python文件,flappy ...
- C# 开放式并发冲突报错处理
1.调用DataSet.GetChanges()获取数据源中改变的数据 var data = ViewData.GetChanges() as ReleaseData; 2.为新增的数据 data 加 ...
- Docker installs
docker要求系统内核必须在3.10以上uname -r 命令查看你当前的内核版本 1.更新yum源并删除旧版docker yum remove docker docker-common docke ...
- Java I/O streams
I/O Streams Byte Streams 输入输出以字节为单位,所有的使用字节流的类都继承自 InputStream 和 OutputStream. Byte Streams 属于 low-l ...
- 开发手机APP过程,不同使用场景APP搜索框的样式及区别
搜索框是 app 内最常见的控件之一,可以帮助用户快速又精准找到期望的内容与功能.不同的使用场景下,根据页面中搜索的重要程度,搜索框也有着不同的样式. 下面就常州开发APP公司和大家聊聊常见的四种样式 ...
- Sql Server 优化----SQL语句的执行方式与锁以及阻塞的关系
阻塞原因之一是不同的Session在访问同一张表的时候因为不兼容锁的原因造成的, 当前执行的SQL语句是否被阻塞(或者死锁),不仅跟当前表上的已有的锁有关,也会跟当前执行的SQL语句的执行方式有关 简 ...
- 【原创】打印GC log
-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:c:/gc.log
- java keytool证书工具使用小结(转载)
原文地址:http://www.micmiu.com/lang/java/keytool-start-guide/ Keytool 是一个Java数据证书的管理工具 ,Keytool将密钥(key)和 ...