Skip to content

Commit

Permalink
Bug 1654266 - Make sure the 'Stop Sharing' button in the WebRTC indic…
Browse files Browse the repository at this point in the history
…ator only stops displays, and not mic/camera streams. r=pbz

Differential Revision: https://phabricator.services.mozilla.com/D84574
  • Loading branch information
mikeconley committed Jul 24, 2020
1 parent a4a3136 commit 950cad2
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 3 deletions.
1 change: 1 addition & 0 deletions browser/base/content/test/webrtc/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ skip-if = (os == 'linux') # Bug 1503991
skip-if = (os == "win" && bits == 64) # win8: bug 1334752
[browser_devices_get_user_media_unprompted_access_queue_request.js]
[browser_notification_silencing.js]
[browser_stop_sharing_button.js]
[browser_stop_streams_on_indicator_close.js]
[browser_tab_switch_warning.js]
[browser_webrtc_hooks.js]
Expand Down
126 changes: 126 additions & 0 deletions browser/base/content/test/webrtc/browser_stop_sharing_button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const TEST_ROOT = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content/",
"https://example.com/"
);
const TEST_PAGE = TEST_ROOT + "get_user_media.html";

/**
* Tests that if the user chooses to "Stop Sharing" a display while
* also sharing their microphone or camera, that only the display
* stream is stopped.
*/
add_task(async function test_close_indicator() {
let prefs = [
[PREF_PERMISSION_FAKE, true],
[PREF_AUDIO_LOOPBACK, ""],
[PREF_VIDEO_LOOPBACK, ""],
[PREF_FAKE_STREAMS, true],
[PREF_FOCUS_SOURCE, false],
];
await SpecialPowers.pushPrefEnv({ set: prefs });

await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
let indicatorPromise = promiseIndicatorWindow();

// First, choose to share the microphone and camera devices.

let promise = promisePopupNotificationShown(
"webRTC-shareDevices",
null,
window
);

await promiseRequestDevice(
true /* audio */,
true /* video */,
null /* frameID */,
null /* screen */,
browser
);
await promise;

checkDeviceSelectors(true /* microphone */, true /* camera */);

let observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
let observerPromise2 = expectObserverCalled("recording-device-events");
promise = promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});

await observerPromise1;
await observerPromise2;
await promise;

promise = promisePopupNotificationShown(
"webRTC-shareDevices",
null,
window
);

// Next, choose to share a display stream.

await promiseRequestDevice(
false /* audio */,
true /* video */,
null /* frameID */,
"screen" /* video type */,
browser
);
await promise;

checkDeviceSelectors(
false /* microphone */,
false /* camera */,
true /* screen */,
window
);

let document = window.document;

// Select one of the windows / screens. It doesn't really matter which.
let menulist = document.getElementById("webRTC-selectWindow-menulist");
menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
let notification = window.PopupNotifications.panel.firstElementChild;

observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage(
"ok",
() => {
notification.button.click();
},
1,
browser
);
await observerPromise1;
await observerPromise2;

let indicator = await indicatorPromise;
let indicatorDoc = indicator.document;

// We're choosing the last item in the display list by default, which
// _should_ be a screen. Just in case it isn't, we check whether or not
// the indicator is showing the "Stop Sharing" button for screens, and
// use that button for the test. Otherwise, we use the "Stop Sharing"
// button for other windows.
let isSharingScreen = indicatorDoc.documentElement.hasAttribute(
"sharingscreen"
);
let stopSharingID = isSharingScreen
? "stop-sharing-screen"
: "stop-sharing-window";

let stopSharingButton = indicator.document.getElementById(stopSharingID);
let stopSharingPromise = expectObserverCalled("recording-device-events");
stopSharingButton.click();
await stopSharingPromise;

// Ensure that we're still sharing the other streams.
await checkSharingUI({ audio: true, video: true });
});
});
44 changes: 41 additions & 3 deletions browser/base/content/webrtcIndicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,23 @@ const WebRTCIndicator = {
true /* screen */,
false /* window */
);
webrtcUI.stopSharingStreams(activeStreams);

if (!activeStreams.length) {
return;
}

// getActiveStreams is filtering for streams that have screen
// sharing, but those streams might _also_ be sharing other
// devices like camera or microphone. This is why we need to
// tell stopSharingStreams explicitly which device type we want
// to stop.
webrtcUI.stopSharingStreams(
[activeStreams[0]],
false /* camera */,
false /* microphone */,
true /* screen */,
false /* window */
);
break;
}
case "stop-sharing-window": {
Expand All @@ -394,8 +410,15 @@ const WebRTCIndicator = {
let browserWindowStreams = activeStreams.filter(stream => {
return stream.devices.some(device => device.scary);
});

if (!browserWindowStreams.length) {
return;
}

// See below comment on why we need to pass the boolean values
// for which device types we want to stop vi stopSharingStreams.
webrtcUI.stopSharingStreams(
browserWindowStreams,
[browserWindowStreams[0]],
false /* camera */,
false /* microphone */,
false /* screen */,
Expand All @@ -404,7 +427,22 @@ const WebRTCIndicator = {
break;
}

webrtcUI.stopSharingStreams(activeStreams);
if (!activeStreams.length) {
return;
}

// getActiveStreams is filtering for streams that have screen
// sharing, but those streams might _also_ be sharing other
// devices like camera or microphone. This is why we need to
// tell stopSharingStreams explicitly which device type we want
// to stop.
webrtcUI.stopSharingStreams(
[activeStreams[0]],
false /* camera */,
false /* microphone */,
false /* screen */,
true /* window */
);
break;
}
case "microphone-button":
Expand Down

0 comments on commit 950cad2

Please sign in to comment.