зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
86775aa29e
Коммит
3ffc2a1848
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче