Android 系统设置中的休眠和屏保

简介

由于客户在Android 系统设置中发现Timeout设置项没有效果,因此我对此研究了一下。Timeout是定时屏幕亮度降低,而Dream则是进入屏幕保护。如果是机顶盒等设备的开发者发现这个设置项没用,别见外,因为这里的亮度调整对TV是没用的,因此 ‘Screen Timeout’ 和‘brightness’ 是没用的。

Timeout休眠

界面代码

效果:设置固定的时间之后根据根据用户活动的时间、设备的电源政策(如 mDisplayPowerRequest.policy),以及当前时间来决定设备是保持亮屏、降低亮度还是进入其他省电状态。

代码位置:

packages/apps/Settings/res/xml/display_settings.xml

<com.android.settings.display.TimeoutListPreference
    android:key="screen_timeout"
    android:title="@string/screen_timeout"
    android:summary="@string/summary_placeholder"
    android:entries="@array/screen_timeout_entries"
    android:entryValues="@array/screen_timeout_values"//当点击的时候弹出的listView显示的内容
    settings:keywords="@string/keywords_screen_timeout" />//listView显示的内容对应的时间

这是这个设置项的资源配置文件,它是一个ListPreference 具有七个设置项,具体设置项的代码如下:
packages/apps/Settings/res/values/arrays.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>

它的国际化适配是在每一个语言文件夹下的arrays.xml都定义了一个screen_timeout_entries。因此如果要增加一个新的设置项比如“Never”那么就需要在所有可能使用的语言下都加上,否则切换语言之后可能会空指针异常。

属性值

这里选择之后,属性值的改变是Settings.System.SCREEN_OFF_TIMEOUT
adb shell settings get System screen_off_timeout
在你改变screen_timeout_values值的时候,记得如果想要永不息屏,就设置为2147483647 。这是可以设置的最大值。

延时降低亮度的具体逻辑

延时降低亮度的具体的逻辑基本都在frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

电源省电策略:
    /** Get wake lock summary flags that correspond to the given wake lock. */
    private int getWakeLockSummaryFlags(WakeLock wakeLock) {
        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.PARTIAL_WAKE_LOCK:
                if (!wakeLock.mDisabled) {
                    // We only respect this if the wake lock is not disabled.
                    return WAKE_LOCK_CPU;
                }
                break;
            case PowerManager.FULL_WAKE_LOCK:
                return WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
                return WAKE_LOCK_SCREEN_BRIGHT;
            case PowerManager.SCREEN_DIM_WAKE_LOCK:
                return WAKE_LOCK_SCREEN_DIM;
            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                return WAKE_LOCK_PROXIMITY_SCREEN_OFF;
            case PowerManager.DOZE_WAKE_LOCK:
                return WAKE_LOCK_DOZE;
            case PowerManager.DRAW_WAKE_LOCK:
                return WAKE_LOCK_DRAW;
        }
        return 0;
    }

    private void updatePowerStateLocked() {
这里省略一段代码.............

                updateWakeLockSummaryLocked(dirtyPhase1);
                updateUserActivitySummaryLocked(now, dirtyPhase1);
                updateAttentiveStateLocked(now, dirtyPhase1);
                if (!updateWakefulnessLocked(dirtyPhase1)) {
                    break;
                }
            }

updateUserActivitySummaryLocked 来更新用户活动状态,这个方法特别重要。这是一个更新用户活动状态的函数。它根据当前时间 (now)、用户活动的最后时间 (mLastUserActivityTime) 以及各种超时设置(如屏幕关闭超时、睡眠超时等),来决定接下来设备的行为(如屏幕变暗、关闭等)。

    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 (getWakefulnessLocked() == WAKEFULNESS_AWAKE
                    || getWakefulnessLocked() == WAKEFULNESS_DREAMING
                    || getWakefulnessLocked() == WAKEFULNESS_DOZING) {
                final long attentiveTimeout = getAttentiveTimeoutLocked();//超时时间用于检测用户是否仍然关注设备
                final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);//时时间表示设备在用户不活动后进入休眠状态的时间
                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                        attentiveTimeout);//表示设备在用户不活动后屏幕关闭的时间。它综合考虑了attentiveTimeout和sleepTimeout,
                final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
                final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
                final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
.....................................
                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;//这里将屏幕设成暗的
                        }
                    }
                }
    }

这里面还有很多种其他条件我就不一一介绍了。如果想要在时间到的时候执行其他操作,就在这里增加逻辑。

变量和方法解释

  • Attentive Timeout (attentiveTimeout)
    • 变量:mAttentiveTimeoutSetting
    • 方法:getAttentiveTimeoutLocked()
    • 解释:这个超时时间用于检测用户是否仍然关注设备。即使用户没有直接与设备交互,系统也可能通过一些方式(如面部识别)检测到用户的注意力。这种超时策略可以延长屏幕亮起时间,避免在用户依然关注设备时屏幕过早熄灭。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒),如果超时设置为0或负数,返回-1,表示不使用这个超时策略。
  • Sleep Timeout (sleepTimeout)
    • 变量:mSleepTimeoutSetting
    • 方法:getSleepTimeoutLocked(long attentiveTimeout)
    • 解释:这个超时时间表示设备在用户不活动后进入休眠状态的时间。它依赖于attentiveTimeout,如果attentiveTimeout有效(非负),则sleepTimeout不会超过attentiveTimeout。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒),如果超时设置为0或负数,返回-1,表示不使用这个超时策略。这里实际上他返回的就是我们设置中的settings get System screen_off_timeout拿到的值
  • Screen Off Timeout (screenOffTimeout)
    • 变量:mScreenOffTimeoutSetting
    • 方法:getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout)
    • 解释:这个超时时间表示设备在用户不活动后屏幕关闭的时间。它综合考虑了attentiveTimeout和sleepTimeout,并受一些额外设置的影响,如设备管理员强制的最大屏幕关闭时间。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒)。

关系分析

  1. attentiveTimeout 与 sleepTimeout
  • attentiveTimeout 是用户是否仍在关注设备的超时策略。sleepTimeout依赖于attentiveTimeout,即如果attentiveTimeout有效(非负),则sleepTimeout不会超过attentiveTimeout。这意味着只要系统检测到用户还在关注设备,设备就不会进入休眠状态。
  1. sleepTimeout 与 screenOffTimeout
  • screenOffTimeout 表示屏幕关闭的超时时间,它依赖于sleepTimeout。如果sleepTimeout有效(非负),则screenOffTimeout不会超过sleepTimeout。这意味着在用户不活动且系统决定设备应该休眠前,屏幕会先关闭。
  1. screenOffTimeout 的其他影响因素
  • screenOffTimeout 还受其他设置影响,如设备管理员设置的最大屏幕关闭时间(mMaximumScreenOffTimeoutFromDeviceAdmin)和窗口管理器覆盖的用户活动超时(mUserActivityTimeoutOverrideFromWindowManager)。这些设置会进一步约束screenOffTimeout的值,确保设备在合规的时间范围内关闭屏幕。

调试信息

如果想要打印这里的调试信息,系统中给了现成的
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
            }

效果如下

updateUserActivitySummaryLocked: mWakefulness=Awake, mUserActivitySummary=0x1, nextTimeout=920990 (in 892906 ms)

永不休眠

  1. 在 PowerManagerService 和 PhoneWindowManager 处理
  2. 直接配置 Settings.System.SCREEN_OFF_TIMEOUT 为Integer.MAX_VALUE( 2147483647 = 24.855 天 一般没有这么长时间亮屏待机 )

screensaver屏幕保护

界面代码
packages/apps/Settings/res/xml/display_settings.xml

<Preference
        android:key="screensaver"
        android:title="@string/screensaver_settings_title"
        android:fragment="com.android.settings.dream.DreamSettings" /> 

我们可以看到其中定义了android:fragment,也就是说当点击该item的时候会跳转到DreamSettings这个fragment。

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

public boolean isAvailable() {
    return mContext.getResources().getBoolean(
            com.android.internal.R.bool.config_dreamsSupported);
}

public void updateState(Preference preference) {
    preference.setSummary(DreamSettings.getSummaryTextWithDreamName(mContext));//获取当前的屏保的名称
}

此处读取com.android.internal.R.bool.config_dreamsSupported的值,true表示支持屏保,false表示不支持
更深入的代码没有去研究了,等待更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/753180.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电路仿真王者之争:SmartEDA如何领跑业界,打破传统仿真软件格局?

在电子设计领域&#xff0c;电路仿真软件一直扮演着至关重要的角色。它们为工程师们提供了一个虚拟的实验室&#xff0c;可以在不耗费大量实际资源的情况下&#xff0c;进行电路设计、优化和测试。在众多电路仿真软件中&#xff0c;SmartEDA以其独特的优势&#xff0c;逐渐崭露…

嵌入式开发十九:SysTick—系统定时器

在前面实验中我们使用到的延时都是通过SysTick进行延时的。 我们知道&#xff0c;延时有两种方式&#xff1a;软件延时&#xff0c;即CPU 循环等待产生的&#xff0c;这个延时是不精确的。第二种就是滴答定时器延时&#xff0c;本篇博客就来介绍 STM32F4 内部 SysTick 系统定时…

浅谈API生态建设:API安全策略的6项原则

API作为连接系统与应用的桥梁&#xff0c;在助力实现高效业务流程的同时&#xff0c;也不可避免出现资产管理困难、敏感数据泄漏风险骤增等安全问题。前段时间&#xff0c;安全公司Fastly公布了一项重磅调查报告&#xff0c;报告中显示95%的企业在过去1年中遭遇过API安全问题。…

AXI接口简介

AXI接口&#xff0c;全称为Advanced eXtensible Interface&#xff0c;是ARM公司推出的一种高性能、低成本、可扩展的高速总线接口。AXI接口是ARM公司提出的AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;高级微控制器总线架构的一部分。2003年发布了…

简易电阻、电容和电感测量仪-FPGA

通过VHDL语言编写程序用于设计电阻、电容和电感测量仪&#xff0c;通过使用试验箱进行验证是否设计正确&#xff0c;资料获取到咸&#x1f41f;&#xff1a;xy591215295250 \\\或者联系wechat 号&#xff1a;comprehensivable 设计并制作--台数字显示的电阻、电容和电感参数测试…

07-border布局的另一个用处

07-border布局的另一个用处 实现如下的布局: 分析: 1.USERNAME和PASSWORD使用form 2.PASSWORD的文本框使用NewMultiLineEntry 布局1 USERNAME和PASSWORD作为一个form整体&#xff0c;使用border布局&#xff0c;form设置为top&#xff0c;文本框设置为center参数。 packa…

Postman 接口测试 安装使用教程

1 下载官网:https://www.postman.com/downloads/ 2 方便下载,特提供百度云网盘: 链接&#xff1a;Postman 3 windows10 安装&#xff0c;点击安装包 #自动安装&#xff0c;并打开 4 举例&#xff0c;比如豆瓣&#xff0c;get 查询时间&#xff0c;图片登 5 举例&#xff0…

HSRP热备份路由协议(VRRP虚拟路由冗余协议)配置以及实现负载均衡

1、相关原理 在网络中&#xff0c;如果一台作为默认网关的三层交换机或者路由器损坏&#xff0c;所有使用该网关为下一跳的主机通信必然中断&#xff0c;即使配置多个默认网关&#xff0c;在不重启终端的情况下&#xff0c;也不能彻底换到新网关。Cisco提出了HSRP热备份路由协…

传神论文中心|第14期人工智能领域论文推荐

在人工智能领域的快速发展中&#xff0c;我们不断看到令人振奋的技术进步和创新。近期&#xff0c;开放传神&#xff08;OpenCSG&#xff09;社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自的论…

【干货】一文讲清楚社群裂变的主要模式和SOP流程

一、社群裂变的主要模式 社群裂变是一种依赖于现有成员的推广以吸引新成员的增长策略。以下是几种主要的社群裂变模式&#xff1a; 老带新裂变 定义&#xff1a;通过老用户带动新用户&#xff0c;同时给予某一方或双方奖励的一种裂变形式。 示例&#xff1a;任务宝活动&…

【精选】数据治理项目实施(合集)06——数据标准在数据治理中的落地实践

导读 本文对数据标准管理进行了深入探讨。重点介绍了数据标准的定义&#xff0c;实施路线和具体标准定义的内容&#xff0c;并总结了企业开展数据标准管理面临的常见问题&#xff0c;由于编写的水平和时间有限&#xff0c; 难免有所纸漏&#xff0c; 欢迎大家批评指正。 在现实…

填报高考志愿时,学校、专业和城市怎么选择呢?

我的观点是&#xff1a; 专业>城市>学校 专业是兴趣导向&#xff0c;符合自己的价值观&#xff0c;失去了这种驱动力的专业学习&#xff0c;会变得非常艰难的&#xff0c;而且没有竞争力&#xff0c;所以我的排序第一位是专业。 其次是城市&#xff0c;最好是一线城市&…

OpenAI发布新模型CriticGPT:利用GPT优化GPT训练,RLHF实现超越人类能力!

目录 01 基于GPT-4&#xff0c;改进GPT-4 02 CriticGPT取得了哪些成果呢&#xff1f; 03 RLHF的上限不再是人类 近日&#xff0c;OpenAI突然发布了一个新模型&#xff01;这个模型基于GPT-4训练&#xff0c;旨在帮助下一代GPT的训练。 CriticGPT能够在代码挑错中找到超过75%…

golang生成RSA公钥和密钥

目录 场景 场景一&#xff1a;加密、解密 场景二&#xff1a;微信退款 场景三&#xff1a;SSL证书 为什么是.key和.pem格式的文件 生成密钥、公钥 密钥、公钥保存到文件中 第一个&#xff1a;保存密钥到文件里 第二个&#xff1a;保存公钥到文件里 场景 场景一&#…

ForkJoinPool浅析

一,概述 相比传统的线程池ExecuteService,ForkJoinPool的优势在于能采用分治算法、工作窃取算法高效利用CPU资源,如下图 Fork即拆分,Join即合并, 通过将大任务拆分成多个小任务,在多个线程中执行后,合并结果即可得到大任务的结果,经典的例子有归并排序、超大数组求和…

如何保护应用?可快速部署的WAF服务器分享

Web应用攻击是安全事件和数据泄露的主要原因。相关统计表明&#xff0c;超过四分之三的网络犯罪直指应用及其漏洞。为保护数量日益增长的应用安全&#xff0c;Web应用防火墙(WAF)因此而生。本文则聚焦于WAF服务器&#xff0c;了解它的性能与具体的实践应用。   新加坡网络安全…

Linux应急响应靶机 2

一、靶机介绍 应急响应靶机-Linux2 前景需要&#xff1a;看监控的时候发现webshell告警&#xff0c;领导让你上机检查你可以救救安服仔吗&#xff01;&#xff01; 1,提交攻击者IP 2,提交攻击者修改的管理员密码(明文) 3,提交第一次Webshell的连接URL(http://xxx.xxx.xxx.…

变“回锅肉”专场的《歌手2024》,是不是高开低走了?

《歌手2024》播出已经过半&#xff0c;似乎出现了高开低走的不妙趋势。 6月26日&#xff0c;《歌手》节目组官宣第八期节目的补位歌手为谭维维&#xff0c;曾主动“请战”的她再次回到了《歌手》舞台&#xff0c;实力歌手加入节目按理说是件好事&#xff0c;却意外并未受到观众…

每天写java到期末考试--复习集合与泛型--6.28

1、定义一个Student类,具有name、sex、age属性,具有getName、setName、getSex、setSex、 getAge、setAge方法和三个参数的构造方法 2、编写一个类,名字为ListDemo,在main方法中做以下工作: 定义一个可以保存Student类型对象的List类型对象list1,然后向list1中放入2个学生:new S…

Web渗透:php反序列化漏洞

反序列化漏洞&#xff08;Deserialization Vulnerability&#xff09;是一种在应用程序处理数据的过程中&#xff0c;因不安全的反序列化操作引发的安全漏洞&#xff1b;反序列化是指将序列化的数据&#xff08;通常是字节流或字符串&#xff09;转换回对象的过程&#xff0c;如…