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 --- ...ser_devices_get_user_media_unprompted_access.js | 666 +++++++++++++++++++++ 1 file changed, 666 insertions(+) create mode 100644 browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js (limited to 'browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js') diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js new file mode 100644 index 0000000000..e3276cebc4 --- /dev/null +++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js @@ -0,0 +1,666 @@ +/* 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/. */ + +const permissionError = + "error: NotAllowedError: The request is not allowed " + + "by the user agent or the platform in the current context."; + +var gTests = [ + { + desc: "getUserMedia audio+camera", + run: async function checkAudioVideoWhileLiveTracksExist_audio_camera() { + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + let observerPromise = expectObserverCalled("getUserMedia:request"); + await promiseRequestDevice(true, true); + await promise; + await observerPromise; + 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(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await indicator; + await checkSharingUI({ audio: true, video: true }); + + // If there's an active audio+camera stream, + // gUM(audio+camera) returns a stream without prompting; + let observerPromises = [ + expectObserverCalled("getUserMedia:request"), + expectObserverCalled("getUserMedia:response:allow"), + expectObserverCalled("recording-device-events"), + ]; + + promise = promiseMessage("ok"); + + await promiseRequestDevice(true, true); + await promise; + await Promise.all(observerPromises); + + await promiseNoPopupNotification("webRTC-shareDevices"); + + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + + await checkSharingUI({ audio: true, video: true }); + + // gUM(screen) causes a prompt. + 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"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + await observerPromise; + + // Revoke screen block (only). Don't over-revoke ahead of remaining steps. + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + + // After closing all streams, gUM(audio+camera) causes a prompt. + await closeStream(); + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, true); + await promise; + await observerPromise; + checkDeviceSelectors(["microphone", "camera"]); + + observerPromise1 = expectObserverCalled("getUserMedia:response:deny"); + observerPromise2 = expectObserverCalled("recording-window-ended"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise1; + await observerPromise2; + + await checkNotSharing(); + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + }, + }, + + { + desc: "getUserMedia audio+camera -camera", + run: async function checkAudioVideoWhileLiveTracksExist_audio_nocamera() { + // State: fresh + + { + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + const request = expectObserverCalled("getUserMedia:request"); + await promiseRequestDevice(true, true); + await popupShown; + await request; + const indicator = promiseIndicatorWindow(); + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await indicator; + await checkSharingUI({ audio: true, video: true }); + + // Stop the camera track. + await stopTracks("video"); + await checkSharingUI({ audio: true, video: false }); + } + + // State: live audio + + { + // If there's an active audio track from an audio+camera request, + // gUM(camera) causes a prompt. + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await popupShown; + await request; + checkDeviceSelectors(["camera"]); + + // Allow and stop the camera again. + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await checkSharingUI({ audio: true, video: true }); + + await stopTracks("video"); + await checkSharingUI({ audio: true, video: false }); + } + + // State: live audio + + { + // If there's an active audio track from an audio+camera request, + // gUM(audio+camera) causes a prompt. + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, true); + await popupShown; + await request; + checkDeviceSelectors(["microphone", "camera"]); + + // Allow and stop the camera again. + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await checkSharingUI({ audio: true, video: true }); + + await stopTracks("video"); + await checkSharingUI({ audio: true, video: false }); + } + + // State: live audio + + { + // After closing all streams, gUM(audio) causes a prompt. + await closeStream(); + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, false); + await popupShown; + await request; + checkDeviceSelectors(["microphone"]); + + const response = expectObserverCalled("getUserMedia:response:deny"); + const windowEnded = expectObserverCalled("recording-window-ended"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await response; + await windowEnded; + + await checkNotSharing(); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + } + }, + }, + + { + desc: "getUserMedia audio+camera -audio", + run: async function checkAudioVideoWhileLiveTracksExist_camera_noaudio() { + // State: fresh + + { + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + const request = expectObserverCalled("getUserMedia:request"); + await promiseRequestDevice(true, true); + await popupShown; + await request; + const indicator = promiseIndicatorWindow(); + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await indicator; + await checkSharingUI({ audio: true, video: true }); + + // Stop the audio track. + await stopTracks("audio"); + await checkSharingUI({ audio: false, video: true }); + } + + // State: live camera + + { + // If there's an active video track from an audio+camera request, + // gUM(audio) causes a prompt. + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, false); + await popupShown; + await request; + checkDeviceSelectors(["microphone"]); + + // Allow and stop the microphone again. + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await checkSharingUI({ audio: true, video: true }); + + await stopTracks("audio"); + await checkSharingUI({ audio: false, video: true }); + } + + // State: live camera + + { + // If there's an active video track from an audio+camera request, + // gUM(audio+camera) causes a prompt. + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, true); + await popupShown; + await request; + checkDeviceSelectors(["microphone", "camera"]); + + // Allow and stop the microphone again. + const response = expectObserverCalled("getUserMedia:response:allow"); + const deviceEvents = expectObserverCalled("recording-device-events"); + await promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await response; + await deviceEvents; + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + await checkSharingUI({ audio: true, video: true }); + + await stopTracks("audio"); + await checkSharingUI({ audio: false, video: true }); + } + + // State: live camera + + { + // After closing all streams, gUM(camera) causes a prompt. + await closeStream(); + const request = expectObserverCalled("getUserMedia:request"); + const popupShown = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await popupShown; + await request; + checkDeviceSelectors(["camera"]); + + const response = expectObserverCalled("getUserMedia:response:deny"); + const windowEnded = expectObserverCalled("recording-window-ended"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await response; + await windowEnded; + + await checkNotSharing(); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + } + }, + }, + + { + desc: "getUserMedia camera", + run: async function checkAudioVideoWhileLiveTracksExist_camera() { + let observerPromise = expectObserverCalled("getUserMedia:request"); + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await promise; + await observerPromise; + 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({ audio: false, video: true }); + + // If there's an active camera stream, + // gUM(audio) causes a prompt; + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, false); + await promise; + await observerPromise; + checkDeviceSelectors(["microphone"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise; + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + + // gUM(audio+camera) causes a prompt; + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, true); + await promise; + await observerPromise; + checkDeviceSelectors(["microphone", "camera"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise; + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + + // gUM(screen) causes a prompt; + 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"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise; + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + + // gUM(camera) returns a stream without prompting. + let observerPromises = [ + expectObserverCalled("getUserMedia:request"), + expectObserverCalled("getUserMedia:response:allow"), + expectObserverCalled("recording-device-events"), + ]; + + promise = promiseMessage("ok"); + await promiseRequestDevice(false, true); + await promise; + await Promise.all(observerPromises); + + await promiseNoPopupNotification("webRTC-shareDevices"); + + Assert.deepEqual( + await getMediaCaptureState(), + { video: true }, + "expected camera to be shared" + ); + + await checkSharingUI({ audio: false, video: true }); + + // close all streams + await closeStream(); + }, + }, + + { + desc: "getUserMedia audio", + run: async function checkAudioVideoWhileLiveTracksExist_audio() { + let observerPromise = expectObserverCalled("getUserMedia:request"); + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, false); + await promise; + await observerPromise; + 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(), + { audio: true }, + "expected microphone to be shared" + ); + await indicator; + await checkSharingUI({ audio: true, video: false }); + + // If there's an active audio stream, + // gUM(camera) causes a prompt; + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(false, true); + await promise; + await observerPromise; + checkDeviceSelectors(["camera"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise; + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + + // gUM(audio+camera) causes a prompt; + observerPromise = expectObserverCalled("getUserMedia:request"); + promise = promisePopupNotificationShown("webRTC-shareDevices"); + await promiseRequestDevice(true, true); + await promise; + await observerPromise; + checkDeviceSelectors(["microphone", "camera"]); + + observerPromise = expectObserverCalled("getUserMedia:response:deny"); + + await promiseMessage(permissionError, () => { + activateSecondaryAction(kActionDeny); + }); + + await observerPromise; + SitePermissions.removeFromPrincipal( + null, + "screen", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "camera", + gBrowser.selectedBrowser + ); + SitePermissions.removeFromPrincipal( + null, + "microphone", + gBrowser.selectedBrowser + ); + + // gUM(audio) returns a stream without prompting. + let observerPromises = [ + expectObserverCalled("getUserMedia:request"), + expectObserverCalled("getUserMedia:response:allow"), + expectObserverCalled("recording-device-events"), + ]; + promise = promiseMessage("ok"); + await promiseRequestDevice(true, false); + await promise; + await observerPromises; + await promiseNoPopupNotification("webRTC-shareDevices"); + + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true }, + "expected microphone to be shared" + ); + + await checkSharingUI({ audio: true, video: false }); + + // close all streams + await closeStream(); + }, + }, +]; + +add_task(async function test() { + await runTests(gTests); +}); -- cgit v1.2.3