diff --git a/index.html b/index.html index 9d7cf5a..8c616fa 100644 --- a/index.html +++ b/index.html @@ -216,7 +216,7 @@

Sampling and Reporting Rate

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=]: +

+

+

+ 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: +

+ +

+ 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=]:
    1. - 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.
    2. - Activate [=data delivery=] of |source| data to |relevantGlobal|. + If |relevantGlobal|'s [=platform collector mapping=] + [=map/contains=] |source|: +
        +
      1. + Set |platformCollector| to |relevantGlobal|'s [=platform + collector mapping=][|source|]. +
      2. +
      +
    3. +
    4. + Otherwise: +
        +
      1. + Let |newCollector| be a new [=platform collector=] whose + [=platform collector/associated pressure source=] is null. +
      2. +
      3. + Let |virtualPressureSource:virtual pressure source or null| + be the result of invoking [=get a virtual pressure source=] + with |source| and |relevantGlobal|. +
      4. +
      5. + If |virtualPressureSource| is not null: +
          +
        1. + If |virtualPressureSource|'s [=virtual pressure + source/can provide samples=] is true: +
            +
          1. + Set |newCollector|'s [=platform collector/associated + pressure source=] to |virtualPressureSource|. +
          2. +
          3. + [=set/Append=] |newCollector| to + |virtualPressureSource|'s [=virtual pressure + source/connected platform collectors=]. +
          4. +
          +
        2. +
        +
      6. +
      7. + Otherwise: +
          +
        1. + Let |realPressureSource| be an [=implementation-defined=] + [=pressure source=] that provides telemetry data about + |source|, or null if none exists. +
        2. +
        3. + Set |newCollector|'s [=platform collector/associated + pressure source=] to |realPressureSource|. +
        4. +
        +
      8. +
      9. + If |newCollector|'s [=platform collector/associated + pressure source=] is not null: +
          +
        1. + Set |platformCollector| to |newCollector|. +
        2. +
        3. + Set |relevantGlobal|'s [=platform collector + mapping=][|source|] to |platformCollector|. +
        4. +
        +
      10. +
      +
    5. +
    6. + If |platformCollector| is null, [=queue a global task=] on the + [=PressureObserver task source=] given |relevantGlobal| to reject + |promise| {{NotSupportedError}} and abort these steps. +
    7. +
    8. + Invoke [=activate data collection=] with |source| and + |relevantGlobal|.
    9. [=Queue a global task=] on the [=PressureObserver task source=] given @@ -623,7 +748,7 @@

      The observe() method

      1. 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|.
      2. Return. @@ -686,9 +811,13 @@

        The unobserve() method

        If |registeredObserverList| is [=list/empty=]:
        1. - Deactivate [=data delivery=] of |source| data to + Invoke [=deactivate data collection=] with |source| and |relevantGlobal|.
        2. +
        3. + [=map/Remove=] |relevantGlobal|'s [=platform collector + mapping=][|source|]. +
      @@ -730,9 +859,13 @@

      The disconnect() method

      If |registeredObserverList| is [=list/empty=]:
      1. - Deactivate [=data delivery=] of |source| data to + Invoke [=deactivate data collection=] with |source| and |relevantGlobal|.
      2. +
      3. + [=map/Remove=] |relevantGlobal|'s [=platform collector + mapping=][|source|]. +
    @@ -1107,49 +1240,193 @@

    Supporting algorithms

    +

    + 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. +

      +
    1. Let |topLevelTraversable| be null.
    2. +
    3. + If |relevantGlobal| is a {{Window}} object: +
        +
      1. + Set |topLevelTraversable| to |relevantGlobal|'s [=Window/navigable=]'s [=top-level traversable=]. +
      2. +
      +
    4. +
    5. + If |relevantGlobal| is a {{DedicatedWorkerGlobalScope}} object: +
        +
      1. + Let |owningDocuments| be |relevantGlobal|'s [=owning document set=]. +
      2. +
      3. + If |owningDocuments| is [=set/empty=], return null. +
      4. +
      5. + [=Assert=]: |owningDocuments|'s [=set/size=] is 1. +
      6. +
      7. + Set |topLevelTraversable| to |owningDocuments|[0]'s [=node navigable=]'s [=top-level traversable=]. +
      8. +
      +
    6. +
    7. + If |topLevelTraversable| is null, return null. +
    8. +
    9. + Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=]. +
    10. +
    11. + Let |virtualPressureSource| be null. +
    12. +
    13. + If |topLevelVirtualPressureSourceMapping| [=map/contains=] |source|: +
        +
      1. + Set |virtualPressureSource| to |topLevelVirtualPressureSourceMapping|[|source|]. +
      2. +
      +
    14. +
    15. + Return |virtualPressureSource|. +
    16. +
    +

    -

    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:

    - +
      +
    1. + If |relevantGlobal|'s [=platform collector mapping=] does not + [=map/contain=] |source|, abort these steps. +
    2. +
    3. + Let |platformCollector| be |relevantGlobal|'s [=platform collector + mapping=][|source|]. +
    4. +
    5. + If |platformCollector|'s [=platform collector/activated=] is true, + abort these steps. +
    6. +
    7. + Set |platformCollector|'s [=platform collector/activated=] to true. +
    8. +
    9. + In an [=implementation-defined=] manner, start running the [=data + collection=] steps with |relevantGlobal|, |source|, and + |platformCollector|. + +
    10. +

    - 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: +

      +
        +
      1. + If |relevantGlobal|'s [=platform collector mapping=] does not + [=map/contain=] |source|, abort these steps. +
      2. +
      3. + Let |platformCollector| be |relevantGlobal|'s [=platform collector + mapping=][|source|]. +
      4. +
      5. + If |platformCollector|'s [=platform collector/activated=] is false, + abort these steps. +
      6. +
      7. + In an [=implementation-defined=] manner, stop running the [=data + collection=] steps with |relevantGlobal|, |source|, and + |platformCollector|. +
      8. +
      9. + Set |platformCollector|'s [=platform collector/activated=] to false. +
      10. +
      11. + If |platformCollector|'s [=platform collector/associated pressure + source=] is a [=virtual pressure source=]: +
          +
        1. + [=set/Remove=] |platformCollector| from its [=platform + collector/associated pressure source=]'s [=virtual pressure + source/connected platform collectors=]. +
        2. +
        +
      12. +
      13. + Otherwise, perform any [=implementation-defined=] steps to signal to + |platformCollector|'s [=platform collector/associated pressure source=] + to stop retrieving telemetry data. +
      14. +
      +

      + The data collection steps given |relevantGlobal|, |source| and + |platformCollector| are as follows: +

      1. - Let |source:PressureSource| be the [=source type=] of the |data| sample. + Let |pressureSource| be |platformCollector|'s [=platform + collector/associated pressure source=].
      2. - Let |state:PressureState| be an [=adjusted pressure state=] given |data| and |source|. - + If |pressureSource| is null, abort these steps.
      3. - 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=]. +
      4. +
      5. + If |sample| is null, abort these steps. +
      6. +
      7. + Let |state:PressureState| be null.
      8. - Let |timeValue| be the [=relative high resolution time=] based on |timestamp| and - |relevantGlobal|. + If |pressureSource| is a [=virtual pressure source=]: +
          +
        1. + Set |state| to |sample|'s [=pressure source sample/data=]. +
        2. +
        +
      9. +
      10. + Otherwise: +
          +
        1. + Set |state| to an [=adjusted pressure state=] calculated from + |source| and |sample|'s [=pressure source sample/data=]. + +
        2. +
        +
      11. +
      12. + [=Assert=]: |state| is not null. +
      13. +
      14. + Let |rawTimestamp| be |sample|'s [=pressure source + sample/timestamp=]. +
      15. +
      16. + Let |timeValue| be the [=relative high resolution time=] based on + |rawTimestamp| and |relevantGlobal|.
      17. [=list/For each=] |observer:PressureObserver| in |relevantGlobal|'s @@ -1313,7 +1590,12 @@

        Handling change of [=Document/fully active=] status

        [=registered observer list=] [=ordered map=]:
        1. - Deactivate [=data delivery=] of |source| to |relevantGlobal|. + Invoke [=deactivate data collection=] with |source| and + |relevantGlobal|. +
        2. +
        3. + [=map/Remove=] |relevantGlobal|'s [=platform collector + mapping=][|source|].
      18. @@ -1358,7 +1640,12 @@

        Handling changes to worker status

        [=registered observer list=] [=ordered map=]:
        1. - Deactivate [=data delivery=] of |source| to |relevantGlobal|. + Invoke [=deactivate data collection=] with |source| and + |relevantGlobal|. +
        2. +
        3. + [=map/Remove=] |relevantGlobal|'s [=platform collector + mapping=][|source|].
        @@ -1654,6 +1941,374 @@

    +
    +

    + Automation +

    +

    + 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: +

    +

    +

    + 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: +

    +
      +
    1. + Let |virtualPressureSourceType| be the result of invoking + get a property "type" from |parameters|. +
    2. +
    3. + If the [=user agent=]'s [=supported source types=] does not + [=list/contain=] |virtualPressureSourceType|, return [=error=] with + [=error code|WebDriver error code=] [=invalid argument=]. +
    4. +
    5. + Let |topLevelTraversable| be the current browsing + context's [=browsing context/top-level traversable=]. +
    6. +
    7. + Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=]. +
    8. +
    9. + If |topLevelVirtualPressureSourceMapping| contains |virtualPressureSourceType|, return [=error=] with + [=error code|WebDriver error code=] [=invalid argument=]. +
    10. +
    11. + Let |supported| be the result of invoking get a + property with default + with "supported" and true from |parameters|. +
    12. +
    13. + Let |virtualPressureSource| be a new [=virtual pressure source=]. +
    14. +
    15. + Set |virtualPressureSource|'s [=virtual pressure source/can provide + samples=] to |supported|. +
    16. +
    17. + Set |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|] to |virtualPressureSource|. +
    18. +
    19. + Return [=success=] with data null. +
    20. +
    +

    + 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: +

    +
      +
    1. + Let |virtualPressureSourceType| be the value of the |URL variables|["type"]. +
    2. +
    3. + If the [=user agent=]'s [=supported source types=] does not + [=list/contain=] |virtualPressureSourceType|, return [=error=] with + [=error code|WebDriver error code=] [=invalid argument=]. +
    4. +
    5. + Let |topLevelTraversable| be the current browsing + context's [=browsing context/top-level traversable=]. +
    6. +
    7. + Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=]. +
    8. +
    9. + Let |pressureSource| be |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|]. +
    10. +
    11. + [=set/For each=] |platformCollector| of |pressureSource|'s [=virtual + pressure source/connected platform collectors=]: +
        +
      1. + Set |platformCollector|'s [=platform collector/associated pressure + source=] to null. +
      2. +
      +
    12. +
    13. + [=map/Remove=] |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|]. +
    14. +
    15. + Return [=success=] with data null. +
    16. +
    + +

    + Update virtual pressure source +

    + + + + + + + + + +
    + HTTP Method + + [=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: +

    +
      +
    1. + Let |virtualPressureSourceType| be the value of the |URL variables|["type"]. +
    2. +
    3. + If the [=user agent=]'s [=supported source types=] does not + [=list/contain=] |virtualPressureSourceType|, return [=error=] with + [=error code|WebDriver error code=] [=invalid argument=]. +
    4. +
    5. + Let |topLevelTraversable| be the current browsing + context's [=browsing context/top-level traversable=]. +
    6. +
    7. + Let |topLevelVirtualPressureSourceMapping| be the |topLevelTraversable|'s [=virtual pressure source mapping=]. +
    8. +
    9. + If |topLevelVirtualPressureSourceMapping| does not [=map/contain=] |virtualPressureSource|, + return [=error=] with [=error code|WebDriver error code=] + unsupported operation. +
    10. +
    11. + Let |virtualPressureSource| be |topLevelVirtualPressureSourceMapping|[|virtualPressureSourceType|]. +
    12. +
    13. + Let |sample| be the result of invoking + get a property "sample" from |parameters|. +
    14. +
    15. + If |sample| is not of type {{PressureState}}, return [=error=] with [=error code|WebDriver error code=] [=invalid argument=]. +
    16. +
    17. + 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=]. +
    18. +
    19. + In an [=implementation-defined=] way, make |virtualPressureSource|'s + [=pressure source/latest sample=] available to |virtualPressureSource|'s + [=virtual pressure source/connected platform collectors=]. +
    20. +
    21. + Return [=success=] with data null. +
    22. +
    +