Android 知识点 110 —— PowerManagerService 进入屏保 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

    <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。

    /**
     * Updates the value of mUserActivitySummary to summarize the user requested
     * state of the system such as whether the screen should be bright or dim.
     * Note that user activity is ignored when the system is asleep.
     *
     * This function must have no other side-effects.
     */
    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) {
                final long sleepTimeout = getSleepTimeoutLocked();
                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
                final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
                final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
                final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
 
                mUserActivitySummary = 0;
                if (mLastUserActivityTime >= mLastWakeTime) {
                    nextTimeout = mLastUserActivityTime
                            + screenOffTimeout - screenDimDuration;
                    if (now < nextTimeout) {
                        mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                    } else {
                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
                        if (now < nextTimeout) {
                            mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                        }
                    }
                }
                if (mUserActivitySummary == 0
                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
                    if (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;
                        }
                    }
                }
 
                if (mUserActivitySummary == 0) {
                    if (sleepTimeout >= 0) {
                        final long anyUserActivity = Math.max(mLastUserActivityTime,
                                mLastUserActivityTimeNoChangeLights);
                        if (anyUserActivity >= mLastWakeTime) {
                            nextTimeout = anyUserActivity + sleepTimeout;
                            if (now < nextTimeout) {
                                mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                            }
                        }
                    } else {
                        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 activity
                        if (nextTimeout >= now && mOverriddenTimeout == -1) {
                            // Save when the next timeout would have occurred
                            mOverriddenTimeout = nextTimeout;
                        }
                    }
                    mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                    nextTimeout = -1;
                }
 
                if (nextProfileTimeout > 0) {
                    nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
                }
 
                if (mUserActivitySummary != 0 && nextTimeout >= 0) {
                    scheduleUserInactivityTimeout(nextTimeout);
                }
            } else {
                mUserActivitySummary = 0;
            }
 
            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
                        + PowerManagerInternal.wakefulnessToString(mWakefulness)
                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
            }
        }
    }

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=false
 
08-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=false
 
08-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.
发布了112 篇原创文章 · 获赞 3 · 访问量 9699

猜你喜欢

转载自blog.csdn.net/yush34/article/details/105118267