From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- ...browser_devices_get_user_media_multi_process.js | 517 +++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js (limited to 'browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js') diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js new file mode 100644 index 0000000000..fa88b5d030 --- /dev/null +++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js @@ -0,0 +1,517 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gTests = [ + { + desc: "getUserMedia audio in a first process + video in a second process", + // These tests call enableObserverVerification manually on a second tab, so + // don't add listeners to the first tab. + skipObserverVerification: true, + run: async function checkMultiProcess() { + // The main purpose of this test is to ensure webrtc sharing indicators + // work with multiple content processes, but it makes sense to run this + // test without e10s too to ensure using webrtc devices in two different + // tabs is handled correctly. + + // Request audio in the first tab. + let observerPromise = expectObserverCalled("getUserMedia:request"); + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true); + await promise; + await observerPromise; + + checkDeviceSelectors(["microphone"]); + + let observerPromise1 = expectObserverCalled( + "getUserMedia:response:allow" + ); + let observerPromise2 = expectObserverCalled("recording-device-events"); + let indicator = promiseIndicatorWindow(); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true }, + "expected microphone to be shared" + ); + + await indicator; + await checkSharingUI({ audio: true }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + !webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator hidden" + ); + ok( + webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator shown" + ); + is( + webrtcUI.getActiveStreams(false, true).length, + 1, + "1 active audio stream" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 1, + "1 active stream" + ); + + // If we have reached the max process count already, increase it to ensure + // our new tab can have its own content process. + let childCount = Services.ppmm.childCount; + let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount"); + // The first check is because if we are on a branch where e10s-multi is + // disabled, we want to keep testing e10s with a single content process. + // The + 1 is because ppmm.childCount also counts the chrome process + // (which also runs process scripts). + if (maxContentProcess > 1 && childCount == maxContentProcess + 1) { + await SpecialPowers.pushPrefEnv({ + set: [["dom.ipc.processCount", childCount]], + }); + } + + // Open a new tab with a different hostname. + let url = gBrowser.currentURI.spec.replace( + "https://example.com/", + "http://127.0.0.1:8888/" + ); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + + await enableObserverVerification(); + + // Request video. + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await promise; + await observerPromise; + + checkDeviceSelectors(["camera"]); + + observerPromise1 = expectObserverCalled("getUserMedia:response:allow"); + observerPromise2 = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + + await checkSharingUI({ video: true }, window, { + audio: true, + video: true, + }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator shown" + ); + ok( + webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator shown" + ); + is( + webrtcUI.getActiveStreams(false, true).length, + 1, + "1 active audio stream" + ); + is(webrtcUI.getActiveStreams(true).length, 1, "1 active video stream"); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 2, + "2 active streams" + ); + + info("removing the second tab"); + + await disableObserverVerification(); + + BrowserTestUtils.removeTab(tab); + + // Check that we still show the sharing indicators for the first tab's stream. + await Promise.all([ + TestUtils.waitForCondition(() => !webrtcUI.showCameraIndicator), + TestUtils.waitForCondition( + () => webrtcUI.getActiveStreams(true, true, true).length == 1 + ), + ]); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + !webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator hidden" + ); + ok( + webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator shown" + ); + is( + webrtcUI.getActiveStreams(false, true).length, + 1, + "1 active audio stream" + ); + + await checkSharingUI({ audio: true }); + + // Close the first tab's stream and verify that all indicators are removed. + await closeStream(false, null, true); + + ok( + !webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator hidden" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 0, + "0 active streams" + ); + }, + }, + + { + desc: "getUserMedia camera in a first process + camera in a second process", + skipObserverVerification: true, + run: async function checkMultiProcessCamera() { + let observerPromise = expectObserverCalled("getUserMedia:request"); + // Request camera in the first tab. + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await promise; + await observerPromise; + + checkDeviceSelectors(["camera"]); + + let indicator = promiseIndicatorWindow(); + let observerPromise1 = expectObserverCalled( + "getUserMedia:response:allow" + ); + let observerPromise2 = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + Assert.deepEqual( + await getMediaCaptureState(), + { video: true }, + "expected camera to be shared" + ); + + await indicator; + await checkSharingUI({ video: true }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator shown" + ); + ok( + !webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator hidden" + ); + is(webrtcUI.getActiveStreams(true).length, 1, "1 active camera stream"); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 1, + "1 active stream" + ); + + // If we have reached the max process count already, increase it to ensure + // our new tab can have its own content process. + let childCount = Services.ppmm.childCount; + let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount"); + // The first check is because if we are on a branch where e10s-multi is + // disabled, we want to keep testing e10s with a single content process. + // The + 1 is because ppmm.childCount also counts the chrome process + // (which also runs process scripts). + if (maxContentProcess > 1 && childCount == maxContentProcess + 1) { + await SpecialPowers.pushPrefEnv({ + set: [["dom.ipc.processCount", childCount]], + }); + } + + // Open a new tab with a different hostname. + let url = gBrowser.currentURI.spec.replace( + "https://example.com/", + "http://127.0.0.1:8888/" + ); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + + await enableObserverVerification(); + + // Request camera in the second tab. + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await promise; + await observerPromise; + + checkDeviceSelectors(["camera"]); + + observerPromise1 = expectObserverCalled("getUserMedia:response:allow"); + observerPromise2 = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + + await checkSharingUI({ video: true }, window, { video: true }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator shown" + ); + ok( + !webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator hidden" + ); + is(webrtcUI.getActiveStreams(true).length, 2, "2 active camera streams"); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 2, + "2 active streams" + ); + + await disableObserverVerification(); + + info("removing the second tab"); + BrowserTestUtils.removeTab(tab); + + // Check that we still show the sharing indicators for the first tab's stream. + await Promise.all([ + TestUtils.waitForCondition(() => webrtcUI.showCameraIndicator), + TestUtils.waitForCondition( + () => webrtcUI.getActiveStreams(true).length == 1 + ), + ]); + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator shown" + ); + ok( + !webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator hidden" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 1, + "1 active stream" + ); + + await checkSharingUI({ video: true }); + + // Close the first tab's stream and verify that all indicators are removed. + await closeStream(false, null, true); + + ok( + !webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator hidden" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 0, + "0 active streams" + ); + }, + }, + + { + desc: "getUserMedia screen sharing in a first process + screen sharing in a second process", + skipObserverVerification: true, + run: async function checkMultiProcessScreen() { + // Request screen sharing in the first tab. + let observerPromise = expectObserverCalled("getUserMedia:request"); + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true, null, "screen"); + await promise; + await observerPromise; + + is( + PopupNotifications.getNotification("webRTC-shareDevices").anchorID, + "webRTC-shareScreen-notification-icon", + "anchored to device icon" + ); + checkDeviceSelectors(["screen"]); + + // Select the last screen so that we can have a stream. + let menulist = document.getElementById("webRTC-selectWindow-menulist"); + menulist.getItemAtIndex(menulist.itemCount - 1).doCommand(); + + let indicator = promiseIndicatorWindow(); + let observerPromise1 = expectObserverCalled( + "getUserMedia:response:allow" + ); + let observerPromise2 = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + Assert.deepEqual( + await getMediaCaptureState(), + { screen: "Screen" }, + "expected screen to be shared" + ); + + await indicator; + await checkSharingUI({ screen: "Screen" }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showScreenSharingIndicator, + "webrtcUI wants the screen sharing indicator shown" + ); + ok( + !webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator hidden" + ); + ok( + !webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator hidden" + ); + is( + webrtcUI.getActiveStreams(false, false, true).length, + 1, + "1 active screen sharing stream" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 1, + "1 active stream" + ); + + // If we have reached the max process count already, increase it to ensure + // our new tab can have its own content process. + let childCount = Services.ppmm.childCount; + let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount"); + // The first check is because if we are on a branch where e10s-multi is + // disabled, we want to keep testing e10s with a single content process. + // The + 1 is because ppmm.childCount also counts the chrome process + // (which also runs process scripts). + if (maxContentProcess > 1 && childCount == maxContentProcess + 1) { + await SpecialPowers.pushPrefEnv({ + set: [["dom.ipc.processCount", childCount]], + }); + } + + // Open a new tab with a different hostname. + let url = gBrowser.currentURI.spec.replace( + "https://example.com/", + "https://example.com/" + ); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + + await enableObserverVerification(); + + // Request screen sharing in the second tab. + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true, null, "screen"); + await promise; + await observerPromise; + + is( + PopupNotifications.getNotification("webRTC-shareDevices").anchorID, + "webRTC-shareScreen-notification-icon", + "anchored to device icon" + ); + checkDeviceSelectors(["screen"]); + + // Select the last screen so that we can have a stream. + menulist.getItemAtIndex(menulist.itemCount - 1).doCommand(); + + observerPromise1 = expectObserverCalled("getUserMedia:response:allow"); + observerPromise2 = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + + await checkSharingUI({ screen: "Screen" }, window, { screen: "Screen" }); + + ok( + webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator shown" + ); + ok( + webrtcUI.showScreenSharingIndicator, + "webrtcUI wants the screen sharing indicator shown" + ); + ok( + !webrtcUI.showCameraIndicator, + "webrtcUI wants the camera indicator hidden" + ); + ok( + !webrtcUI.showMicrophoneIndicator, + "webrtcUI wants the mic indicator hidden" + ); + is( + webrtcUI.getActiveStreams(false, false, true).length, + 2, + "2 active desktop sharing streams" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 2, + "2 active streams" + ); + + await disableObserverVerification(); + + info("removing the second tab"); + BrowserTestUtils.removeTab(tab); + + await TestUtils.waitForCondition( + () => webrtcUI.getActiveStreams(true, true, true).length == 1 + ); + + // Close the first tab's stream and verify that all indicators are removed. + await closeStream(false, null, true); + + ok( + !webrtcUI.showGlobalIndicator, + "webrtcUI wants the global indicator hidden" + ); + is( + webrtcUI.getActiveStreams(true, true, true).length, + 0, + "0 active streams" + ); + }, + }, +]; + +add_task(async function test() { + await runTests(gTests); +}); -- cgit v1.2.3