写这个的原因是在一个新的方案中,发现reboot recovery无法进入recovery模式。按照以往的理解,我一直以为android到recovery流程是因为在misc分区中写入了boot-recovery字段,但是翻来翻去,也没找到是在哪里写入,所以跟了一下reboot流程,发现好像不是我原来想的那么一回事 。

以重启进入recovery来说。

1、framework

1)RecoverySystem提供的接口中,顺序如此:

installPackage->bootCommand->pm.reboot(“recovery”);

2)这里调用powerManager的reboot接口

该接口唯一参数reason代表需要的特定重启模式,比如recovery,当然也可以为null。

public void reboot(String reason) {

try {

mService.reboot(false, reason, true);

} catch (RemoteException e) {

}

}

通过binder,调用到powerManagerService的reboot函数

@Override // Binder call

public void reboot(boolean confirm, String reason, boolean wait) {

mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

final long ident = Binder.clearCallingIdentity();

try {

shutdownOrRebootInternal(false, confirm, reason, wait);

} finally {

Binder.restoreCallingIdentity(ident);

}

}

private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,

final String reason, boolean wait) {

if (mHandler == null || !mSystemReady) {

throw new IllegalStateException("Too early to call shutdown() or reboot()");

}

Runnable runnable = new Runnable() {

@Override

public void run() {

synchronized (this) {

if (shutdown) {

ShutdownThread.shutdown(mContext, confirm);

} else {

ShutdownThread.reboot(mContext, reason, confirm);

}

}

}

};

.....省略

}

3)调用到ShutdownThread.reboot(mContext, reason, confirm);

public static void reboot(final Context context, String reason, boolean confirm) {

mReboot = true;

mRebootSafeMode = false;

mRebootReason = reason;

shutdownInner(context, confirm);

}

这里说明是需要重启,且不是安全模式,重启参数为传递下来的reason,shutdownInner的confirm参数是用来设置是否有确认提示框的,通过reboot接口调用重启是没有的,为false。

重启的实现在run()中,因为ShutdownThread是Thread的扩展,所以run会自动运行。

run中会调用rebootOrShutdown(mReboot, mRebootReason);

然后又重新回到PowerManagerService.lowLevelShutdown();

public static void rebootOrShutdown(boolean reboot, String reason) {

if (reboot) {

Log.i(TAG, "Rebooting, reason: " + reason);

PowerManagerService.lowLevelReboot(reason);

Log.e(TAG, "Reboot failed, will attempt shutdown instead");

}

...省略

PowerManagerService.lowLevelShutdown();

}

我们跟回PowerManagerService看下,其实无论是lowLevelShutdown还是lowLevelReboot,就是设置属性”sys.powerctl”。

reboot是SystemProperties.set(“sys.powerctl”, “reboot,” + reason);

public static void lowLevelReboot(String reason) {

if (reason == null) {

reason = "";

}

SystemProperties.set("sys.powerctl", "reboot," + reason);

try {

Thread.sleep(20000);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

2、init

SystemProperties.set(“sys.powerctl”, “reboot,” + reason);我们看下init.rc是怎么写的。

on property:sys.powerctl=*

powerctl ${sys.powerctl}

所以我们要再看下init的代码,可以看到对应的函数是do_powerctl

KEYWORD(powerctl, COMMAND, 1, do_powerctl)

int do_powerctl(int nargs, char **args)

{

char command[PROP_VALUE_MAX];

int res;

int len =0;

int cmd =0;

char *reboot_target;

res = expand_props(command, args[1], sizeof(command));

if (res) {

ERROR("powerctl: cannot expand '%s'\n", args[1]);

return -EINVAL;

}

if (strncmp(command, "shutdown",8) ==0) {

cmd = ANDROID_RB_POWEROFF;

len =8;

} else if (strncmp(command, "reboot",6) ==0) {

cmd = ANDROID_RB_RESTART2;

len =6;

} else {

ERROR("powerctl: unrecognized command '%s'\n", command);

return -EINVAL;

}

if (command[len] == ',') {

reboot_target = &command[len +1];

} else if (command[len] == '\0') {

reboot_target = "";

} else {

ERROR("powerctl: unrecognized reboot target '%s'\n", &command[len]);

return -EINVAL;

}

return android_reboot(cmd,0, reboot_target);

}

这里会继续去调用android_reboot函数,根据参入参数的不同

1)关机 ANDROID_RB_POWEROFF, 无需reason,直接调用reboot进行关机;

2)带参数的特殊重启 ANDROID_RB_RESTART2,可以有reason,也可以为“”

android_reboot在system/core/libcutils/android_reboot.c

int android_reboot(int cmd, int flags, char *arg) { int ret,fd; sync(); fd = open("/sys/class/remount/need_remount", O_WRONLY); if (fd < 0) { return -1; } write(fd, "1", 1); close(fd); remount_ro(); switch (cmd) { case ANDROID_RB_RESTART: ret = reboot(RB_AUTOBOOT); break; case ANDROID_RB_POWEROFF: ret = reboot(RB_POWER_OFF); break; case ANDROID_RB_RESTART2: ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg); break; default: ret = -1; } return ret; }

首先做了一些关机重启前的预处理工作,sync()作用是将缓存中的信息写入磁盘,以免程序异常结束导致文件被损坏,linux系统关机前会做几次这样的动作;而remount_ro()作用是通过调用emergency_remount()强制将文件系统挂载为只读,不再允许任何写入操作,同时会通过检查/proc/mounts的设备状态来确认是否当前的所有写入工作已经完成,这个检查过程是阻塞操作。

以reboot recovery为例,arg即为recovery,会传入ANDROID_RB_RESTART2。

最终会调用:

__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,

LINUX_REBOOT_CMD_RESTART2, arg);

3、kernel

android reboot 消息,android reboot 流程相关推荐

  1. android应用消息,Android学习笔记(05)——Android应用程序的三种消息提示(通知方式)...

    Android有三种消息提示方式,分别是:状态栏通知.对话框通知和吐西(Toast)通知,下面记录这三种不同方式的用法以及区别: 一.状态栏通知(Notification) 通知用于在状态栏显示消息, ...

  2. android 按键消息,Android监听Home按键消息

    Android对屏幕下方常用的四个按键消息处理是不一致的: 搜索按键的消息在onKeyDown或者onKeyUp中接收: 菜单按键的消息在onCreateOptionsMenu.onKeyDown或o ...

  3. android 静默重启 QUIESCENT REBOOT

    背景 项目中需要处理Android的原生开机动画,一定条件下还需要做到静默重启(android系统启动进入到桌面前,屏幕保持完全没有亮度的状态).因为项目使用的rom是MTK平台支持,一开始并不知道A ...

  4. android物理按键输入法,Android输入法框架中按键消息的处理流程

    最近研究了一下Android输入法,发现Android输入法框架中按键消息的处理流程和一般应用程序的处理流程有很大的不同,故在此做个总结. 一.一些名词缩写 IMF(Input MethodFrame ...

  5. android 恢复出厂设置代码流程(Good!)

    android的恢复出厂设置 文章问多一般都是从完整的recover mode讲起,恢复出厂设置只是 recovery mode下一个小部分. recovery mode流程分析的文章很多,比较完整的 ...

  6. Android OTA升级原理和流程分析(五)---update.zip包从上层进入Recovery服务

    转载自:http://blog.chinaunix.net/uid-22028566-id-3533854.html 文章开头我们就提到update.zip包来源有两种: 一个是OTA在线下载(一般下 ...

  7. Android 恢复出厂设置上层流程

    最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程: 在setting-->备份与重置--->恢复出厂设置--->重置手机---> ...

  8. 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析

    今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...

  9. Android恢复出厂设置代码流程分析

    工作中排查到了恢复出厂设置的bug, 有一些细节是需要注意的,于是把这块的代码流程看一下: 代码基于:Android9.0 应用层: 就发送MASTER_CLEAR的广播, 这里没有带参数的 priv ...

  10. Android 4.4KK系统关机流程分析

    在PowerManager的API文档中,给出了一个关机/重启接口 public void reboot (String reason) 对于这个接口的描述很简单,就是几句话. 接口的作用就是重启设备 ...

最新文章

  1. 报名 | 图灵奖得主John Hopcroft做客清华,与你畅谈信息革命!
  2. 内存对齐与sizeof
  3. uiuc工程学院计算机,UIUC计算机工程专业排名2020年
  4. vue时间控件美化成IOS样式(移动端),vux组件datatime添加星期几/周几教程
  5. java调度:(二)在项目中调度策略的选择
  6. 红黑树 删除某节点后 旋转3次 举例
  7. 漫步数理统计七——随机变量(上)
  8. 【渝粤教育】国家开放大学2018年秋季 0275-22T内科护理学 参考试题
  9. 云锁惊艳亮相2016杭州云栖大会
  10. [转]C# 3.0入门系列(二)
  11. java 加减乘除_Java实现加减乘除 | 学步园
  12. H5满屏彩色泡泡小特效(适合表白哦~做完发给让你每天想念的人吧~)
  13. 精彩揭秘,一个高大上的机器人自动化工厂需要哪些标配?
  14. vscode背景图片设置分享
  15. 麦克风阵列声音定位简介【转】
  16. 安卓投屏大师_安卓免费录屏软件哪个好用 免费长时间录屏软件推荐
  17. 权限 授权之 - License
  18. 10 movies for it
  19. FCAA部分题库(有答案)
  20. electron+ffmpeg+VUE3 录屏 推流

热门文章

  1. JSON.stringify(value[, replacer[, space]])中三个参数详解
  2. Facebook内战:关于欲望、天才和背叛的故事
  3. VOIP 语音视频通话 ---总述
  4. 4412——Linux驱动入门01
  5. PHP混淆zym解密
  6. failed to req API:/nacos/v1/ns/instance after all servers([192.168.43.148:8848]) tried: ErrCode:503,
  7. 新项目六之集成新版友盟统计
  8. 常用的卫星公司数据查询(包括SPOT、QuickBird、Worldview、IKONOS、GF等)
  9. 公鸡每只值5文钱,母鸡每只值3文钱,而三只小鸡值一文钱。用100文钱买100只鸡,问:公鸡,母鸡,小鸡各有多少只?
  10. fresco 显示缩略图,不直接使用setImageURI,防止卡顿和显示不全:纯黑色或纯白色