diff --git a/index.bs b/index.bs index 7a529d4..8dc20b8 100644 --- a/index.bs +++ b/index.bs @@ -94,6 +94,10 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/browsers.html# type: dfn text: browsing context; url: browsing-context +spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/system-state.html# + type: dfn + text: associated Navigator; url: associated-navigator + spec: WebIDL; urlPrefix: https://heycam.github.io/webidl/# type: dfn text: a copy of the bytes held; url: dfn-get-buffer-source-copy @@ -543,6 +547,9 @@ that UAs will choose not to prompt. Bluetooth includes ServiceEventHandlers; +Methods defined in this specification typically complete asynchronously, queuing +work on the Bluetooth task source. +
Note: {{Bluetooth/getAvailability()}} informs the page whether Bluetooth is available at all. An adapter that's disabled through software should count as @@ -1218,8 +1225,9 @@ To getDevices() method, when invoked and given a {{BluetoothPermissionStorage}} |storage|, MUST return [=a new promise=] |promise| and run the following steps [=in parallel=]: -1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not - [=allowed to use=] the [=policy-controlled feature=] named +1. If [=this=]'s [=relevant global object=]'s + associated Document is not [=allowed to use=] the + [=policy-controlled feature=] named "[=policy-controlled feature/bluetooth=]", reject |promise| with a {{SecurityError}} and abort these steps. 1. Let |devices| be a new empty {{Array}}. @@ -1291,8 +1299,9 @@ all devices can match, a sequence of {{BluetoothServiceUUID}}s, devices, but for now it only ever returns a single one.
-1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not - [=allowed to use=] the [=policy-controlled feature=] named +1. If [=this=]'s [=relevant global object=]'s associated + Document is not [=allowed to use=] the + [=policy-controlled feature=] named "[=policy-controlled feature/bluetooth=]", throw a {{SecurityError}} and abort these steps. 1.

Check that the algorithm is triggered @@ -1825,10 +1834,13 @@ The getAvailability() method, when invoked, MUST return a new promise |promise| and run the following steps in parallel: -1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not - [=allowed to use=] the [=policy-controlled feature=] named - "[=policy-controlled feature/bluetooth=]", queue a task to - resolve |promise| with `false`, and abort these steps. +1. Let |global| be the [=relevant global object=] of [=this=]. +1. If [=this=]'s [=relevant global object=]'s associated + Document is not [=allowed to use=] the + [=policy-controlled feature=] named + "[=policy-controlled feature/bluetooth=]", [=queue a global task=] on + |global| using the [=Bluetooth task source=] to resolve |promise| + with `false`, and abort these steps. 1.

If the user has configured the UA to return a particular answer from this function for the current origin, queue a task to resolve |promise| with the configured answer, and abort @@ -1841,7 +1853,8 @@ steps in parallel: 1. If the UA is running on a system that has a Bluetooth radio queue a task to resolve |promise| with `true` regardless of the powered state of the Bluetooth radio. -1. Otherwise, queue a task to resolve |promise| with `false`. +1. Otherwise, [=queue a global task=] on |global| using the + [=Bluetooth task source=] to resolve |promise| with `false`.

Note: The promise is resolved in parallel to let the UA call out to @@ -1880,17 +1893,21 @@ navigator.permissions.query({name: "bl If the UA becomes able or unable to use Bluetooth, for example because a radio was physically attached or detached, or the user has changed their configuration for the answer returned from -{{getAvailability()}}, the UA must queue a task on each global -object |global|'s responsible event loop to run the following steps: +{{getAvailability()}}, the UA must [=queue a global task=] on each [=global +object=] |global| using the [=Bluetooth task source=] to run the following +steps: 1. Let |oldAvailability| be the value {{getAvailability()}} would have returned before the change. 1. Let |newAvailability| be the value {{getAvailability()}} would return after the change. -1. If |oldAvailability| is not the same as |newAvailability|, fire an - event named {{availabilitychanged}} using the {{ValueEvent}} interface - at |global|.navigator.bluetooth with its {{ValueEvent/value}} - attribute initialized to |newAvailability|. +1. If |oldAvailability| is not the same as |newAvailability|, + 1. Let |navigator| be |global|'s associated Navigator. + 1. Let |bluetooth| be |navigator|'s associated + Bluetooth. + 1. [=Fire an event=] named {{availabilitychanged}} using the {{ValueEvent}} + interface at |bluetooth| with its {{ValueEvent/value}} attribute + initialized to |newAvailability|.
@@ -2149,6 +2166,7 @@ The watchAdvertisements(|options|) method, when invoked, MUST return a new promise |promise| and run the following steps: +1. Let |global| be the [=relevant global object=] of [=this=]. 1. If |options|.{{AbortSignal|signal}} is present, then perform the following sub-steps: 1. If |options|.{{AbortSignal|signal}} is @@ -2171,8 +2189,9 @@ run the following steps: 1. Ensure that the UA is scanning for this device's advertisements. The UA SHOULD NOT filter out "duplicate" advertisements for the same device. - 1. If the UA fails to enable scanning, [=queue a task=] to - perform the following steps, and abort these steps: + 1. If the UA fails to enable scanning, [=queue a global task=] on + |global| using the [=Bluetooth task source=] to perform the + following steps, and abort these steps: 1. Set this.{{[[watchAdvertisementsState]]}} to `'not-watching'`. 1. [=Reject=] |promise| with one of the following errors: @@ -2186,9 +2205,11 @@ run the following steps: :: {{UnknownError}} - 1. [=Queue a task=] to perform the following steps, but [=abort - when=] this.{{[[watchAdvertisementsState]]}} - becomes `not-watching`: + 1. [=Queue a global task=] on |global| using the + [=Bluetooth task source=] to perform the following steps, but + [=abort when=] + this.{{[[watchAdvertisementsState]]}} becomes + `not-watching`: 1. Set this.{{[[watchAdvertisementsState]]}} to `watching`. 1. Set this.{{watchingAdvertisements}} to `true`. @@ -2227,12 +2248,11 @@ To abort {{BluetoothDevice/watchAdvertisements}} for a
To abort all active {{BluetoothDevice/watchAdvertisements}} -operations, run these steps: +operations given a {{Bluetooth}} |bluetooth|, run these steps: -1. [=map/For each=] |device| in - {{Bluetooth}}.{{[[deviceInstanceMap]]}}, perform the - following steps: - 1. If |device|.{{[[watchAdvertisementsState]]}} is +1. [=map/For each=] |device| in + |bluetooth|.{{[[deviceInstanceMap]]}}, perform the following steps: + 1. If |device|.{{[[watchAdvertisementsState]]}} is `pending-watch` or `watching`, run [=abort watchAdvertisements=] with |device|. @@ -2248,15 +2268,19 @@ aborted.
When the user agent determines that the [=document visibility state|visibility -state=] of the associated Document of the -[=current settings object=]'s [=relevant global object=] changes, it must run -these steps: - -1. Let |document| be the associated Document of - the [=current settings object=]'s [=relevant global object=]. -1. If |document|'s [=document visibility state|visibility state=] - is not "visible", then [=abort all active watchAdvertisements=] - operations. +state=] of a {{Document}} changes, it must run these steps: + +1. Let |document| be the {{Document}} where the + [=document visibility state|visibility state=] changed. +1. Let |global| be |document|'s [=relevant global object=]. +1. [=Queue a global task=] on |global| using the [=Bluetooth task source=] to + perform the following steps: + 1. Let |navigator| be |global|'s associated Navigator. + 1. Let |bluetooth| be |navigator|'s associated + Bluetooth. + 1. If |document|'s [=document visibility state|visibility state=] + is not "visible", then [=abort all active + watchAdvertisements=] operations on |bluetooth|.
@@ -2269,11 +2293,17 @@ active=] [=document=]. When [=fully active|full activity=] is lost, scanning operations for that [=document=] need to be aborted.
-When the user agent determines that a associated Document of -the [=current settings object=]'s [=relevant global object=] is no longer -[=fully active=], it must run these steps: - -1. Run [=abort all active watchAdvertisements=] operations. +When the user agent determines that a {{Document}} is no longer [=fully +active=], it must run these steps: + +1. Let |document| be the {{Document}} that is no longer [=fully active=]. +1. Let |global| be |document|'s [=relevant global object=]. +1. [=Queue a global task=] on |global| using the [=Bluetooth task source=] to + perform the following steps: + 1. Let |navigator| be |global|'s associated Navigator. + 1. Let |bluetooth| be |navigator|'s associated + Bluetooth. + 1. Run [=abort all active watchAdvertisements=] operations on |bluetooth|.
@@ -2909,12 +2939,13 @@ The connect() method, when invoked, MUST perform the following steps: 1. Let |promise| be a new promise. +1. Let |global| be [=this=]'s [=relevant global object=]. 1. If this.device.{{[[representedDevice]]}} is `null`, queue a task to reject |promise| with a {{NetworkError}}, return |promise|, and abort these steps. -1. If the UA is currently using the Bluetooth system, it MAY queue a task - to reject |promise| with a {{NetworkError}}, return |promise|, and - abort these steps. +1. If the UA is currently using the Bluetooth system, it MAY [=queue a global + task=] on |global| using the [=Bluetooth task source=] to [=reject=] + |promise| with a {{NetworkError}}, return |promise|, and abort these steps. Issue(188): Implementations may be able to avoid this {{NetworkError}}, but for now sites need to serialize their use of this API @@ -2954,7 +2985,8 @@ method, when invoked, MUST perform the following steps: platforms where that's possible. This may cause a user-visible pairing dialog to appear when a connection is created, instead of when a restricted characteristic is accessed. - 1. Queue a task to perform the following sub-steps: + 1. [=Queue a global task=] on |global| using the [=Bluetooth task source=] + to perform the following sub-steps: 1. If |promise| is not in this.{{[[activeAlgorithms]]}}, reject promise with an {{AbortError}}, garbage-collect the connection of @@ -3355,7 +3387,8 @@ The readValue() Handle errors as described in . 1. If the previous step returned an error, reject promise with that error and abort these steps. - 1. Queue a task to perform the following steps: + 1. [=Queue a global task=] on [=this=]'s [=relevant global object=] using + the [=Bluetooth task source=] to perform the following steps: 1. If promise is not in this.service.device.gatt.{{[[activeAlgorithms]]}}, reject promise with a {{NetworkError}} and abort @@ -3423,7 +3456,8 @@ the UA MUST perform the following steps: Handle errors as described in . 1. If the previous step returned an error, reject promise with that error and abort these steps. - 1. Queue a task to perform the following steps: + 1. [=Queue a global task=] on [=this=]'s [=relevant global object=] using + the [=Bluetooth task source=] to perform the following steps: 1. If promise is not in |this|.service.device.gatt.{{[[activeAlgorithms]]}}, reject promise with a {{NetworkError}} and abort @@ -3562,7 +3596,8 @@ promise promise and run the following steps in parallel: Descriptors procedures to clear the Notification and Indication bits in characteristic's Client Characteristic Configuration descriptor. -1. Queue a task to resolve promise with `this`. +1. [=Queue a global task=] on [=this=]'s [=relevant global object=] using the + [=Bluetooth task source=] to [=resolve=] |promise| with `this`.
Note: Queuing a task to resolve the promise ensures that no @@ -3757,7 +3792,8 @@ readValue() method, when invoked, MUST run the following steps: href="#error-handling">. 1. If the previous step returned an error, reject promise with that error and abort these steps. - 1. Queue a task to perform the following steps: + 1. [=Queue a global task=] on [=this=]'s [=relevant global object=] using the + [=Bluetooth task source=] to perform the following steps: 1. If promise is not in this.characteristic.service.device.gatt.{{[[activeAlgorithms]]}}, reject promise with a {{NetworkError}} and abort @@ -3802,7 +3838,8 @@ following steps: . 1. If the previous step returned an error, reject promise with that error and abort these steps. - 1. Queue a task to perform the following steps: + 1. [=Queue a global task=] on [=this=]'s [=relevant global object=] using the + [=Bluetooth task source=] to perform the following steps: 1. If promise is not in this.characteristic.service.device.gatt.{{[[activeAlgorithms]]}}, reject promise with a {{NetworkError}} and abort @@ -3929,8 +3966,8 @@ interface participate in a tree. When a Bluetooth device device's ATT Bearer is lost (e.g. because the remote device moved out of range or the user used a platform feature to disconnect it), for each {{BluetoothDevice}} deviceObj the -UA MUST queue a task on deviceObj's relevant settings -object's responsible event loop to perform the following steps: +UA MUST [=queue a global task=] on |deviceObj|'s [=relevant global object=] +using the [=Bluetooth task source=] to perform the following steps: 1. If deviceObj.{{BluetoothDevice/[[representedDevice]]}} is not the same device as device, abort these steps. @@ -3988,9 +4025,9 @@ When the UA receives a Bluetooth Characteristic Value Notification or Indication, it must perform the following steps: -1. For each bluetoothGlobal in the Characteristic's active - notification context set, queue a task on the event loop of the - script settings object of bluetoothGlobal to do the following +1. For each |bluetoothGlobal| in the Characteristic's [=active notification + context set=], [=queue a global task=] on |bluetoothGlobal|'s [=relevant + global object=] using the [=Bluetooth task source=] to do the following sub-steps: 1. Let characteristicObject be the {{BluetoothRemoteGATTCharacteristic}} in the Bluetooth tree @@ -4163,9 +4200,10 @@ Changed characteristic, it MUST perform the following steps. 1. Let changedDevices be the set of Bluetooth devices that contain any Service in removedAttributes, addedAttributes, and changedServices. -1. For each {{BluetoothDevice}} deviceObj that is connected to a - device in changedDevices, queue a task on its relevant - global object's responsible event loop to do the following steps: +1. For each {{BluetoothDevice}} |deviceObj| that is connected to a device in + |changedDevices|, [=queue a global task=] on |deviceObj|'s [=relevant + global object=] using the [=Bluetooth task source=] to do the following + steps: 1. For each Service service in removedAttributes: 1. If deviceObj.{{BluetoothDevice/[[allowedServices]]}} @@ -4587,6 +4625,14 @@ blocklist. }; +Each {{Navigator}} has an associated Bluetooth, which is +a {{Bluetooth}} object. Upon creation of the {{Navigator}} object, its +associated Bluetooth must be set to a [=new=] {{Bluetooth}} +object created in the {{Navigator}} object's [=relevant Realm=]. + +The {{Navigator/bluetooth}} getter steps are to return [=this=]'s associated +Bluetooth. + # Integrations # {#integrations} ## Permissions Policy ## {#permissions-policy}