1. Scope of this document
This section is non-normative.
This document specifies a model for permissions to use powerful features on the Web platform and an API to query the current permission state of those features.
Current Web APIs have different ways to deal with permissions. For example, the [notifications] API allows developers to request a permission and check the permission status explicitly. Others expose the status to web pages when they try to use the API, like the [geolocation-API] which fails if the permission was not granted without allowing the developer to check beforehand.
The
query()
method
allows
querying
the
state
of
a
given
permission,
which
a
developer
can
then
use
to
make
UI
decisions
within
a
web
application.
The solution described in this document is meant to be extensible, but isn’t expected to be applicable to all the current and future permissions available in the web platform. Working Groups that are creating specifications whose permission model doesn’t fit in the model described in this document should contact the editors by filing an issue .
2. Security and privacy considerations
This section is non-normative.
An
adversary
could
use
a
permission
state
as
an
element
in
creating
a
"fingerprint"
corresponding
to
an
end-user.
Although
an
adversary
can
already
determine
the
state
of
a
permission
by
actually
using
the
API,
that
often
leads
to
a
permission
request
UI
being
presented
to
the
end-user
(if
the
permission
was
not
already
"granted"
).
Thus,
even
though
this
API
doesn’t
expose
new
fingerprinting
information
to
websites,
it
makes
it
easier
for
an
adversary
to
have
discreet
access
to
this
information.
Thus,
implementations
are
encouraged
to
have
an
option
for
users
to
block
(globally
or
selectively)
the
querying
of
permission
states
.
3. Definitions
- New information about the user’s intent
-
The
UA
may
collect
information
about
a
user’s
intentions
in
any
way
its
authors
believe
is
appropriate.
This
information
can
come
from
explicit
user
action,
aggregate
behavior
of
both
the
relevant
user
and
other
users,
or
implicit
signals
this
specification
hasn’t
anticipated.
The implicit signals could be, for example, the install status of a web application or frequency and recency of visits. A user that has installed a web application and used it frequently and recently is more likely to trust it. Implementations are advised to exercise caution when relying on implicit signals.
- Powerful feature
- A feature of a UA that some code might not be allowed to access, for example because its environment settings object doesn’t satisfy some criteria, or because the user hasn’t given permission.
4. Descriptions of permission requests
dictionary {PermissionDescriptor required PermissionName ; };name
Each
powerful
feature
has
one
or
more
aspects
that
websites
can
request
permission
to
access.
To
describe
these
aspects,
each
feature
defines
a
subtype
of
PermissionDescriptor
to
be
its
permission
descriptor
type
.
The
"midi"
feature
has
two
aspects
:
access
to
normal
messages,
and
access
to
system
exclusive
messages.
Thus,
its
permission
descriptor
type
is:
dictionary MidiPermissionDescriptor : PermissionDescriptor {
boolean sysex = false;
};
The
"bluetooth"
feature
lets
sites
request
to
access
whatever
Bluetooth
devices
are
close
to
to
the
user’s
device.
Thus,
its
permission
descriptor
type
is:
dictionary BluetoothPermissionDescriptor : PermissionDescriptor {
DOMString deviceId;
sequence<BluetoothLEScanFilterInit> filters;
sequence<BluetoothServiceUUID> optionalServices = [];
boolean acceptAllDevices = false;
};
General
access
to
Bluetooth
devices
is
represented
by
{name:
'bluetooth'}
;
access
to
a
particular
device
is
represented
by
{name:
'bluetooth',
deviceId:
"id"}
;
and
access
to
a
device
with
a
particular
service
is
represented
by
{name:
'bluetooth',
filters:
[{services:
['service']}]}
5. Permission states
The user agent is responsible for tracking what powerful features each realm has the user’s permission to use. Other specifications can use the operations defined in this section to retrieve the UA’s notion of what permissions are granted or denied, and to ask the user to grant or deny more permissions.
Other specifications can also add more constraints on the UA’s behavior in these algorithms.
Within
this
section,
descriptor
is
an
instance
of
the
permission
descriptor
type
of
the
powerful
feature
named
by
descriptor
.
.
name
5.1. Reading the current permission state
A
descriptor
’s
permission
state
for
an
optional
environment
settings
object
settings
is
the
result
of
the
following
algorithm,
which
returns
one
of
the
enum
values
or
"granted"
,
"prompt"
PermissionState
,
"denied"
:
failure:
- If settings wasn’t passed, set it to the current settings object .
-
If
settings
is
a
non-secure
context
and
descriptor .isn’t allowed in non-secure contexts , then returnname"denied". -
If
there
exists
a
policy-controlled
feature
identified
by
descriptor .and settings has an associatednameDocumentnamed document , run the following step:- If document is not fully active , return failure.
-
If
document
is
not
allowed
to
use
the
feature
identified
by
descriptor .returnname"denied".
- If there was a previous invocation of this algorithm with the same descriptor and settings , returning previousResult , and the UA has not received new information about the user’s intent since that invocation, return previousResult .
-
Return
whichever
of
the
following
options
most
accurately
reflects
the
user’s
intent
for
the
calling
algorithm,
taking
into
account
any
permission
state
constraints
for
descriptor .:name
Safari is the only known UA that returns different results from this algorithm for different settings objects with the same origin. We should test which of the several possible settings objects it uses.
As
a
shorthand,
a
PermissionName
name
’s
permission
state
is
the
permission
state
of
a
PermissionDescriptor
with
its
name
member
set
to
name
.
Some
powerful
features
have
more
information
associated
with
them
than
just
a
PermissionState
.
For
example,
getUserMedia()
needs
to
determine
which
cameras
the
user
has
granted
the
current
realm
permission
to
access.
Each
of
these
features
defines
an
extra
permission
data
type
.
If
a
PermissionName
name
names
one
of
these
features,
then
name
’s
extra
permission
data
for
an
optional
environment
settings
object
settings
is
the
result
of
the
following
algorithm:
- If settings wasn’t passed, set it to the current settings object .
- If there was a previous invocation of this algorithm with the same name and settings , returning previousResult , and the UA has not received new information about the user’s intent since that invocation, return previousResult .
- Return the instance of name ’s extra permission data type that matches the UA’s impression of the user’s intent, taking into account any extra permission data constraints for name .
5.2. Requesting more permission
Spec authors, please note that algorithms in this section can wait for user input; so they shouldn’t be used from other algorithms running on the main thread.
To
request
permission
to
use
a
descriptor
,
the
UA
must
perform
the
following
steps.
This
algorithm
returns
either
"granted"
or
"denied"
.
- Let current state be the descriptor ’s permission state .
-
If
current
state
is
not
"prompt", return current state and abort these steps. - Ask the user’s permission for the calling algorithm to use the powerful feature described by descriptor .
-
If
the
user
grants
permission,
return
"granted"; otherwise return"denied". The user’s interaction may provide new information about the user’s intent for this realm and other realms with the same origin .This is intentionally vague about the details of the permission UI and how the UA infers user intent. UAs should be able to explore lots of UI within this framework.
As
a
shorthand,
requesting
permission
to
use
a
PermissionName
name
,
is
the
same
as
requesting
permission
to
use
a
PermissionDescriptor
with
its
name
member
set
to
name
.
To
prompt
the
user
to
choose
one
of
several
options
associated
with
a
descriptor
,
the
UA
must
perform
the
following
steps.
This
algorithm
returns
either
"denied"
or
one
of
the
options.
-
If
descriptor
’s
permission
state
is
"denied", return"denied"and abort these steps. -
If
descriptor
’s
permission
state
is
"granted", the UA may return one of options and abort these steps. If the UA returns without prompting, then subsequent prompts for the user to choose from the same set of options with the same descriptor must return the same option, unless the UA receives new information about the user’s intent . - Ask the user to choose one of the options or deny permission, and wait for them to choose. If the calling algorithm specified extra information to include in the prompt, include it.
-
If
the
user
chose
an
option,
return
it;
otherwise
return
"denied". If the user’s interaction indicates they intend this choice to apply to other realms, then treat this this as new information about the user’s intent for other realms with the same origin .This is intentionally vague about the details of the permission UI and how the UA infers user intent. UAs should be able to explore lots of UI within this framework.
As
a
shorthand,
prompting
the
user
to
choose
from
options
associated
with
a
PermissionName
name
,
is
the
same
as
prompting
the
user
to
choose
from
those
options
associated
with
a
PermissionDescriptor
with
its
name
member
set
to
name
.
5.3. Reacting to users revoking permission
When the UA learns that the user no longer intends to grant permission for a realm to use a feature , it must queue a task on the Realm’s settings object ’s responsible event loop to run that feature’s permission revocation algorithm .
6. Status of a permission
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
enum {PermissionState , , ,"granted" ,"denied" ,"prompt" , };
The
"granted"
state
represents
that
the
caller
will
be
able
to
successfully
access
the
feature
without
having
the
user
agent
asking
the
user’s
permission.
The
"denied"
state
represents
that
the
caller
will
not
be
able
to
access
the
feature.
The
"prompt"
state
represents
that
the
user
agent
will
be
asking
the
user’s
permission
if
the
caller
tries
to
access
the
feature.
The
user
might
grant,
deny
or
dismiss
the
request.
[Exposed =(Window ,Worker )]interface :PermissionStatus EventTarget {;readonly attribute PermissionState state ;attribute EventHandler onchange ; };
PermissionStatus
instances
are
created
with
a
[[query]]
internal
slot,
which
is
an
instance
of
a
feature’s
permission
descriptor
type
.
To
create
a
PermissionStatus
for
a
given
PermissionDescriptor
permissionDesc
,
return
a
new
instance
of
the
permission
result
type
for
the
feature
named
by
permissionDesc
.
,
with
the
name
[[query]]
internal
slot
initialized
to
permissionDesc
.
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 44+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
The
state
attribute
MUST
return
the
latest
value
that
was
set
on
the
current
instance.
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
The
onchange
attribute
is
an
event
handler
whose
corresponding
event
handler
event
type
is
change
.
Whenever
the
user
agent
is
aware
that
the
state
of
a
PermissionStatus
instance
status
has
changed,
it
MUST
asynchronously
run
the
following
steps:
- Let document this status ’s relevant global object 's associated Document .
- If document is null or document is not fully active , terminate this algorithm.
-
Run
status @’s permission query algorithm , passing[[query]].namestatus @and status .[[query]] -
Queue
a
task
on
the
permission
task
source
to
fire
an
event
named
changeat status .
7.
Extensions
to
the
Navigator
and
WorkerNavigator
interfaces
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
[Exposed =(Window )]partial interface Navigator { [SameObject ]readonly attribute Permissions ; };permissions
In only one current engine.
Opera 30+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android None iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile 30+
[Exposed =(Worker )]partial interface WorkerNavigator { [SameObject ]readonly attribute Permissions ; };permissions
8.
Permissions
interface
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
[Exposed =(Window ,Worker )]interface {Permissions Promise <PermissionStatus >query (object ); };permissionDesc
8.1.
query()
method
Opera Yes Edge 79+
Edge (Legacy) None IE None
Firefox for Android 46+ iOS Safari None Chrome for Android 43+ Android WebView None Samsung Internet 4.0+ Opera Mobile Yes
When
the
query(permissionDesc)
method
is
invoked,
the
user
agent
MUST
run
the
following
query
a
permission
algorithm,
passing
the
parameter
permissionDesc
:
-
If
this
relevant
global
object
is
a
Windowobject, then:-
If
the
current
settings
object’s
associated
Documentis not fully active , return a promise rejected with a"InvalidStateError"DOMException.
-
If
the
current
settings
object’s
associated
-
Let
rootDesc
be
the
object
permissionDesc
refers
to,
converted
to
an
IDL
value
of
type
PermissionDescriptor. If this throws an exception, return a promise rejected with that exception and abort these steps. -
Let
typedDescriptor
be
the
object
permissionDesc
refers
to,
converted
to
an
IDL
value
of
rootDesc .’s permission descriptor type . If this throws an exception, return a promise rejected with that exception and abort these steps.name -
Let
promise
be
a
newly-created
Promise. - Return promise and continue the following steps asynchronously.
- Run the steps to create a PermissionStatus for typedDescriptor , and let status be the result.
-
Run
status @’s permission query algorithm , passing[[query]].namestatus @and status .[[query]] - Resolve promise with status .
Promise
.all()
.
An
example
can
be
found
in
the
Examples
section
.
9. Common permission algorithms
The
boolean
permission
query
algorithm
,
given
a
PermissionDescriptor
permissionDesc
and
a
PermissionStatus
status
,
runs
the
following
steps:
-
Set
status .stateto permissionDesc ’s permission state .
10. Permission Registry
enum {PermissionName "accelerometer" ,"ambient-light-sensor" ,"background-fetch" ,"background-sync" ,"bluetooth" ,"camera" ,"device-info" ,"display-capture" ,"gamepad" ,"geolocation" ,"gyroscope" ,"magnetometer" ,"microphone" ,"midi" ,"nfc" ,"notifications" ,"persistent-storage" ,"push" ,"screen-wake-lock" ,"speaker-selection" , };
Each
enumeration
value
in
the
PermissionName
enum
identifies
a
powerful
feature
.
Each
powerful
feature
has
the
following
permission-related
flags,
algorithms,
and
types:
- An allowed in non-secure contexts flag
- By default, only secure contexts can use powerful features . If this flag is set for a feature, the UA may grant access to it in non-secure contexts too.
- A permission descriptor type
-
PermissionDescriptoror one of its subtypes. If unspecified, this defaults toPermissionDescriptor.The feature can define a partial order on descriptor instances. If descriptorA is stronger than descriptorB , then if descriptorA ’s permission state is
"granted", descriptorB ’s permission state must also be"granted", and if descriptorB ’s permission state is"denied", descriptorA ’s permission state must also be"denied".{name:("midi-with-sysex") is stronger than"midi", sysex: true}{name:("midi-without-sysex"), so if the user denies access to midi-without-sysex, the UA must also deny access to midi-with-sysex, and similarly if the user grants access to midi-with-sysex, the UA must also grant access to midi-without-sysex."midi", sysex: false} - Optional permission state constraints
- Constraints on the values that the UA can return as a descriptor’s permission state . Defaults to no constraints beyond the user’s intent.
- An optional extra permission data type
- If specified, the extra permission data algorithm is usable for this feature.
- Optional extra permission data constraints
-
Constraints
on
the
values
that
the
UA
can
return
as
a
PermissionName's extra permission data . Defaults to no constraints beyond the user’s intent. - A permission result type
-
PermissionStatusor one of its subtypes. If unspecified, this defaults toPermissionStatus. - A permission query algorithm
-
Takes
an
instance
of
the
permission
descriptor
type
and
a
new
or
existing
instance
of
the
permission
result
type
,
and
updates
the
permission
result
type
instance
with
the
query
result.
Used
by
Permissions'query(permissionDesc)method and the PermissionStatus update steps . If unspecified, this defaults to the boolean permission query algorithm . - A permission revocation algorithm
- Takes no arguments. Updates any other parts of the implementation that need to be kept in sync with changes in the results of permission states or extra permission data . Run by § 5.3 Reacting to users revoking permission . If unspecified, this defaults to doing nothing.
A boolean feature is a powerful feature with all of the above types and algorithms defaulted.
10.1. Geolocation
Headers/Feature-Policy/geolocation
Opera 47+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android 🔰 65+ iOS Safari None Chrome for Android 60+ Android WebView 60+ Samsung Internet 8.0+ Opera Mobile 44+
The
"geolocation"
permission
is
the
permission
associated
with
the
usage
of
the
[geolocation-API]
.
It
is
a
boolean
feature
and
is
allowed
in
non-secure
contexts
.
10.2. Gamepad
The
"gamepad"
permission
is
the
permission
associated
with
the
usage
of
the
[Gamepad]
.
It
is
a
boolean
feature
and
is
allowed
in
non-secure
contexts
.
10.3. Notifications
The
"notifications"
permission
is
the
permission
associated
with
the
usage
of
the
[notifications]
API.
It
is
a
boolean
feature
and
is
allowed
in
non-secure
contexts
.
10.4. Push
The
"push"
permission
is
the
permission
associated
with
the
usage
of
the
[push-api]
.
- permission descriptor type
-
dictionary :PushPermissionDescriptor PermissionDescriptor {boolean =userVisibleOnly false ; };{name: "push", userVisibleOnly: false}is stronger than{name: "push", userVisibleOnly: true}.
10.5. Midi
Opera 47+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android 🔰 65+ iOS Safari None Chrome for Android 60+ Android WebView 60+ Samsung Internet 8.0+ Opera Mobile 44+
The
"midi"
permission
is
the
permission
associated
with
the
usage
of
[webmidi]
.
"midi"
is
allowed
in
non-secure
contexts
.
- permission descriptor type
-
dictionary :MidiPermissionDescriptor PermissionDescriptor {boolean =sysex false ; };{name: "midi", sysex: true}is stronger than{name: "midi", sysex: false}.
10.6. Screen wake lock
The
"screen-wake-lock"
permission
is
the
permission
associated
with
the
usage
of
the
[screen-wake-lock]
API.
It
is
a
boolean
feature
.
10.7. Media Devices
In all current engines.
Opera 48+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android 🔰 65+ iOS Safari 11.3+ Chrome for Android 60+ Android WebView 60+ Samsung Internet 8.0+ Opera Mobile 45+
Headers/Feature-Policy/microphone
In all current engines.
Opera 48+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android 🔰 65+ iOS Safari 11.3+ Chrome for Android 60+ Android WebView 60+ Samsung Internet 8.0+ Opera Mobile 45+
The
"camera"
,
"microphone"
,
and
"speaker-selection"
permissions
are
associated
with
permission
to
use
media
devices
as
specified
in
[GETUSERMEDIA]
and
[audio-output]
.
- permission descriptor type
-
dictionary :DevicePermissionDescriptor PermissionDescriptor {DOMString ; };deviceId dictionary :CameraDevicePermissionDescriptor DevicePermissionDescriptor {boolean =panTiltZoom false ; };A permission covers access to the device given in the associated descriptor.
If the descriptor does not have a
deviceId, its semantic is that it queries for access to all devices of that class. Thus, if a query for the"camera"permission with nodeviceIdreturns"granted", the client knows that there will never be a permission prompt for a camera, and if"denied"is returned, it knows that no getUserMedia request for a camera will succeed.If a permission state is present for access to some, but not all, cameras, a query without the
deviceIdwill return"prompt".{name: "camera", panTiltZoom: true}is stronger than{name: "camera", panTiltZoom: false}.Note that a "granted" permission is no guarantee that getUserMedia will succeed. It only guarantees that the user will not be prompted for permission. There are many other things (such as constraints or the camera being in use) that can cause getUserMedia to fail.
- extra permission data type
-
A
list
of
deviceIdvalues for the devices the user has made a non-default decision on access to. - permission query algorithm
-
The
permission
query
algorithm
runs
the
following
steps:
-
If
permissionDesc
.deviceId
exists
in
the
extra
permission
data
,
set
status .stateto permissionDesc ’s permission state and terminate these steps. -
Let
global
be
a
copy
of
permissionDesc
with
the
deviceIdmember removed. -
Set
status .stateto global ’s permission state .
-
If
permissionDesc
.deviceId
exists
in
the
extra
permission
data
,
set
- permission request algorithm
-
The
permission
request
algorithm
runs
the
following
steps:
- Let result be the result of running the boolean permission request algorithm .
-
If
result
is
"granted", the UA MUST set the"device-info"permission to"granted"for this realm . -
The
UA
MAY
treat
result
as
new
information
about
the
user’s
intent
with
respect
to
the
"device-info"permission for this realm and other realms with the same origin , provided it doesn’t violate the previous step. - Return result .
- permission revocation algorithm
-
This
is
the
result
of
calling
the
device
permission
revocation
algorithm
passing
nameanddeviceIdas arguments. If the descriptor does not have adeviceId, thenundefinedis passed in place ofdeviceId.
The
"device-info"
permission
controls
access
to
the
name
and
capabilities
associated
with
a
deviceId
,
as
well
as
whether
devicechange
events
fire
when
the
current
browsing
context
is
not
in
focus.
The
"device-info"
permission
MUST
be
revoked
when
deviceId
s
for
an
origin
are
reset.
10.8. Background Fetch
The
"background-fetch"
permission
is
the
permission
associated
with
the
usage
of
[background-fetch]
.
10.9. Background Sync
The
"background-sync"
permission
is
the
permission
associated
with
the
usage
of
[web-background-sync]
.
10.10. Bluetooth
The
"bluetooth"
permission
(
Web
Bluetooth
§3.1
Permission
API
Integration
)
controls
usage
of
[web-bluetooth]
.
10.11. Persistent Storage
The
"persistent-storage"
permission
(
Storage
§5
Persistence
permission
)
is
the
permission
associated
with
the
usage
of
the
"persistent"
storage
bucket
mode
.
10.12. Ambient Light Sensor
Headers/Feature-Policy/ambient-light-sensor
In only one current engine.
Opera 54+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android None iOS Safari None Chrome for Android 67+ Android WebView 67+ Samsung Internet 9.0+ Opera Mobile 48+
The
"ambient-light-sensor"
permission
is
the
permission
associated
with
the
usage
of
the
[ambient-light]
API.
Its
permission
revocation
algorithm
is
the
result
of
calling
generic
sensor
permission
revocation
algorithm
passing
it
"ambient-light-sensor"
as
argument.
10.13. Accelerometer
Headers/Feature-Policy/accelerometer
In only one current engine.
Opera 54+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android None iOS Safari None Chrome for Android 67+ Android WebView 67+ Samsung Internet 9.0+ Opera Mobile 48+
The
"accelerometer"
permission
is
the
permission
associated
with
the
usage
of
the
[accelerometer]
API.
Its
permission
revocation
algorithm
is
the
result
of
calling
generic
sensor
permission
revocation
algorithm
passing
it
"accelerometer"
as
argument.
10.14. Gyroscope
Headers/Feature-Policy/gyroscope
In only one current engine.
Opera 54+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android None iOS Safari None Chrome for Android 67+ Android WebView 67+ Samsung Internet 9.0+ Opera Mobile 48+
The
"gyroscope"
permission
is
the
permission
associated
with
the
usage
of
the
[gyroscope]
API.
Its
permission
revocation
algorithm
is
the
result
of
calling
generic
sensor
permission
revocation
algorithm
passing
it
"gyroscope"
as
argument.
10.15. Magnetometer
Headers/Feature-Policy/magnetometer
In only one current engine.
Opera 54+ Edge 79+
Edge (Legacy) None IE None
Firefox for Android None iOS Safari None Chrome for Android 67+ Android WebView None Samsung Internet 9.0+ Opera Mobile 48+
The
"magnetometer"
permission
is
the
permission
associated
with
the
usage
of
the
[magnetometer]
API.
Its
permission
revocation
algorithm
is
the
result
of
calling
generic
sensor
permission
revocation
algorithm
passing
it
"magnetometer"
as
argument.
10.16. Display Capture
The
"display-capture"
permission
is
the
permission
associated
with
the
usage
of
[screen-capture]
.
- permission state constraints
-
Valid
values
for
this
descriptor’s
permission
state
are
"prompt"and"denied". The user agent MUST NOT ever set this descriptor’s permission state to"granted".
10.17. NFC
The
"nfc"
permission
is
the
permission
associated
with
the
usage
of
the
[web-nfc]
API.
11. Automation
For the purposes of user-agent automation and application testing, this document defines the following extension command for the [WebDriver] specification.
dictionary {PermissionSetParameters required PermissionDescriptor ;descriptor ;required PermissionState ;state boolean =oneRealm false ; };
11.1. Set Permission
| HTTP Method | URI Template |
|---|---|
| POST | /session/{session id}/permissions |
The
Set
Permission
extension
command
simulates
user
modification
of
a
PermissionDescriptor
's
permission
state
.
The remote end steps are:
-
Let
parameters
be
the
parameters
argument,
converted
to
an
IDL
value
of
type
PermissionSetParameters. If this throws an exception, return a WebDriver error with WebDriver error code invalid argument . -
Let
rootDesc
be
parameters
.
descriptor. -
Let
typedDescriptor
be
the
object
rootDesc
refers
to,
converted
to
an
IDL
value
of
rootDesc .’s permission descriptor type . If this throws an exception, return a WebDriver error with WebDriver error code invalid argument .name -
If
parameters
.
stateis an inappropriate permission state for any implementation-defined reason, return a WebDriver error with WebDriver error code invalid argument .For example, user agents that define the
"midi"feature as "always on" may choose to reject command to set the permission state to"denied"at this step. - Let settings be the environment settings object of the current browsing context ’s active document .
-
If
settings
is
a
non-secure
context
and
rootDesc .isn’t allowed in non-secure contexts , return a WebDriver error with WebDriver error code invalid argument .name -
If
parameters
.
oneRealmis true, let targets be a list whose sole member is settings . - Otherwise, let targets be a list containing all environment settings objects whose origin is the same as the origin of settings .
- Let tasks be an empty list .
-
For
each
environment
settings
object
target
in
targets
:
-
Queue
a
task
task
on
the
permission
task
source
of
target
’s
relevant
settings
object
's
global
object
's
browsing
context
to
perform
the
following
step:
-
Interpret
parameters
.
stateas if it were the result of an invocation of permission state for typedDescriptor with the argument target made at this moment.
-
Interpret
parameters
.
- Append task to tasks .
-
Queue
a
task
task
on
the
permission
task
source
of
target
’s
relevant
settings
object
's
global
object
's
browsing
context
to
perform
the
following
step:
- Wait for all tasks in tasks to have executed.
-
Return
success
with
data
null.
{name:
"midi"
,
sysex:
true}
of
the
current
browsing
context
of
the
session
with
ID
23
to
"
granted
",
the
local
end
would
POST
to
/session/23/permissions
with
the
body:
{ "descriptor" : { "name" : "midi" , "sysex" : true }, "state" : "granted" }
12. Examples
This example uses the Permissions API to decide whether local news should be shown using the Geolocation API or with a button offering to add the feature.
const { state} = await navigator. permissions. query({ name: "geolocation" }); switch ( state) { case "granted" : showLocalNewsWithGeolocation(); break ; case "prompt" : showButtonToEnableLocalNews(); break ; default : // Don’t do anything if the permission was denied. break ; }
This
example
is
using
the
"notifications"
permission
for
a
chat
application
to
show
a
notification
button
depending
on
the
permission
state.
function updateNotificationButton( state) { const button= document. getElementById( "chat-notification-button" ); button. disabled= state=== "denied" ; } const permission= navigator. permissions. query({ name: "notifications" , }); updateNotificationButton( permission. state); permission. addEventListener( "change" , () => { updateNotificationButton( permission. state); });
This
example
is
checking
whether
the
page
has
the
"geolocation"
and
the
"notifications"
permissions
using
.
Promise
.all
Promise. all([ navigator. permissions. query({ name: "geolocation" }), navigator. permissions. query({ name: "notifications" }) ]) . then(([{ state: geoState}, { state: notifState}]) => { console. log( "Geolocation permission state is:" , geoState); console. log( "Notifications permission state is:" , notifState); });
This example is checking the permission state of the available cameras.
const devices= await navigator. mediaDevices. enumerateDevices(); // filter on video inputs, and map to query object const queries= devices. filter(({ kind}) => kind=== "videoinput" ) . map(({ deviceId}) => ({ name: "camera" , deviceId})); const promises= queries. map(( queryObj) => navigator. permissions. query( queryObj) ); try { const results= await Promise. all( promises); // log the state or each camera results. forEach(({ state}, i) => console. log( "Camera" , i, state)); } catch ( error) { console. error( error); }
Acknowledgments
The editors would like to thank Adrienne Porter Felt, Anne van Kesteren, Domenic Denicola, Jake Archibald and Wendy Seltzer for their help with the API design and editorial work.