屏幕超时休眠-Android13

屏幕超时休眠-Android13

  • 1、设置界面
    • [1.2 属性值](#1.2 属性值)
      • [1.2.1 默认值](#1.2.1 默认值)
      • [1.2.2 最小值限制](#1.2.2 最小值限制)
    • [1.3 属性值疑问 Settings.System.SCREEN_OFF_TIMEOUT](#1.3 属性值疑问 Settings.System.SCREEN_OFF_TIMEOUT)
  • 2、超时灭屏
    • [2.1 锁定屏幕的超时](#2.1 锁定屏幕的超时)
    • [2.2 屏幕灭屏的超时](#2.2 屏幕灭屏的超时)
  • 3、永不休眠
  • [* 关键日志](#* 关键日志)

1、设置界面

packages/apps/Settings/src/com/android/settings/display/ScreenTimeoutSettings.java

packages/apps/Settings/res/xml/screen_timeout_settings.xml

xml 复制代码
12-16 12:13:54.707  7976  7976 D SettingsActivity: Switching to fragment com.android.settings.display.ScreenTimeoutSettings

1.2 属性值

Settings.System.SCREEN_OFF_TIMEOUT

powershell 复制代码
adb shell settings get System screen_off_timeout

packages/apps/Settings/res/values/arrays.xml

xml 复制代码
    <!-- Display settings.  The delay in inactivity before the screen is turned off. These are shown in a list dialog. -->
    <string-array name="screen_timeout_entries">
        <item>15 seconds</item>
        <item>30 seconds</item>
        <item>1 minute</item>
        <item>2 minutes</item>
        <item>5 minutes</item>
        <item>10 minutes</item>
        <item>30 minutes</item>
    </string-array>

    <!-- Do not translate. -->
    <string-array name="screen_timeout_values" translatable="false">
        <!-- Do not translate. -->
        <item>15000</item>
        <!-- Do not translate. -->
        <item>30000</item>
        <!-- Do not translate. -->
        <item>60000</item>
        <!-- Do not translate. -->
        <item>120000</item>
        <!-- Do not translate. -->
        <item>300000</item>
        <!-- Do not translate. -->
        <item>600000</item>
        <!-- Do not translate. -->
        <item>1800000</item>
    </string-array>

1.2.1 默认值

def_screen_off_timeout : frameworks/base/packages/SettingsProvider/res/values/defaults.xml

frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java

java 复制代码
    private void loadSystemSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");

            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
                    R.bool.def_dim_screen);
            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                    R.integer.def_screen_off_timeout);

            // Set default cdma DTMF type
            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);

            // Set default hearing aid
            loadSetting(stmt, Settings.System.HEARING_AID, 0);

            // Set default tty mode
            loadSetting(stmt, Settings.System.TTY_MODE, 0);

            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                    R.integer.def_screen_brightness);

            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
                    com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault);

            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                    R.bool.def_screen_brightness_automatic_mode);

            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                    R.bool.def_accelerometer_rotation);

            loadIntegerSetting(stmt, Settings.System.USER_ROTATION, R.integer.def_user_rotation);

            loadDefaultHapticSettings(stmt);

            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                    R.bool.def_notification_pulse);

            loadUISoundEffectsSettings(stmt);

            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
                    R.integer.def_pointer_speed);

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

frameworks/base/packages/SettingsProvider/res/values/defaults.xml

xml 复制代码
<integer name="def_screen_off_timeout">60000</integer>

1.2.2 最小值限制

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

java 复制代码
mMinimumScreenOffTimeoutConfig = resources.getInteger(com.android.internal.R.integer.config_minimumScreenOffTimeout);
Math.max(timeout, mMinimumScreenOffTimeoutConfig);

1.3 属性值疑问 Settings.System.SCREEN_OFF_TIMEOUT

在设置屏幕超时代码代码中,最大值可以为"Long.MAX_VALUE",属性设置Settings.System.putLong(context.getContentResolver(), SCREEN_OFF_TIMEOUT, value);,但是实质最大值只能是Integer.MAX_VALUE(2147483647);该属性实质在fwk中是Integer保存,获取方式mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT);

frameworks/base/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java 中 NON_NEGATIVE_INTEGER_VALIDATOR 检查非法值

java 复制代码
    private Long getMaxScreenTimeout(Context context) {
        if (context == null) {
            return Long.MAX_VALUE;
        }
        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
        if (dpm == null) {
            return Long.MAX_VALUE;
        }
        mAdmin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(context);
        if (mAdmin != null) {
            return dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
        }
        return Long.MAX_VALUE;
    }

    private String getCurrentSystemScreenTimeout(Context context) {
        if (context == null) {
            return Long.toString(FALLBACK_SCREEN_TIMEOUT_VALUE);
        } else {
            return Long.toString(Settings.System.getLong(context.getContentResolver(),
                    SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE));
        }
    }

    private void setCurrentSystemScreenTimeout(Context context, String key) {
        try {
            if (context != null) {
                final long value = Long.parseLong(key);
                mMetricsFeatureProvider.action(context, SettingsEnums.ACTION_SCREEN_TIMEOUT_CHANGED,
                        (int) value);
                Settings.System.putLong(context.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "could not persist screen timeout setting", e);
        }
    }

2、超时灭屏

2.1 锁定屏幕的超时

更新延时 mLockScreenTimeout 执行 mScreenLockTimeout

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

java 复制代码
mLockScreenTimeout = Settings.System.getIntForUser(resolver,Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);

    class ScreenLockTimeout implements Runnable {
        Bundle options;

        @Override
        public void run() {
            synchronized (this) {
                if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
                if (mKeyguardDelegate != null) {
                    mKeyguardDelegate.doKeyguardTimeout(options);
                }
                mLockScreenTimerActive = false;
                mLockNowPending = false;
                options = null;
            }
        }

        public void setLockOptions(Bundle options) {
            this.options = options;
        }
    }

2.2 屏幕灭屏的超时

updateUserActivitySummaryLocked更新mUserActivitySummary的值,用户活动超时时调用updateUserActivitySummaryLocked,这里获取getScreenOffTimeoutLocked状态更新

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

java 复制代码
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT);

    @GuardedBy("mLock")
    private long getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout) {
        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);
        }
        if (attentiveTimeout >= 0) {
            timeout = Math.min(timeout, attentiveTimeout);
        }
        return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
    }

    private void handleUserActivityTimeout() { // runs on handler thread
        synchronized (mLock) {
            if (DEBUG_SPEW) {
                Slog.d(TAG, "handleUserActivityTimeout");
            }

            mDirty |= DIRTY_USER_ACTIVITY;
            updatePowerStateLocked();
        }
    }

    /**
     * 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.
     */
    @GuardedBy("mLock")
    private void updateUserActivitySummaryLocked(long now, int dirty) {
        // Update the status of the user activity timeout timer.
        if ((dirty & (DIRTY_DISPLAY_GROUP_WAKEFULNESS | DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
                | DIRTY_WAKEFULNESS | DIRTY_SETTINGS | DIRTY_ATTENTIVE)) == 0) {
            return;
        }
        mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);

        final long attentiveTimeout = getAttentiveTimeoutLocked();
        final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
        long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                attentiveTimeout);
        final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
        screenOffTimeout =
                getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
        final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
        long nextTimeout = -1;
        boolean hasUserActivitySummary = false;
        for (int idx = 0; idx < mPowerGroups.size(); idx++) {
            int groupUserActivitySummary = 0;
            long groupNextTimeout = 0;
            final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
            final int wakefulness = powerGroup.getWakefulnessLocked();
            if (wakefulness != WAKEFULNESS_ASLEEP) {
                final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked();
                final long lastUserActivityTimeNoChangeLights =
                        powerGroup.getLastUserActivityTimeNoChangeLightsLocked();
                if (lastUserActivityTime >= powerGroup.getLastWakeTimeLocked()) {
                    groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration;
                    if (now < groupNextTimeout) {
                        groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                    } else {
                        groupNextTimeout = lastUserActivityTime + screenOffTimeout;
                        if (now < groupNextTimeout) {
                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                        }
                    }
                }
                if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights
                        >= powerGroup.getLastWakeTimeLocked()) {
                    groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout;
                    if (now < groupNextTimeout) {
                        if (powerGroup.isPolicyBrightLocked() || powerGroup.isPolicyVrLocked()) {
                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                        } else if (powerGroup.isPolicyDimLocked()) {
                            groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                        }
                    }
                }

                if (groupUserActivitySummary == 0) {
                    if (sleepTimeout >= 0) {
                        final long anyUserActivity = Math.max(lastUserActivityTime,
                                lastUserActivityTimeNoChangeLights);
                        if (anyUserActivity >= powerGroup.getLastWakeTimeLocked()) {
                            groupNextTimeout = anyUserActivity + sleepTimeout;
                            if (now < groupNextTimeout) {
                                groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                            }
                        }
                    } else {
                        groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                        groupNextTimeout = -1;
                    }
                }

                if (groupUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM
                        && userInactiveOverride) {
                    if ((groupUserActivitySummary &
                            (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
                        // Device is being kept awake by recent user activity
                        if (mOverriddenTimeout == -1) {
                            // Save when the next timeout would have occurred
                            mOverriddenTimeout = groupNextTimeout;
                        }
                    }
                    groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
                    groupNextTimeout = -1;
                }

                if ((groupUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
                        && (powerGroup.getWakeLockSummaryLocked()
                        & WAKE_LOCK_STAY_AWAKE) == 0) {
                    groupNextTimeout = mAttentionDetector.updateUserActivity(groupNextTimeout,
                            screenDimDuration);
                }

                if (isAttentiveTimeoutExpired(powerGroup, now)) {
                    groupUserActivitySummary = 0;
                    groupNextTimeout = -1;
                }

                hasUserActivitySummary |= groupUserActivitySummary != 0;

                if (nextTimeout == -1) {
                    nextTimeout = groupNextTimeout;
                } else if (groupNextTimeout != -1) {
                    nextTimeout = Math.min(nextTimeout, groupNextTimeout);
                }
            }

            powerGroup.setUserActivitySummaryLocked(groupUserActivitySummary);

            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateUserActivitySummaryLocked: groupId=" + powerGroup.getGroupId()
                        + ", mWakefulness=" + wakefulnessToString(wakefulness)
                        + ", mUserActivitySummary=0x" + Integer.toHexString(
                        groupUserActivitySummary)
                        + ", nextTimeout=" + TimeUtils.formatUptime(groupNextTimeout));
            }
        }

        final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
        if (nextProfileTimeout > 0) {
            nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
        }

        if (hasUserActivitySummary && nextTimeout >= 0) {
            scheduleUserInactivityTimeout(nextTimeout);
        }
    }

    private void scheduleUserInactivityTimeout(long timeMs) {
        final Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
        msg.setAsynchronous(true);
        mHandler.sendMessageAtTime(msg, timeMs);
    }

3、永不休眠

    1. 在 PowerManagerService 和 PhoneWindowManager 处理
    1. 直接配置 Settings.System.SCREEN_OFF_TIMEOUT 为Integer.MAX_VALUE( 2147483647 = 24.855 天 一般没有这么长时间亮屏待机 ),设置更长时间替换 Settings.System.SCREEN_OFF_TIMEOUT属性 VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR) 中NON_NEGATIVE_INTEGER_VALIDATOR检测为NONE_NEGATIVE_LONG_VALIDATOR

* 关键日志

xml 复制代码
SettingsActivity:|SubSettings: Launching fragment|start u|ScreenTimeout:|sysui_multi_action: \[757,1754|screen_toggled:|sysui_multi_action:.*screen_timeout|power_screen_state:|PowerManagerService: Waking up|PowerManagerService: Going to sleep

sysui_multi_action: 757,1754,758,4,759,**`15000`**

sysui_multi_action: 757,1754,758,4,759,**`30000`**

sysui_multi_action: 757,1754,758,4,759,**`60000`**

sysui_multi_action: 757,1754,758,4,759,**`120000`**

sysui_multi_action: 757,1754,758,4,759,**`300000`**

sysui_multi_action: 757,1754,758,4,759,**`600000`**

sysui_multi_action: 757,1754,758,4,759,**`1800000`**

xml 复制代码
12-17 07:13:37.536   645   678 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity (has extras)} from uid 0
12-17 07:13:40.128   645  2427 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.settings/.Settings bnds=[581,351][858,771]} from uid 10149
12-17 07:13:46.309   645  2510 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cmp=com.android.settings/.SubSettings (has extras)} from uid 1000
12-17 07:13:46.408  7976  7976 D SettingsActivity: Switching to fragment com.android.settings.DisplaySettings
12-17 07:13:46.409  7976  7976 D SubSettings: Launching fragment com.android.settings.DisplaySettings
12-17 07:13:48.942  7976  7976 I sysui_multi_action: [757,830,758,4,833,0,854,screen_timeout,1089,0]
12-17 07:13:48.948   645  1716 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cmp=com.android.settings/.SubSettings (has extras)} from uid 1000
12-17 07:13:49.036  7976  7976 D SettingsActivity: Switching to fragment com.android.settings.display.ScreenTimeoutSettings
12-17 07:13:49.037  7976  7976 D SubSettings: Launching fragment com.android.settings.display.ScreenTimeoutSettings
12-17 07:13:50.690  7976  7976 I sysui_multi_action: [757,1754,758,4,759,15000]
12-17 07:13:52.884  7976  7976 I sysui_multi_action: [757,1754,758,4,759,30000]
12-17 07:13:54.152  7976  7976 I sysui_multi_action: [757,1754,758,4,759,60000]
12-17 07:13:55.559  7976  7976 I sysui_multi_action: [757,1754,758,4,759,120000]
12-17 07:13:57.041  7976  7976 I sysui_multi_action: [757,1754,758,4,759,300000]
12-17 07:13:58.400  7976  7976 I sysui_multi_action: [757,1754,758,4,759,600000]
12-17 07:13:59.653  7976  7976 I sysui_multi_action: [757,1754,758,4,759,1800000]
12-17 07:14:01.446  7976  7976 I sysui_multi_action: [757,1754,758,4,759,15000]
12-17 07:14:16.400   645   708 I PowerManagerService: Going to sleep due to timeout (uid 1000)...
12-17 07:14:17.032   645   645 I power_screen_state: [0,3,0,0,628]
12-17 07:14:17.032   645   645 I screen_toggled: 0
12-17 07:14:17.032   645   645 I sysui_multi_action: [757,804,799,screen_timeout,801,15,802,1]
12-17 07:14:28.765   645   793 I PowerManagerService: Waking up from Asleep (uid=1000, reason=WAKE_REASON_POWER_BUTTON, details=android.policy:POWER)...
12-17 07:14:28.770   645   645 I screen_toggled: 1
12-17 07:14:28.905   645   645 I power_screen_state: [1,0,0,0,110]
相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui