Recovery启动流程(2)---UI界面【转】
Recovery启动流程系列文章把recvoery目录下文件分成小块讲解,最后再以一条主线贯穿所有的内容。这篇文章主要讲解Recovery-UI的相关内容。
我们知道,当我们通过按键或者应用进入recovery模式,实质是kernel后加载recovery.img,kernel起来后执行的第一个进程就是init,此进程会读入init.rc启动相应的服务。在recovery模式中,启动的服务是执行recovery可执行文件,此文件是bootable/recovery/recovery.cpp文件生成,我们就从recovery.cpp文件开始分析。
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);
}
....
}
首先新建了一个Device类的对象, Device类封装了一些操作,包括UI的操作
调用Device类的GetUI()返回一个RecoveryUI对象
调用ui->SetLocale(locale)设置语言,调用SetBackground方法设置背景图片
调用Init()进行初始化。
这里的Init从代码上看应该是ui.cpp文件中RecoveryUI类的Init()方法,是ScreenRecoveryUI,这里我是按照ScreenRecoveryUI::Init追的代码。其中RecoveryUI是ScreenRecoveryUI的父类。
显示recovery的主界面,即一个选择菜单
实现头部显示和列表项device.h
static const char* MENU_ITEMS[] = {
"Reboot system now",
"Apply update from ADB",
"Wipe data/factory reset",
"Wipe cache partition",
"Reboot to bootloader",
"Power off",
"View recovery logs",
"Apply update from sdcard",
"Apply update from usbotg",
"Security unlock",
"Download secure info",
"Download hwc info",
"Apply OTAconfig update from sdcard",
"Apply OTAconfig update from usbotg",
"Apply OTAconfig update from usbotg path",
NULL,
};
static const Device::BuiltinAction MENU_ACTIONS[] = {
Device::REBOOT,
Device::APPLY_ADB_SIDELOAD,
Device::WIPE_DATA,
Device::WIPE_CACHE,
Device::REBOOT_BOOTLOADER,
Device::SHUTDOWN,
Device::VIEW_RECOVERY_LOGS,
Device::APPLY_SDCARD,
Device::APPLY_USB,
Device::SECURE_UNLOCK,
Device::DOWNLOAD_SECURE_INFO,
Device::DOWNLOAD_HWC_INFO,
Device::APPLY_OTACONFIG_EXT,
Device::APPLY_OTACONFIG_USB,
Device::APPLY_OTACONFIG_USB_PATH,
//Device::MOUNT_SYSTEM,
};
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_ = 6 * text_cols_; //max is 6 char for 1 utf8 character.
text_ = Alloc2d(text_rows_, ml_cols_ + 1);
file_viewer_text_ = Alloc2d(text_rows_, ml_cols_ + 1);
menu_ = Alloc2d(text_rows_, ml_cols_ + 1);
menu_headers_wrap = Alloc2d(text_rows_, ml_cols_ + 1);
#else
text_ = Alloc2d(text_rows_, text_cols_ + 1);
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
menu_ = Alloc2d(text_rows_, text_cols_ + 1);
#endif
text_col_ = text_row_ = 0;
text_top_ = 1;
backgroundIcon[NONE] = nullptr;
LoadBitmapArray("icon_installing", &installing_frames, &installation);
backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : 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, 所有
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") == 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);
} 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)
SetBackground函数比较简洁,关键部分在update_screen_locked。
update_screen_locked 和update_progress_locked是recovery的UI部分的关键函数,update_screen_locked用来更新背 景, update_progress_locked用来更新进度条,因为显示的画面会一直在更新,所以这两个函数会在不同的地方被反复调用
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(0, 0, 0, 255);
gr_clear();
draw_background_locked(currentIcon); //************
.........
}
}
Recovery启动流程(2)---UI界面【转】的更多相关文章
- Recovery启动流程(2)---UI界面
转载请注明来源:cuixiaolei的技术博客 Recovery启动流程系列文章把recvoery目录下文件分成小块讲解,最后再以一条主线贯穿所有的内容.这篇文章主要讲解Recovery-UI的相关内 ...
- 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) 这篇文章算是对整个引导界 ...
随机推荐
- MYSQL--表与表之间的关系、修改表的相关操作
表与表之间的操作: 如果所有信息都在一张表中: 1.表的结构不清晰 2.浪费硬盘空间 3.表的扩展性变得极差(致命的缺点) 确立表与表之间的关系.一定要换位思考(必须在两者考虑清楚之后才能得出结论) ...
- vim基础命令,查找和替换
vim 基本命令查找和替换 vim简单的命令用着还好.比如插入,删除,查询.但替换就用的比较少.所以,还是需要用的时候拿出来对照者看. 使用vim编辑文件: vim xxx 进入之后的界面叫做命令模式 ...
- Leetcode solution 124: Binary Tree Maximum Path Sum
Problem Statement Given a non-empty binary tree, find the maximum path sum. For this problem, a path ...
- Shell-->变量的数值计算
1.----------------------------->>>>>文件改名,使用命令mv 2.----------------------------->&g ...
- 企查查app 初步探索
企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 已删除!!!! 上边一些变量已经找到了,其中就有时间戳,其余两个需要 ...
- Vue仿微信app页面跳转动画
10:14:11独立开发者在开发移动端产品时,为了更高效,通常会使用Web技术来开发移动端项目,可以同时适配Android.iOS.H5,稍加改动还可适配微信小程序. 在使用Vue.js开发移动端页面 ...
- python 35 多线程
目录 多线程 1. 线程 2. 线程vs进程 3. 开启线程的两种方法. 4. 线程的特性 5. 线程的相关方法 6. join 阻塞 7. 守护线程 daemon 8. 互斥锁 多线程 1. 线程 ...
- Java IO体系之RandomAccessFile浅析
Java IO体系之RandomAccessFile浅析 一.RandomAccessFile综述: 1.1RandomAccessFile简介 RandomAccessFile是java Io体系中 ...
- Immutable Object模式 - 多线程
Immutable Object模式 - 多线程 前言 在多线程编程中,我们常会碰到修改一个对象的值,如果在不加锁的情况下 ,就会出现值不一致的问题,那么有没有一种方式可以不通过加锁的方式也可以保证数 ...
- Asp.net MVC 集成AD域认证
1.首先WebApi 应用下Web.config要配置域认证服务器节点,如下 <!--LDAP地址 用于项目AD系统账号密码验证--> <!--0:关闭域认证:1:开启域认证--&g ...