Copyright © 2019 W3C ® ( MIT , ERCIM , Keio , Beihang ). W3C liability , trademark and permissive document license rules apply.
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).
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
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.
This document was published by the Device APIs Working Group as an Editor's Draft.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-device-apis@w3.org ( archives ).
Please see the Working Group's implementation report .
Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This document is governed by the 1 March 2019 W3C Process Document .
Modern OSs achieve longer battery life by implementing aggressive power management, meaning that shortly after the lack of user activity, a host device may lower the screen brightness, turn the screen off and even let the CPU go into a deep power state, allowing to sip as little power as possible.
Though this is great for prolonged battery life, it can sometime hinder good, valid use-cases such as:
More use-cases can be found in Use Cases and Requirements .
A wake lock will generally prevent something from happening, but UAs (and the underlying OS) may time limit a wake lock given the battery status (wall power connected, discharging, low battery level), or even disallow wake locks in the case a power saving mode is activated.
Any active wake lock MUST also prevent the page from entering UA induced CPU suspension as defined by [ PAGE-LIFECYCLE ].
This specification defines the following wake lock types :
A
user
agent
can
deny
a
wake
lock
of
a
particular
wake
lock
type
for
a
particular
Document
by
any
implementation-specific
reason,
for
example,
a
user
or
platform
setting
or
preference.
The
Wake
Lock
API
defines
a
policy-controlled
feature
identified
by
the
string
"wake-lock"
.
Its
default
allowlist
is
["self"]
.
The [ PERMISSIONS ] API provides a uniform way for websites to request permissions from users and query which permissions they have.
It is recommended that a UA shows some form of unobtrusive notification that informs the user when a wake lock is active, as well as provides the user with the means to block the ongoing operation, or simply dismiss the notification.
WakeLockPermissionDescriptor
dictionary
The
"wake-lock"
powerful
feature
is
defined
as
follows:
The
permission
descriptor
type
is
represented
by
the
WakeLockPermissionDescriptor
dictionary
,
which
extends
the
PermissionDescriptor
with
a
type
member,
allowing
for
more
fine-grained
permissions.
dictionary WakeLockPermissionDescriptor : PermissionDescriptor {
WakeLockType type;
};
The
PermissionDescriptor
.
name
is
"wake-lock"
.
To block a permission , run these steps:
WakeLockPermissionDescriptor
.
"
denied
"
.
type
member.
[[
InstanceList
]]
:
To
obtain
permission
for
wake
lock
type
type
,
run
these
steps
in
parallel
.
This
async
algorithm
returns
either
"
granted
"
or
"
denied
"
.
WakeLockPermissionDescriptor
.
name
member
to
"
wake-lock
".
type
to
type
.
"
denied
"
.
state
.
"
prompt
"
,
run
the
following
steps:
"
denied
"
.
WakeLockType
enum
For the purpose of wake lock type description, this specification defines the following enumeration:
enum
WakeLockType
{
"
screen
"
,
"
system
"
};
screen
system
The term platform wake lock refers to platform interfaces with which the user agent interacts to query state and acquire and release a wake lock.
A platform wake lock can be defined by the underlying platform (e.g. in a native wake lock framework) or by the user agent, if it has direct hardware control.
Each platform wake lock (one per wake lock type ) has an associated state record with the following internal slots :
| Internal slot | Initial value | Description ( non-normative ) |
|---|---|---|
| [[InstanceList]] | The empty ordered set . |
A
ordered
set
of
instances.
|
| [[RequestCounter]] | 0. | The value indicates the amount of current requests for the wake lock type . |
WakeLock
interface
The
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.
WakeLock
[Constructor(WakeLockType type), SecureContext, Exposed=(DedicatedWorker, Window)]
interface WakeLock : EventTarget {
[Exposed=Window] static Promise<PermissionState> requestPermission(WakeLockType type);
readonly attribute WakeLockType type;
readonly attribute boolean active;
attribute EventHandler onactivechange;
Promise<void> request(optional WakeLockRequestOptions options);
};
| Internal slot | Description ( non-normative ) |
|---|---|
| [[requestPromise]] |
The
pending
promise
created
during
request()
.
|
To
create
and
initialize
a
object
of
type
type
,
the
following
steps
MUST
be
performed:
WakeLock
DedicatedWorkerGlobalScope
object
and
its
owner
set
is
empty
,
throw
a
"
NotAllowedError
"
DOMException
.
Window
object
and
the
document
's
browsing
context
is
null
,
throw
a
"
NotAllowedError
"
DOMException
.
wake-lock
",
throw
a
"
NotAllowedError
"
DOMException
.
NotAllowedError
"
DOMException
.
WakeLock
object.
[[
InstanceList
]]
.
true
,
otherwise
to
false
.
requestPermission()
static
method
The
requestPermission(
type
)
method,
when
invoked,
MUST
run
the
following
steps.
This
algorithm
resolves
with
either
"
granted
"
or
"
denied
"
.
type
attribute
When
getting,
the
type
attribute
returns
this
's
wake
lock
type
.
WakeLock
active
attribute
The
attribute
represents
whether
a
wake
lock
is
currently
acquired
by
the
active
instance.
WakeLock
onactivechange
attribute
A
's
WakeLock
onactivechange
attribute
is
an
EventHandler
with
the
corresponding
event
handler
event
type
of
activechange
.
Fired
when
current
wake
lock
status
indicated
by
the
active
attribute
changes.
WakeLockRequestOptions
dictionary
dictionary WakeLockRequestOptions {
AbortSignal?
AbortSignal? signal;
};
The
signal
member
is
used
to
abort
the
wake
lock
request.
request()
method
To
abort
the
request
steps
for
a
running
instance
of
request()
,
run
these
additional
steps:
[[
requestPromise
]]
to
undefined
.
request()
algorithm.
The
request()
method,
when
invoked,
MUST
run
the
following
steps:
[[
requestPromise
]]
is
not
undefined
,
reject
promise
with
a
"
InvalidStateError
"
DOMException
,
and
run
abort
the
request
steps
.
AbortError
"
DOMException
,
and
run
abort
the
request
steps
.
null
,
then
add
to
options
.
signal
:
[[
requestPromise
]]
to
promise.
"
denied
"
,
then
reject
promise
with
a
"
NotAllowedError
"
DOMException
,
and
run
abort
the
request
steps
.
DedicatedWorkerGlobalScope
object,
run
the
following
steps:
NotAllowedError
"
DOMException
,
and
run
abort
the
request
steps
.
"
screen
"
and
the
Document
of
the
top-level
browsing
context
is
hidden
,
reject
promise
with
a
"
NotAllowedError
"
DOMException
,
and
run
abort
the
request
steps
.
false
then
reject
promise
with
a
"
NotAllowedError
"
DOMException
,
and
run
abort
the
request
steps
.
void
.
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.
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 screen wake lock MUST NOT be applicable after the screen is manually switched off by the user until it is switched on again. Manually switching off the screen MUST NOT affect the applicability of the system wake lock .
A user agent may release a wake lock at any time it:
When the user agent determines that a responsible document of the current settings object is no longer fully active , it must run these steps:
"
screen
"
and
"
system
"
.
[[
InstanceList
]]
:
When
the
user
agent
determines
that
the
visibility
state
of
the
Document
of
the
top-level
browsing
context
changes,
it
must
run
these
steps:
Document
of
the
top-level
browsing
context
.
"visible"
,
abort
these
steps.
"
screen
"
.
[[
InstanceList
]]
:
WakeLock
object
lock
,
run
these
steps
in
parallel
:
type
.
false
.
true
if
the
platform
wake
lock
has
an
active
wake
lock
for
type
.
true
if
the
operation
succeeded,
or
else
false
.
active
,
set
lock
's
active
to
active
and
fire
an
event
named
"activechange"
at
lock
.
To
release
a
wake
lock
for
a
given
object
lock
,
run
these
steps
in
parallel
:
WakeLock
type
.
[[
requestPromise
]]
not
undefined
and
is
pending,
reject
it
with
an
"
AbortError
"
DOMException
and
abort
the
request
steps
for
the
associated
running
request()
algorithm.
true
if
the
operation
succeeded,
or
else
false
.
true
and
lock
's
type
is
"screen"
run
the
following:
false
.
active
,
set
lock
's
active
to
active
and
fire
an
event
named
"activechange"
at
lock
.
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.
The
ability
to
observe
the
global
state
of
a
wake
lock
can
create
a
communication
channel
between
two
otherwise
isolated
Document
objects.
One
document
can
request
wake
lock
which
changes
the
global
wake
lock
state,
and
another
document
can
observe
this
change
by
subscribing
to
events
in
.
WakeLock
When the user agent does not acquire wake lock even though a browsing context has requested it, this can be observed by the browsing context and can possibly disclose sensitive information about the state of the device such as that battery level is low.
This section is non-normative.
function tryKeepScreenAlive(minutes) {
const controller = new AbortController();
const signal = controller.signal;
const lock = new WakeLock("screen");
lock.request({ signal });
setTimeout(() => controller.abort(), minutes * 60 * 1000);
}
tryKeepScreenAlive(
10
);
This example allows the user to request a screen wake lock by clicking on a checkbox, but updates the checkbox checked state in case the wake lock state changes:
const checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
document.body.appendChild(checkbox);
const lock = new WakeLock("screen");
lock.onactivechange = () => checkbox.checked = lock.active;
const controller = new AbortController();
try {
checkbox.disabled = true;
if (checkbox.checked) {
await lock.request({ signal: controller.signal });
} else {
controller.abort();
}
} catch {
// On failure, reset the checkbox to reflect the
// current state. `onactivechanged` will not have fired.
checkbox.checked = lock.active;
} finally {
checkbox.disabled = false;
}
In
this
example,
two
different
wake
lock
requests
are
created
and
released
together
using
an
AbortController
:
const screen = new WakeLock("screen");
const system = new WakeLock("system");
const controller = new AbortController();
const signal = controller.signal;
screen.request({ signal });
system.request({ signal });
controller.abort();
Document's
hidden
attribute,
and
visibility
state
are
defined
in
[
PAGE-VISIBILITY
].
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST and MUST NOT are to be interpreted as described in [ RFC2119 ].
This specification defines conformance criteria for a single product: a user agent that implements the interfaces that it contains.
dictionaryWakeLockPermissionDescriptor: PermissionDescriptor {WakeLockTypetype; }; enumWakeLockType{ "screen", "system" }; [Constructor(WakeLockTypetype), SecureContext, Exposed=(DedicatedWorker, Window)] interfaceWakeLock: EventTarget { [Exposed=Window] static Promise<PermissionState>requestPermission(WakeLockTypetype); readonly attributeWakeLockTypetype; readonly attribute booleanactive; attribute EventHandleronactivechange; Promise<void>request(optionalWakeLockRequestOptionsoptions); }; dictionaryWakeLockRequestOptions{AbortSignal?AbortSignal?signal; };
This section is non-normative.
We would like to offer our sincere thanks to Mounir Lamouri, Sergey Konstantinov, Matvey Larionov, Dominique Hazael-Massieux, Domenic Denicola, Thomas Steiner for their contributions to this work.