Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* 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);
});