summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js')
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js517
1 files changed, 517 insertions, 0 deletions
diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
new file mode 100644
index 0000000000..fa88b5d030
--- /dev/null
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
@@ -0,0 +1,517 @@
+/* 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/. */
+
+var gTests = [
+ {
+ desc: "getUserMedia audio in a first process + video in a second process",
+ // These tests call enableObserverVerification manually on a second tab, so
+ // don't add listeners to the first tab.
+ skipObserverVerification: true,
+ run: async function checkMultiProcess() {
+ // The main purpose of this test is to ensure webrtc sharing indicators
+ // work with multiple content processes, but it makes sense to run this
+ // test without e10s too to ensure using webrtc devices in two different
+ // tabs is handled correctly.
+
+ // Request audio in the first tab.
+ let observerPromise = expectObserverCalled("getUserMedia:request");
+ let promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(true);
+ await promise;
+ await observerPromise;
+
+ checkDeviceSelectors(["microphone"]);
+
+ let observerPromise1 = expectObserverCalled(
+ "getUserMedia:response:allow"
+ );
+ let observerPromise2 = expectObserverCalled("recording-device-events");
+ let indicator = promiseIndicatorWindow();
+ 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 });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ !webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator hidden"
+ );
+ ok(
+ webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator shown"
+ );
+ is(
+ webrtcUI.getActiveStreams(false, true).length,
+ 1,
+ "1 active audio stream"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 1,
+ "1 active stream"
+ );
+
+ // If we have reached the max process count already, increase it to ensure
+ // our new tab can have its own content process.
+ let childCount = Services.ppmm.childCount;
+ let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount");
+ // The first check is because if we are on a branch where e10s-multi is
+ // disabled, we want to keep testing e10s with a single content process.
+ // The + 1 is because ppmm.childCount also counts the chrome process
+ // (which also runs process scripts).
+ if (maxContentProcess > 1 && childCount == maxContentProcess + 1) {
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.ipc.processCount", childCount]],
+ });
+ }
+
+ // Open a new tab with a different hostname.
+ let url = gBrowser.currentURI.spec.replace(
+ "https://example.com/",
+ "http://127.0.0.1:8888/"
+ );
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+
+ await enableObserverVerification();
+
+ // Request video.
+ observerPromise = expectObserverCalled("getUserMedia:request");
+ promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true);
+ await promise;
+ await observerPromise;
+
+ checkDeviceSelectors(["camera"]);
+
+ observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
+ observerPromise2 = expectObserverCalled("recording-device-events");
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstElementChild.button.click();
+ });
+ await observerPromise1;
+ await observerPromise2;
+
+ await checkSharingUI({ video: true }, window, {
+ audio: true,
+ video: true,
+ });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator shown"
+ );
+ ok(
+ webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator shown"
+ );
+ is(
+ webrtcUI.getActiveStreams(false, true).length,
+ 1,
+ "1 active audio stream"
+ );
+ is(webrtcUI.getActiveStreams(true).length, 1, "1 active video stream");
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 2,
+ "2 active streams"
+ );
+
+ info("removing the second tab");
+
+ await disableObserverVerification();
+
+ BrowserTestUtils.removeTab(tab);
+
+ // Check that we still show the sharing indicators for the first tab's stream.
+ await Promise.all([
+ TestUtils.waitForCondition(() => !webrtcUI.showCameraIndicator),
+ TestUtils.waitForCondition(
+ () => webrtcUI.getActiveStreams(true, true, true).length == 1
+ ),
+ ]);
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ !webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator hidden"
+ );
+ ok(
+ webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator shown"
+ );
+ is(
+ webrtcUI.getActiveStreams(false, true).length,
+ 1,
+ "1 active audio stream"
+ );
+
+ await checkSharingUI({ audio: true });
+
+ // Close the first tab's stream and verify that all indicators are removed.
+ await closeStream(false, null, true);
+
+ ok(
+ !webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 0,
+ "0 active streams"
+ );
+ },
+ },
+
+ {
+ desc: "getUserMedia camera in a first process + camera in a second process",
+ skipObserverVerification: true,
+ run: async function checkMultiProcessCamera() {
+ let observerPromise = expectObserverCalled("getUserMedia:request");
+ // Request camera in the first tab.
+ let promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true);
+ await promise;
+ await observerPromise;
+
+ checkDeviceSelectors(["camera"]);
+
+ 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({ video: true });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator shown"
+ );
+ ok(
+ !webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator hidden"
+ );
+ is(webrtcUI.getActiveStreams(true).length, 1, "1 active camera stream");
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 1,
+ "1 active stream"
+ );
+
+ // If we have reached the max process count already, increase it to ensure
+ // our new tab can have its own content process.
+ let childCount = Services.ppmm.childCount;
+ let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount");
+ // The first check is because if we are on a branch where e10s-multi is
+ // disabled, we want to keep testing e10s with a single content process.
+ // The + 1 is because ppmm.childCount also counts the chrome process
+ // (which also runs process scripts).
+ if (maxContentProcess > 1 && childCount == maxContentProcess + 1) {
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.ipc.processCount", childCount]],
+ });
+ }
+
+ // Open a new tab with a different hostname.
+ let url = gBrowser.currentURI.spec.replace(
+ "https://example.com/",
+ "http://127.0.0.1:8888/"
+ );
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+
+ await enableObserverVerification();
+
+ // Request camera in the second tab.
+ observerPromise = expectObserverCalled("getUserMedia:request");
+ promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true);
+ await promise;
+ await observerPromise;
+
+ checkDeviceSelectors(["camera"]);
+
+ observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
+ observerPromise2 = expectObserverCalled("recording-device-events");
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstElementChild.button.click();
+ });
+ await observerPromise1;
+ await observerPromise2;
+
+ await checkSharingUI({ video: true }, window, { video: true });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator shown"
+ );
+ ok(
+ !webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator hidden"
+ );
+ is(webrtcUI.getActiveStreams(true).length, 2, "2 active camera streams");
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 2,
+ "2 active streams"
+ );
+
+ await disableObserverVerification();
+
+ info("removing the second tab");
+ BrowserTestUtils.removeTab(tab);
+
+ // Check that we still show the sharing indicators for the first tab's stream.
+ await Promise.all([
+ TestUtils.waitForCondition(() => webrtcUI.showCameraIndicator),
+ TestUtils.waitForCondition(
+ () => webrtcUI.getActiveStreams(true).length == 1
+ ),
+ ]);
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator shown"
+ );
+ ok(
+ !webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 1,
+ "1 active stream"
+ );
+
+ await checkSharingUI({ video: true });
+
+ // Close the first tab's stream and verify that all indicators are removed.
+ await closeStream(false, null, true);
+
+ ok(
+ !webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 0,
+ "0 active streams"
+ );
+ },
+ },
+
+ {
+ desc: "getUserMedia screen sharing in a first process + screen sharing in a second process",
+ skipObserverVerification: true,
+ run: async function checkMultiProcessScreen() {
+ // Request screen sharing in the first tab.
+ let observerPromise = expectObserverCalled("getUserMedia:request");
+ let 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"]);
+
+ // Select the last screen so that we can have a stream.
+ let menulist = document.getElementById("webRTC-selectWindow-menulist");
+ menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
+
+ 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(),
+ { screen: "Screen" },
+ "expected screen to be shared"
+ );
+
+ await indicator;
+ await checkSharingUI({ screen: "Screen" });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showScreenSharingIndicator,
+ "webrtcUI wants the screen sharing indicator shown"
+ );
+ ok(
+ !webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator hidden"
+ );
+ ok(
+ !webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(false, false, true).length,
+ 1,
+ "1 active screen sharing stream"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 1,
+ "1 active stream"
+ );
+
+ // If we have reached the max process count already, increase it to ensure
+ // our new tab can have its own content process.
+ let childCount = Services.ppmm.childCount;
+ let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount");
+ // The first check is because if we are on a branch where e10s-multi is
+ // disabled, we want to keep testing e10s with a single content process.
+ // The + 1 is because ppmm.childCount also counts the chrome process
+ // (which also runs process scripts).
+ if (maxContentProcess > 1 && childCount == maxContentProcess + 1) {
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.ipc.processCount", childCount]],
+ });
+ }
+
+ // Open a new tab with a different hostname.
+ let url = gBrowser.currentURI.spec.replace(
+ "https://example.com/",
+ "https://example.com/"
+ );
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+
+ await enableObserverVerification();
+
+ // Request screen sharing in the second tab.
+ 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"]);
+
+ // Select the last screen so that we can have a stream.
+ menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
+
+ observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
+ observerPromise2 = expectObserverCalled("recording-device-events");
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstElementChild.button.click();
+ });
+ await observerPromise1;
+ await observerPromise2;
+
+ await checkSharingUI({ screen: "Screen" }, window, { screen: "Screen" });
+
+ ok(
+ webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator shown"
+ );
+ ok(
+ webrtcUI.showScreenSharingIndicator,
+ "webrtcUI wants the screen sharing indicator shown"
+ );
+ ok(
+ !webrtcUI.showCameraIndicator,
+ "webrtcUI wants the camera indicator hidden"
+ );
+ ok(
+ !webrtcUI.showMicrophoneIndicator,
+ "webrtcUI wants the mic indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(false, false, true).length,
+ 2,
+ "2 active desktop sharing streams"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 2,
+ "2 active streams"
+ );
+
+ await disableObserverVerification();
+
+ info("removing the second tab");
+ BrowserTestUtils.removeTab(tab);
+
+ await TestUtils.waitForCondition(
+ () => webrtcUI.getActiveStreams(true, true, true).length == 1
+ );
+
+ // Close the first tab's stream and verify that all indicators are removed.
+ await closeStream(false, null, true);
+
+ ok(
+ !webrtcUI.showGlobalIndicator,
+ "webrtcUI wants the global indicator hidden"
+ );
+ is(
+ webrtcUI.getActiveStreams(true, true, true).length,
+ 0,
+ "0 active streams"
+ );
+ },
+ },
+];
+
+add_task(async function test() {
+ await runTests(gTests);
+});