当前位置:   article > 正文

Android 知识点 110 —— PowerManagerService 进入屏保 updateUserActivitySummaryLocked

updateuseractivitysummarylocked

屏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

  1. <integer name="def_screen_off_timeout">60000</integer>
  2. <integer name="def_sleep_timeout">-1</integer>

60000 ms , 看code里面的时间都是毫秒。

overlay的情况

这里面默认的睡眠时间是20s,屏保时间是10s,也就是说没事做10s进屏保,再过10s进睡眠。

  1. <integer name="def_sleep_timeout">20000</integer>
  2. <integer name="def_screen_off_timeout">10000</integer>

 参考日志如下,uid 1000 指的是Process.SYSTEM_UID, 说明是系统发起的。

  1. 08-22 05:09:51.244 3067 3092 I PowerManagerService: Nap time (uid 1000)...
  2. 08-22 05:09:51.245 3067 3092 I DreamManagerService: Entering dreamland.
  3. 08-22 05:09:51.245 3067 3092 I PowerManagerService: Dreaming...
  4. 08-22 05:10:01.243 3067 3092 I PowerManagerService: Going to sleep due to screen timeout (uid 1000)...
  5. 08-22 05:10:01.244 3067 3092 I DreamManagerService: Gently waking up from dream.
  6. 08-22 05:10:01.245 3067 3092 I PowerManagerService: Sleeping (uid 1000)...
  7. 08-22 05:10:01.247 2892 2954 E : getRealActiveConfig to config(0).
  8. 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。

  1. private void updateUserActivitySummaryLocked(long now, int dirty) {
  2. // Update the status of the user activity timeout timer.
  3. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
  4. | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
  5. mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
  6. long nextTimeout = 0;
  7. if (mWakefulness == WAKEFULNESS_AWAKE
  8. || mWakefulness == WAKEFULNESS_DREAMING
  9. || mWakefulness == WAKEFULNESS_DOZING) {
  10. //获取睡眠时长,为Settings.Secure.SLEEP_TIMEOUT的值和最小休眠时间的最大值,Settings.Secure.SLEEP_TIMEOUT一般为-1,
  11. //表示禁用,因此该值默认为-1
  12. final int sleepTimeout = getSleepTimeoutLocked();
  13. //获取休眠时长,在Settings中设置的值
  14. final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
  15. //获取Dim时长,由休眠时长剩Dim百分比得到
  16. final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
  17. //用户活动是否由Window覆盖
  18. final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
  19. //该值用来统计用户活动状态,每次进入该方法,置为0
  20. mUserActivitySummary = 0;
  21. //上次用户活动时间>=上次唤醒时间
  22. if (mLastUserActivityTime >= mLastWakeTime) {
  23. //下次超时时间为上次用户活动时间+休眠时间-Dim时间,到达这个时间后,将进入Dim状态
  24. nextTimeout = mLastUserActivityTime
  25. + screenOffTimeout - screenDimDuration;
  26. //如果当前时间<nextTimeout,则此时处于亮屏状态,标记mUserActivitySummary为USER_ACTIVITY_SCREEN_BRIGHT
  27. if (now < nextTimeout) {
  28. mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
  29. } else {
  30. //如果当前时间>nextTimeout,此时有两种情况,要么进入Dim要么进入Sleep
  31. //将上次用户活动时间+灭屏时间赋值给nextTimeout,如果该值大于当前时间,则说明此时应该处于Dim状态
  32. //因此将标记mUserActivitySummary为USER_ACTIVITY_SCREEN_DIM
  33. nextTimeout = mLastUserActivityTime + screenOffTimeout;
  34. if (now < nextTimeout) {
  35. mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
  36. }
  37. }
  38. }
  39. //判断和USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS标记相关,如果带有此标记,才会进入该if
  40. if (mUserActivitySummary == 0
  41. && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
  42. //下次超时时间=上次用户活动时间+灭屏时间
  43. nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
  44. //根据当前时间和nextTimeout设置mUserActivitySummary
  45. if (now < nextTimeout) {
  46. if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
  47. || mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
  48. mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
  49. } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
  50. mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
  51. }
  52. }
  53. }
  54. //不满足以上条件时,此时mUserActivitySummary为0,这种情况应该为当mUserActivitySummary经历了USER_ACTIVITY_SCREEN_BRIGHT
  55. //和USER_ACTIVITY_SCREEN_DIM之后才会执行到这里
  56. if (mUserActivitySummary == 0) {
  57. if (sleepTimeout >= 0) {
  58. //获取上次用户活动时间的最后一次时间
  59. final long anyUserActivity = Math.max(mLastUserActivityTime,
  60. mLastUserActivityTimeNoChangeLights);
  61. if (anyUserActivity >= mLastWakeTime) {
  62. nextTimeout = anyUserActivity + sleepTimeout;
  63. //将mUserActivitySummary值置为USER_ACTIVITY_SCREEN_DREAM,表示屏保
  64. if (now < nextTimeout) {
  65. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  66. }
  67. }
  68. } else {
  69. //将mUserActivitySummary值置为USER_ACTIVITY_SCREEN_DREAM,表示屏保
  70. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  71. nextTimeout = -1;
  72. }
  73. }
  74. if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
  75. if ((mUserActivitySummary &
  76. (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
  77. // Device is being kept awake by recent user activity
  78. if (nextTimeout >= now && mOverriddenTimeout == -1) {
  79. // Save when the next timeout would have occurred
  80. mOverriddenTimeout = nextTimeout;
  81. }
  82. }
  83. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  84. nextTimeout = -1;
  85. }
  86. if (mUserActivitySummary != 0 && nextTimeout >= 0) {
  87. //发送一个异步Handler定时消息
  88. Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
  89. msg.setAsynchronous(true);
  90. mHandler.sendMessageAtTime(msg, nextTimeout);
  91. }
  92. } else {//当wakefulness=Sleep的时候,直接将mUserActivitySummary置为0
  93. mUserActivitySummary = 0;
  94. }
  95. }
  96. }

mUserActivitySummary 的取值如下,这个状态的改变需要打开PowerManagerService的debug 才好看。能看到从 0x1 -> 0x2 - >0x4 这个状态切换。

  1. // Summarizes the user activity state.
  2. private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
  3. private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
  4. private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;

updateUserActivitySummaryLocked 入口参数 now ,我们可以看到时间是系统的SYSTEM_TIME_MONOTONIC 时间,是系统启动以后流逝的时间。所有的时间操作都是相对于这个时间进行的。

 

获得系统睡眠超时时间,要从设定值和最小灭屏值选一个大的出来,最小灭屏值一般是10s,也就是说睡眠时间不能比最小的灭屏值还小。mSleepTimeoutSetting 是可以从设置菜单设置的,菜单 "Put device to sleep" 指定多长时间进入睡眠。

  1. private long getSleepTimeoutLocked() {
  2. final long timeout = mSleepTimeoutSetting;
  3. if (timeout <= 0) {
  4. return -1;
  5. }
  6. return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
  7. }

在初始化updateSettingsLocked里面,从SettingsProvider读数据,如果没有设定过就是默认值。

  1. mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
  2. Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
  3. UserHandle.USER_CURRENT);
  4. mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
  5. Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
  6. UserHandle.USER_CURRENT);

后取 系统灭屏超时时间,这个主要是选一个睡眠超时和系统灭屏时间的较小值。比如前面的是灭屏是10s,睡眠是20s,那就是10s,反之还是10s。前面的两个if里面的条件一般不满足。mScreenOffTimeoutSetting 同样也是在设置菜单里可以设置的,Screen saver菜单 -》 When to start 菜单。这里可能不同型号的机器,菜单放置的位置不一样。

  1. private long getScreenOffTimeoutLocked(long sleepTimeout) {
  2. long timeout = mScreenOffTimeoutSetting;
  3. if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
  4. timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
  5. }
  6. if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
  7. timeout = Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
  8. }
  9. if (sleepTimeout >= 0) {
  10. timeout = Math.min(timeout, sleepTimeout);
  11. }
  12. return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
  13. }

最小灭屏值是在framework/base里面config.xml里面设定的

<integer name="config_minimumScreenOffTimeout">10000</integer>

参考日志

mWakefulness从Dreaming到Dozing到Asleep,mUserActivitySummary从USER_ACTIVITY_SCREEN_DREAM到啥都没。

  1. 08-22 06:22:02.828 3064 5660 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dreaming, mUserActivitySummary=0x4, nextTimeout=146181 (in 264 ms)
  2. 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=false
  3. 08-22 06:22:03.093 3064 3089 D PowerManagerService: handleUserActivityTimeout
  4. 08-22 06:22:03.093 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dreaming, mUserActivitySummary=0x0, nextTimeout=146181 (1 ms ago)
  5. 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
  6. 08-22 06:22:03.093 3064 3089 D PowerManagerService: goToSleepNoUpdateLocked: eventTime=146182, reason=2, flags=0, uid=1000
  7. 08-22 06:22:03.093 3064 3089 I PowerManagerService: Going to sleep due to screen timeout (uid 1000)...
  8. 08-22 06:22:03.094 3064 3089 D PowerManagerService: updateWakeLockSummaryLocked: mWakefulness=Dozing, mWakeLockSummary=0x3
  9. 08-22 06:22:03.094 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Dozing, mUserActivitySummary=0x0, nextTimeout=146181 (2 ms ago)
  10. 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=false
  11. 08-22 06:22:03.094 3064 3089 I DreamManagerService: Gently waking up from dream.
  12. 08-22 06:22:03.095 3064 3089 D PowerManagerService: reallyGoToSleepNoUpdateLocked: eventTime=146184, uid=1000
  13. 08-22 06:22:03.095 3064 3089 I PowerManagerService: Sleeping (uid 1000)...
  14. 08-22 06:22:03.095 3064 3089 D PowerManagerService: updateWakeLockSummaryLocked: mWakefulness=Asleep, mWakeLockSummary=0x1
  15. 08-22 06:22:03.095 3064 3089 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Asleep, mUserActivitySummary=0x0, nextTimeout=0 (146185 ms ago)
  16. 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
  17. 08-22 06:22:03.096 3064 3085 I DreamManagerService: Performing gentle wake from dream.

 

这个分享很好,有些省略的知识都在里面了。

https://www.jianshu.com/p/9241f3a91095

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45687
推荐阅读
相关标签
  

闽ICP备14008679号