Skip to content

Commit

Permalink
Bug 1655078 - Make the 'Stop Sharing' button in the WebRTC indicator …
Browse files Browse the repository at this point in the history
…stop all screen sharing streams. r=pbz

Differential Revision: https://phabricator.services.mozilla.com/D85414
  • Loading branch information
mikeconley committed Aug 4, 2020
1 parent b1af5a2 commit ae15a94
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 209 deletions.
161 changes: 75 additions & 86 deletions browser/base/content/test/webrtc/browser_stop_sharing_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@ const TEST_ROOT = getRootDirectory(gTestPath).replace(
);
const TEST_PAGE = TEST_ROOT + "get_user_media.html";

add_task(async function setup() {
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 });
});

/**
* 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() {
add_task(async function test_stop_sharing() {
let prefs = [
[PREF_PERMISSION_FAKE, true],
[PREF_AUDIO_LOOPBACK, ""],
Expand All @@ -27,100 +38,78 @@ add_task(async function test_close_indicator() {
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 shareDevices(
browser,
true /* camera */,
true /* microphone */,
true /* screen */
);
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 stopSharingButton = indicator.document.getElementById("stop-sharing");
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 });

// Ensure that the "display-share" section of the indicator is now hidden
Assert.ok(
BrowserTestUtils.is_hidden(
indicator.document.getElementById("display-share")
),
"The display-share section of the indicator should now be hidden."
);
});
});

/**
* Tests that if the user chooses to "Stop Sharing" a display while
* sharing their display on multiple sites, all of those display sharing
* streams are closed.
*/
add_task(async function test_stop_sharing_multiple() {
let indicatorPromise = promiseIndicatorWindow();

info("Opening first tab");
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera, microphone and screen");
await shareDevices(tab1.linkedBrowser, true, true, true);

info("Opening second tab");
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
info("Sharing camera and screen");
await shareDevices(tab2.linkedBrowser, true, false, true);

let indicator = await indicatorPromise;

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

Assert.equal(gBrowser.selectedTab, tab2, "Should have tab2 selected.");
await checkSharingUI({ audio: false, video: true }, window, {
audio: true,
video: true,
});
BrowserTestUtils.removeTab(tab2);

Assert.equal(gBrowser.selectedTab, tab1, "Should have tab1 selected.");
await checkSharingUI({ audio: true, video: true }, window, {
audio: true,
video: true,
});

// Ensure that the "display-share" section of the indicator is now hidden
Assert.ok(
BrowserTestUtils.is_hidden(
indicator.document.getElementById("display-share")
),
"The display-share section of the indicator should now be hidden."
);

BrowserTestUtils.removeTab(tab1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,6 @@ const TEST_ROOT = getRootDirectory(gTestPath).replace(
);
const TEST_PAGE = TEST_ROOT + "get_user_media.html";

/**
* Given a browser from a tab in this window, chooses to share
* some combination of camera, mic or screen.
*
* @param {<xul:browser} browser - The browser to share devices with.
* @param {boolean} camera - True to share a camera device.
* @param {boolean} mic - True to share a microphone device.
* @param {boolean} screen - True to share a display device.
* @return {Promise}
* @resolves {undefined} - Once the sharing is complete.
*/
async function shareDevices(browser, camera, mic, screen) {
if (camera || mic) {
let promise = promisePopupNotificationShown(
"webRTC-shareDevices",
null,
window
);

await promiseRequestDevice(mic, camera, null, null, browser);
await promise;

checkDeviceSelectors(mic, 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;
}

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

await promiseRequestDevice(false, true, null, "screen", browser);
await promise;

checkDeviceSelectors(false, false, true, 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;

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

/**
* Tests that if the indicator is closed somehow by the user when streams
* still ongoing, that all of those streams are stopped, and the most recent
Expand Down
68 changes: 68 additions & 0 deletions browser/base/content/test/webrtc/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -950,3 +950,71 @@ async function runTests(tests, options = {}) {
// Some tests destroy the original tab and leave a new one in its place.
BrowserTestUtils.removeTab(gBrowser.selectedTab);
}

/**
* Given a browser from a tab in this window, chooses to share
* some combination of camera, mic or screen.
*
* @param {<xul:browser} browser - The browser to share devices with.
* @param {boolean} camera - True to share a camera device.
* @param {boolean} mic - True to share a microphone device.
* @param {boolean} screen - True to share a display device.
* @return {Promise}
* @resolves {undefined} - Once the sharing is complete.
*/
async function shareDevices(browser, camera, mic, screen) {
if (camera || mic) {
let promise = promisePopupNotificationShown(
"webRTC-shareDevices",
null,
window
);

await promiseRequestDevice(mic, camera, null, null, browser);
await promise;

checkDeviceSelectors(mic, 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;
}

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

await promiseRequestDevice(false, true, null, "screen", browser);
await promise;

checkDeviceSelectors(false, false, true, 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;

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

0 comments on commit ae15a94

Please sign in to comment.