Bug 1693644 - Only show a label for the camera/mic in the WebRTC device selector if there's only 1 device available or requested. r=pbz

Differential Revision: https://phabricator.services.mozilla.com/D105932
This commit is contained in:
Mike Conley 2021-02-23 15:13:45 +00:00
Родитель 86775aa29e
Коммит 3ffc2a1848
6 изменённых файлов: 157 добавлений и 11 удалений

Просмотреть файл

@ -700,20 +700,28 @@ function prompt(aActor, aBrowser, aRequest) {
return true;
}
function listDevices(menupopup, devices) {
function listDevices(menupopup, devices, label, deck) {
while (menupopup.lastChild) {
menupopup.removeChild(menupopup.lastChild);
}
let menulist = menupopup.parentNode;
// Removing the child nodes of the menupopup doesn't clear the value
// attribute of the menulist. This can have unfortunate side effects
// when the list is rebuilt with a different content, so we remove
// the value attribute and unset the selectedItem explicitly.
menupopup.parentNode.removeAttribute("value");
menupopup.parentNode.selectedItem = null;
menulist.removeAttribute("value");
menulist.selectedItem = null;
for (let device of devices) {
addDeviceToList(menupopup, device.name, device.deviceIndex);
}
if (devices.length == 1) {
label.value = devices[0].name;
deck.selectedIndex = 1;
} else {
deck.selectedIndex = 0;
}
}
function checkDisabledWindowMenuItem() {
@ -988,14 +996,18 @@ function prompt(aActor, aBrowser, aRequest) {
listScreenShareDevices(windowMenupopup, videoDevices);
checkDisabledWindowMenuItem();
} else {
listDevices(camMenupopup, videoDevices);
let label = doc.getElementById("webRTC-selectCamera-label");
let deck = doc.getElementById("webRTC-selectCamera-deck");
listDevices(camMenupopup, videoDevices, label, deck);
doc
.getElementById("webRTC-shareDevices-notification")
.removeAttribute("invalidselection");
}
if (!sharingAudio) {
listDevices(micMenupopup, audioDevices);
let label = doc.getElementById("webRTC-selectMicrophone-label");
let deck = doc.getElementById("webRTC-selectMicrophone-deck");
listDevices(micMenupopup, audioDevices, label, deck);
}
this.mainAction.callback = async function(aState) {

Просмотреть файл

@ -12,9 +12,12 @@
<popupnotificationcontent id="webRTC-selectCamera" orient="vertical">
<label data-l10n-id="popup-select-camera"
control="webRTC-selectCamera-menulist"/>
<menulist id="webRTC-selectCamera-menulist">
<menupopup id="webRTC-selectCamera-menupopup"/>
</menulist>
<deck id="webRTC-selectCamera-deck">
<menulist id="webRTC-selectCamera-menulist">
<menupopup id="webRTC-selectCamera-menupopup"/>
</menulist>
<label id="webRTC-selectCamera-label" class="webRTC-selectDevice-label"></label>
</deck>
</popupnotificationcontent>
<popupnotificationcontent id="webRTC-selectWindowOrScreen" orient="vertical">
@ -38,9 +41,12 @@
<popupnotificationcontent id="webRTC-selectMicrophone" orient="vertical">
<label data-l10n-id="popup-select-microphone"
control="webRTC-selectMicrophone-menulist"/>
<menulist id="webRTC-selectMicrophone-menulist">
<menupopup id="webRTC-selectMicrophone-menupopup"/>
</menulist>
<deck id="webRTC-selectMicrophone-deck">
<menulist id="webRTC-selectMicrophone-menulist">
<menupopup id="webRTC-selectMicrophone-menupopup"/>
</menulist>
<label id="webRTC-selectMicrophone-label" class="webRTC-selectDevice-label"></label>
</deck>
</popupnotificationcontent>
</popupnotification>

Просмотреть файл

@ -16,6 +16,7 @@ prefs =
[browser_devices_get_user_media.js]
skip-if = (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_anim.js]
[browser_devices_get_user_media_by_device_id.js]
[browser_devices_get_user_media_default_permissions.js]
[browser_devices_get_user_media_in_frame.js]
skip-if = debug # bug 1369731

Просмотреть файл

@ -0,0 +1,82 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_ROOT = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content/",
"https://example.com/"
);
const TEST_PAGE = TEST_ROOT + "get_user_media.html";
/**
* Utility function that should be called after a request for a device
* has been made. This function will allow sharing that device, and then
* immediately close the stream.
*/
async function allowStreamsThenClose() {
let observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
let observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
await closeStream();
}
/**
* Tests that if a site requests a particular device by ID, that
* the Permission Panel menulist for that device shows only that
* device and is disabled.
*/
add_task(async function test_get_user_media_by_device_id() {
let prefs = [
[PREF_PERMISSION_FAKE, true],
[PREF_AUDIO_LOOPBACK, ""],
[PREF_VIDEO_LOOPBACK, ""],
[PREF_FAKE_STREAMS, true],
[PREF_FOCUS_SOURCE, false],
];
await SpecialPowers.pushPrefEnv({ set: prefs });
let devices = await navigator.mediaDevices.enumerateDevices();
let audioId = devices
.filter(d => d.kind == "audioinput")
.map(d => d.deviceId)[0];
let videoId = devices
.filter(d => d.kind == "videoinput")
.map(d => d.deviceId)[0];
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let promise = promisePopupNotificationShown("webRTC-shareDevices");
let observerPromise = expectObserverCalled("getUserMedia:request");
await promiseRequestDevice({ deviceId: { exact: audioId } });
await promise;
await observerPromise;
checkDeviceSelectors(true /* aAudio */);
await allowStreamsThenClose();
promise = promisePopupNotificationShown("webRTC-shareDevices");
observerPromise = expectObserverCalled("getUserMedia:request");
await promiseRequestDevice(false, { deviceId: { exact: videoId } });
await promise;
await observerPromise;
checkDeviceSelectors(false, true /* aVideo */);
await allowStreamsThenClose();
promise = promisePopupNotificationShown("webRTC-shareDevices");
observerPromise = expectObserverCalled("getUserMedia:request");
await promiseRequestDevice(
{ deviceId: { exact: audioId } },
{ deviceId: { exact: videoId } }
);
await promise;
await observerPromise;
checkDeviceSelectors(true /* aAudio */, true /* aVideo */);
await allowStreamsThenClose();
});
});

Просмотреть файл

@ -736,15 +736,55 @@ async function reloadAndAssertClosedStreams() {
function checkDeviceSelectors(aAudio, aVideo, aScreen, aWindow = window) {
let document = aWindow.document;
let micSelector = document.getElementById("webRTC-selectMicrophone");
let micDeck = document.getElementById("webRTC-selectMicrophone-deck");
let micLabel = document.getElementById("webRTC-selectMicrophone-label");
if (aAudio) {
ok(!micSelector.hidden, "microphone selector visible");
let micSelectorList = document.getElementById(
"webRTC-selectMicrophone-menulist"
);
// If there's only 1 device listed, the deck should show the label instead.
if (micSelectorList.itemCount == 1) {
is(micDeck.selectedIndex, "1", "Should be showing the microphone label.");
is(
micLabel.value,
micSelectorList.selectedItem.getAttribute("label"),
"Label should be showing the lone device label."
);
} else {
is(
micDeck.selectedIndex,
"0",
"Should be showing the microphone menulist."
);
}
} else {
ok(micSelector.hidden, "microphone selector hidden");
}
let cameraSelector = document.getElementById("webRTC-selectCamera");
let cameraDeck = document.getElementById("webRTC-selectCamera-deck");
let cameraLabel = document.getElementById("webRTC-selectCamera-label");
if (aVideo) {
ok(!cameraSelector.hidden, "camera selector visible");
let cameraSelectorList = document.getElementById(
"webRTC-selectCamera-menulist"
);
// If there's only 1 device listed, the deck should show the label instead.
if (cameraSelectorList.itemCount == 1) {
is(cameraDeck.selectedIndex, "1", "Should be showing the camera label.");
is(
cameraLabel.value,
cameraSelectorList.selectedItem.getAttribute("label"),
"Label should be showing the lone device label."
);
} else {
is(
cameraDeck.selectedIndex,
"0",
"Should be showing the camera menulist."
);
}
} else {
ok(cameraSelector.hidden, "camera selector hidden");
}

Просмотреть файл

@ -768,3 +768,8 @@ menupopup::part(drop-indicator) {
#sharing-warning-proceed-to-tab:hover {
background-color: rgb(0,62,170);
}
.webRTC-selectDevice-label {
margin-top: 6px;
font-weight: 600;
}