http://www.2cto.com/kf/201501/367859.html
ShutdownThread.java文件
stop playing music,因为后面可能要playing shutdown music.
代码如下:
show system dialog to indicate phone is shutting down,如果没有关机动画的话,要show一个关机提示出来。
代码如下:
Hold the wakelock,make sure we never fall asleep again,抓锁防止机器关机过程中休眠
代码如下:
make sure the screen stays on,再抓一个full锁,防止屏幕半暗
代码如下:
起一下新进程
sending shutdown broadcast,发出广播,通知各app该保存数据赶紧的,我要关机了
代码如下:
shutdown activity manager,关闭activity manager,即关闭AppOpsService,UsageStatsService,BatteryStatsService
注意:android L 与KK在关闭UsageStatsService上有所区别
代码如下:
[ActivityManagerService.java]
shutdown package manager,保存app使用时间到 disk里,这是android L新增的功能。
代码如下:
[PackageManagerService.java]
show shutdown animation,播放关机动画了
代码如下:
shutdown radio[NFC,BT,MODEM],注意这里关闭modem这块与andorid KK的不一样。
代码如下:
shutdownRadios(MAX_RADIO_WAIT_TIME);
shutdown MountService,特别这里会导致关机失败。
代码如下:
走完上层关机流程,下面就要执行关机动作了。
代码如下:
从代码上看始终会走到lowLevelShutdown(),但如果是重启就不会,lowLevelReboot()就停止了。
lowLevelShutdown()与lowLevelReboot()都在PowerManagerService.java实现,其实都只是设置一个属性:SystemProperties.set(sys.powerctl, xxx);
正是这个动作触发关机流程往下走,这涉及到init进程的4大功能,请参考我的另一篇文章的init进程
sys.powerctl属性触发开关在init.rc定义
我们来解读这句话,on property:sys.powerctl=*表示当属性sys.powerctl设置为任何值是都会跑到这里,触发动作是powerctl ${sys.powerctl},这个动作的意思是调用powerctl指令,并把sys.powerctl的值传给它。powerctl指令在init进程会执行。
从下面的表可知,powerctl对应的操作是do_powerctl
[system/core/init/keywords.h]
do_powerctl的实现
代码如下:
[system/core/init/builtins.c]
它调用android_reboot()函数,实现如下:
[system/core/libcutils/android_reboot.c]
从这里看出它的主要工作:
sync() 回写block设备的内容,这是阻塞型操作。
remount_ro() 把block设备remount成ro,这里有个关键LOG:SysRq : Emergency Remount R/O,这是在logkit所能看到的最后一句LOG,因为remount成ro了,后面的LOG要通过last kmsg技术导出来。
reboot()或者syscall(__NR_reboot....,这点与android KK不同,这边直接用syscall功能,KK则通过汇编。
后面syscall(__NR_reboot...知道,直接调用了linux的__NR_reboot调用,这个系统调用会跑哪里?后面会讲。
reboot()这个函数实现如下:
[bionic/libc/bionic/reboot.cpp]
调用了__reboot,它在汇编实现 如下:
[bionic/libc/arch-arm/syscalls/__reboot.S]
__NR_reboot对应的内核入口在哪里?
如下:
[bionic/libc/kernel/uapi/asm-generic/unistd.h]
它在内核入口如下:
注:bionic/libc/kernel/uapi/asm-generic/unistd.h与kernel/include/uapi/asm-generic/unistd.h是对应的,方便以后代码追踪
[kernel/include/uapi/asm-generic/unistd.h]
__NR_reboot 映射到 sys_reboot
grep 下sys_reboot 找不到,其实在这里
用SYSCALL_DEFINE定义
[kernel/kernel/sys.c]
有很多分支,我们只关心kernel_power_off()和kernel_restart()两函数就行
如下:
都执行XX_prepare()函数
除了前面不同,都调用了device_shutdown()函数,关闭外设。
machine_power_off() machine_resestart()函数实现
pm_power_offf() arm_pm_restart()都是一个函数指针
赋值如下:
[kernel/drivers/power/reset/msm-poweroff.c]
高通平台的关机代码与之前有所不同,现在文件msm-poweroff.c以前是restart.c。
do_msm_poweroff()与do_msm_restart()实现如下:
msm_restart_prepare()实现
do_msm_poweroff()与do_msm_restart()都设置了dload,PMIC,唯一不同的是do_msm_restart()里多了一个__raw_writel的动作,即reason写入IMEM,目的在于重启进入sbl1时判断应该进入那种模式,如我们开发用的bootloader模式,恢复出厂设置的recovery模式等。