RescueParty 简述
Android O中增加了一个新的功能,当核心系统组件发生循环崩溃的时候,就会触发“救援程序”,也就是本篇要介绍的RescueParty 。然后RescueParty 会通过自身判断逻辑来进行崩溃级别的提升,直到最后触发ResetFactory,进而进入Recovery,然后提示用户恢复出厂设置。
接下来根据源码(基于Android Q)来分析下是如何触发救援程序以及进入Recovery。
涉及到的源码路径:
frameworks/base/services/core/java/com/android/server/RescueParty.java
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/AppErrors.java
通过RescueParty类的概述可以了解到,程序崩溃的足够频繁,并且逐步上升级别,最终通过提示用户擦除数据解决。救援级别分为5级,只有达到LEVEL_FACTORY_RESET这个级别,才会触发设备进入Recovery。而通过"sys.rescue_level"这个属性可以查询当前处于什么级别?
/*** Utilities to help rescue the system from crash loops. Callers are expected to* report boot events and persistent app crashes, and if they happen frequently* enough this class will slowly escalate through several rescue operations* before finally rebooting and prompting the user if they want to wipe data as* a last resort.*///救援级别
static final int LEVEL_NONE = 0;
static final int LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 1;
static final int LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES = 2;
static final int LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS = 3;
static final int LEVEL_FACTORY_RESET = 4;
接着来看下如何触发级别上升,并最终达到LEVEL_FACTORY_RESET。RescueParty 类中有一个用来提升级别的方法incrementRescueLevel,从方法名就可以看出作用。存储方式就是从属性中读出,然后+1再写进属性,默认的值就是0。
/*** Escalate to the next rescue level. After incrementing the level you'll* probably want to call {@link #executeRescueLevel(Context)}.*/
private static void incrementRescueLevel(int triggerUid) {final int level = MathUtils.constrain(SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) + 1,LEVEL_NONE, LEVEL_FACTORY_RESET);SystemProperties.set(PROP_RESCUE_LEVEL, Integer.toString(level));EventLogTags.writeRescueLevel(level, triggerUid);logCriticalInfo(Log.WARN, "Incremented rescue level to "+ levelToString(level) + " triggered by UID " + triggerUid);
}
该方法是私有方法,本类中的调用方有两处,分别对应了两种不同的场景——
永久性系统应用在 30 秒内崩溃 5 次以上和system_server 在 10 分钟内重启 5 次以上。
1、noteAppCrash; //记录App奔溃
2、noteBoot; //记录Boot阶段奔溃,也就是system_server奔溃
//场景1:
/*** Take note of a persistent app or apex module crash. If we notice too many of these* events happening in rapid succession, we'll send out a rescue party.*/
public static void noteAppCrash(Context context, int uid) {if (isDisabled()) return; //该功能是否已经关闭Threshold t = sApps.get(uid); //查看该uid对应的app是否已经出现过crashif (t == null) {t = new AppThreshold(uid);sApps.put(uid, t); //未出现就新增一个记录}if (t.incrementAndTest()) { //判断是否需要提升救援级别t.reset();incrementRescueLevel(t.uid);executeRescueLevel(context);}
}//场景2
/*** Take note of a boot event. If we notice too many of these events* happening in rapid succession, we'll send out a rescue party.*/
public static void noteBoot(Context context) {if (isDisabled()) return;if (sBoot.incrementAndTest()) {sBoot.reset();incrementRescueLevel(sBoot.uid);executeRescueLevel(context);}
}
场景1就是AMS记录到app crash后调到AppErrors中的crashApplication方法来处理该crash,之后会判断是常驻进程或者是Apex组件化模块就调用noteAppCrash触发救援程序。
void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,int callingPid, int callingUid) {{...if (r.isPersistent() || isApexModule) {// If a persistent app or apex module is stuck in a crash loop, the device isn't// very usable, so we want to consider sending out a rescue party.RescueParty.noteAppCrash(mContext, r.uid);}...
}
场景2则判断是否存在boot阶段持续崩溃,也就是会不会有连续重启的事件发生。该场景触发是在system_server进程启动的过程中。所以判断的机制相当于是对system_server的监控,实际上该进程也可以理解为一个特殊的app。
private void startBootstrapServices() {...RescueParty.noteBoot(mSystemContext);...
}
该场景的触发是针对Q以及之前的源码逻辑,R上已经将该逻辑调整到PackagesWatchDog这个类中来实现,此类也是在system_server启动过程拉起来的,因此殊途同归。
最后来看下RescueParty的逻辑,如何实现crash的监控。前面提到,每次触发救援级别提升前,都会先通过incrementAndTest来判断是否需要提升,所以该方法是实际上对救援级别提升的判断标准。
public boolean incrementAndTest() {final long now = getElapsedRealtime(); //获取系统现在的时间final long window = now - getStart(); //系统时间与救援开始时间的差值//triggerWindow对应BOOT_TRIGGER_WINDOW_MILLIS或者PERSISTENT_APP_CRASH_TRIGGER_WINDOW_MILLIS分别对应600s和30sif (window > triggerWindow) { //超过预定的时间后则重新开始,计数为1,时间从现在开始计算;setCount(1);setStart(now);return false;} else { //反之,如果在预定的时间内再次触发,则计数+1,int count = getCount() + 1;setCount(count);EventLogTags.writeRescueNote(uid, count, window);Slog.w(TAG, "Noticed " + count + " events for UID " + uid + " in last "+ (window / 1000) + " sec");return (count >= triggerCount); //返回计数是否达到预期,也就是5次}
}
以上便是RescueParty的整体逻辑,逻辑清晰明了。目的也很纯粹,就是通过监控崩溃的程序来确认系统是否遇到了严重的问题,通过提示用户清除数据来恢复。
RescueParty 简述相关推荐
- 简述计算机科学的核心内容,北京大学-计算机科学与技术(2018秋)作业及复习
59.(第十章)外排序是指在排序前后,数据在外存上,排序时数据调入内存进行的排序方法. 60.(第十章)在选择排序.冒泡排序.归并排序中, 归并排序是空间复杂度最大的. 三.简答和程序题(共10题,每 ...
- 设计模式学习1:设计模式简述和设计模式原则
设计模式简述 什么是设计模式? 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案. 设计模式的目的: 代码高可用(相同作用的代码能重复 ...
- Java中常见的锁简述
在Java的应用中,或多或少的都会接触到一些锁,那么问题就来了,在Java中,常见的锁有哪些,都有什么样的作用?? 这里给大家简单的简述一下这些学常见的锁. 本文件所涉及到的锁: 1.公平锁 / 非公 ...
- 简述DataInputStream和DataOuputStream
2019独角兽企业重金招聘Python工程师标准>>> Java开发中经常会用到IO流,那么就会碰到DataInputStream和DataOuputStream这两个包装类.下面就 ...
- 简要叙述matlab的含义,1,简述MATLAB组成部分? 2,说明使用M文件编辑/调试器的方法和优点? 3,存储在工作空间中的数组能编辑吗...
匿名用户 1级 2012-05-17 回答 我也考这个....祝你好运 1,简述MATLAB组成部分? (1)开发环境(development Environment); (2)MATLAB数学函数库 ...
- 简述Linux和Windows下Python搭建步骤
简述就Windows和Linux环境下安装Python的步骤. Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linu ...
- 简述 OAuth 2.0 的运作流程
本文将以用户使用 github 登录网站留言为例,简述 OAuth 2.0 的运作流程. 假如我有一个网站,你是我网站上的访客,看了文章想留言表示「朕已阅」,留言时发现有这个网站的帐号才能够留言,此时 ...
- 简述机器指令与微指令之间的关系_自考《计算机组成原理》模拟试题(一)
一.单项选择题(本大题共 25小题,每小题1分,共25分)在每小题列出的四个选项中只有一个选项是符合题目要求的,请将正确选项前的字母填在题后的括号内. 1.-0的8位二进制补码是( ) A.10000 ...
- day1简述、输入输出、运算符、条件语句、文件读写、三元运算
文章目录 1.Python 简述 2.变量 3.输入输出 4.数据运算 5. 条件语句 if..else.elif 循环语句 for.while 6.文件读写 7.三元运算 1.Python 简述 ...
最新文章
- 阿里副总裁肖利华:数智化转型的7个关键词
- 基于用例点来度量软件规模并管理进度 之二
- [Verilog] parameter
- c语言错误重定义,C语言的重定义错误求解
- 一建机电实务教材电子版_20年一建其实并不难,官方出版:复习题集(精修),速做速提90分...
- 学习笔记7-C语言-进制转换、原返补、位运算、函数
- 服务器数据库密码修改了,服务器密码修改后数据库
- 12月22日 冬至 隋文帝赏柳上上签
- 3D顶点转换和法线转换
- BZOJ 1857: [Scoi2010]传送带
- html中如何调整图片的对比色,风光照片如何调出冷暖对比色?后期案例分享
- 【Python基础】制作一个汇率换算程序
- 接收IWebBrowser2的自动化事件
- nexus5 博通芯片WIFI详解 (2)
- 饥荒为啥显示专用服务器,饥荒服务器和专用服务器有什么区别 | 手游网游页游攻略大全...
- C++基础概念(初步代码示例英石与磅单位互换)
- UE4材质—UV和贴图坐标系
- PHP:抓取网页指定内容
- 知明:技术 Leader 的思考法
- java画星星_用java画色彩斑斓的星星