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) 这篇文章算是对整个引导界 ...
随机推荐
- <Araxis Merge>快速一览文件的比较与合并
重要的文件比较与合并特性在下面都指出了.对每个特性的说明性内容在下面可以找到. 注意:只有双向的比较/合并被展示了,专业版的Merge还支持三向的比较/合并. 1.文件夹比较按钮 单击这个工具栏按钮会 ...
- 办公室网络二三事 - chunyu
开始的时候,我们办公室拉了两条家庭百兆宽带,两条宽带分别接到路由器的wan1/wan2口上,我们愉快的工作愉快的上网. 后来,再拉了一条十兆企业专线,接到了路由器的wan3口上面,配了一些静态路由,希 ...
- [iOS 多线程 & 网络 - 1.1] - 多线程NSThread
A.NSThread的基本使用 1.创建和启动线程 一个NSThread对象就代表一条线程创建.启动线程NSThread *thread = [[NSThread alloc] initWithTar ...
- 转载 C#使用Salt + Hash来为密码加密
转载 http://www.csharpwin.com/csharpspace/13412r9615.shtml (一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考 ...
- [转载代码]VB.NET 中查询 Linq to SQL 执行时的SQL语句
在搜索使用LINQ TO SQL 添加数据后获得自增长ID的方法时,发现C#可以使用DebuggerWritter把使用Linq to SQL执行的SQL语句显示到即时窗口,于是在网上搜索到在VB.N ...
- opennebula 自定义安装目录
/bin//mkinstalldirs /usr/local/lib /bin//mkinstalldirs /usr/local/include /bin//mkinstalldirs /usr/l ...
- 使用Unity制作游戏关卡的教程(三)
转自:http://gamerboom.com/archives/75593 作者:Matthias Zarzecki 本文是“使用Unity制作<The Fork Of Truth>的关 ...
- ios开发——仿新版iBooks书本打开与关闭动画
IOS新版iBooks吸引人的地方除了有干净整洁的界面.方便灵活的操作以及大容量的书籍容量以外.还有其优秀的用户交互,尤其是其动画的使用.打开一本书时书本缓慢放大并打开.关闭一本书后书本关闭并回到原位 ...
- pjsip视频通信开发(上层应用)之数字键盘的制作
在pjsip视频通信开发(上层应用)之EditText重写中我制作了一个显示输入内容的EditText,这里将制作一个数字键盘,其实跟计算器一样,最多的就是用TableLayout来实现,内部通过权重 ...
- 密码强度应用(js)
<!-- 密码强度div --> <div id="tips" class="help-block"> <b class=&quo ...