The reporting rate for a pressure observer is the rate at which it runs
- the [=data delivery=] steps, and it will never exceed the [=sampling rate=].
+ the [=data collection=] steps, and it will never exceed the [=sampling rate=].
The [=sampling rate=] differs from the [=requested sampling rate=] when the
@@ -243,26 +243,76 @@
Sampling and Reporting Rate
Platform primitives
- The [=platform collector=] refers to a platform interface, with which the [=user agent=] interacts to
- obtain the telemetry readings required by this specification.
+ A pressure source is an abstract, [=implementation-defined=]
+ interface to hardware counters or an underlying framework that provides
+ telemetry data about a source type
+ defined by {{PressureSource}}. A [=pressure source=] can make use of data
+ fusion with data from additional sources if that provides more precise
+ results.
- A [=platform collector=] can be defined by the underlying platform (e.g. in a native telemetry
- framework) or by the [=user agent=], if it has a direct access to hardware counters.
+ The telemetry data provided by a [=pressure source=] is represented in this
+ specification as a pressure source sample, a [=struct=]
+ consisting of the following [=struct/items=]:
+
+
+ data: [=contributing
+ factors=] obtained from the underlying hardware or operating system or,
+ in the case of a [=virtual pressure source=], a {{PressureState}}.
+
+
+ timestamp: the
+ [=unsafe shared current time=] when [=pressure source sample/data=] was
+ obtained.
+
+
+
+
+
+ A [=pressure source=] has an associated latest sample, a [=pressure source
+ sample=] or null. It is initially null.
- A [=platform collector=] can support telemetry for different source types of computing
- devices defined by {{PressureSource}}, or there can be multiple [=platform collectors=].
+ A platform collector is an abstract interface responsible for
+ obtaining telemetry samples from a [=pressure source=], transforming them
+ into [=pressure states=] and providing them to the [=user agent=].
+
+
+ A [=platform collector=] has the following associated data:
+
+
+
+ an associated pressure
+ source, which is a [=pressure source=] or null.
+
+
+ an activated boolean,
+ initially false.
+
+
+
+ The format of the telemetry data provided by a [=pressure source=]
+ and stored in its [=pressure source/latest sample=]'s [=pressure source
+ sample/data=] is [=implementation-defined=], and so is the process through
+ which a [=platform collector=] transforms it into a [=pressure state=].
- From the implementation perspective [=platform collector=] can be treated as a software proxy for the
- corresponding hardware counters. It is possible to have multiple [=platform collector=] simultaneously
- interacting with the same underlying hardware if the underlying platform supports it.
+ For this specification's purposes, [=platform collectors=] are scoped to a
+ [=global object=] via the [=platform collector mapping=].
- In simple cases, a [=platform collector=] represents individual hardware counters, but if the provided
- counter readings are a product of data fusion performed in software, the [=platform collector=]
- represents the results of the data fusion process. This may happen in user space or in kernel space.
+ For automation purposes, a [=platform collector=] must have the ability to
+ connect to [=virtual pressure sources=] and use their simulated [=pressure
+ source sample/data=] as [=pressure states=] rather than raw platform data
+ that must be transformed into an [=adjusted pressure state=].
As collecting telemetry data often means polling hardware counters, it is not a free operation and thus,
@@ -361,7 +411,8 @@
a registered observer list per supported [=source type=], which is initially empty.
- a reference to an underlying platform collector as detailed in [[[#platform-primitives]]].
+ a platform collector mapping, an [=ordered map=] of [=source
+ types=] to [=platform collectors=].
A registered observer consists of an observer (a {{PressureObserver}} object).
@@ -606,13 +657,87 @@
The observe() method
Run the following steps [=in parallel=]:
- If |source:PressureSource| is not a [=valid source type=],
- [=queue a global task=] on the [=PressureObserver task source=]
- given |relevantGlobal|
- to reject |promise| {{NotSupportedError}} and abort these steps.
+ Let |platformCollector| be null.
- Activate [=data delivery=] of |source| data to |relevantGlobal|.
+ If |relevantGlobal|'s [=platform collector mapping=]
+ [=map/contains=] |source|:
+
+
+ Set |platformCollector| to |relevantGlobal|'s [=platform
+ collector mapping=][|source|].
+
+
+
+
+ Otherwise:
+
+
+ Let |newCollector| be a new [=platform collector=] whose
+ [=platform collector/associated pressure source=] is null.
+
+
+ Let |virtualPressureSource:virtual pressure source or null|
+ be the result of invoking [=get a virtual pressure source=]
+ with |source| and |relevantGlobal|.
+
+
+ If |virtualPressureSource| is not null:
+
+
+ If |virtualPressureSource|'s [=virtual pressure
+ source/can provide samples=] is true:
+
+
+ Set |newCollector|'s [=platform collector/associated
+ pressure source=] to |virtualPressureSource|.
+
+ Let |realPressureSource| be an [=implementation-defined=]
+ [=pressure source=] that provides telemetry data about
+ |source|, or null if none exists.
+
+
+ Set |newCollector|'s [=platform collector/associated
+ pressure source=] to |realPressureSource|.
+
+
+
+
+ If |newCollector|'s [=platform collector/associated
+ pressure source=] is not null:
+
+
+ Set |platformCollector| to |newCollector|.
+
+
+ Set |relevantGlobal|'s [=platform collector
+ mapping=][|source|] to |platformCollector|.
+
+
+
+
+
+
+ If |platformCollector| is null, [=queue a global task=] on the
+ [=PressureObserver task source=] given |relevantGlobal| to reject
+ |promise| {{NotSupportedError}} and abort these steps.
+
+
+ Invoke [=activate data collection=] with |source| and
+ |relevantGlobal|.
[=Queue a global task=] on the [=PressureObserver task source=] given
@@ -623,7 +748,7 @@
The observe() method
If |relevantGlobal|'s [=registered observer list=] for |source| is [=list/empty=],
- deactivate [=data delivery=] of |source| data to |relevantGlobal|.
+ invoke [=deactivate data collection=] with |source| and |relevantGlobal|.
Return.
@@ -686,9 +811,13 @@
The unobserve() method
If |registeredObserverList| is [=list/empty=]:
- Deactivate [=data delivery=] of |source| data to
+ Invoke [=deactivate data collection=] with |source| and
|relevantGlobal|.
+ To get a virtual pressure source, given a [=source type=]
+ |source| and |relevantGlobal|, perform the following steps. They return a
+ [=virtual pressure source=] or null.
+
+
Let |topLevelTraversable| be null.
+
+ If |relevantGlobal| is a {{Window}} object:
+
+
+ Set |topLevelTraversable| to |relevantGlobal|'s [=Window/navigable=]'s [=top-level traversable=].
+
+
+
+
+ If |relevantGlobal| is a {{DedicatedWorkerGlobalScope}} object:
+
+
+ Let |owningDocuments| be |relevantGlobal|'s [=owning document set=].
+
+
+ If |owningDocuments| is [=set/empty=], return null.
+
+
+ [=Assert=]: |owningDocuments|'s [=set/size=] is 1.
+
+
+ Set |topLevelTraversable| to |owningDocuments|[0]'s [=node navigable=]'s [=top-level traversable=].
+
+
+
+
+ If |topLevelTraversable| is null, return null.
+
+
+ Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=].
+
+
+ Let |virtualPressureSource| be null.
+
+
+ If |topLevelVirtualPressureSourceMapping| [=map/contains=] |source|:
+
+
+ Set |virtualPressureSource| to |topLevelVirtualPressureSourceMapping|[|source|].
+
+
+
+
+ Return |virtualPressureSource|.
+
+
+
-
Data delivery
+
Data Collection and Delivery
- [=Data delivery=] from a [=platform collector=] can be activate and deactivated in an
- [=implementation-defined=] manner per [=source type=] and [=global object=].
+ To activate data collection given a [=source type=] |source|
+ and |relevantGlobal|, perform the following steps:
-
+
+
+ If |relevantGlobal|'s [=platform collector mapping=] does not
+ [=map/contain=] |source|, abort these steps.
+
+
+ Let |platformCollector| be |relevantGlobal|'s [=platform collector
+ mapping=][|source|].
+
+
+ If |platformCollector|'s [=platform collector/activated=] is true,
+ abort these steps.
+
+
+ Set |platformCollector|'s [=platform collector/activated=] to true.
+
+
+ In an [=implementation-defined=] manner, start running the [=data
+ collection=] steps with |relevantGlobal|, |source|, and
+ |platformCollector|.
+
+
+
- The data delivery steps that are run when
- an [=implementation-defined=] |data| sample of [=source type=] |source:PressureSource| is
- obtained from [=global object=] |relevantGlobal|'s [=platform collector=],
- are as follows:
-
+ To deactivate data collection given a [=source type=] |source|
+ and |relevantGlobal|, perform the following steps:
+
+
+
+ If |relevantGlobal|'s [=platform collector mapping=] does not
+ [=map/contain=] |source|, abort these steps.
+
+
+ Let |platformCollector| be |relevantGlobal|'s [=platform collector
+ mapping=][|source|].
+
+
+ If |platformCollector|'s [=platform collector/activated=] is false,
+ abort these steps.
+
+
+ In an [=implementation-defined=] manner, stop running the [=data
+ collection=] steps with |relevantGlobal|, |source|, and
+ |platformCollector|.
+
+
+ Set |platformCollector|'s [=platform collector/activated=] to false.
+
+
+ If |platformCollector|'s [=platform collector/associated pressure
+ source=] is a [=virtual pressure source=]:
+
+
+ [=set/Remove=] |platformCollector| from its [=platform
+ collector/associated pressure source=]'s [=virtual pressure
+ source/connected platform collectors=].
+
+
+
+
+ Otherwise, perform any [=implementation-defined=] steps to signal to
+ |platformCollector|'s [=platform collector/associated pressure source=]
+ to stop retrieving telemetry data.
+
+
+
+ The data collection steps given |relevantGlobal|, |source| and
+ |platformCollector| are as follows:
+
- Let |source:PressureSource| be the [=source type=] of the |data| sample.
+ Let |pressureSource| be |platformCollector|'s [=platform
+ collector/associated pressure source=].
- Let |state:PressureState| be an [=adjusted pressure state=] given |data| and |source|.
-
+ If |pressureSource| is null, abort these steps.
- Let |timestamp| be the [=unsafe shared current time=] corresponding
- to the moment when |data| was obtained from |relevantGlobal|'s
- [=platform collector=].
-
+ Let |sample| be |pressureSource|'s [=pressure source/latest sample=].
+
+
+ If |sample| is null, abort these steps.
+
+
+ Let |state:PressureState| be null.
- Let |timeValue| be the [=relative high resolution time=] based on |timestamp| and
- |relevantGlobal|.
+ If |pressureSource| is a [=virtual pressure source=]:
+
+
+ Set |state| to |sample|'s [=pressure source sample/data=].
+
+
+
+
+ Otherwise:
+
+
+ Set |state| to an [=adjusted pressure state=] calculated from
+ |source| and |sample|'s [=pressure source sample/data=].
+
+
+
+
+
+ [=Assert=]: |state| is not null.
+
+
+ Let |rawTimestamp| be |sample|'s [=pressure source
+ sample/timestamp=].
+
+
+ Let |timeValue| be the [=relative high resolution time=] based on
+ |rawTimestamp| and |relevantGlobal|.
[=list/For each=] |observer:PressureObserver| in |relevantGlobal|'s
@@ -1313,7 +1590,12 @@
Handling change of [=Document/fully active=] status
[=registered observer list=] [=ordered map=]:
- Deactivate [=data delivery=] of |source| to |relevantGlobal|.
+ Invoke [=deactivate data collection=] with |source| and
+ |relevantGlobal|.
+
+ The Compute Pressure API poses a challenge to test authors, as fully
+ exercising interface requires physical hardware devices that respond in
+ predictable ways.
+
+
+ To address this challenge this document defines a [[!WEBDRIVER2]] [=extension
+ commands=] that allows defining and controlling virtual pressure sources that behave
+ like real ones and which can have particular properties and whose readings can be
+ entirely defined by users.
+
+
+ Virtual Pressure Source
+
+
+ A virtual pressure source is a [=pressure source=] that
+ simulates the behavior of a real one in controlled ways. It reports
+ pressure changes to zero or more [=platform collectors=] connected to it.
+
+
+ Contrary to a real [=pressure source=], however, it reports [=pressure
+ state=] values directly instead of [=implementation-defined=] values that
+ must be processed into [=pressure states=] by a [=platform collector=]. In
+ other words, a [=virtual pressure source=]'s [=pressure source sample=]'s
+ [=pressure source sample/data=] is a {{PressureState}}.
+
+
+ In addition to the data associated with all [=pressure sources=] (such as
+ [=pressure source sample=]), each [=virtual pressure source=] has:
+
+
+ a can provide samples
+ boolean.
+
+
+ a connected platform
+ collectors [=set=] of [=platform collectors=].
+
+
+
+
+ Each [=top-level traversable=] has a virtual pressure source mapping, which is an [=ordered map=] of
+ [=source types=] to [=virtual pressure source=].
+
+
+
+
+ Extension Commands
+
+
+ Create virtual pressure source
+
+
+
+
+ HTTP Method
+
+
+ [=extension command URI Template|URI Template=]
+
+
+
+
+ POST
+
+
+ /session/{session id}/pressuresource
+
+
+
+
+ This [=extension command=] creates a new [=virtual pressure source=] of a specified
+ [=source type=]. Calls to {{PressureObserver/observe()}} from {{PressureObserver}} instances
+ of the same [=source type=] will cause this [=virtual pressure source=] to be used as their
+ backing [=pressure source=] until [[[#delete-virtual-pressure-source]]] is run.
+
+
+
+ Properties of the parameters argument used by this algorithm
+
+
+
+ Parameter name
+
+
+ Value type
+
+
+ Required
+
+
+
+
+ type
+
+
+ String
+
+
+ yes
+
+
+
+
+ supported
+
+
+ Boolean
+
+
+ no
+
+
+
+
+ The [=remote end steps=] given |session|, |URL variables| and |parameters| are:
+
+
+
+ Let |virtualPressureSourceType| be the result of invoking
+ get a property "type" from |parameters|.
+
+
+ If the [=user agent=]'s [=supported source types=] does not
+ [=list/contain=] |virtualPressureSourceType|, return [=error=] with
+ [=error code|WebDriver error code=] [=invalid argument=].
+
+
+ Let |topLevelTraversable| be the current browsing
+ context's [=browsing context/top-level traversable=].
+
+
+ Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=].
+
+
+ If |topLevelVirtualPressureSourceMapping| contains |virtualPressureSourceType|, return [=error=] with
+ [=error code|WebDriver error code=] [=invalid argument=].
+
+
+ Let |supported| be the result of invoking get a
+ property with default
+ with "supported" and true from |parameters|.
+
+
+ Let |virtualPressureSource| be a new [=virtual pressure source=].
+
+
+ Set |virtualPressureSource|'s [=virtual pressure source/can provide
+ samples=] to |supported|.
+
+
+ Set |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|] to |virtualPressureSource|.
+
+
+ Return [=success=] with data null.
+
+
+
+ Delete virtual pressure source
+
+
+
+
+ HTTP Method
+
+
+ [=extension command URI Template|URI Template=]
+
+
+
+
+ DELETE
+
+
+ /session/{session id}/pressuresource/{type}
+
+
+
+
+ This [=extension command=] deletes a given [=virtual pressure source=], meaning that,
+ if available, data for the given [=source type=] will be delivered the regular way, by non-virtual means.
+
+
+ The [=remote end steps=] given |session|, |URL variables| and |parameters| are:
+
+
+
+ Let |virtualPressureSourceType| be the value of the |URL variables|["type"].
+
+
+ If the [=user agent=]'s [=supported source types=] does not
+ [=list/contain=] |virtualPressureSourceType|, return [=error=] with
+ [=error code|WebDriver error code=] [=invalid argument=].
+
+
+ Let |topLevelTraversable| be the current browsing
+ context's [=browsing context/top-level traversable=].
+
+
+ Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=].
+
+
+ Let |pressureSource| be |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|].
+
+ [=extension command URI Template|URI Template=]
+
+
+
+
+ POST
+
+
+ /session/{session id}/pressuresource/{type}
+
+
+
+
+ This [=extension command=] allows updating the state of a [=virtual pressure source=] by pushing
+ a new [=pressure source sample=].
+
+
+
+
+ Properties of the parameters argument used by this algorithm
+
+
+
+ Parameter name
+
+
+ Value type
+
+
+ Required
+
+
+
+
+ sample
+
+
+ {{PressureState}}
+
+
+ yes
+
+
+
+
+ The [=remote end steps=] given |session|, |URL variables| and |parameters| are:
+
+
+
+ Let |virtualPressureSourceType| be the value of the |URL variables|["type"].
+
+
+ If the [=user agent=]'s [=supported source types=] does not
+ [=list/contain=] |virtualPressureSourceType|, return [=error=] with
+ [=error code|WebDriver error code=] [=invalid argument=].
+
+
+ Let |topLevelTraversable| be the current browsing
+ context's [=browsing context/top-level traversable=].
+
+
+ Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=].
+
+
+ If |topLevelVirtualPressureSourceMapping| does not [=map/contain=] |virtualPressureSource|,
+ return [=error=] with [=error code|WebDriver error code=]
+ unsupported operation.
+
+
+ Let |virtualPressureSource| be |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|].
+
+
+ Let |sample| be the result of invoking
+ get a property "sample" from |parameters|.
+
+
+ If |sample| is not of type {{PressureState}}, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=].
+
+
+ Set |virtualPressureSource|'s [=pressure source/latest sample=] to a new
+ [=pressure source sample=] whose [=pressure source sample/data=] is
+ |sample| and [=pressure source sample/timestamp=] is the [=unsafe shared
+ current time=].
+
+
+ In an [=implementation-defined=] way, make |virtualPressureSource|'s
+ [=pressure source/latest sample=] available to |virtualPressureSource|'s
+ [=virtual pressure source/connected platform collectors=].
+