屏幕唤醒锁 API

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2024/WD-screen-wake-lock-20241024/
最新发布版本:
https://www.w3.org/TR/screen-wake-lock/
最新编辑草案:
https://w3c.github.io/screen-wake-lock/
历史记录:
https://www.w3.org/standards/history/screen-wake-lock/
提交历史
测试套件:
https://wpt.live/screen-wake-lock/
实现报告:
https://www.w3.org/wiki/DAS/Implementations
编辑:
Kenneth Rohde Christiansen (英特尔公司)
Marcos Cáceres (苹果公司)
前编辑:
Raphael Kubo da Costa (英特尔 公司)
(Yandex)
(Yandex)
反馈:
GitHub w3c/screen-wake-lock (拉取请求, 新建议题, 开放议题)
质量保证负责人
Wanming Lin(英特尔)

摘要

本文档规定了一种 API,允许 Web 应用请求 屏幕唤醒锁。在适当的条件下,并且获得允许时, 屏幕唤醒锁会阻止系统关闭设备的 屏幕。

本文档的状态

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

实现者需要注意,本规范极不 稳定。未参与 讨论的实现者会发现,本规范会不断发生 不兼容的更改。有意在本 规范最终进入候选推荐标准 阶段之前实现它的供应商应订阅 GitHub 上的 仓库并参与讨论。

本文档由设备与传感器工作 组Web 应用工作组使用 推荐标准轨道作为工作草案发布。

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

本文档是一份草案,可能随时被其他 文档更新、替代或废止。不应将本文档作为 开展中的工作以外的内容加以引用。

本文档由依据 W3C 专利 政策运作的工作组制作。 W3C 维护着 所有专利披露的公开列表 (设备与传感器工作组)所有专利披露的公开列表 (Web 应用工作组), 这些披露与各工作组的 交付成果有关;这些页面还包含 披露专利的说明。任何实际 知晓某项专利并认为该专利包含 必要权利要求 的个人,都必须按照 W3C 专利政策第 6 节披露相关信息。

本文档受 2023年11月03日 W3C 流程文档约束。

1. 引言

本节为非规范性内容。

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

虽然这非常有利于延长电池续航时间,但有时也会妨碍 某些用例,例如扫描条形码、阅读电子书、按照 食谱操作、向观众演示等。另请参阅 唤醒锁:用例

唤醒锁通常会阻止某些事情发生,但 UA (以及底层操作系统)可能会根据电池 状态(已连接外部电源、正在放电、电池电量低)限制唤醒锁的持续时间,甚至 在启用省电模式时禁止使用唤醒锁。

2. 唤醒锁

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

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

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

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

3. 策略控制

屏幕唤醒锁 API 定义了一个由字符串 "screen-wake-lock" 标识的策略控制功能。 其默认允许列表'self'

4. 权限和用户提示

[PERMISSIONS] API 为网站提供了一种统一的方式来向用户请求 权限,并查询它们拥有的权限。

用户 代理可以出于任何 实现特定的原因(例如平台设置或用户 偏好),针对特定 Document 拒绝唤醒锁 的某个特定唤醒锁类型

建议用户代理显示某种不显眼的 通知,在唤醒锁处于活动状态时告知用户,同时 为用户提供阻止正在进行的操作,或 直接关闭 通知的方法。

4.1 "screen-wake-lock" 强大功能

"screen-wake-lock" 强大功能启用本规范定义的 能力。

4.2 权限算法

"screen-wake-lock" 强大功能定义了一个权限撤销 算法。要调用屏幕 唤醒锁权限撤销算法,运行以下步骤:

  1. document当前全局对象关联 Document
  2. lockListdocument.[[ActiveLocks]]["screen"]。
  3. 对于 lockList 中的每个 lock
    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" 的策略控制功能,则返回 "NotAllowedError" DOMException 拒绝的 promise。
  4. 如果 用户代理针对 document 拒绝type 的唤醒锁,则返回 "NotAllowedError" DOMException 拒绝的 promise。
  5. 如果 document可见性状态为 "hidden",则返回 "NotAllowedError" DOMException 拒绝的 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. lock 追加document.[[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 设置 为 thistype 设置为 thistype 属性的值。
  2. 返回 undefined 兑现的 promise。

9.5 onrelease 属性

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

它用于通知脚本,给定 WakeLockSentinel 对象的句柄已被释放,其原因可能是调用了 release() 方法,也可能是 唤醒锁被用户代理释放。

9.6 垃圾回收

当一个 WakeLockSentinel 对象 注册了一个或多个针对 "release" 的事件监听器,并且该 WakeLockSentinel 对象尚未被 释放时,从调用该 WakeLockSentinel 对象构造函数的 Window 对象到 WakeLockSentinel 对象本身必须 存在强引用。

当存在一个由 WakeLockSentinel 对象排入 屏幕唤醒锁任务源的任务时,从调用该 WakeLockSentinel 对象 构造函数的 Window 对象到该 WakeLockSentinel 对象必须存在强引用。

10. WakeLockType 枚举

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

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

11. 管理唤醒锁

除非明确提及某个特定唤醒锁类型,否则本节以相同且 相互独立的方式适用于每个唤醒锁类型

用户 代理通过请求底层操作系统应用 锁来获取唤醒 锁。不会检查向底层 操作系统发出的请求可能返回的值。换言之,用户代理 必须将唤醒锁获取视为仅具建议性

相反,用户代理通过请求底层操作系统不再应用 唤醒锁来释放唤醒锁。 只有当向操作系统发出的请求成功时,才认为该锁已被释放。

如果操作系统的状态允许应用该锁(例如有 足够的电池电量),则唤醒锁是适用的

在用户手动关闭屏幕后,直到屏幕再次打开之前, 屏幕唤醒锁不得适用的

11.1 自动释放唤醒锁

用户代理可以随时释放唤醒锁。例如, 当:

11.2 处理文档失去完全活跃状态

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

  1. 对于 document.[[ActiveLocks]]["screen"] 中的每个 lock
    1. 使用 documentlock 和 "screen" 运行释放唤醒锁

11.3 处理文档失去可见性

本规范定义以下页面可见性更改步骤,其可见性状态state,文档为 document

  1. 如果 state 不是 "hidden",则中止这些步骤。
  2. 对于 document.[[ActiveLocks]]["screen"] 中的每个 lock
    1. 使用 documentlock 和 "screen" 运行释放唤醒锁

11.4 获取唤醒锁算法

要为给定 type 获取 唤醒锁, 运行以下步骤:

  1. 如果类型 type 的唤醒锁不是适用的,则中止 这些步骤。
  2. 请求底层操作系统获取 唤醒锁类型 type

11.5 释放唤醒锁算法

要为给定 documentlocktype 释放 唤醒锁,运行以下 步骤:

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

12. 安全和隐私考虑

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

例如,如果电池容量较低,或者用户已将设备 置于省电模式,实现可以忽略屏幕唤醒锁请求。

建议用户代理提供某种 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. 一致性

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

本文档中的关键词可以必须不得 建议 应按照 BCP 14 [RFC2119] [RFC8174] 中所述进行解释,并且仅当它们像此处所示以全部大写形式出现时才如此。

本规范为单一产品定义一致性标准:即实现其中所含接口的 用户代理

A. 致谢

本节为非规范性内容。

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

B. 更改

本节为非规范性内容。

本节记录自先前发布版本以来的更改。

B.1 自 2017 年 12 月 14 日 CR 以来的更改

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 标准。Anne van Kesteren。WHATWG。 现行标准。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.spec.whatwg.org/multipage/
[infra]
Infra 标准。Anne van Kesteren;Domenic Denicola。WHATWG。现行标准。URL:https://infra.spec.whatwg.org/
[PERMISSIONS]
权限。Marcos Caceres;Mike Taylor。W3C。2024 年 3 月 19 日。W3C 工作草案。URL:https://www.w3.org/TR/permissions/
[PERMISSIONS-POLICY]
权限策略。Ian Clelland。W3C。2024 年 9 月 25 日。W3C 工作草案。URL:https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFC 中用于指示 要求级别的关键词。S. Bradner。IETF。1997 年 3 月。最佳当前实践。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 标准。Edgar Chen;Timothy Gu。 WHATWG。现行标准。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://www.w3.org/TR/wake-lock-use-cases/