Bug 1703674 - Revoking cam or mic permission revokes both if either is capturing. r=pbz

Differential Revision: https://phabricator.services.mozilla.com/D111174
This commit is contained in:
Jan-Ivar Bruaroey 2021-04-09 20:48:41 +00:00
Родитель 492ca0fcc5
Коммит 13771db18d
3 изменённых файлов: 100 добавлений и 65 удалений

Просмотреть файл

@ -653,7 +653,12 @@ var gTests = [
{
desc: "Stop Sharing removes permissions",
run: async function checkStopSharingRemovesPermissions() {
async function stopAndCheckPerm(aRequestAudio, aRequestVideo) {
async function stopAndCheckPerm(
aRequestAudio,
aRequestVideo,
aStopAudio = aRequestAudio,
aStopVideo = aRequestVideo
) {
let uri = gBrowser.selectedBrowser.documentURI;
// Initially set both permissions to 'allow'.
@ -677,32 +682,37 @@ var gTests = [
10000000
);
let indicator = promiseIndicatorWindow();
let observerPromise1 = expectObserverCalled("getUserMedia:request");
let observerPromise2 = expectObserverCalled(
"getUserMedia:response:allow"
);
let observerPromise3 = expectObserverCalled("recording-device-events");
// Start sharing what's been requested.
let promise = promiseMessage("ok");
await promiseRequestDevice(aRequestAudio, aRequestVideo);
await promise;
await observerPromise1;
await observerPromise2;
await observerPromise3;
if (aRequestAudio || aRequestVideo) {
let indicator = promiseIndicatorWindow();
let observerPromise1 = expectObserverCalled("getUserMedia:request");
let observerPromise2 = expectObserverCalled(
"getUserMedia:response:allow"
);
let observerPromise3 = expectObserverCalled(
"recording-device-events"
);
// Start sharing what's been requested.
let promise = promiseMessage("ok");
await promiseRequestDevice(aRequestAudio, aRequestVideo);
await promise;
await observerPromise1;
await observerPromise2;
await observerPromise3;
await indicator;
await checkSharingUI(
{ video: aRequestVideo, audio: aRequestAudio },
undefined,
undefined,
{
video: { scope: SitePermissions.SCOPE_PERSISTENT },
audio: { scope: SitePermissions.SCOPE_PERSISTENT },
}
);
await stopSharing(aRequestVideo ? "camera" : "microphone");
await indicator;
await checkSharingUI(
{ video: aRequestVideo, audio: aRequestAudio },
undefined,
undefined,
{
video: { scope: SitePermissions.SCOPE_PERSISTENT },
audio: { scope: SitePermissions.SCOPE_PERSISTENT },
}
);
await stopSharing(aStopVideo ? "camera" : "microphone");
} else {
await revokePermission(aStopVideo ? "camera" : "microphone");
}
// Check that permissions have been removed as expected.
let audioPerm = SitePermissions.getForPrincipal(
@ -716,7 +726,12 @@ var gTests = [
gBrowser.selectedBrowser
);
if (aRequestAudio) {
if (
aRequestAudio ||
aRequestVideo ||
aStopAudio ||
(aStopVideo && aRequestAudio)
) {
Assert.deepEqual(
audioPerm,
{
@ -762,7 +777,12 @@ var gTests = [
"camera^myDevice2",
gBrowser.selectedBrowser
);
if (aRequestVideo) {
if (
aRequestAudio ||
aRequestVideo ||
aStopVideo ||
(aStopAudio && aRequestVideo)
) {
Assert.deepEqual(
videoPerm,
{
@ -797,6 +817,7 @@ var gTests = [
"camera device-specific permissions untouched"
);
}
await checkNotSharing();
// Cleanup.
await closeStream(true);
@ -813,12 +834,20 @@ var gTests = [
);
}
info("request audio+video, stop sharing resets both");
info("request audio+video, stop sharing video resets both");
await stopAndCheckPerm(true, true);
info("request audio, stop sharing resets audio only");
info("request audio only, stop sharing audio resets both");
await stopAndCheckPerm(true, false);
info("request video, stop sharing resets video only");
info("request video only, stop sharing video resets both");
await stopAndCheckPerm(false, true);
info("request audio only, stop sharing video resets both");
await stopAndCheckPerm(true, false, false, true);
info("request video only, stop sharing audio resets both");
await stopAndCheckPerm(false, true, true, false);
info("request neither, stop audio affects audio only");
await stopAndCheckPerm(false, false, true, false);
info("request neither, stop video affects video only");
await stopAndCheckPerm(false, false, false, true);
},
},

Просмотреть файл

@ -582,22 +582,6 @@ async function stopSharing(
1,
aFrameBC
);
aWindow.gPermissionPanel._identityPermissionBox.click();
let popup = aWindow.gPermissionPanel._permissionPopup;
// If the popup gets hidden before being shown, by stray focus/activate
// events, don't bother failing the test. It's enough to know that we
// started showing the popup.
let hiddenEvent = BrowserTestUtils.waitForEvent(popup, "popuphidden");
let shownEvent = BrowserTestUtils.waitForEvent(popup, "popupshown");
await Promise.race([hiddenEvent, shownEvent]);
let doc = aWindow.document;
let permissions = doc.getElementById("permission-popup-permission-list");
let cancelButton = permissions.querySelector(
".permission-popup-permission-icon." +
aType +
"-icon ~ " +
".permission-popup-permission-remove-button"
);
let observerPromise1 = expectObserverCalled(
"getUserMedia:revoke",
1,
@ -615,9 +599,7 @@ async function stopSharing(
);
}
cancelButton.click();
popup.hidePopup();
await revokePermission(aType, aShouldKeepSharing, aFrameBC, aWindow);
await promiseRecordingEvent;
await observerPromise1;
await observerPromise2;
@ -627,6 +609,37 @@ async function stopSharing(
}
}
async function revokePermission(
aType = "camera",
aShouldKeepSharing = false,
aFrameBC,
aWindow = window
) {
aWindow.gPermissionPanel._identityPermissionBox.click();
let popup = aWindow.gPermissionPanel._permissionPopup;
// If the popup gets hidden before being shown, by stray focus/activate
// events, don't bother failing the test. It's enough to know that we
// started showing the popup.
let hiddenEvent = BrowserTestUtils.waitForEvent(popup, "popuphidden");
let shownEvent = BrowserTestUtils.waitForEvent(popup, "popupshown");
await Promise.race([hiddenEvent, shownEvent]);
let doc = aWindow.document;
let permissions = doc.getElementById("permission-popup-permission-list");
let cancelButton = permissions.querySelector(
".permission-popup-permission-icon." +
aType +
"-icon ~ " +
".permission-popup-permission-remove-button"
);
cancelButton.click();
popup.hidePopup();
if (!aShouldKeepSharing) {
await checkNotSharing();
}
}
function getBrowsingContextForFrame(aBrowsingContext, aFrameId) {
if (!aFrameId) {
return aBrowsingContext;

Просмотреть файл

@ -600,22 +600,18 @@ var webrtcUI = {
// devices related to the permission.
let perms = SitePermissions.getAllForBrowser(browser);
let sharingCameraAndMic =
sharingState?.camera &&
sharingState?.microphone &&
// If capturing, don't revoke one of camera/microphone without the other.
let sharingCameraOrMic =
(sharingState?.camera || sharingState?.microphone) &&
(types.includes("camera") || types.includes("microphone"));
perms
.filter(perm => {
let [permId] = perm.id.split(SitePermissions.PERM_KEY_DELIMITER);
// It's not possible to stop sharing one of camera/microphone
// without the other.
if (
sharingCameraAndMic &&
(permId == "camera" || permId == "microphone")
) {
let [id] = perm.id.split(SitePermissions.PERM_KEY_DELIMITER);
if (sharingCameraOrMic && (id == "camera" || id == "microphone")) {
return true;
}
return types.includes(permId);
return types.includes(id);
})
.forEach(perm => {
SitePermissions.removeFromPrincipal(
@ -637,10 +633,7 @@ var webrtcUI = {
if (types.includes("screen") && sharingState.screen) {
windowIds.push(`screen:${windowId}`);
}
if (
(types.includes("camera") && sharingState.camera) ||
(types.includes("microphone") && sharingState.microphone)
) {
if (sharingCameraOrMic) {
windowIds.push(windowId);
}