屏幕唤醒锁定 API

W3C 工作草案

关于此文档的更多细节
此版本
https://w3org.cn/TR/2024/WD-screen-wake-lock-20241024/
最新发布版本
https://w3org.cn/TR/screen-wake-lock/
最新编辑草案
https://w3c.github.io/screen-wake-lock/
历史
https://w3org.cn/standards/history/screen-wake-lock/
提交历史
测试套件
https://wpt.live/screen-wake-lock/
实现报告
https://w3org.cn/wiki/DAS/Implementations
编辑
Kenneth Rohde Christiansen (英特尔公司)
Marcos Cáceres (苹果公司)
前任编辑
Raphael Kubo da Costa (英特尔公司)
(Yandex)
(Yandex)
反馈
GitHub w3c/screen-wake-lock (pull requests, new issue, open issues)
质量保证主管
Wanming Lin (英特尔)

摘要

本文档定义了一个 API,允许 Web 应用请求屏幕唤醒锁。在满足适当条件且得到允许的情况下,屏幕唤醒锁会阻止系统关闭设备的屏幕。

本文档状态

本节描述本文档在发布时的状态。当前的 W3C 出版物列表以及本技术报告的最新修订版可在 https://w3org.cn/TR/ 的 W3C 技术报告索引 中找到。

实现者需要注意,此规范极其不稳定。未参与讨论的实现者会发现规范在不兼容的方式下发生改变。 想要在规范进入候选推荐阶段之前实现它的厂商应当在 GitHub 上关注该仓库并参与讨论。

本文档由设备与传感器工作组Web 应用工作组推荐轨道的工作草案形式发布。

发布为工作草案并不意味着 W3C 及其成员的认可。

这是一份草案文档,可能会随时被其他文档更新、替换或废弃。将其作为非进行中工作引用是不恰当的。

本文档由遵守W3C 专利政策的组织制作。W3C 维护关于设备与传感器工作组的公开专利披露列表以及关于 Web 应用工作组的公开专利披露列表;这些页面还包括专利披露的说明。实际了解自己掌握的包含必要权利要求的专利的个人必须依据W3C 专利政策》第 6 节进行披露。

本文档受 2023 年 11 月 3 日 W3C 流程文档 管辖。

1. 简介

本节是非规范性的。

现代操作系统通过实现激进的电源管理来实现更长的电池续航,这意味着在用户不活动后不久,主机设备可能会降低屏幕亮度、关闭屏幕,甚至让 CPU 进入深度省电状态,以尽可能限制功耗。

虽然这对延长电池寿命非常有利,但有时会妨碍某些使用场景,例如扫描条形码、阅读电子书、烹饪食谱、向观众演示等。另请参阅唤醒锁:用例

唤醒锁通常会阻止某些行为,但用户代理(以及底层操作系统)可能会根据电池状态(是否接通外部电源、是否正在放电、低电量等)对唤醒锁施加时间限制,甚至在开启省电模式时直接禁用唤醒锁。

2. 唤醒锁

本规范定义了以下唤醒锁类型

  1. 一种屏幕唤醒锁会阻止屏幕关闭。只有可见文档才能获取屏幕唤醒锁。

在 API 中,唤醒锁类型WakeLockType 枚举值表示。

其他规范可能定义不同的唤醒锁类型。

3. 策略控制

Screen Wake Lock API 定义了一个策略受控特性,其标识字符串为"screen-wake-lock"。它的默认允许列表'self'

4. 权限与用户提示

本节的[PERMISSIONS] API 为网站提供了一种统一的方式来向用户请求权限并查询已获批准的权限。

用户代理可以因实现特定原因(例如平台设置或用户偏好)拒绝某个唤醒锁类型在特定Document上的使用。

强烈建议用户代理在唤醒锁激活时显示一种不引人注意的通知,以告知用户当前有唤醒锁在运行,并提供用户阻止该操作的手段,或仅仅让用户关闭通知。

4.1 "screen-wake-lock" 强大特性

"screen-wake-lock" 强大特性启用了本规范所定义的能力。

4.2 权限算法

"screen-wake-lock" 强大特性定义了一个权限撤销算法。要调用Screen Wake Lock 权限撤销算法,请执行以下步骤:

  1. document当前全局对象关联 Document
  2. lockListdocument.[[ActiveLocks]]["screen"]。
  3. 对每个 locklockList
    1. 运行释放唤醒锁,参数为 documentlock 与“screen”。

5. 概念

本规范中提到的任务源任务屏幕唤醒锁任务源

术语 平台唤醒锁 指的是用户代理与之交互以查询状态并获取/释放唤醒锁的底层平台接口。

平台唤醒锁可以由底层平台(例如本机唤醒锁框架)定义,也可以由拥有直接硬件控制权的用户代理自行实现。

6. Document 接口的扩展

6.1 内部槽位

内部槽位 初始值 描述
[[ActiveLocks]] 一个有序映射,将唤醒锁类型映射到空列表 一个有序映射,将唤醒锁类型映射到与此Document关联的列表,列表中保存WakeLockSentinel对象。

7. Navigator 接口的扩展

WebIDL[SecureContext]
partial interface Navigator {
  [SameObject] readonly attribute WakeLock wakeLock;
};

8. WakeLock 接口

WakeLock 接口允许文档获取屏幕唤醒锁

WebIDL[SecureContext, Exposed=(Window)]
interface WakeLock {
  Promise<WakeLockSentinel> request(optional WakeLockType type = "screen");
};

8.1 request() 方法

request(type) 方法的步骤如下:

  1. documentthis相关全局对象关联 Document
  2. 如果 document 不是完全活跃的,则返回一个被拒绝的 Promise,拒因使用NotAllowedError DOMException
  3. 如果 document 未被允许使用名为screen-wake-lock策略受控特性,则返回一个被拒绝的 Promise,拒因使用NotAllowedErrorDOMException
  4. 如果用户代理拒绝了此type的唤醒锁请求,对 document,则返回一个被拒绝的 Promise,拒因NotAllowedError DOMException
  5. 如果 document可见性状态为"hidden",则返回一个被拒绝的 Promise,原因同上。
  6. promise一个新 Promise
  7. 并行执行以下步骤
    1. state 为请求使用"screen-wake-lock"的权限请求的结果。
    2. 如果 state 为"denied",则
      1. 屏幕唤醒锁任务源排队一个全局任务,该任务使用 document相关全局对象来用NotAllowedError DOMException拒绝 promise
      2. 中止这些步骤。
    3. 屏幕唤醒锁任务源排队一个全局任务,该任务使用 document相关全局对象来执行以下步骤:
      1. 如果 document 不是完全活跃的,则
        1. NotAllowedError DOMException拒绝 promise
        2. 中止这些步骤。
      2. 如果 document可见性状态为"hidden",则
        1. NotAllowedError DOMException拒绝 promise
        2. 中止这些步骤。
      3. 如果 document.[[ActiveLocks]]["screen"]为空,则并行执行以下步骤
        1. 使用"screen"调用获取唤醒锁
      4. lock 为一个新创建的WakeLockSentinel对象,其type属性设为 type
      5. 追加 lockdocument.[[ActiveLocks]]["screen"]。
      6. lock 解析 promise
  8. 返回 promise

9. WakeLockSentinel 接口

WebIDL[SecureContext, Exposed=(Window)]
interface WakeLockSentinel : EventTarget {
  readonly attribute boolean released;
  readonly attribute WakeLockType type;
  Promise<undefined> release();
  attribute EventHandler onrelease;
};

一个WakeLockSentinel对象提供了对平台唤醒锁的句柄,并在该句柄被手动释放或底层平台唤醒锁被释放前保持其存在。该对象的存在使得对应唤醒锁类型平台唤醒锁保持激活;而释放所有对应唤醒锁类型WakeLockSentinel实例会导致底层平台唤醒锁被释放。

9.1 内部槽位

WakeLockSentinel实例通过以下内部槽位创建:

内部槽位 初始值 描述(非规范性)
[[Released]] false 指示该WakeLockSentinel是否已被释放。

9.2 released 属性

released getter 的步骤是返回this.[[Released]]

9.3 type 属性

type getter 的步骤是返回this唤醒锁类型

9.4 release() 方法

release() 方法的步骤如下:

  1. 如果this[[Released]]false,则运行释放唤醒锁,参数为 lock(即this)以及对应的type(取自thistype属性)。
  2. 返回已解析为 undefined 的 Promise

9.5 onrelease 属性

onrelease 属性是针对"onrelease"事件处理器IDL 事件处理属性,其事件类型为"release"。

它用于在WakeLockSentinel对象的句柄被释放时(无论是因调用release()方法,还是因用户代理自行释放)通知脚本。

9.6 垃圾回收

只要WakeLockSentinel对象有一个或多个针对"release"的事件监听器,并且该对象尚未被释放,必须存在一个从创建该对象的Window到该WakeLockSentinel对象的强引用。

只要在WakeLockSentinel对象上有任务排入屏幕唤醒锁任务源必须存在一个从创建该对象的Window到该WakeLockSentinel对象的强引用。

10. WakeLockType 枚举

为描述唤醒锁类型的目的,本规范定义以下枚举来表示唤醒锁类型

WebIDLenum WakeLockType { "screen" };
screen
屏幕唤醒锁 类型。

11. 管理唤醒锁

本节对每一种唤醒锁类型均同等且独立适用,除非明确指出特定的唤醒锁类型

用户代理获取唤醒锁的方式是向底层操作系统请求应用该锁。对操作系统返回值的检查不是强制的。换言之,用户代理必须将唤醒锁的获取视为仅为建议性

相反,用户代理释放唤醒锁的方式是向底层操作系统请求不再应用该锁。只有当向操作系统的请求成功时,锁才被视为已释放。

只有当操作系统的状态允许锁的应用(例如电池电量充足)时,唤醒锁才是适用的

在用户手动关闭屏幕后,屏幕唤醒锁 不得再是适用的,直至屏幕再次打开。

11.1 自动释放唤醒锁

用户代理可以在任何时候释放唤醒锁。例如,当

11.2 处理文档失去完整活动状态

Documentdocument不再完全活跃时,用户代理必须执行以下步骤:

  1. 对每个 lockdocument.[[ActiveLocks]]["screen"]
    1. 运行 release a wake lock 使用 documentlock,以及 “screen”。

11.3 处理文档可见性丢失

本规范定义了以下页面可见性更改步骤,使用可见性状态 statedocument

  1. 如果 state 不是 “hidden”,则中止这些步骤。
  2. 对每个 lockdocument.[[ActiveLocks]]["screen"]
    1. 运行 release a wake lock 使用 documentlock,以及 “screen”。

11.4 获取唤醒锁算法

acquire a wake lock(获取唤醒锁)给定的 type,请运行以下步骤

  1. 如果类型为 type 的 wake lock 不是 applicable,则中止这些步骤。
  2. 请求底层操作系统 acquire the wake lock(获取)类型为 type 的唤醒锁。

11.5 释放唤醒锁算法

release a wake lock(释放唤醒锁)针对给定的 documentlocktype,请运行以下步骤

  1. 如果 document.[[ActiveLocks]][type] 不包含 lock,则中止这些步骤。
  2. lockdocument.[[ActiveLocks]][type] 中移除。
  3. 如果 document.[[ActiveLocks]][type] 为空,则以并行方式运行以下步骤
    1. 请求底层操作系统 release the wake lock(释放)类型为 type 的唤醒锁,并让 successtrue(若操作成功)否则为 false
    2. 如果 successtruetype"screen",则运行以下步骤
      1. 重置平台特定的非活动计时器(该计时器决定何时实际关闭屏幕)。
  4. lock[[Released]] 设为 true
  5. 触发一个事件,名称为 “release” 于 lock

12. 安全性与隐私考虑

屏幕唤醒锁可能导致各种设备组件——尤其是显示屏——在比平常更高的功耗水平下运行。这会产生不良影响,例如阻止设备自动锁定以及加速电池耗尽。电池耗尽尤为移动设备所关注,因为它们通常没有随时可用的固定电源。意外的电池完全耗尽会导致用户无法拨打或接听电话以及使用网络服务,包括紧急呼叫服务。

实现 MAY 在电池电量低、或用户已将设备切换至省电模式等情况下忽略对屏幕唤醒锁的请求。

强烈 RECOMMENDED(建议)用户代理提供某种 UI 或指示器,以便用户知道何时屏幕唤醒锁处于激活状态。提供此类 UI 有助于终端用户辨别某个特定 Web 应用是否对设备产生负面能耗影响,并在需要时采取相应操作。

13. 示例

本节是非规范性的。

示例 1:获取并释放屏幕唤醒锁
function tryKeepScreenAlive(minutes) {
  navigator.wakeLock.request("screen").then(lock => {
    setTimeout(() => lock.release(), minutes * 60 * 1000);
  });
}

tryKeepScreenAlive(10);

此示例通过点击复选框让用户请求屏幕唤醒锁,并在唤醒锁状态变化时同步更新复选框的勾选状态。

const checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
document.body.appendChild(checkbox);

const sentinel = await navigator.wakeLock.request("screen");
checkbox.checked = !sentinel.released;
sentinel.onrelease = () => checkbox.checked = !sentinel.released;

在本示例中,创建并独立释放了两个不同的唤醒锁请求。

let lock1 = await navigator.wakeLock.request("screen");
let lock2 = await navigator.wakeLock.request("screen");

lock1.release();
lock2.release();

14. 符合性

除了标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文件中的关键字 MAYMUSTMUST NOTRECOMMENDED 应按 BCP 14 [RFC2119] [RFC8174] 的定义进行解释,仅在全部大写出现时才生效,如本处所示。

本规范为单一产品定义符合性准则:实现其所包含接口的 user agent

A. 致谢

本节是非规范性的。

我们衷心感谢 Mounir Lamouri、Sergey Konstantinov、Matvey Larionov、Dominique Hazael‑Massieux、Domenic Denicola、Thomas Steiner、Anne van Kesteren 对本工作的贡献。

B. 变更

本节是非规范性的。

本节记录了自上次发布以来的变更。

B.1 自 2017 年 12 月 14 日候选推荐以来的变更

C. 索引

C.1 本规范定义的术语

C.2 引用定义的术语

D. IDL 索引

WebIDL[SecureContext]
partial interface Navigator {
  [SameObject] readonly attribute WakeLock wakeLock;
};

[SecureContext, Exposed=(Window)]
interface WakeLock {
  Promise<WakeLockSentinel> request(optional WakeLockType type = "screen");
};

[SecureContext, Exposed=(Window)]
interface WakeLockSentinel : EventTarget {
  readonly attribute boolean released;
  readonly attribute WakeLockType type;
  Promise<undefined> release();
  attribute EventHandler onrelease;
};

enum WakeLockType { "screen" };

E. 参考文献

E.1 规范性引用

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 语言规范. Ecma International. URL: https://tc39.es/ecma262/multipage/
[html]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 活标准. URL: https://html.whatwg.cn/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
权限. Marcos Caceres; Mike Taylor. W3C. 2024 年 3 月 19 日. W3C 工作草案. URL: https://w3org.cn/TR/permissions/
[PERMISSIONS-POLICY]
Permissions Policy. Ian Clelland. W3C. 25 September 2024. W3C Working Draft. URL: https://w3org.cn/TR/permissions-policy-1/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 关键词中大小写的歧义. B. Leiba. IETF. 2017年5月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

E.2 参考性引用

[wake-lock-use-cases]
唤醒锁:使用案例. Marcos Caceres; Natasha Rooney; Dominique Hazaël‑Massieux. W3C. 2014 年 8 月 14 日. W3C 工作组说明. URL: https://w3org.cn/TR/wake-lock-use-cases/