1. 电源办理的状况
Android的Linux内核为体系供给了4种电源状况,内核的源代码为其间的3种界说了姓名和对应的宏界说,姓名界说在kernel/power/suspend.c中:
[cpp] view plain copyconst char *const pm_states[PM_SUSPEND_MAX] = {
#ifdef CONFIG_EARLYSUSPEND
[PM_SUSPEND_ON] = “on”,
#endif
[PM_SUSPEND_STANDBY] = “standby”,
[PM_SUSPEND_MEM] = “mem”,
};
对应的宏界说在:include/linux/suspend.h中:
[cpp] view plain copytypedef int __bitwise suspend_state_t;
#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
很奇怪的是,第四种状况(disk)没有详细的界说,而是硬编码在代码中,不明白为什么会这样做,至少我现在看的版本是这样(2.6.35),这种便是所谓的suspend to disk或许叫hibernate。不过这不是要点,再说,现在也很少有Android的设备支撑hibernate。
望文生义:
PM_SUSPEND_ON — 设备处于全电源状况,也便是正常作业状况;
PM_SUSPEND_STANDBY — 设备处于省电状况,但还能够接纳某些事情,详细的行为取决与详细的设备;
PM_SUSPEND_MEM — suspend to memory,设备进入睡觉状况,但一切的数据还保存在内存中,只要某些外部中止才能够唤醒设备;
现在,大多数的Android设备都只支撑其间的两种:PM_SUSPEND_ON 和 PM_SUSPEND_MEM,所以下面的评论说道suspend的当地,均是指PM_SUSPEND_MEM。
2. Early Suspend、Late Resume
Early Suspend和Late Resume是Android在规范Linux的基础上添加的一项特性。当用户空间的向内核恳求进入suspend时,这时候会先进入early suspend状况,驱动程序能够注册early suspend的回调函数,当进入该状况时,内核会逐个地调用这些回调函数。例如显示屏的驱动程序通常会注册early suspend,在他的回调函数中,驱动程序会把屏幕和背光都封闭。在这种状况下,一切的后台进程都还在活动中,该播放歌曲的播放歌曲,该下载数据的仍然在下载,仅仅显示屏不良罢了。进入early suspend状况今后,一旦一切的电源锁(wake lock)被开释,体系马上会进入真实的suspend流程,直到最终体系停止作业,等候外部事情的唤醒。
图2.1 电源状况的转化
3. Android的电源锁机制:wake lock
Android比较规范的Linux内核,在电源办理中加入了wake lock机制。一旦请求了某种类型的锁,电源办理模块将会“锁住”某一种电源状况,现在,Android供给了两种类型的锁:
WAKE_LOCK_SUSPEND — 阻挠体系进入suspend状况;
WAKE_LOCK_IDLE — 阻挠体系进入idle状况;
wake lock也能够设定超时,时刻一到,主动开释该锁。
有关wake lock的代码在:kernel/power/wakelock.c中。
4. 电源状况搬迁
内核发动完结今后,电源办理体系会在sysfs文件体系中树立3个文件:
/sys/power/state
/sys/power/wake_lock
/sys/power/wake_unlock
电源状况的搬迁首先由用户空间的使用程序建议,当体系使用检测到必定时刻内没有用户活动后(例如触摸屏、按键),能够向/sys/power /state文件写入相应的电源状况称号(请参阅第一节内容),假如写入“mem”,将会触发内核发动suspend的流程,内核将会依照图2.1进行状况的搬迁。使用程序也能够经过/sys/power/wake_lock请求一个WAKE_LOCK_SUSPEND 类型的锁,相应地,经过/sys/power/wake_unlock则能够开释一个锁。内核在进入suspend之前假如检测到某个锁没有开释,则会抛弃本次的suspend进程,直到这个锁开释停止。