--- 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
@@ -107,13 +107,221 @@ var gTests = [
// Close the first tab's stream and verify that all indicators are removed.
await closeStream();
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",
+ run: async function checkMultiProcessCamera() {
+
+ // Request camera in the first tab.
+ let promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true);
+ await promise;
+ await expectObserverCalled("getUserMedia:request");
+
+ checkDeviceSelectors(false, true);
+
+ let indicator = promiseIndicatorWindow();
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstChild.button.click();
+ });
+ await expectObserverCalled("getUserMedia:response:allow");
+ await expectObserverCalled("recording-device-events");
+ 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");
+
+ await expectNoObserverCalled();
+
+ // If we have reached the max process count already, increase it to ensure
+ // our new tab can have its own content process.
+ var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+ .getService(Ci.nsIMessageBroadcaster);
+ ppmm.QueryInterface(Ci.nsIProcessScriptLoader);
+ let childCount = 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);
+ tab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
+
+ // Request camera in the second tab.
+ promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true);
+ await promise;
+ await expectObserverCalled("getUserMedia:request");
+
+ checkDeviceSelectors(false, true);
+
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstChild.button.click();
+ });
+ await expectObserverCalled("getUserMedia:response:allow");
+ await expectObserverCalled("recording-device-events");
+
+ 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");
+
+ info("removing the second tab");
+ await BrowserTestUtils.removeTab(tab);
+
+ // Check that we still show the sharing indicators for the first tab's stream.
+ await promiseWaitForCondition(() => webrtcUI.showCameraIndicator);
+ 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");
+
+ await checkSharingUI({video: true});
+
+ // When both tabs use the same content process, the frame script for the
+ // first tab receives observer notifications for things happening in the
+ // second tab, so let's clear the observer call counts before we cleanup
+ // in the first tab.
+ await ignoreObserversCalled();
+
+ // Close the first tab's stream and verify that all indicators are removed.
+ await closeStream();
+
+ 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",
+ run: async function checkMultiProcessScreen() {
+
+ // Request screen sharing in the first tab.
+ let promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true, null, "screen");
+ await promise;
+ await expectObserverCalled("getUserMedia:request");
+
+ is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
+ "webRTC-shareScreen-notification-icon", "anchored to device icon");
+ checkDeviceSelectors(false, false, true);
+
+ // Select the first screen so that we can have a stream.
+ document.getElementById("webRTC-selectWindow-menulist").getItemAtIndex(2).doCommand();
+
+ let indicator = promiseIndicatorWindow();
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstChild.button.click();
+ });
+ await expectObserverCalled("getUserMedia:response:allow");
+ await expectObserverCalled("recording-device-events");
+ 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");
+
+ await expectNoObserverCalled();
+
+ // If we have reached the max process count already, increase it to ensure
+ // our new tab can have its own content process.
+ var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+ .getService(Ci.nsIMessageBroadcaster);
+ ppmm.QueryInterface(Ci.nsIProcessScriptLoader);
+ let childCount = 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);
+ tab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
+
+ // Request screen sharing in the second tab.
+ promise = promisePopupNotificationShown("webRTC-shareDevices");
+ await promiseRequestDevice(false, true, null, "screen");
+ await promise;
+ await expectObserverCalled("getUserMedia:request");
+
+ is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
+ "webRTC-shareScreen-notification-icon", "anchored to device icon");
+ checkDeviceSelectors(false, false, true);
+
+ // Select the first screen so that we can have a stream.
+ document.getElementById("webRTC-selectWindow-menulist").getItemAtIndex(2).doCommand();
+
+ await promiseMessage("ok", () => {
+ PopupNotifications.panel.firstChild.button.click();
+ });
+ await expectObserverCalled("getUserMedia:response:allow");
+ await expectObserverCalled("recording-device-events");
+
+ 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");
+
+ info("removing the second tab");
+ await BrowserTestUtils.removeTab(tab);
+
+ // When both tabs use the same content process, the frame script for the
+ // first tab receives observer notifications for things happening in the
+ // second tab, so let's clear the observer call counts before we cleanup
+ // in the first tab.
+ await ignoreObserversCalled();
+
+ // Close the first tab's stream and verify that all indicators are removed.
+ await closeStream();
+
+ 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);
});