Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const TEST_ROOT = getRootDirectory(gTestPath).replace(
);
const TEST_PAGE = TEST_ROOT + "get_user_media.html";
const MUTE_TOPICS = [
"getUserMedia:muteVideo",
"getUserMedia:unmuteVideo",
"getUserMedia:muteAudio",
"getUserMedia:unmuteAudio",
];
add_setup(async function () {
let prefs = [
[PREF_PERMISSION_FAKE, true],
[PREF_AUDIO_LOOPBACK, ""],
[PREF_VIDEO_LOOPBACK, ""],
[PREF_FAKE_STREAMS, true],
[PREF_FOCUS_SOURCE, false],
["privacy.webrtc.globalMuteToggles", true],
];
await SpecialPowers.pushPrefEnv({ set: prefs });
});
/**
* Returns a Promise that resolves when the content process for
* <browser> fires the right observer notification based on the
* value of isMuted for the camera.
*
* Note: Callers must ensure that they first call
* BrowserTestUtils.startObservingTopics to monitor the mute and
* unmute observer notifications for this to work properly.
*
* @param {<xul:browser>} browser - The browser running in the content process
* to be monitored.
* @param {Boolean} isMuted - True if the muted topic should be fired.
* @return {Promise}
* @resolves {undefined} When the notification fires.
*/
function waitForCameraMuteState(browser, isMuted) {
let topic = isMuted ? "getUserMedia:muteVideo" : "getUserMedia:unmuteVideo";
return BrowserTestUtils.contentTopicObserved(browser.browsingContext, topic);
}
/**
* Returns a Promise that resolves when the content process for
* <browser> fires the right observer notification based on the
* value of isMuted for the microphone.
*
* Note: Callers must ensure that they first call
* BrowserTestUtils.startObservingTopics to monitor the mute and
* unmute observer notifications for this to work properly.
*
* @param {<xul:browser>} browser - The browser running in the content process
* to be monitored.
* @param {Boolean} isMuted - True if the muted topic should be fired.
* @return {Promise}
* @resolves {undefined} When the notification fires.
*/
function waitForMicrophoneMuteState(browser, isMuted) {
let topic = isMuted ? "getUserMedia:muteAudio" : "getUserMedia:unmuteAudio";
return BrowserTestUtils.contentTopicObserved(browser.browsingContext, topic);
}
/**
* Tests that the global mute toggles fire the right observer
* notifications in pre-existing content processes.
*/
add_task(async function test_notifications() {
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(browser, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
let microphoneMute = doc.getElementById("microphone-mute-toggle");
let cameraMute = doc.getElementById("camera-mute-toggle");
Assert.ok(
!microphoneMute.checked,
"Microphone toggle should not start checked."
);
Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
await BrowserTestUtils.startObservingTopics(
browser.browsingContext,
MUTE_TOPICS
);
info("Muting microphone...");
let microphoneMuted = waitForMicrophoneMuteState(browser, true);
microphoneMute.click();
await microphoneMuted;
info("Microphone successfully muted.");
info("Muting camera...");
let cameraMuted = waitForCameraMuteState(browser, true);
cameraMute.click();
await cameraMuted;
info("Camera successfully muted.");
Assert.ok(
microphoneMute.checked,
"Microphone toggle should now be checked."
);
Assert.ok(cameraMute.checked, "Camera toggle should now be checked.");
info("Unmuting microphone...");
let microphoneUnmuted = waitForMicrophoneMuteState(browser, false);
microphoneMute.click();
await microphoneUnmuted;
info("Microphone successfully unmuted.");
info("Unmuting camera...");
let cameraUnmuted = waitForCameraMuteState(browser, false);
cameraMute.click();
await cameraUnmuted;
info("Camera successfully unmuted.");
await BrowserTestUtils.stopObservingTopics(
browser.browsingContext,
MUTE_TOPICS
);
});
});
/**
* Tests that if sharing stops while muted, and the indicator closes,
* then the mute state is reset.
*/
add_task(async function test_closing_indicator_resets_mute() {
await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(browser, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
let microphoneMute = doc.getElementById("microphone-mute-toggle");
let cameraMute = doc.getElementById("camera-mute-toggle");
Assert.ok(
!microphoneMute.checked,
"Microphone toggle should not start checked."
);
Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
await BrowserTestUtils.startObservingTopics(
browser.browsingContext,
MUTE_TOPICS
);
info("Muting microphone...");
let microphoneMuted = waitForMicrophoneMuteState(browser, true);
microphoneMute.click();
await microphoneMuted;
info("Microphone successfully muted.");
info("Muting camera...");
let cameraMuted = waitForCameraMuteState(browser, true);
cameraMute.click();
await cameraMuted;
info("Camera successfully muted.");
Assert.ok(
microphoneMute.checked,
"Microphone toggle should now be checked."
);
Assert.ok(cameraMute.checked, "Camera toggle should now be checked.");
let allUnmuted = Promise.all([
waitForMicrophoneMuteState(browser, false),
waitForCameraMuteState(browser, false),
]);
await closeStream();
await allUnmuted;
await BrowserTestUtils.stopObservingTopics(
browser.browsingContext,
MUTE_TOPICS
);
});
});
/**
* Test that if the global mute state is set, then newly created
* content processes also have their tracks muted after sending
* a getUserMedia request.
*/
add_task(async function test_new_processes() {
let tab1 = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: TEST_PAGE,
});
let browser1 = tab1.linkedBrowser;
let indicatorPromise = promiseIndicatorWindow();
await shareDevices(browser1, true /* camera */, true /* microphone */);
let indicator = await indicatorPromise;
let doc = indicator.document;
let microphoneMute = doc.getElementById("microphone-mute-toggle");
let cameraMute = doc.getElementById("camera-mute-toggle");
Assert.ok(
!microphoneMute.checked,
"Microphone toggle should not start checked."
);
Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
await BrowserTestUtils.startObservingTopics(
browser1.browsingContext,
MUTE_TOPICS
);
info("Muting microphone...");
let microphoneMuted = waitForMicrophoneMuteState(browser1, true);
microphoneMute.click();
await microphoneMuted;
info("Microphone successfully muted.");
info("Muting camera...");
let cameraMuted = waitForCameraMuteState(browser1, true);
cameraMute.click();
await cameraMuted;
info("Camera successfully muted.");
// We'll make sure a new process is being launched by observing
// for the ipc:content-created notification.
let processLaunched = TestUtils.topicObserved("ipc:content-created");
let tab2 = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: TEST_PAGE,
forceNewProcess: true,
});
let browser2 = tab2.linkedBrowser;
await processLaunched;
await BrowserTestUtils.startObservingTopics(
browser2.browsingContext,
MUTE_TOPICS
);
let microphoneMuted2 = waitForMicrophoneMuteState(browser2, true);
let cameraMuted2 = waitForCameraMuteState(browser2, true);
info("Sharing the microphone and camera from a new process.");
await shareDevices(browser2, true /* camera */, true /* microphone */);
await Promise.all([microphoneMuted2, cameraMuted2]);
info("Unmuting microphone...");
let microphoneUnmuted = Promise.all([
waitForMicrophoneMuteState(browser1, false),
waitForMicrophoneMuteState(browser2, false),
]);
microphoneMute.click();
await microphoneUnmuted;
info("Microphone successfully unmuted.");
info("Unmuting camera...");
let cameraUnmuted = Promise.all([
waitForCameraMuteState(browser1, false),
waitForCameraMuteState(browser2, false),
]);
cameraMute.click();
await cameraUnmuted;
info("Camera successfully unmuted.");
await BrowserTestUtils.stopObservingTopics(
browser1.browsingContext,
MUTE_TOPICS
);
await BrowserTestUtils.stopObservingTopics(
browser2.browsingContext,
MUTE_TOPICS
);
BrowserTestUtils.removeTab(tab2);
BrowserTestUtils.removeTab(tab1);
});