├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── auto-publish.yml │ └── tidy.yml ├── .pr-preview.json ├── .tidyrc ├── LICENSE.md ├── README.md ├── brightness-mode-explainer.md ├── explainer.md ├── index.html └── w3c.json /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 2 | [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and 3 | [Software and Document License](https://www.w3.org/Consortium/Legal/copyright- 4 | software). To make substantive contributions to specifications, you must either participate 5 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 6 | 7 | If you are not the sole contributor to a contribution (pull request), please identify all 8 | contributors in the pull request comment. 9 | 10 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 11 | 12 | ``` 13 | +@github_username 14 | ``` 15 | 16 | If you added a contributor by mistake, you can remove them in a comment with: 17 | 18 | ``` 19 | -@github_username 20 | ``` 21 | 22 | If you are making a pull request on behalf of someone else but you had no part in designing the 23 | feature, you can remove yourself with the above syntax. 24 | 25 | # Tests 26 | 27 | For normative changes, a corresponding 28 | [web-platform-tests](https://github.com/web-platform-tests/wpt) PR is highly appreciated. Typically, 29 | both PRs will be merged at the same time. Note that a test change that contradicts the spec should 30 | not be merged before the corresponding spec change. If testing is not practical, please explain why 31 | and if appropriate [file a web-platform-tests issue](https://github.com/web-platform-tests/wpt/issues/new) 32 | to follow up later. Add the `type:untestable` or `type:missing-coverage` label as appropriate. 33 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Closes #??? 2 | 3 | The following tasks have been completed: 4 | 5 | * [ ] Modified Web platform tests (link to pull request) 6 | 7 | Implementation commitment: 8 | 9 | * [ ] Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=) 10 | * [ ] Gecko (https://bugzilla.mozilla.org/show_bug.cgi?id=) 11 | * [ ] WebKit (https://bugs.webkit.org/show_bug.cgi?id=) 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | # Workflow based on the w3c/spec-prod action example to deploy to W3C using Echidna: 2 | # https://github.com/w3c/spec-prod/blob/main/docs/examples.md#deploy-to-w3c-using-echidna 3 | 4 | name: CI 5 | 6 | on: 7 | pull_request: {} 8 | push: 9 | branches: [gh-pages] 10 | paths: 11 | - 'index.html' 12 | jobs: 13 | main: 14 | name: Build, Validate and Deploy 15 | runs-on: ubuntu-20.04 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: w3c/spec-prod@v2 19 | with: 20 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 21 | # Replace following with appropriate value. See options.md for details. 22 | W3C_WG_DECISION_URL: https://lists.w3.org/Archives/Public/public-device-apis/2021May/0008.html 23 | W3C_NOTIFICATIONS_CC: ${{ secrets.CC }} 24 | W3C_BUILD_OVERRIDE: | 25 | specStatus: WD 26 | shortName: screen-wake-lock 27 | -------------------------------------------------------------------------------- /.github/workflows/tidy.yml: -------------------------------------------------------------------------------- 1 | name: Tidy document 2 | on: 3 | workflow_dispatch: {} 4 | push: 5 | branches: 6 | - gh-pages 7 | 8 | jobs: 9 | tidy: 10 | name: Tidy up 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - run: brew install tidy-html5 15 | - run: tidy -config .tidyrc -o index.html index.html 16 | - uses: peter-evans/create-pull-request@v3 17 | with: 18 | title: "Tidied up document using tidy-html5" 19 | commit-message: "chore(tidy): tidy up document" 20 | branch: html-tidy 21 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } 5 | -------------------------------------------------------------------------------- /.tidyrc: -------------------------------------------------------------------------------- 1 | char-encoding: utf8 2 | indent: yes 3 | wrap: 80 4 | tidy-mark: no 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Screen Wake Lock API 2 | ============= 3 | 4 | You can view the full document [here](https://w3c.github.io/screen-wake-lock/). 5 | -------------------------------------------------------------------------------- /brightness-mode-explainer.md: -------------------------------------------------------------------------------- 1 | # Design Document: the need to control screen brightness 2 | 3 | ## Introduction 4 | 5 | Since 2018, the working group has received [significant requests](https://github.com/w3c/screen-wake-lock/issues/129) from web developers surrounding the need to increase the brightness of a device's screen. 6 | 7 | For developers, it would help address the following use cases: 8 | 9 | - a user scans a QR/barcode under various lighting conditions, in which case boosting the screen brightness creates more contrast. 10 | - this is already possible on native mobile apps such as [Starbucks'](https://play.google.com/store/apps/details?id=com.starbucks.mobilecard), [the UK Home Office's Document Check app](https://play.google.com/store/apps/details?id=uk.gov.HomeOffice.ho1) and the [Dutch government's CoronaCheck app](https://play.google.com/store/apps/details?id=nl.rijksoverheid.ctr.holder). 11 | - increasing the screen brightness can help illuminate a user's facial features, improving the viability of certain application that rely on the front facing camera (e.g., [make up mirror](https://play.google.com/store/apps/details?id=mmapps.mirror.pro&hl=en&gl=US) style apps, and applications that can scan people's facial features to perform some particular action). 12 | 13 | ## Interested partners 14 | 15 | - authenticates users online for remote onboarding and verification, as well as kiosks inside banks and civic institutions. It also provides authentication for users in physical access settings. 16 | - automates anesthesia charting. Increasing the screen brightness would allow customers to quickly enter "monitoring mode" where their laptop essentially becomes a patient vitals monitor display. In this mode, they'd like to present the option of increasing brightness. Additionally, there is a planned feature involving scanning barcodes on screens as a means of quickly opening a case on another device. 17 | 18 | ## Open design issues 19 | 20 | The following issues remain open for discussion: 21 | - should UAs be free to limit the maximum brightness level and/or do other things like increase the contrast? 22 | - Should this be mobile first/only? (i.e., not worry about external displays)? 23 | - Should this trigger `prefers-contrast: more` in [CSS Media Queries](https://drafts.csswg.org/mediaqueries-5/#prefers-contrast)? 24 | - From [https://github.com/w3c/devicesensors-wg/issues/51](https://github.com/w3c/devicesensors-wg/issues/51) 25 | - Brightness levels 26 | - How bright is too bright? Consider 100% brightness with HDR displays, for example. 27 | - Take a discrete or continuous value? 28 | - Related to whether script should be allowed to reduce brightness. 29 | - When dropping a screen brightness request 30 | - What about external displays? Do UAs need to keep track of levels for each display? 31 | 32 | ## Goals 33 | 34 | - Provide the ability to request an increase to the display's brightness. This could be a UA-controlled maximum (which *could* be the maximum display brightness), either indefinitely or for a period of time. 35 | - Provide the ability to release the request so that the device's brightness returns to its pre-request value (i.e., hand back control to OS). 36 | - Handle error or low battery cases, where such requests are denied or not possible. For privacy, the API must not make it possible to determine whether a request failed due to low battery. 37 | 38 | ## Non-goals 39 | 40 | - Reading the current screen brightness level. 41 | - Adjusting the display brightness level to arbitrary values (absolute or relative). 42 | - [\ integration to allow, e.g., granular brightness control](https://github.com/w3c/screen-wake-lock/issues/129#issuecomment-926603108) is an instance of the above. This is most likely better handled elsewhere and should probably be a UA-specific control. 43 | 44 | ## Proposed Solutions 45 | 46 | The following represents some rough proposals that could address the use cases using various web technologies. 47 | 48 | We present them here only to foster discussion, and the working group has not settled on any particular one. We are open to feedback to pursue any of the proposals below. Or, if there is a better alternative solution we have not considered, we would be open to hearing it! 49 | 50 | ### Screen IDL interface extension 51 | 52 | >🆕 This API shape is currently being experimented with. 53 | >For WIP spec draft and Chromium CL, see https://github.com/beaufortfrancois/screen-brightness 54 | 55 | Extend the [`Screen` interface](https://drafts.csswg.org/cssom-view/#the-screen-interface) with a new operation, inspired by the [Wake Lock API](https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel). Something like: 56 | 57 | ```webidl 58 | [SecureContext] 59 | partial interface Screen { 60 | Promise requestBrightnessIncrease(); 61 | }; 62 | 63 | interface ScreenBrightnessSentinel { 64 | Promise release(); 65 | }; 66 | ``` 67 | 68 | Proposed usage: 69 | 70 | ```javascript 71 | myButton.addEventListener("click", async () => { 72 | try { 73 | const sentinel = await screen.requestBrightnessIncrease(); 74 | console.log("The display's brightness level has increased"); 75 | // …and release it after 5s. 76 | window.setTimeout(() => { 77 | await sentinel.release(); 78 | }, 5000); 79 | } catch (e) { 80 | console.error(e); 81 | } 82 | }); 83 | ``` 84 | 85 | ### Screen Wake Lock integration 86 | 87 | The idea was to extend the existing Screen Wake Lock API and tie the change in brightness to a `WakeLockSentinel`. Something like: 88 | 89 | ``` javascript 90 | const lock = await navigator.wakeLock.request({ increaseBrightness: true }); 91 | ``` 92 | 93 | This was considered for a long time until the [2021-11-17 DAS WG meeting to discuss the topic](https://www.w3.org/events/meetings/0f623aa1-2026-4366-846b-c2faedda4180). 94 | 95 | ### `navigator.screenBrightness` 96 | 97 | The API proposed there had a larger surface that allowed reading the brightness value (leading to potential fingerprinting issues). Originally proposed in [WICG issue 17](https://github.com/WICG/proposals/issues/17). 98 | 99 | ### `requestFullscreen()` integration 100 | 101 | The idea to integrate with `Element.requestFullscreen()`, to do something like: 102 | 103 | ```webidl 104 | partial dictionary FullscreenOptions { 105 | boolean increaseBrightness = false; 106 | }; 107 | ``` 108 | 109 | Proposed usage: 110 | 111 | ```javascript 112 | myButton.addEventListener("click", async () => { 113 | try { 114 | await document.body.requestFullscreen({ increaseBrightness: true }); 115 | console.log("The display's brightness level has increased"); 116 | } catch (e) { 117 | console.error(e); 118 | } 119 | }); 120 | ``` 121 | 122 | To take advantage of existing UA privacy mitigations and UX indications that would show to the user that a web application is increasing the brightness, and leaving full screen mode would make it clear that the UA should stop increasing the device's screen's brightness level. 123 | See [whatwg/fullscreen](https://fullscreen.spec.whatwg.org/) issues [185](https://github.com/whatwg/fullscreen/issues/185) and [198](https://github.com/whatwg/fullscreen/issues/198). 124 | 125 | ### getUserMedia() integration 126 | 127 | Add something to `getUserMedia()` to bundle the request for brightness into the media capture request itself. 128 | 129 | This is complicated because this feature is not doing media capture (and there is no `MediaStream` to get out of screen brightness), and the need to ask for camera permission before, e.g., entering full screen mode [complicates some use cases](https://github.com/w3c/screen-wake-lock/issues/129#issuecomment-858790397). 130 | 131 | ### CSS property 132 | 133 | Some form of "scannable element" property. When an element with said property is visible, the UA would take care of increasing the brightness level. 134 | 135 | *Note: this is the least hashed out proposal at this point. It is unclear how this would work with zoom, permissions, low-battery mode, what happens when an element scrolls in/out of view, or even how to mitigate something like* 136 | 137 | ``` html 138 | * 139 | ``` 140 | 141 | ## Security considerations 142 | 143 | - The API is available to secure browsing contexts. 144 | 145 | - The screen brightness can be controlled only in response to a user gesture to ensure user retain control over their screen brightness. This prevents a situation where a site increases screen brightness every time the system or user overrides it manually. 146 | 147 | - If the page visibility becomes hidden after screen brightness has been increased, the screen brightness should be restored automatically. 148 | 149 | - To avoid possible user fingerprinting issues, when the request to control screen brightness is denied, a site should not be able to detect the exact reason why it happened. In other words, a generic `NotAllowedError` DOMException should be raised when there is no user gesture or battery level is too low for instance. 150 | 151 | - If the screen brightness is at its maximum and a site requests a brighter screen, the request should succeed anyway so that it can't infer the screen brightness. 152 | 153 | ## Past discussions 154 | - https://github.com/WICG/proposals/issues/17 155 | - https://github.com/w3c/screen-wake-lock/issues/129 156 | - https://github.com/w3c/devicesensors-wg/issues/51 157 | - https://www.w3.org/2021/11/17-dap-minutes.html 158 | - https://twitter.com/quicksave2k/status/1534867198342311936 (❤️ from web developers) 159 | 160 | ## Review requests 161 | - [CSSWG](https://github.com/w3c/csswg-drafts/issues/6990) 162 | - [@tabatkins](https://github.com/w3c/csswg-drafts/issues/6990#issuecomment-1022678458) - in favour of a permissioned JS API over CSS property 163 | - [Mozilla review](https://github.com/mozilla/standards-positions/issues/623) - in favour of similar solution to wake lock, i.e. Screen IDL interface extension with `requestBrightnessIncrease` 164 | - [WebKit review](https://github.com/WebKit/standards-positions/issues/19) 165 | - [Review feedback](https://github.com/w3c/screen-wake-lock/issues/335) 166 | -------------------------------------------------------------------------------- /explainer.md: -------------------------------------------------------------------------------- 1 | # Screen Wake Lock API 2 | 3 | ## Introduction 4 | The **Screen Wake Lock API** allows web applications to prevent a device's 5 | screen from dimming and locking. 6 | 7 | See also: 8 | * [The current specification](https://w3c.github.io/screen-wake-lock/) 9 | * [web.dev article](https://web.dev/wakelock/) on the Screen Wake Lock API 10 | 11 | ## Why? 12 | To avoid draining the battery, most devices quickly go to sleep when left idle. 13 | While this is fine most of the time, some applications need to keep the screen 14 | awake to complete their work. For example: 15 | 16 | * A recipe website that keeps the screen on while you are cooking. 17 | * A web page that presents a bar code, which has to be physically scanned by 18 | another person. 19 | * A web page that provides monitoring or dashboard-style functionality where the 20 | screen must be on at all times. 21 | * A web-based presentation app that keeps the screen on during a presentation. 22 | 23 | Without this API, web developers have had to rely on libraries such as 24 | [NoSleep.js](https://github.com/richtr/NoSleep.js), which essentially added a 25 | [small 26 | video](https://github.com/richtr/NoSleep.js/blob/eaf52afd1dfbb80145b4a39f3ec29307b80ab154/src/index.js#L37-L57) 27 | to a page to keep the display on. 28 | 29 | > Recent NoSleep.js releases have added support for the Screen Wake Lock API. 30 | 31 | The purpose of this specification is to allow sites to be explicit about when 32 | they want to acquire a wake lock so that browsers can provide better automated 33 | and manual controls to prevent intentional and incidental issues. 34 | 35 | ## Non-goals 36 | A previous iteration of this spec included both Screen and System wake locks, 37 | which prevented the CPU from entering a deep power state. The latter has been 38 | moved to a separate spec, and is out of scope for this explainer. For more 39 | context, see: 40 | * [Anyone implementing "system" 41 | lock?](https://github.com/w3c/screen-wake-lock/issues/232) 42 | * [Break specification into 43 | levels](https://github.com/w3c/screen-wake-lock/issues/253) 44 | * [Convert to purely screen wake 45 | lock](https://github.com/w3c/screen-wake-lock/pull/255) 46 | 47 | ## API 48 | Users can request a screen wake lock, and if the request succeeds it can be 49 | either manually released later or released automatically by the platform due to 50 | OS-specific policies that might be in place. The code looks like this: 51 | 52 | ```js 53 | const lock = await navigator.wakeLock.request("screen"); 54 | 55 | lock.addEventListener("release", doSomething); 56 | 57 | // Later, check and release the lock if necessary. 58 | if (lock.released === false) { 59 | await lock.release(); 60 | } 61 | ``` 62 | 63 | ### Requesting permission to use WakeLocks 64 | To use the API, one must request access via 65 | `navigator.wakeLock.request("screen")` (`"screen"` is optional). This 66 | returns a promise which, if allowed by the user, resolves with a 67 | `WakeLockSentinel`. 68 | 69 | ```js 70 | let sentinel; 71 | try { 72 | sentinel = await navigator.wakeLock.request("screen") 73 | } catch (err) { 74 | // Access denied, or something went wrong. 75 | } 76 | ``` 77 | 78 | ### WakeLockSentinel 79 | A `WakeLockSentinel` object provides a handle to the lock that has been 80 | acquired. 81 | 82 | `WakeLockSentinel` has two read-only attributes for introspection: `released` 83 | indicates whether the lock has already been released, `type` returns the lock's 84 | type (which is always _"screen"_). 85 | 86 | The `WakeLockSentinel`'s `.release()` method is used to release the platform 87 | wake lock. It asynchronously dispatches a _"release"_ event that one can listen 88 | for in order to know that the lock is no longer being held. 89 | 90 | The lock might also be released automatically by the platform without 91 | `.release()` being called (for example, when the page is no longer visible). The 92 | _"release_" event is still emitted the same way. 93 | 94 | ## Security considerations 95 | * To avoid possible user fingerprinting issues, `WakeLock.prototype.request()` 96 | does not indicate to API users whether the actual call to obtain a lock from 97 | the operating system has succeeded or not. In other words, successful 98 | `WakeLock.prototype.request()` calls might be granted, but are not guaranteed 99 | to keep the screen awake. Ultimately, it is up to the browser and/or operating 100 | system if a lock is honored or not. 101 | 102 | * Screen Wake Locks can only be acquired and held if the document is visible. If 103 | `WakeLock.request()` is called while the document is hidden, the request will 104 | be denied with a `NotAllowedError`. If the page is hidden after a lock has 105 | been acquired, it will be released automatically. 106 | 107 | * Screen Wake Locks can cause various device components such as display or CPU 108 | to operate at higher power levels than they otherwise would. This can lead to 109 | undesirable effects such as faster than normal battery charge depletion. This 110 | is particularly relevant to mobile devices, which may not have a stationary 111 | power source readily available. 112 | 113 | ## Stakeholder Feedback / Opposition 114 | * Chromium has been shipping this API by default to users since version 84. 115 | * Mozilla has deemed this specification [worth 116 | prototyping](https://github.com/mozilla/standards-positions/pull/299). 117 | * Apple is not a part of the Devices and Sensors WG, but voiced 118 | [concerns](https://lists.webkit.org/pipermail/webkit-dev/2020-February/031081.html) 119 | about the impact this API can have on battery life. 120 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Screen Wake Lock API 7 | 8 | 10 | 61 | 62 | 63 |
64 |

65 | This document specifies an API that allows web applications to request 66 | a screen wake lock. Under the right conditions, and if allowed, the 67 | screen wake lock prevents the system from turning off a device's 68 | screen. 69 |

70 |
71 |
72 |

73 | Implementors need to be aware that this specification is extremely 74 | unstable. Implementors who are not taking part in the 75 | discussions will find the specification changing out from under them in 76 | incompatible ways. Vendors interested in implementing this 77 | specification before it eventually reaches the Candidate Recommendation 78 | phase should subscribe to the 80 | repository on GitHub and take part in the discussions. 81 |

82 |
83 |
84 |

85 | Introduction 86 |

87 |

88 | Modern operating systems achieve longer battery life by implementing 89 | aggressive power management, meaning that shortly after the lack of 90 | user activity, a host device may lower the screen brightness, turn the 91 | screen off and even let the CPU go into a deep power state, limiting 92 | power usage as much as possible. 93 |

94 |

95 | Though this is great for prolonged battery life, it can sometime hinder 96 | some use cases such as scanning a barcode, reading an ebook, following 97 | a recipe, presenting to an audience, and so on. See also 98 | [[[wake-lock-use-cases]]]. 99 |

100 |

101 | A wake lock will generally prevent something from happening, but UAs 102 | (and the underlying OS) may time limit a wake lock given the battery 103 | status (wall power connected, discharging, low battery level), or even 104 | disallow wake locks in the case a power saving mode is activated. 105 |

106 |
107 |
108 |

109 | Wake Locks 110 |

111 |

112 | This specification defines the following wake lock 113 | type: 114 |

115 |
    116 |
  1. A screen wake lock prevents the screen 117 | from turning off. Only visible documents can acquire the screen wake 118 | lock. 119 |
  2. 120 |
121 |

122 | In the API, the [=wake lock types=] are represented by the 123 | {{WakeLockType}} enum values. 124 |

125 |

126 | Other specifications might define different wake lock types. 127 |

128 |
129 |
130 |

131 | Policy control 132 |

133 |

135 | The Screen Wake Lock API defines a [=policy-controlled feature=] 136 | identified by the string `"screen-wake-lock"`. Its [=policy-controlled 137 | feature/default allowlist=] is `'self'`. 138 |

139 | 164 |
165 |
166 |

167 | Permissions and user prompts 168 |

169 |

170 | The [[PERMISSIONS]] API provides a uniform way for websites to request 171 | permissions from users and query which permissions they have. 172 |

173 |

174 | A user agent can deny a wake lock of a 176 | particular wake lock type for a particular {{Document}} by any 177 | implementation-specific reason, such as platform setting or user 178 | preference. 179 |

180 |

181 | It is RECOMMENDED that a user agent show some form of unobtrusive 182 | notification that informs the user when a wake lock is active, as well 183 | as provides the user with the means to [=screen wake lock permission 184 | revocation algorithm|block=] the ongoing operation, or simply dismiss 185 | the notification. 186 |

187 |
188 |

189 | The `"screen-wake-lock"` powerful feature 190 |

191 |

192 | The `"screen-wake-lock"` powerful feature enables the 193 | capability defined by this specification. 194 |

195 |
196 |
197 |

198 | Permission algorithms 199 |

200 |

201 | The `"screen-wake-lock"` powerful feature defines a [=powerful 202 | feature/permission revocation algorithm=]. To invoke the Screen 203 | Wake Lock permission revocation algorithm, run these steps: 204 |

205 |
    206 |
  1. Let |document:Document| be the [=current global object=]'s 207 | [=associated Document=]. 208 |
  2. 209 |
  3. Let |lockList| be 210 | |document|.{{Document/[[ActiveLocks]]}}["`screen`"]. 211 |
  4. 212 |
  5. [=list/For each=] |lock:WakeLockSentinel| in |lockList|: 213 |
      214 |
    1. Run release a wake lock with |document|, |lock|, and 215 | {{WakeLockType/"screen"}}. 216 |
    2. 217 |
    218 |
  6. 219 |
220 |
221 |
222 |
223 |

224 | Concepts 225 |

226 |

227 | The task source for the tasks mentioned in this 228 | specification is the screen wake lock task source. 229 |

230 |

231 | The term platform wake lock refers to platform interfaces 232 | with which the user agent interacts to query state and acquire and 233 | release a wake lock. 234 |

235 |

236 | A platform wake lock can be defined by the underlying platform 237 | (e.g. in a native wake lock framework) or by the user agent, if it has 238 | direct hardware control. 239 |

240 |
241 |
242 |

243 | Extensions to the `Document` interface 244 |

245 |
246 |

247 | Internal slots 248 |

249 | 250 | 251 | 252 | 255 | 258 | 261 | 262 | 263 | 264 | 265 | 268 | 272 | 277 | 278 | 279 |
253 | Internal slot 254 | 256 | Initial value 257 | 259 | Description 260 |
266 | [[\ActiveLocks]] 267 | 269 | An ordered map mapping wake lock types to empty 270 | lists. 271 | 273 | An ordered map of wake lock types to a 274 | list of {{WakeLockSentinel}} objects associated with 275 | this {{Document}}. 276 |
280 |
281 |
282 |
283 |

284 | Extensions to the `Navigator` interface 285 |

286 |
287 |         [SecureContext]
288 |         partial interface Navigator {
289 |           [SameObject] readonly attribute WakeLock wakeLock;
290 |         };
291 |       
292 |
293 |
294 |

295 | The WakeLock interface 296 |

297 |

298 | The {{WakeLock}} interface allows a document to acquire a [=screen wake 299 | lock=]. 300 |

301 |
302 |         [SecureContext, Exposed=(Window)]
303 |         interface WakeLock {
304 |           Promise<WakeLockSentinel> request(optional WakeLockType type = "screen");
305 |         };
306 |       
307 |
308 |

309 | The request() method 310 |

311 |

312 | The request(|type:WakeLockType|) method steps are: 313 |

314 |
    315 |
  1. Let |document:Document| be [=this=]'s [=relevant global 316 | object=]'s [=associated Document=]. 317 |
  2. 318 |
  3. If 319 | |document| is not [=Document/fully active=], return [=a promise 320 | rejected with=] with a {{"NotAllowedError"}} {{DOMException}}. 321 |
  4. 322 |
  5. If 324 | |document| is not [=allowed to use=] the [=policy-controlled 325 | feature=] named "`screen-wake-lock`", return [=a promise rejected 326 | with=] a {{"NotAllowedError"}} {{DOMException}}. 327 |
  6. 328 |
  7. If 329 | the user agent denies the wake lock of this |type| for 330 | |document|, return [=a promise rejected with=] a 331 | {{"NotAllowedError"}} {{DOMException}}. 332 |
  8. 333 |
  9. If 334 | |document|'s [=Document/visibility state=] is "`hidden`", return [=a 335 | promise rejected with=] {{"NotAllowedError"}} {{DOMException}}. 336 |
  10. 337 |
  11. Let |promise:Promise| be [=a new promise=]. 338 |
  12. 339 |
  13. Run the following steps in parallel: 340 |
      341 |
    1. Let |state:PermissionState| be the result of requesting 342 | permission to use "`screen-wake-lock`". 343 |
    2. 344 |
    3. If |state| is 345 | {{PermissionState/"denied"}}, then: 346 |
        347 |
      1. 348 | Queue a global task on the screen wake lock task 349 | source given |document|'s relevant global object 350 | to reject |promise| with a {{"NotAllowedError"}} 351 | {{DOMException}}. 352 |
      2. 353 |
      3. Abort these steps. 354 |
      4. 355 |
      356 |
    4. 357 |
    5. 358 | Queue a global task on the screen wake lock task 359 | source given |document|'s relevant global object to 360 | run these steps: 361 |
        362 |
      1. If |document| is not [=Document/fully active=], then: 363 |
          364 |
        1. Reject |promise| with a {{"NotAllowedError"}} 365 | {{DOMException}}. 366 |
        2. 367 |
        3. Abort these steps. 368 |
        4. 369 |
        370 |
      2. 371 |
      3. If |document|'s [=Document/visibility state=] is 372 | "`hidden`", then: 373 |
          374 |
        1. Reject |promise| with a {{"NotAllowedError"}} 375 | {{DOMException}}. 376 |
        2. 377 |
        3. Abort these steps. 378 |
        4. 379 |
        380 |
      4. 381 |
      5. If |document|.{{Document/[[ActiveLocks]]}}["`screen`"] 382 | [=list/is empty=], then invoke the following steps in 383 | parallel: 384 |
          385 |
        1. Invoke acquire a wake lock with 386 | {{WakeLockType/"screen"}}. 387 | 395 |
        2. 396 |
        397 |
      6. 398 |
      7. Let |lock:WakeLockSentinel| be a new {{WakeLockSentinel}} 399 | object with its {{WakeLockSentinel/type}} attribute set to 400 | |type|. 401 |
      8. 402 |
      9. [=List/Append=] |lock| to 403 | |document|.{{Document/[[ActiveLocks]]}}["`screen`"]. 404 |
      10. 405 |
      11. Resolve |promise| with |lock|. 406 |
      12. 407 |
      408 |
    6. 409 |
    410 |
  14. 411 |
  15. Return |promise|. 412 |
  16. 413 |
414 |
415 |
416 |
417 |

418 | The WakeLockSentinel interface 419 |

420 |
421 |         [SecureContext, Exposed=(Window)]
422 |         interface WakeLockSentinel : EventTarget {
423 |           readonly attribute boolean released;
424 |           readonly attribute WakeLockType type;
425 |           Promise<undefined> release();
426 |           attribute EventHandler onrelease;
427 |         };
428 |       
429 |

430 | A {{WakeLockSentinel}} object provides a handle to a platform wake 431 | lock, and it holds on to it until it is either manually released or 432 | until the underlying platform wake lock is released. Its 433 | existence keeps a platform wake lock for a given wake lock 434 | type active, and releasing all {{WakeLockSentinel}} instances of a 435 | given wake lock type will cause the underlying platform wake 436 | lock to be released. 437 |

438 | 444 |
445 |

446 | Internal slots 447 |

448 |

449 | {{WakeLockSentinel}} instances are created with the following 450 | internal 452 | slots: 453 |

454 | 455 | 456 | 457 | 460 | 463 | 466 | 467 | 468 | 469 | 470 | 473 | 476 | 479 | 480 | 481 |
458 | Internal slot 459 | 461 | Initial value 462 | 464 | Description (non-normative) 465 |
471 | [[\Released]] 472 | 474 | `false` 475 | 477 | Whether the given {{WakeLockSentinel}} has been released. 478 |
482 |
483 |
484 |

485 | The released attribute 486 |

487 |

488 | The {{WakeLockSentinel/released}} getter steps are to return 489 | [=this=].{{WakeLockSentinel/[[Released]]}}. 490 |

491 | 496 |
497 |
498 |

499 | The type attribute 500 |

501 |

502 | The {{WakeLockSentinel/type}} getter steps are to return [=this=]'s 503 | wake lock type. 504 |

505 |
506 |
507 |

508 | The release() method 509 |

510 |

511 | The {{WakeLockSentinel/release()}} method steps are: 512 |

513 |
    514 |
  1. If this's {{WakeLockSentinel/[[Released]]}} is `false`, 515 | then run release a wake lock with |lock:WakeLockSentinel| set 516 | to this and |type:WakeLockType| set to the value of 517 | this's {{WakeLockSentinel/type}} attribute. 518 |
  2. 519 |
  3. Return a promise resolved with `undefined`. 520 |
  4. 521 |
522 |
523 |
524 |

525 | The onrelease attribute 526 |

527 |

528 | The {{WakeLockSentinel/onrelease}} attribute is an event handler 529 | IDL attribute for the "onrelease" event 530 | handler, whose event handler event type is 531 | "release". 532 |

533 |

534 | It is used to notify scripts that a given {{WakeLockSentinel}} 535 | object's handle has been released, either due to the 536 | {{WakeLockSentinel/release()}} method being called or because the 537 | wake lock was released by the user agent. 538 |

539 | 546 | 550 |
551 |
552 |

553 | Garbage collection 554 |

555 |

556 | While a {{WakeLockSentinel}} object has one or more event listeners 557 | registered for "release", and the 558 | {{WakeLockSentinel}} object hasn't already been released, there MUST 559 | be a strong reference from the {{Window}} object that the 560 | {{WakeLockSentinel}} object's constructor was invoked from to the 561 | {{WakeLockSentinel}} object itself. 562 |

563 |

564 | While there is a task queued by an {{WakeLockSentinel}} object on the 565 | screen wake lock task source, there MUST be a strong reference 566 | from the {{Window}} object that the {{WakeLockSentinel}} object's 567 | constructor was invoked from to that {{WakeLockSentinel}} object. 568 |

569 |
570 |
571 |
572 |

573 | The WakeLockType enum 574 |

575 |

576 | For the purpose of wake lock type description, this specification 577 | defines the following enumeration to represent [=wake lock types=]: 578 |

579 |
580 |         enum WakeLockType { "screen" };
581 |       
582 |
583 |
584 | screen 585 |
586 |
587 | Screen wake lock type. 588 |
589 |
590 |
591 |
592 |

593 | Managing Wake Locks 594 |

595 |

596 | This section applies to each wake lock type equally and 597 | independently, unless a particular wake lock type is explicitly 598 | mentioned. 599 |

600 |

601 | The user agent acquires the wake 603 | lock by requesting the underlying operating system to apply the 604 | lock. A possible return value of the request to the underlying 605 | operating system is not checked. In other words, user agents 606 | MUST treat wake lock acquisition as advisory-only. 607 |

608 |

609 | Conversely, the user agent releases the wake lock 611 | by requesting the underlying operating system to no longer apply the 612 | wake lock. The lock is considered released only when the request to the 613 | operating system succeeds. 614 |

615 |

616 | The wake lock is applicable if the state of 618 | the operating system permits application of the lock (e.g. there is 619 | sufficient battery charge). 620 |

621 |

622 | The screen wake lock MUST NOT be applicable after the 623 | screen is manually switched off by the user until it is switched on 624 | again. 625 |

626 | 633 |
634 |

635 | Auto-releasing wake locks 636 |

637 |

638 | A user agent may release a wake lock at any time. For example, 639 | when: 640 |

641 |
    642 |
  • It detects abnormal operation: such as infinite loops and tasks 643 | exceeding imposed time limits (if any). 644 |
  • 645 |
  • Battery is considered low and discharging. 646 |
  • 647 |
  • The user turns on some kind of device power conservation mode. 648 |
  • 649 |
  • The operating system is configured to dim or turn off the screen 650 | based on the user presence state. 651 |
  • 652 |
653 |
654 |
655 |

656 | Handling document loss of full activity 657 |

658 |

659 | When a {{Document}} |document:Document| becomes no longer 660 | [=Document/fully active=], the user agent must run these steps: 661 |

662 |
    663 |
  1. [=list/For each=] |lock:WakeLockSentinel| in 664 | |document|.{{Document/[[ActiveLocks]]}}["`screen`"]: 665 |
      666 |
    1. Run release a wake lock with |document|, |lock|, and 667 | {{WakeLockType/"screen"}}. 668 |
    2. 669 |
    670 |
  2. 671 |
672 |
673 |
674 |

675 | Handling document loss of visibility 676 |

677 |

678 | This specification defines the following [=page visibility change 679 | steps=] with [=Document/visibility state=] |state| and 680 | |document:Document|: 681 |

682 |
    683 |
  1. If |state| is not "`hidden`", abort these steps. 684 |
  2. 685 |
  3. [=list/For each=] |lock:WakeLockSentinel| in 686 | |document|.{{Document/[[ActiveLocks]]}}["`screen`"]: 687 |
      688 |
    1. Run release a wake lock with |document|, |lock|, and 689 | {{WakeLockType/"screen"}}. 690 |
    2. 691 |
    692 |
  4. 693 |
694 |
695 |
696 |

697 | Acquire wake lock algorithm 698 |

699 |

700 | To acquire a wake lock for a given |type:WakeLockType|, 701 | run these steps: 702 |

703 |
    704 |
  1. If the wake lock for type |type| is not applicable, abort 705 | these steps. 706 |
  2. 707 |
  3. Ask the underlying operating system to acquire the wake 708 | lock of type |type|. 709 |
  4. 710 |
711 |
712 |
713 |

714 | Release wake lock algorithm 715 |

716 |

717 | To release a wake lock for a given |document:Document|, 718 | |lock:WakeLockSentinel|, and |type:WakeLockType|, run these steps: 719 |

720 |
    721 |
  1. If |document|.{{Document/[[ActiveLocks]]}}[|type|] does not 722 | contain |lock|, abort these steps. 723 |
  2. 724 |
  3. Remove |lock| from 725 | |document|.{{Document/[[ActiveLocks]]}}[|type|]. 726 |
  4. 727 |
  5. If |document|.{{Document/[[ActiveLocks]]}}[|type|] [=list/is 728 | empty=], then run the following steps in parallel: 729 |
      730 |
    1. Ask the underlying operating system to release the wake 731 | lock of type |type| and let |success:boolean| be `true` if 732 | the operation succeeded, or else `false`. 733 |
    2. 734 |
    3. If |success| is `true` and |type| is `"screen"` run the 735 | following: 736 |
        737 |
      1. Reset the platform-specific inactivity timer after which 738 | the screen is actually turned off. 739 |
      2. 740 |
      741 | 745 |
    4. 746 |
    747 |
  6. 748 |
  7. Set |lock|'s {{WakeLockSentinel/[[Released]]}} to `true`. 749 |
  8. 750 |
  9. 751 | Fire an event named "release" at |lock|. 752 |
  10. 753 |
754 |
755 |
756 |
757 |

758 | Security and privacy considerations 759 |

760 |

761 | Screen wake locks can cause various device components - particularly 762 | the display - to operate at higher power levels than they otherwise 763 | would. This can lead to undesirable effects, such as preventing the 764 | device from automatically locking itself and faster battery depletion. 765 | Faster battery depletion is of particular concern for mobile devices, 766 | which often don't have a stationary power source readily available. 767 | Complete battery depletion at an unexpected time can lead to inability 768 | of the user to make or receive calls and use network services, 769 | including the emergency call service. 770 |

771 |

772 | Implementations MAY ignore requests for screen wake lock if, for 773 | example, the battery capacity is low, or the user has put their device 774 | in a power-saving mode. 775 |

776 |

777 | It is RECOMMENDED that a user agent provide some UI or indicator that 778 | allows the user to know when a screen wake lock is active. Providing 779 | such a UI could help end users to identify if a particular web 780 | application is having a negative energy impact on the device, and allow 781 | them to take action if so desired. 782 |

783 |
784 |
785 |

786 | Examples 787 |

788 |
789 |         function tryKeepScreenAlive(minutes) {
790 |           navigator.wakeLock.request("screen").then(lock => {
791 |             setTimeout(() => lock.release(), minutes * 60 * 1000);
792 |           });
793 |         }
794 | 
795 |         tryKeepScreenAlive(10);
796 |       
797 |

798 | This example allows the user to request a screen wake lock by clicking 799 | on a checkbox, but updates the checkbox checked state in case the wake 800 | lock state changes: 801 |

802 |
803 |         const checkbox = document.createElement("input");
804 |         checkbox.setAttribute("type", "checkbox");
805 |         document.body.appendChild(checkbox);
806 | 
807 |         const sentinel = await navigator.wakeLock.request("screen");
808 |         checkbox.checked = !sentinel.released;
809 |         sentinel.onrelease = () => checkbox.checked = !sentinel.released;
810 |       
811 |

812 | In this example, two different wake lock requests are created and 813 | released independently: 814 |

815 |
816 |         let lock1 = await navigator.wakeLock.request("screen");
817 |         let lock2 = await navigator.wakeLock.request("screen");
818 | 
819 |         lock1.release();
820 |         lock2.release();
821 |       
822 |
823 |
824 |

825 | This specification defines conformance criteria for a single product: a 826 | user agent that implements the interfaces that it contains. 827 |

828 |
829 |
830 |

831 | Acknowledgments 832 |

833 |

834 | We would like to offer our sincere thanks to Mounir Lamouri, Sergey 835 | Konstantinov, Matvey Larionov, Dominique Hazael-Massieux, Domenic 836 | Denicola, Thomas Steiner, Anne van Kesteren for their contributions to 837 | this work. 838 |

839 |
840 |
841 |

842 | Changes 843 |

844 |

845 | This section documents the changes since previous publications. 846 |

847 |
848 |

849 | Changes since the 14 December 2017 CR 850 |

851 |
    852 |
  • Convert the document to purely screen wake lock, and move system 853 | lock to a new specification. 854 |
  • 855 |
  • Rewrite user-visible API. 856 |
  • 857 |
  • Add an if aborted step to WakeLock.request() 858 | to deal with hidden documents. 859 |
  • 860 |
  • Add an IDL Index. 861 |
  • 862 |
  • Remove duplicate normative statements. 863 |
  • 864 |
  • Modernize the examples. 865 |
  • 866 |
  • Use internal slots instead of prose. 867 |
  • 868 |
  • Add info on when the user agent may release a wake lock. 869 |
  • 870 |
  • Handle document visibility. 871 |
  • 872 |
  • Make `ScreenWakeLock` constructable. 873 |
  • 874 |
  • Integrate optional permission prompting. 875 |
  • 876 |
  • Handle loss of full activity, as well as running in workers. 877 |
  • 878 |
  • Rewrite the introduction section. 879 |
  • 880 |
  • Rename Feature Policy to Permissions Policy. 881 |
  • 882 |
  • Add WakeLockSentinel.released. 883 |
  • 884 |
  • Define a task source for tasks in this specification. 885 |
  • 886 |
887 |
888 |
889 |
890 |
891 | 892 | 893 | -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": 43696, 3 | "contacts": [ 4 | "himorin" 5 | ], 6 | "shortName": "screen-wake-lock", 7 | "repo-type": "rec-track", 8 | "policy": "open" 9 | } 10 | --------------------------------------------------------------------------------