Bug 1669801 - Fix the shared device menupopup when sharing an application window over WebRTC. r=pbz

Differential Revision: https://phabricator.services.mozilla.com/D92994
This commit is contained in:
Mike Conley 2020-10-13 01:13:04 +00:00
Родитель 5c8f07b488
Коммит 76bb38fdcb
8 изменённых файлов: 101 добавлений и 37 удалений

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

@ -11,6 +11,7 @@ prefs =
privacy.webrtc.legacyGlobalIndicator=false
privacy.webrtc.sharedTabWarning=true
[browser_device_controls_menus.js]
[browser_devices_get_user_media.js]
skip-if = (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_anim.js]

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

@ -0,0 +1,54 @@
/* 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";
/**
* Regression test for bug 1669801, where sharing a window would
* result in a device control menu that showed the wrong count.
*/
add_task(async function test_bug_1669801() {
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 });
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(
browser,
false /* camera */,
false /* microphone */,
SHARE_WINDOW
);
let indicator = await indicatorPromise;
let doc = indicator.document;
let menupopup = doc.querySelector("menupopup[type='Screen']");
let popupShownPromise = BrowserTestUtils.waitForEvent(
menupopup,
"popupshown"
);
menupopup.openPopup(doc.body, {});
await popupShownPromise;
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
menupopup,
"popuphidden"
);
menupopup.hidePopup();
await popupHiddenPromise;
});
});

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

@ -75,12 +75,7 @@ add_task(async function test_notifications() {
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(
browser,
true /* camera */,
true /* microphone */,
false /* screen */
);
await shareDevices(browser, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
@ -144,12 +139,7 @@ add_task(async function test_closing_indicator_resets_mute() {
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(
browser,
true /* camera */,
true /* microphone */,
false /* screen */
);
await shareDevices(browser, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
@ -215,12 +205,7 @@ add_task(async function test_new_processes() {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(
browser1,
true /* camera */,
true /* microphone */,
false /* screen */
);
await shareDevices(browser1, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
@ -272,12 +257,7 @@ add_task(async function test_new_processes() {
let microphoneMuted2 = waitForMicrophoneMuteState(browser2, true);
let cameraMuted2 = waitForCameraMuteState(browser2, true);
info("Sharing the microphone and camera from a new process.");
await shareDevices(
browser2,
true /* camera */,
true /* microphone */,
false /* screen */
);
await shareDevices(browser2, true /* camera */, true /* microphone */);
await Promise.all([microphoneMuted2, cameraMuted2]);
info("Unmuting microphone...");

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

@ -32,7 +32,7 @@ add_task(async function test_popuphiding() {
browser,
true /* camera */,
true /* microphone */,
true /* screen */
SHARE_SCREEN
);
let indicator = await indicatorPromise;

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

@ -42,7 +42,7 @@ add_task(async function test_stop_sharing() {
browser,
true /* camera */,
true /* microphone */,
true /* screen */
SHARE_SCREEN
);
let indicator = await indicatorPromise;
@ -76,12 +76,12 @@ add_task(async function test_stop_sharing_multiple() {
info("Opening first tab");
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera, microphone and screen");
await shareDevices(tab1.linkedBrowser, true, true, true);
await shareDevices(tab1.linkedBrowser, true, true, SHARE_SCREEN);
info("Opening second tab");
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera and screen");
await shareDevices(tab2.linkedBrowser, true, false, true);
await shareDevices(tab2.linkedBrowser, true, false, SHARE_SCREEN);
let indicator = await indicatorPromise;

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

@ -29,17 +29,17 @@ add_task(async function test_close_indicator() {
info("Opening first tab");
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera, microphone and screen");
await shareDevices(tab1.linkedBrowser, true, true, true);
await shareDevices(tab1.linkedBrowser, true, true, SHARE_SCREEN);
info("Opening second tab");
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera and screen");
await shareDevices(tab2.linkedBrowser, true, false, true);
await shareDevices(tab2.linkedBrowser, true, false, SHARE_SCREEN);
info("Opening third tab");
let tab3 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing screen");
await shareDevices(tab3.linkedBrowser, false, false, true);
await shareDevices(tab3.linkedBrowser, false, false, SHARE_SCREEN);
info("Opening fourth tab");
let tab4 = await BrowserTestUtils.openNewForegroundTab(

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

@ -42,6 +42,9 @@ const INDICATOR_PATH = USING_LEGACY_INDICATOR
const IS_MAC = AppConstants.platform == "macosx";
const SHARE_SCREEN = 1;
const SHARE_WINDOW = 2;
let observerTopics = [
"getUserMedia:response:allow",
"getUserMedia:revoke",
@ -976,11 +979,12 @@ async function runTests(tests, options = {}) {
* @param {<xul:browser} browser - The browser to share devices with.
* @param {boolean} camera - True to share a camera device.
* @param {boolean} mic - True to share a microphone device.
* @param {boolean} screen - True to share a display device.
* @param {Number} [screenOrWin] - One of either SHARE_WINDOW or SHARE_SCREEN
* to share a window or screen. Defaults to neither.
* @return {Promise}
* @resolves {undefined} - Once the sharing is complete.
*/
async function shareDevices(browser, camera, mic, screen) {
async function shareDevices(browser, camera, mic, screenOrWin = 0) {
if (camera || mic) {
let promise = promisePopupNotificationShown(
"webRTC-shareDevices",
@ -1003,7 +1007,7 @@ async function shareDevices(browser, camera, mic, screen) {
await promise;
}
if (screen) {
if (screenOrWin) {
let promise = promisePopupNotificationShown(
"webRTC-shareDevices",
null,
@ -1017,9 +1021,29 @@ async function shareDevices(browser, camera, mic, screen) {
let document = window.document;
// Select one of the windows / screens. It doesn't really matter which.
let menulist = document.getElementById("webRTC-selectWindow-menulist");
menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
let displayMediaSource;
if (screenOrWin == SHARE_SCREEN) {
displayMediaSource = "screen";
} else if (screenOrWin == SHARE_WINDOW) {
displayMediaSource = "window";
} else {
throw new Error("Got an invalid argument to shareDevices.");
}
let menuitem = null;
for (let i = 0; i < menulist.itemCount; ++i) {
let current = menulist.getItemAtIndex(i);
if (current.mediaSource == displayMediaSource) {
menuitem = current;
break;
}
}
Assert.ok(menuitem, "Should have found an appropriate display menuitem");
menuitem.doCommand();
let notification = window.PopupNotifications.panel.firstElementChild;
let observerPromise1 = expectObserverCalled("getUserMedia:response:allow");

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

@ -486,7 +486,7 @@ const WebRTCIndicator = {
} else if (type == "Microphone") {
activeStreams = webrtcUI.getActiveStreams(false, true, false);
} else if (type == "Screen") {
activeStreams = webrtcUI.getActiveStreams(false, false, true);
activeStreams = webrtcUI.getActiveStreams(false, false, true, true);
type = webrtcUI.showScreenSharingIndicator;
}
@ -494,6 +494,11 @@ const WebRTCIndicator = {
"chrome://browser/locale/webrtcIndicator.properties"
);
if (!activeStreams.length) {
event.preventDefault();
return;
}
if (activeStreams.length == 1) {
let stream = activeStreams[0];