summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js')
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js666
1 files changed, 666 insertions, 0 deletions
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);
+});