From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser_stop_streams_on_indicator_close.js | 215 +++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 browser/base/content/test/webrtc/browser_stop_streams_on_indicator_close.js (limited to 'browser/base/content/test/webrtc/browser_stop_streams_on_indicator_close.js') diff --git a/browser/base/content/test/webrtc/browser_stop_streams_on_indicator_close.js b/browser/base/content/test/webrtc/browser_stop_streams_on_indicator_close.js new file mode 100644 index 0000000000..b5d4229fdc --- /dev/null +++ b/browser/base/content/test/webrtc/browser_stop_streams_on_indicator_close.js @@ -0,0 +1,215 @@ +/* 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"; + +add_setup(async function () { + 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 }); +}); + +/** + * Tests that if the indicator is closed somehow by the user when streams + * still ongoing, that all of those streams it represents are stopped, and + * the most recent tab that a stream was shared with is selected. + * + * This test makes sure the global mute toggles for camera and microphone + * are disabled, so the indicator only represents display streams, and only + * those streams should be stopped on close. + */ +add_task(async function test_close_indicator_no_global_toggles() { + await SpecialPowers.pushPrefEnv({ + set: [["privacy.webrtc.globalMuteToggles", false]], + }); + + let indicatorPromise = promiseIndicatorWindow(); + + info("Opening first tab"); + let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing camera, microphone and screen"); + await shareDevices(tab1.linkedBrowser, true, true, SHARE_SCREEN, false); + + info("Opening second tab"); + let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing camera, microphone and screen"); + await shareDevices(tab2.linkedBrowser, true, true, SHARE_SCREEN, true); + + info("Opening third tab"); + let tab3 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing screen"); + await shareDevices(tab3.linkedBrowser, false, false, SHARE_SCREEN, false); + + info("Opening fourth tab"); + let tab4 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "https://example.com" + ); + + Assert.equal( + gBrowser.selectedTab, + tab4, + "Most recently opened tab is selected" + ); + + let indicator = await indicatorPromise; + + indicator.close(); + + // Wait a tick of the event loop to give the unload handler in the indicator + // a chance to run. + await new Promise(resolve => executeSoon(resolve)); + + // Make sure the media capture state has a chance to flush up to the parent. + await getMediaCaptureState(); + + // The camera and microphone streams should still be active. + let camStreams = webrtcUI.getActiveStreams(true, false); + Assert.equal(camStreams.length, 2, "Should have found two camera streams"); + let micStreams = webrtcUI.getActiveStreams(false, true); + Assert.equal( + micStreams.length, + 2, + "Should have found two microphone streams" + ); + + // The camera and microphone permission were remembered for tab2, so check to + // make sure that the permissions remain. + let { state: camState, scope: camScope } = SitePermissions.getForPrincipal( + tab2.linkedBrowser.contentPrincipal, + "camera", + tab2.linkedBrowser + ); + Assert.equal(camState, SitePermissions.ALLOW); + Assert.equal(camScope, SitePermissions.SCOPE_PERSISTENT); + + let { state: micState, scope: micScope } = SitePermissions.getForPrincipal( + tab2.linkedBrowser.contentPrincipal, + "microphone", + tab2.linkedBrowser + ); + Assert.equal(micState, SitePermissions.ALLOW); + Assert.equal(micScope, SitePermissions.SCOPE_PERSISTENT); + + Assert.equal( + gBrowser.selectedTab, + tab3, + "Most recently tab that streams were shared with is selected" + ); + + SitePermissions.removeFromPrincipal( + tab2.linkedBrowser.contentPrincipal, + "camera", + tab2.linkedBrowser + ); + + SitePermissions.removeFromPrincipal( + tab2.linkedBrowser.contentPrincipal, + "microphone", + tab2.linkedBrowser + ); + + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); + BrowserTestUtils.removeTab(tab3); + BrowserTestUtils.removeTab(tab4); +}); + +/** + * Tests that if the indicator is closed somehow by the user when streams + * still ongoing, that all of those streams is represents are stopped, and + * the most recent tab that a stream was shared with is selected. + * + * This test makes sure the global mute toggles are enabled. This means that + * when the user manages to close the indicator, we should revoke camera + * and microphone permissions too. + */ +add_task(async function test_close_indicator_with_global_toggles() { + await SpecialPowers.pushPrefEnv({ + set: [["privacy.webrtc.globalMuteToggles", true]], + }); + + let indicatorPromise = promiseIndicatorWindow(); + + info("Opening first tab"); + let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing camera, microphone and screen"); + await shareDevices(tab1.linkedBrowser, true, true, SHARE_SCREEN, false); + + info("Opening second tab"); + let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing camera, microphone and screen"); + await shareDevices(tab2.linkedBrowser, true, true, SHARE_SCREEN, true); + + info("Opening third tab"); + let tab3 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE); + info("Sharing screen"); + await shareDevices(tab3.linkedBrowser, false, false, SHARE_SCREEN, false); + + info("Opening fourth tab"); + let tab4 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "https://example.com" + ); + + Assert.equal( + gBrowser.selectedTab, + tab4, + "Most recently opened tab is selected" + ); + + let indicator = await indicatorPromise; + + indicator.close(); + + // Wait a tick of the event loop to give the unload handler in the indicator + // a chance to run. + await new Promise(resolve => executeSoon(resolve)); + + Assert.deepEqual( + await getMediaCaptureState(), + {}, + "expected nothing to be shared" + ); + + // Ensuring we no longer have any active streams. + let streams = webrtcUI.getActiveStreams(true, true, true, true); + Assert.equal(streams.length, 0, "Should have found no active streams"); + + // The camera and microphone permissions should have been cleared. + let { state: camState } = SitePermissions.getForPrincipal( + tab2.linkedBrowser.contentPrincipal, + "camera", + tab2.linkedBrowser + ); + Assert.equal(camState, SitePermissions.UNKNOWN); + + let { state: micState } = SitePermissions.getForPrincipal( + tab2.linkedBrowser.contentPrincipal, + "microphone", + tab2.linkedBrowser + ); + Assert.equal(micState, SitePermissions.UNKNOWN); + + Assert.equal( + gBrowser.selectedTab, + tab3, + "Most recently tab that streams were shared with is selected" + ); + + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); + BrowserTestUtils.removeTab(tab3); + BrowserTestUtils.removeTab(tab4); +}); -- cgit v1.2.3