Recovery启动流程(2)---UI界面
转载请注明来源:cuixiaolei的技术博客
Recovery启动流程系列文章把recvoery目录下文件分成小块讲解,最后再以一条主线贯穿所有的内容。这篇文章主要讲解Recovery-UI的相关内容。
我们知道,当我们通过按键或者应用进入recovery模式,实质是kernel后加载recovery.img,kernel起来后执行的第一个进程就是init,此进程会读入init.rc启动相应的服务。在recovery模式中,启动的服务是执行recovery可执行文件,此文件是bootable/recovery/recovery.cpp文件生成,我们就从recovery.cpp文件开始分析。此出可参考我的另一篇文章android-ramdisk.img分析、recovery.img&boot.img执行过程
bootable/recovery/recovery.cpp
int
main(int argc, char **argv) { ....
Device* device = make_device();
ui = device->GetUI();
gCurrentUI = ui; ui->SetLocale(locale);
ui->Init(); ui->SetBackground(RecoveryUI::NONE);
if (show_text) ui->ShowText(true);
....
if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
prompt_and_wait(device, status);
}
.... }
1.首先新建了一个Device类的对象, Device类封装了一些操作,包括UI的操作
2.调用Device类的GetUI()返回一个RecoveryUI对象
3.调用ui->SetLocale(locale)设置语言,调用SetBackground方法设置背景图片
4.调用Init()进行初始化。
5.这里的Init从代码上看应该是ui.cpp文件中RecoveryUI类的Init()方法,但是经验上走的应该是ScreenRecoveryUI,其中的愿意我还在看,这里我是按照ScreenRecoveryUI::Init追的代码。其中RecoveryUI是ScreenRecoveryUI的父类。
6.显示recovery的主界面,即一个选择菜单
初始化
void ScreenRecoveryUI::Init() {
gr_init(); //初始化图形设备,分配Pixelflinger库渲染的内存
gr_font_size(&char_width, &char_height);
text_rows_ = gr_fb_height() / char_height;
text_cols_ = gr_fb_width() / char_width;
#ifdef SUPPORT_UTF8_MULTILINGUAL
int ml_cols_ = * text_cols_; //max is 6 char for 1 utf8 character.
text_ = Alloc2d(text_rows_, ml_cols_ + );
file_viewer_text_ = Alloc2d(text_rows_, ml_cols_ + );
menu_ = Alloc2d(text_rows_, ml_cols_ + );
menu_headers_wrap = Alloc2d(text_rows_, ml_cols_ + );
#else
text_ = Alloc2d(text_rows_, text_cols_ + );
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + );
menu_ = Alloc2d(text_rows_, text_cols_ + );
#endif
text_col_ = text_row_ = ;
text_top_ = ;
backgroundIcon[NONE] = nullptr;
LoadBitmapArray("icon_installing", &installing_frames, &installation);
backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[] : nullptr;
backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
LoadBitmap("icon_error", &backgroundIcon[ERROR]); //LoadBitmap() 将png生成surface, 每个png图片对应一个surface, 所有surface存放在一个数组中
backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
LoadBitmap("icon_recovery", &backgroundIcon[RECOVERY]);
LoadBitmap("progress_empty", &progressBarEmpty);
LoadBitmap("progress_fill", &progressBarFill);
LoadBitmap("stage_empty", &stageMarkerEmpty);
LoadBitmap("stage_fill", &stageMarkerFill);
/* add for AT&T recovery update install UI begin */
#ifdef TARGET_ATT_RECOVERY_UI
LoadBitmap("icon_attinstalling", &backgroundIcon[ATT_INSTALLING_UPDATE]);
LoadBitmap("progress_attempty", &progressBarEmpty_ATT);
LoadBitmap("progress_attfill", &progressBarFill_ATT);
LoadLocalizedBitmap("installing_atttext", &backgroundText[ATT_INSTALLING_UPDATE]); //LoadLocalizedBitmap() 将区域文字所在的图片中的text信息根据当前的locale提取出来,生成对应的surface, 所有
#endif
/* add for AT&T recovery update install UI end */ LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]);
LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]);
LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]);
LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this); //创建一个线程,在该循环中不停地检测currentIcon以及progressBarType来决定是不是要更新进度条。
RecoveryUI::Init(); //初始化RecoveryUI类
}
bootable/recovery/minui/ui.cpp
void RecoveryUI::Init() {
ev_init(InputCallback, this);
ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr);
}
通过RecoveryUI::Init(); 调用events.cpp文件,界面和按键/触摸联系在一起了,后面会用单独的文章介绍recovery按键和触屏的相关内容。 下面介绍几个常用的函数
void ScreenRecoveryUI::SetLocale(const char* new_locale) {
if (new_locale) {
this->locale = new_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") == || // Arabic
strcmp(lang, "fa") == || // Persian (Farsi)
strcmp(lang, "he") == || // Hebrew (new language code)
strcmp(lang, "iw") == || // Hebrew (old language code)
strcmp(lang, "ur") == ) { // Urdu
rtl_locale = true;
}
free(lang);
} else {
new_locale = nullptr;
}
}
从recovery.cpp main()中可知,进入recovery后会分析/cache/recovery/command文件,根据内容来设定显示的文字语言
SetLocale函数根据locale判断所用的字体是否属于阿拉伯语系,阿拉伯语的书写习惯是从右到左,如果是阿拉伯语系的话,就设置一个标志,后面根据这个标志决定从右到左显示文字或进度条。关于显示文字的语言通过代码即可查看,这里只简单的列出语言设置的几条主线,不贴出具体的代码(太多了)。
g_ml_str[] (mi_string.h)-> ml_string_fetch() (multilingual.c) ml_set_language (multilingual.c) -> ml_select() (recovery.cpp) -> prompt_and_wait() (recovery.cpp) -> main() (recovery.cpp)
void ScreenRecoveryUI::SetBackground(Icon icon) {
pthread_mutex_lock(&updateMutex);
currentIcon = icon;
update_screen_locked();
pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::update_screen_locked() {
draw_screen_locked();
gr_flip();
}
void ScreenRecoveryUI::draw_screen_locked() {
if (!show_text) {
draw_background_locked(currentIcon); //************ 有一个bug因为此行没有,导致SetBackground函数无法更换背景图片
draw_progress_locked();
} else {
gr_color(, , , );
gr_clear();
draw_background_locked(currentIcon); //************
.........
}
}
此文章持续更新.......
Recovery启动流程(2)---UI界面的更多相关文章
- Recovery启动流程(2)---UI界面【转】
Recovery启动流程系列文章把recvoery目录下文件分成小块讲解,最后再以一条主线贯穿所有的内容.这篇文章主要讲解Recovery-UI的相关内容. 我们知道,当我们通过按键或者应用进入rec ...
- Recovery启动流程(3)--recovery.cpp分析
转载请注明来源:cuixiaolei的技术博客 这篇文章主要通过分析高通recovery目录下的recovery.cpp源码,对recovery启动流程有一个宏观的了解.MTK和高通的recovery ...
- Recovery启动流程--recovery.cpp分析
这篇文章主要通过分析高通recovery目录下的recovery.cpp源码,对recovery启动流程有一个宏观的了解. 当开机以后,在lk阶段,如果是recovery,会设置boot_into_r ...
- Recovery启动流程(1)--- 应用层到开机进入recovery详解
转载请注明来源:cuixiaolei的技术博客 进入recovery有两种方式,一种是通过组合键进入recovery,另一种是上层应用设置中执行安装/重置/清除缓存等操作进行recovery.这篇文档 ...
- 小记--------CDH版本启动cloudera manager UI界面
首先需要启动mysql源数据库 server所在服务器的路径:/opt/cm-5.14.0/etc/cloudera-scm-server 下 查看配置文件: db.properties 查看my ...
- C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件.配置.应用启动流程代码和界面代码.然而这些文件在 UWP 程序中到底是如何工作起来的? 我从零开始 ...
- (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件.配置.应用启动流程代码和界面代码.然而这些文件在 UWP 程序中到底是如何工作起来的? 我从零开始 ...
- 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面
[Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...
随机推荐
- Spark SQL概念学习系列之Spark SQL的简介(一)
Spark SQL提供在大数据上的SQL查询功能,类似于Shark在整个生态系统的角色,它们可以统称为SQL on Spark. 之前,Shark的查询编译和优化器依赖于Hive,使得Shark不得不 ...
- Java缓存学习之三:CDN缓存机制
CDN是什么? 关于CDN是什么,此前网友详细介绍过. CDN是Content Delivery Network的简称,即"内容分发网络"的意思.一般我们所说的CDN加速,一般是指 ...
- HDU 5810 Balls and Boxes (找规律)
Balls and Boxes 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5810 Description Mr. Chopsticks is i ...
- POJ 2446 Chessboard (二分图最大匹配)
题目链接:http://poj.org/problem?id=2446 给你一个n*m的棋盘,其中有k个洞,现在有1*2大小的纸片,纸片不能覆盖洞,并且每个格子最多只能被覆盖一次.问你除了洞口之外这个 ...
- SGU 171 Sarov zones (贪心)
题目 SGU 171 相当好的贪心的题目!!!!! 题目意思就是说有K个赛区招收参赛队员,每个地区招收N[i]个,然后每个地区都有一个Q值,而N[i]的和就是N,表示总有N个参赛队员,每个队员都有 ...
- Webstorm2016激活码[ 转]
转至:http://blog.csdn.net/tingwode2014_/article/details/51063657 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QT ...
- Centos 卸载OpenJdk
[root@localhost ~]# rpm -qa|grep jdkjava-1.6.0-openjdk-devel-1.6.0.0-1.50.1.11.5.el6_3.i686java-1.7. ...
- Rstudio设置永久工作路径
Rstudio中 getwd() 获取工作路径 setwd() 设置工作路径 但这种方式设置后每次打开都要重新设置,现在介绍一种设置永久路径的方法
- 【不积跬步,无以致千里】安装roundcube 时出现 “DSN (write): NOT OK(SQLSTATE[HY000] [2002] No such file or directory)”
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 【zabbix系列】报警系统的设置和排除
关于邮件报警,有非常多方案,这里选择的是稳定性较好.使用较多的msmtp+mutt方案. 该方案有一个非常好的地方在于不用自己来搭建独立的mailserver,能够使用第三方mail.这样的方法不仅能 ...