Android 重启流程(一)

一、概述

重启动作从按键触发中断,linux kernel层给Android framework层返回按键事件进入 framework层,再从 framework层到kernel层执行kernel层关机任务。当然还有非按键触发,比如系统异常导致重启,或者直接调用PM的reboot()方法重启。

这里就先从PowerManager说起。

二、关机流程

2.1 PM.reboot

[-> PowerManager.java]

2.2 BinderService.reboot

[-> PowerManagerService.java]

此时参数为shutdownOrRebootInternal(false, false, reason, true);

  • shutdown=false:代表重启;
  • confirm=false:代表直接重启,无需弹出询问提示框;
  • wait=true:代表阻塞等待重启操作完成。

2.3 PMS.shutdownOrRebootInternal

[-> PowerManagerService.java]

2.4 ShutdownThread.reboot

[-> ShutdownThread.java]

mReboot为true则代表重启操作,值为false则代表关机操作。

2.5 shutdownInner

[-> ShutdownThread.java]

2.6 beginShutdownSequence

[-> ShutdownThread.java]

此处ProgressDialog根据不同reboot reason会不同UI框:

  1. 重启到recovery模式,并安装更新
    • Condition:mReason == REBOOT_RECOVERY and mRebootUpdate == True
    • 检查/cache/recovery/uncrypt_file文件存在,则mRebootUpdate为True
    • UI: 进度条(progress bar)
  2. 重启到recovery,用于工厂重置模式
    • Condition: mReason == REBOOT_RECOVERY and mRebootUpdate == False
    • UI: 仅显示spinning circle
  3. 常规重启/关机
    • Condition: Otherwise
    • UI: 仅显示spinning circle

2.7 ShutdownThread.run

[-> ShutdownThread.java]

设置”sys.shutdown.requested”,记录下mRebootmReason。如果是进入安全模式,则”persist.sys.safemode=1”。

接下来主要关闭一些系统服务:

  1. 发送关机广播
  2. 关闭AMS
  3. 关闭PMS
  4. 关闭radios
  5. 关闭MountService

之后就需要进入重启/关机流程。

2.7.1 AMS.shutdown

通过AMP.shutdown,通过binder调用到AMS.shutdown.

此处timeout为MAX_BROADCAST_TIME=10s

2.7.2 PMS.shutdown

此处mPackageUsage数据类型是PMS的内部类PackageUsage。

对于force=true,接下来调用writeInternal方法。

/data/system/package-usage.list文件中每一行记录一条package及其上次使用时间(单位ms)。

由于IO操作的过程中,写入文件并非立刻就会真正意义上写入物理磁盘,以及在写入文件的过程中还可能中断或者出错等原因的考虑,采用的策略是先将老的文件package-usage.list,重命为增加后缀package-usage.list.bak;然后再往package-usage.list文件写入新的数据,数据写完之后再执行sync操作,将内存数据彻底写入物理磁盘,此时便可以安全地删除原来的package-usage.list.bak文件。

2.7.3 ST.shutdownRadios

[-> ShutdownThread.java]

创建新的线程来处理NFC, Radio and Bluetooth这些射频相关的模块的shutdown过程。每间隔500ms,check一次,直到nfc、bluetooth、radio全部关闭或者超时(MAX_RADIO_WAIT_TIME=12s)才会退出循环。

2.7.4 MS.shutdown

[-> MountService.java]

public void shutdown(final IMountShutdownObserver observer) { enforcePermission(android.Manifest.permission.SHUTDOWN); //向名为“MountService”的线程发送H_SHUTDOWN消息 mHandler.obtainMessage(H_SHUTDOWN, observer).sendToTarget(); }

“MountService”线程收到消息后进入handleMessage出来相应消息

observer的回调方法onShutDownComplete(),会调用actionDone(),该方法通知mActionDoneSync已完成

调用mActionDoneSync.notifyAll()之后,那么便可以继续往下执行rebootOrShutdown方法。

2.8 rebootOrShutdown

[-> ShutdownThread.java]

对于重启原因,logcat会直接输出”Rebooting, reason: “,如果重启失败,则会输出“Reboot failed”,如果无法重启,则会尝试直接关机。

2.9 PMS.lowLevelReboot

  • 当reboot原因是“recovery”,则设置属性ctl.start=pre-recovery
  • 当其他情况,则设置属性”sys.powerctl=reboot,[reason]”。

到此,framework层面的重启就流程基本介绍完了,那么接下来就要进入属性服务,即设置sys.powerctl=reboot,

三、总结

先用一句话总结,从最开始的PM.reboot(),经过层层调用,最终重启的核心方法等价于调用SystemProperties.set(“sys.powerctl”, “reboot,” + reason); 也就意味着调用下面命令,也能重启手机:

本文还未结束,还需要进一步上面命令的执行流程,如何进入native,如何进入kernel来完成重启的,以及PM.reboot如何触发的。。。

作者微博:@Gityuan

原文出处:Gityuan.com

1 收藏 评论

关于作者:gityuan

Android系统工程师,www.gityuan.com博主,个人新浪微博:http://weibo.com/gityuan 个人主页 · 我的文章 · 3 ·     

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部