This document specifies an API that allows web applications to request a wake lock. A wake lock prevents some aspect of the device from entering a power-saving state (e.g., preventing the system from turning off the screen).
Implementors need to be aware that this specification is extremely unstable. Implementors who are not taking part in the discussions will find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the repository on GitHub and take part in the discussions.
A wake lock prevents some aspect of the device or operating system from entering a power-saving state.
This specification defines two wake lock types:
A user agent MAY deny wake lock of a particular type or all types on per-browsing context basis, and MUST do so in cases explicitly defined by this specification.
A user agent MAY check user settings or request user permission in order to decide whether it will deny wake lock of a particular type for a particular browsing context.
If the browsing context is not a top-level browsing context and its active document's origin is not the same as that of the active document of its top-level browsing context, the user agent MUST deny wake lock.
The same-origin requirement prevents unauthorized nested third-party content from requesting a wake lock on behalf of the top-level page.
An alternative approach could be requiring a permission as defined in [[!PERMISSIONS]] which would effectively delegate decisions about wake lock in nested browsing contexts to the user agent. The downside is that permission inheritance model is currently non-portable between implementations and sometimes inconsistent even within the same implementation. For more details see e.g. this Chromium design document.
For the purpose of wake lock type description, this specification defines the following enumeration:
enum WakeLockType { "screen", "system" };
partial interface Navigator { Promise<WakeLock> getWakeLock(WakeLockType type); };
For each Navigator object, there is a wake lock map
which contains a single wake lock promise for each wake
lock type. Each wake lock promise in the wake lock map
is a Promise object which holds a WakeLock. All
wake lock promises are initially set
to null
.
The getWakeLock()
method, when invoked with an argument
type, MUST run the following steps:
null
, return
wakeLockPromise and abort these steps.
When the user agent cannot synchronously determine if it will deny wake lock of the given type for the given browsing context, such as when user permission is required, the following deferred wake lock initialization procedure is performed asynchronously:
type
for this browsing context,
reject wakeLockPromise
and abort these steps.
type
in the
Realm of this Navigator object, and let
wakeLock
be that object.
wakeLockPromise
with wakeLock
.
The WakeLock interface allows the page to request wake locks of a particular type, to determine the current wake lock state and to receive notifications when the wake lock state is changed.
interface WakeLock : EventTarget { readonly attribute WakeLockType type; readonly attribute boolean active; attribute EventHandler onactivechange; WakeLockRequest createRequest(); };
activechange
. Fired when current wake lock
status indicated by the active
attribute changes.
To initialize a WakeLock object of type type, the following steps MUST be performed:
type
attribute to
type.
active
attribute to true
, otherwise
to false
.
Internally, each WakeLock object contains
request counter which is initially set to zero. Each time the
createRequest()
method is called on the object, the
request counter is increased by one.
A WakeLock object has an outstanding wake lock request when its request counter is greater than zero.
When the createRequest()
method is invoked, the following
steps MUST be performed:
interface WakeLockRequest { void cancel(); };
Each WakeLockRequest object has an implicit owner wake lock
reference to the WakeLock object through which this object
was created. When the cancel()
method is invoked, the
following steps MUST be performed:
cancel()
method has already been invoked on this
object, abort these steps.
wakeLock
be the object referred to by this object's
owner wake lock reference. Decrease wakeLock
's
request counter by one.
This section applies to each wake lock type equally and independently, unless a particular wake lock type is explicitly mentioned.
The user agent acquires the wake lock by requesting the underlying operating system to apply the lock. The lock is considered acquired only when the request to the operating system succeeds.
Conversely, the user agent releases the wake lock by requesting the underlying operating system to no longer apply the wake lock. The lock is considered released only when the request to the operating system succeeds.
A browsing context is requesting the wake lock of type
type if and only if the following procedure returns
true
:
null
, pending, or
rejected, return false
and abort these steps.
"screen"
and browsing
context's active document is hidden, return
false
and abort these steps.
true
,
otherwise return false
.
The wake lock is applicable if the state of the operating system permits application of the lock (e.g. there is sufficient battery charge).
The user agent MUST acquire the wake lock of type type when all of the following conditions become true:
The user agent MUST release the wake lock when any of the conditions above become false.
Whenever user agent acquires or releases a wake lock, the user agent MUST perform the following steps for each WakeLock object:
type
attribute is not equal
to type, abort these steps.
active
attribute and fires an
event named activechange
at the WakeLock
object.
In the task described above, the WakeLock objects's active
attribute MUST be set to true
if the wake lock has
been acquired or to false
if the wake lock has been
released.
Application of a wake lock causes various device components such as display or CPU to operate at higher power levels than they otherwise would. This can lead to undesirable and potentially dangerous effects such as excessive heating and faster than normal battery charge depletion. The latter is particularly relevant to mobile devices which may not have a stationary power source readily available. Complete battery depletion at an unexpected time can lead to inability of the user to make or receive calls and use network services, including the emergency call service. Implementations should consider preventing wake lock application if they determine that the remaining battery capacity is low.
This example acquires a screen wake lock and releases it after a while:
navigator.getWakeLock("screen").then(function(wakeLock) { var request = wakeLock.createRequest(); setTimeout(function() { request.cancel(); }, 1000); });
This example requests a screen wake lock and listens to wake lock state changes:
var request; navigator.getWakeLock("screen").then(function(wakeLock) { request = wakeLock.createRequest(); document.getElementById("wakeLockActive").innerHTML = wakeLock.active; wakeLock.onactivechange = function() { document.getElementById("wakeLockActive").innerHTML = wakeLock.active; }; });
In this example, two screen wake lock requests are created and cancelled independently:
var request1; navigator.getWakeLock("screen").then(function(wakeLock) { request1 = wakeLock.createRequest(); }); // ... var request2; navigator.getWakeLock("screen").then(function(wakeLock) { request2 = wakeLock.createRequest(); }); // ... request1.cancel(); request2.cancel();
The following concepts and interfaces are defined in [[!HTML]]:
The following concepts and interfaces are defined in [[!DOM]]:
The following concepts and interfaces are defined in [[!ECMASCRIPT]]:
The following concepts and interfaces are defined in [[!PAGE-VISIBILITY]]:
The use cases and requirements are documented in [[WAKE-LOCK-USE-CASES]].
This specification defines conformance criteria for a single product: a user agent that implements the interfaces that it contains.
The user agent MUST implement the APIs defined in this specification in a manner that conforms to the ECMAScript Bindings defined in [[!WEBIDL]].
We would like to offer our sincere thanks to Mounir Lamouri, Sergey Konstantinov, Matvey Larionov, Dominique Hazael-Massieux (via the HTML5Apps project) for their contributions to this work.