一.SettingsProvider def_screen_off_timeout
1.1.frameworks\base\packages\SettingsProvider\res\values\defaults.xml
为什么是0x7fffffff 换算 十进制 是2147483647
ro.rk.screenoff_time 也是2147483647
整形最大取值就是 2147483647 换算成天数也就是24.85
1 2 3 4 |
|
1.2.frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
1 2 3 |
|
1.3.frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
a.观察 数据库 变化
1 2 3 4 5 6 7 8 9 10 11 12 |
|
b.updateSettings mLockScreenTimeout
1 2 3 4 5 6 7 8 |
|
c.postDelayed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1.4.frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
获取休眠时间
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
//根据nextTimeOut延迟发送信息,信息被处理后,将重新调用updatePowerStateLocked,于是再次进入到该方法
//通过不断进入该方法,不断评估是否根据用户动作亮、熄屏等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
屏screen_off和睡眠sleep都有对应的配置时间,如果Settings开了接口也都是可以配置的。默认情况下要看SettingsProvider里面对应的default的值,当然特定的产品要考虑到overlay的情况。
比如在这里def_screen_off_timeout则是60s,而def_sleep_timeout是-1则表示关闭了睡眠功能。换句话说,机器不用过1分钟系统会进入屏保,不会睡眠,屏幕或者hdmi是一直都有信号输出的。
/p-base/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<integer name="def_screen_off_timeout">60000</integer><integer name="def_sleep_timeout">-1</integer>
60000 ms , 看code里面的时间都是毫秒。
overlay的情况
这里面默认的睡眠时间是20s,屏保时间是10s,也就是说没事做10s进屏保,再过10s进睡眠。
<integer name="def_sleep_timeout">20000</integer><integer name="def_screen_off_timeout">10000</integer>
参考日志如下,uid 1000 指的是Process.SYSTEM_UID, 说明是系统发起的。
08-22 05:09:51.244 3067 3092 I PowerManagerService: Nap time (uid 1000)...
08-22 05:09:51.245 3067 3092 I DreamManagerService: Entering dreamland.
08-22 05:09:51.245 3067 3092 I PowerManagerService: Dreaming...08-22 05:10:01.243 3067 3092 I PowerManagerService: Going to sleep due to screen timeout (uid 1000)...
08-22 05:10:01.244 3067 3092 I DreamManagerService: Gently waking up from dream.
08-22 05:10:01.245 3067 3092 I PowerManagerService: Sleeping (uid 1000)...
08-22 05:10:01.247 2892 2954 E : getRealActiveConfig to config(0).
08-22 05:10:01.248 3067 3088 I DreamManagerService: Performing gentle wake from dream.
在每次更新系统power状态的时候,都要基于当前的user activity计算再次唤醒或者睡眠的时间。关键函数updateUserActivitySummaryLocked,主要是计算出下次超时时间nextTimeout和用户状态mUserActivitySummary,当满足nextTimeout到下次更新状态的时候会基于这个用户状态来进行相应的动作,是dim、dream、还是sleep。注意,这个状态的计算是逐层变深的,后面的计算如果满足条件会覆盖掉前面的计算。另一方面,整个系统进入休眠的顺序也一定是dim、dream、doze、sleep。
private void updateUserActivitySummaryLocked(long now, int dirty) {// Update the status of the user activity timeout timer.if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY| DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);long nextTimeout = 0;if (mWakefulness == WAKEFULNESS_AWAKE|| mWakefulness == WAKEFULNESS_DREAMING|| mWakefulness == WAKEFULNESS_DOZING) {//获取睡眠时长,为Settings.Secure.SLEEP_TIMEOUT的值和最小休眠时间的最大值,Settings.Secure.SLEEP_TIMEOUT一般为-1,//表示禁用,因此该值默认为-1final int sleepTimeout = getSleepTimeoutLocked();//获取休眠时长,在Settings中设置的值final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);//获取Dim时长,由休眠时长剩Dim百分比得到final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);//用户活动是否由Window覆盖final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;//该值用来统计用户活动状态,每次进入该方法,置为0mUserActivitySummary = 0;//上次用户活动时间>=上次唤醒时间if (mLastUserActivityTime >= mLastWakeTime) {//下次超时时间为上次用户活动时间+休眠时间-Dim时间,到达这个时间后,将进入Dim状态nextTimeout = mLastUserActivityTime+ screenOffTimeout - screenDimDuration;//如果当前时间<nextTimeout,则此时处于亮屏状态,标记mUserActivitySummary为USER_ACTIVITY_SCREEN_BRIGHTif (now < nextTimeout) {mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;} else {//如果当前时间>nextTimeout,此时有两种情况,要么进入Dim要么进入Sleep//将上次用户活动时间+灭屏时间赋值给nextTimeout,如果该值大于当前时间,则说明此时应该处于Dim状态//因此将标记mUserActivitySummary为USER_ACTIVITY_SCREEN_DIMnextTimeout = mLastUserActivityTime + screenOffTimeout;if (now < nextTimeout) {mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;}}}//判断和USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS标记相关,如果带有此标记,才会进入该ifif (mUserActivitySummary == 0&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {//下次超时时间=上次用户活动时间+灭屏时间nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;//根据当前时间和nextTimeout设置mUserActivitySummaryif (now < nextTimeout) {if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT|| mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;} else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;}}}//不满足以上条件时,此时mUserActivitySummary为0,这种情况应该为当mUserActivitySummary经历了USER_ACTIVITY_SCREEN_BRIGHT//和USER_ACTIVITY_SCREEN_DIM之后才会执行到这里if (mUserActivitySummary == 0) {if (sleepTimeout >= 0) {//获取上次用户活动时间的最后一次时间final long anyUserActivity = Math.max(mLastUserActivityTime,mLastUserActivityTimeNoChangeLights);if (anyUserActivity >= mLastWakeTime) {nextTimeout = anyUserActivity + sleepTimeout;//将mUserActivitySummary值置为USER_ACTIVITY_SCREEN_DREAM,表示屏保if (now < nextTimeout) {mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;}}} else {//将mUserActivitySummary值置为USER_ACTIVITY_SCREEN_DREAM,表示屏保mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;nextTimeout = -1;}}if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {if ((mUserActivitySummary &(USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {// Device is being kept awake by recent user activityif (nextTimeout >= now && mOverriddenTimeout == -1) {// Save when the next timeout would have occurredmOverriddenTimeout = nextTimeout;}}mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;nextTimeout = -1;}if (mUserActivitySummary != 0 && nextTimeout >= 0) {//发送一个异步Handler定时消息Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);msg.setAsynchronous(true);mHandler.sendMessageAtTime(msg, nextTimeout);}} else {//当wakefulness=Sleep的时候,直接将mUserActivitySummary置为0mUserActivitySummary = 0;}}}
mUserActivitySummary 的取值如下,这个状态的改变需要打开PowerManagerService的debug 才好看。能看到从 0x1 -> 0x2 - >0x4 这个状态切换。
// Summarizes the user activity state.private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
updateUserActivitySummaryLocked 入口参数 now ,我们可以看到时间是系统的SYSTEM_TIME_MONOTONIC 时间,是系统启动以后流逝的时间。所有的时间操作都是相对于这个时间进行的。
获得系统睡眠超时时间,要从设定值和最小灭屏值选一个大的出来,最小灭屏值一般是10s,也就是说睡眠时间不能比最小的灭屏值还小。mSleepTimeoutSetting 是可以从设置菜单设置的,菜单 "Put device to sleep" 指定多长时间进入睡眠。
private long getSleepTimeoutLocked() {final long timeout = mSleepTimeoutSetting;if (timeout <= 0) {return -1;}return Math.max(timeout, mMinimumScreenOffTimeoutConfig);}
在初始化updateSettingsLocked里面,从SettingsProvider读数据,如果没有设定过就是默认值。
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,UserHandle.USER_CURRENT);mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,UserHandle.USER_CURRENT);
后取 系统灭屏超时时间,这个主要是选一个睡眠超时和系统灭屏时间的较小值。比如前面的是灭屏是10s,睡眠是20s,那就是10s,反之还是10s。前面的两个if里面的条件一般不满足。mScreenOffTimeoutSetting 同样也是在设置菜单里可以设置的,Screen saver菜单 -》 When to start 菜单。这里可能不同型号的机器,菜单放置的位置不一样。
private long getScreenOffTimeoutLocked(long sleepTimeout) {long timeout = mScreenOffTimeoutSetting;if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);}if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {timeout = Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);}if (sleepTimeout >= 0) {timeout = Math.min(timeout, sleepTimeout);}return Math.max(timeout, mMinimumScreenOffTimeoutConfig);}
最小灭屏值是在framework/base里面config.xml里面设定的
<integer name="config_minimumScreenOffTimeout">10000</integer>
参考日志
mWakefulness从Dreaming到Dozing到Asleep,mUserActivitySummary从USER_ACTIVITY_SCREEN_DREAM到啥都没。08-22 06:22:02.828 3064 5660 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dreaming, mUserActivitySummary=0x4, nextTimeout=146181 (in 264 ms)
08-22 06:22:02.828 3064 5660 D PowerManagerService: updateDisplayPowerStateLocked: mDisplayReady=true, policy=3, mWakefulness=2, mWakeLockSummary=0x3, mUserActivitySummary=0x4, mBootCompleted=true, screenBrightnessOverride=-1, useAutoBrightness=false, mScreenBrightnessBoostInProgress=false, mIsVrModeEnabled= false, sQuiescent=false08-22 06:22:03.093 3064 3089 D PowerManagerService: handleUserActivityTimeout
08-22 06:22:03.093 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dreaming, mUserActivitySummary=0x0, nextTimeout=146181 (1 ms ago)
08-22 06:22:03.093 3064 3089 D PowerManagerService: updateDisplayPowerStateLocked: mDisplayReady=true, policy=3, mWakefulness=2, mWakeLockSummary=0x3, mUserActivitySummary=0x0, mBootCompleted=true, screenBrightnessOverride=-1, useAutoBrightness=false, mScreenBrightnessBoostInProgress=false, mIsVrModeEnabled= false, sQuiescent=false
08-22 06:22:03.093 3064 3089 D PowerManagerService: goToSleepNoUpdateLocked: eventTime=146182, reason=2, flags=0, uid=1000
08-22 06:22:03.093 3064 3089 I PowerManagerService: Going to sleep due to screen timeout (uid 1000)...08-22 06:22:03.094 3064 3089 D PowerManagerService: updateWakeLockSummaryLocked: mWakefulness=Dozing, mWakeLockSummary=0x3
08-22 06:22:03.094 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dozing, mUserActivitySummary=0x0, nextTimeout=146181 (2 ms ago)
08-22 06:22:03.094 3064 3089 D PowerManagerService: updateDisplayPowerStateLocked: mDisplayReady=true, policy=3, mWakefulness=3, mWakeLockSummary=0x3, mUserActivitySummary=0x0, mBootCompleted=true, screenBrightnessOverride=-1, useAutoBrightness=false, mScreenBrightnessBoostInProgress=false, mIsVrModeEnabled= false, sQuiescent=false08-22 06:22:03.094 3064 3089 I DreamManagerService: Gently waking up from dream.
08-22 06:22:03.095 3064 3089 D PowerManagerService: reallyGoToSleepNoUpdateLocked: eventTime=146184, uid=1000
08-22 06:22:03.095 3064 3089 I PowerManagerService: Sleeping (uid 1000)...
08-22 06:22:03.095 3064 3089 D PowerManagerService: updateWakeLockSummaryLocked: mWakefulness=Asleep, mWakeLockSummary=0x1
08-22 06:22:03.095 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Asleep, mUserActivitySummary=0x0, nextTimeout=0 (146185 ms ago)
08-22 06:22:03.096 3064 3089 D PowerManagerService: updateDisplayPowerStateLocked: mDisplayReady=false, policy=0, mWakefulness=0, mWakeLockSummary=0x1, mUserActivitySummary=0x0, mBootCompleted=true, screenBrightnessOverride=-1, useAutoBrightness=false, mScreenBrightnessBoostInProgress=false, mIsVrModeEnabled= false, sQuiescent=false
08-22 06:22:03.096 3064 3085 I DreamManagerService: Performing gentle wake from dream.