Bug 1712892 Comment 2 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

(In reply to Karl Tomlinson (:karlt) from comment #0)
> There is a choice to make re whether to implement "Allow" either per speaker device or for all speaker devices.

My understanding is this is inherently per speaker, because this is first and foremoest a device picker, not a permission prompt. It's meant to stop JS from building its own in-content dropdown list, and instead call this one directly from the button showing the current selection: click → **Speakers:** `System default` which calls:
```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = await navigator.mediaDevices.selectAudioOutput();
    button.innerText = (await enumerateDevices()).filter(d => d.deviceId = deviceId).label;
  }
  await video.setSinkId(deviceId);
}
```
...which then reads:  **Speakers:** `Jan-Ivar's AirPods`

be called by JS in place of implementing in-content 

> If permission is granted for all speaker devices the UI may need to clarify that this is happening.

We wouldn't do that, because that would defeat getting rid of in-content device selection.

Instead, my [design](https://docs.google.com/document/d/1YOeyfaE-8pVqXbu4wxkvPIWd3t_YpWgZfE3dV1Wd2DQ/edit#heading=h.xqwymljyrda0) on this was that checking `☑ Remember this decision` would control whether we persist deviceIds to local storage. This lets JS bypass the prompt on future visits like this:

```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = localStorage.speakersId;
    deviceId = await navigator.mediaDevices.selectAudioOutput({deviceId}); // may bypass prompt
    button.innerText = (await enumerateDevices()).filter(d => d.deviceId = deviceId).label;
    localStorage.speakersId = deviceId;
  }
  await video.setSinkId(deviceId);
}
```
It's important that JS still go through the `selectAudioOutput` method, so we can prompt if the device is no longer permitted, providing a disincentive for trackers to validate these ids with `setSinkId` to fingerprint people.

In spite of the JS model being quite different, this should give a familiar user experience in that clicking `☑ Remember this decision` should side-step any future prompts from sites that want to reuse the speakers used last time.

Karl, does this match your understanding? With this model in mind, I had some difficulty parsing some of the suggestions in comment 0.
(In reply to Karl Tomlinson (:karlt) from comment #0)
> There is a choice to make re whether to implement "Allow" either per speaker device or for all speaker devices.

My understanding is this is inherently per speaker, because this is first and foremoest a device picker, not a permission prompt. It's meant to stop JS from building its own in-content dropdown list, and instead call this one directly from the button showing the current selection: click → **Speakers:** `System default` which calls:
```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = await navigator.mediaDevices.selectAudioOutput();
    button.innerText = (await enumerateDevices()).filter(d => d.deviceId == deviceId).label;
  }
  await video.setSinkId(deviceId);
}
```
...which then reads:  **Speakers:** `Jan-Ivar's AirPods`

be called by JS in place of implementing in-content 

> If permission is granted for all speaker devices the UI may need to clarify that this is happening.

We wouldn't do that, because that would defeat getting rid of in-content device selection.

Instead, my [design](https://docs.google.com/document/d/1YOeyfaE-8pVqXbu4wxkvPIWd3t_YpWgZfE3dV1Wd2DQ/edit#heading=h.xqwymljyrda0) on this was that checking `☑ Remember this decision` would control whether we persist deviceIds to local storage. This lets JS bypass the prompt on future visits like this:

```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = localStorage.speakersId;
    deviceId = await navigator.mediaDevices.selectAudioOutput({deviceId}); // may bypass prompt
    button.innerText = (await enumerateDevices()).filter(d => d.deviceId == deviceId).label;
    localStorage.speakersId = deviceId;
  }
  await video.setSinkId(deviceId);
}
```
It's important that JS still go through the `selectAudioOutput` method, so we can prompt if the device is no longer permitted, providing a disincentive for trackers to validate these ids with `setSinkId` to fingerprint people.

In spite of the JS model being quite different, this should give a familiar user experience in that clicking `☑ Remember this decision` should side-step any future prompts from sites that want to reuse the speakers used last time.

Karl, does this match your understanding? With this model in mind, I had some difficulty parsing some of the suggestions in comment 0.
(In reply to Karl Tomlinson (:karlt) from comment #0)
> There is a choice to make re whether to implement "Allow" either per speaker device or for all speaker devices.

My understanding is this is inherently per speaker, because this is first and foremoest a device picker, not a permission prompt. It's meant to stop JS from building its own in-content dropdown list, and instead call this one directly from the button showing the current selection: click → **Speakers:** `System default` which calls:
```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = await navigator.mediaDevices.selectAudioOutput();
    button.innerText = (await navigator.mediaDevices.enumerateDevices()).filter(d => d.deviceId == deviceId).label;
  }
  await video.setSinkId(deviceId);
}
```
...which then reads:  **Speakers:** `Jan-Ivar's AirPods`

be called by JS in place of implementing in-content 

> If permission is granted for all speaker devices the UI may need to clarify that this is happening.

We wouldn't do that, because that would defeat getting rid of in-content device selection.

Instead, my [design](https://docs.google.com/document/d/1YOeyfaE-8pVqXbu4wxkvPIWd3t_YpWgZfE3dV1Wd2DQ/edit#heading=h.xqwymljyrda0) on this was that checking `☑ Remember this decision` would control whether we persist deviceIds to local storage. This lets JS bypass the prompt on future visits like this:

```js
button.onclick = async () => {
  if (!deviceId) {
    deviceId = localStorage.speakersId;
    deviceId = await navigator.mediaDevices.selectAudioOutput({deviceId}); // may bypass prompt
    button.innerText = (await navigator.mediaDevices.enumerateDevices()).filter(d => d.deviceId == deviceId).label;
    localStorage.speakersId = deviceId;
  }
  await video.setSinkId(deviceId);
}
```
It's important that JS still go through the `selectAudioOutput` method, so we can prompt if the device is no longer permitted, providing a disincentive for trackers to validate these ids with `setSinkId` to fingerprint people.

In spite of the JS model being quite different, this should give a familiar user experience in that clicking `☑ Remember this decision` should side-step any future prompts from sites that want to reuse the speakers used last time.

Karl, does this match your understanding? With this model in mind, I had some difficulty parsing some of the suggestions in comment 0.

Back to Bug 1712892 Comment 2