зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1579489) for causing bc failures at browser_ext_webrtc.js CLOSED TREE
Backed out changeset 71978ebe41f1 (bug 1579489) Backed out changeset b5e35c96c2f7 (bug 1579489) Backed out changeset 71130160afee (bug 1579489)
This commit is contained in:
Родитель
9b17ca23e1
Коммит
ee8e5475f4
|
@ -273,7 +273,6 @@ skip-if = os == 'mac' # Save as PDF not supported on Mac OS X
|
||||||
[browser_ext_urlbar_contextual_tip.js]
|
[browser_ext_urlbar_contextual_tip.js]
|
||||||
[browser_ext_user_events.js]
|
[browser_ext_user_events.js]
|
||||||
[browser_ext_webRequest.js]
|
[browser_ext_webRequest.js]
|
||||||
[browser_ext_webrtc.js]
|
|
||||||
[browser_ext_webNavigation_frameId0.js]
|
[browser_ext_webNavigation_frameId0.js]
|
||||||
[browser_ext_webNavigation_getFrames.js]
|
[browser_ext_webNavigation_getFrames.js]
|
||||||
[browser_ext_webNavigation_onCreatedNavigationTarget.js]
|
[browser_ext_webNavigation_onCreatedNavigationTarget.js]
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const { PermissionTestUtils } = ChromeUtils.import(
|
|
||||||
"resource://testing-common/PermissionTestUtils.jsm"
|
|
||||||
);
|
|
||||||
|
|
||||||
add_task(async function test_background_request() {
|
|
||||||
let extension = ExtensionTestUtils.loadExtension({
|
|
||||||
manifest: {},
|
|
||||||
async background() {
|
|
||||||
browser.test.onMessage.addListener(async msg => {
|
|
||||||
if (msg.type != "testGUM") {
|
|
||||||
browser.test.fail("unknown message");
|
|
||||||
}
|
|
||||||
|
|
||||||
await browser.test.assertRejects(
|
|
||||||
navigator.mediaDevices.getUserMedia({ audio: true }),
|
|
||||||
/The request is not allowed/,
|
|
||||||
"Calling gUM in background pages throws an error"
|
|
||||||
);
|
|
||||||
browser.test.notifyPass("done");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await extension.startup();
|
|
||||||
|
|
||||||
let policy = WebExtensionPolicy.getByID(extension.id);
|
|
||||||
let principal = policy.extension.principal;
|
|
||||||
// Add a permission for the extension to make sure that we throw even
|
|
||||||
// if permission was given.
|
|
||||||
PermissionTestUtils.add(principal, "microphone", Services.perms.ALLOW_ACTION);
|
|
||||||
|
|
||||||
let finished = extension.awaitFinish("done");
|
|
||||||
extension.sendMessage({ type: "testGUM" });
|
|
||||||
await finished;
|
|
||||||
|
|
||||||
PermissionTestUtils.remove(principal, "microphone");
|
|
||||||
await extension.unload();
|
|
||||||
});
|
|
||||||
|
|
||||||
let scriptPage = url =>
|
|
||||||
`<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>${url}</body></html>`;
|
|
||||||
|
|
||||||
add_task(async function test_popup_request() {
|
|
||||||
let extension = ExtensionTestUtils.loadExtension({
|
|
||||||
manifest: {
|
|
||||||
browser_action: {
|
|
||||||
default_popup: "popup.html",
|
|
||||||
browser_style: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
files: {
|
|
||||||
"popup.html": scriptPage("popup.js"),
|
|
||||||
"popup.js": function() {
|
|
||||||
browser.test
|
|
||||||
.assertRejects(
|
|
||||||
navigator.mediaDevices.getUserMedia({ audio: true }),
|
|
||||||
/The request is not allowed/,
|
|
||||||
"Calling gUM in popup pages without permission throws an error"
|
|
||||||
)
|
|
||||||
.then(function() {
|
|
||||||
browser.test.notifyPass("done");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await extension.startup();
|
|
||||||
clickBrowserAction(extension);
|
|
||||||
await extension.awaitFinish("done");
|
|
||||||
await extension.unload();
|
|
||||||
|
|
||||||
extension = ExtensionTestUtils.loadExtension({
|
|
||||||
manifest: {
|
|
||||||
// Use the same url for background page and browserAction popup,
|
|
||||||
// to double-check that the page url is not being used to decide
|
|
||||||
// if webRTC requests should be allowed or not.
|
|
||||||
background: { page: "page.html" },
|
|
||||||
browser_action: {
|
|
||||||
default_popup: "page.html",
|
|
||||||
browser_style: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
files: {
|
|
||||||
"page.html": scriptPage("page.js"),
|
|
||||||
"page.js": async function() {
|
|
||||||
const isBackgroundPage =
|
|
||||||
window == (await browser.runtime.getBackgroundPage());
|
|
||||||
|
|
||||||
if (isBackgroundPage) {
|
|
||||||
await browser.test.assertRejects(
|
|
||||||
navigator.mediaDevices.getUserMedia({ audio: true }),
|
|
||||||
/The request is not allowed/,
|
|
||||||
"Calling gUM in background pages throws an error"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
||||||
browser.test.notifyPass("done");
|
|
||||||
} catch (err) {
|
|
||||||
browser.test.fail(`Failed with error ${err.message}`);
|
|
||||||
browser.test.notifyFail("done");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add a permission for the extension to make sure that we throw even
|
|
||||||
// if permission was given.
|
|
||||||
await extension.startup();
|
|
||||||
|
|
||||||
let policy = WebExtensionPolicy.getByID(extension.id);
|
|
||||||
let principal = policy.extension.principal;
|
|
||||||
|
|
||||||
PermissionTestUtils.add(principal, "microphone", Services.perms.ALLOW_ACTION);
|
|
||||||
clickBrowserAction(extension);
|
|
||||||
|
|
||||||
await extension.awaitFinish("done");
|
|
||||||
PermissionTestUtils.remove(principal, "microphone");
|
|
||||||
await extension.unload();
|
|
||||||
});
|
|
|
@ -468,115 +468,6 @@ function stopRecording(aBrowser, aRequest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the principal has sufficient permissions
|
|
||||||
* to fulfill the given request. If the request can be
|
|
||||||
* fulfilled, a message is sent to the child
|
|
||||||
* signaling that WebRTC permissions were given and
|
|
||||||
* this function will return true.
|
|
||||||
*/
|
|
||||||
function checkRequestAllowed(aRequest, aPrincipal, aBrowser) {
|
|
||||||
if (!aRequest.secure) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { audioDevices, videoDevices, sharingScreen } = aRequest;
|
|
||||||
|
|
||||||
let micAllowed =
|
|
||||||
SitePermissions.getForPrincipal(aPrincipal, "microphone").state ==
|
|
||||||
SitePermissions.ALLOW;
|
|
||||||
let camAllowed =
|
|
||||||
SitePermissions.getForPrincipal(aPrincipal, "camera").state ==
|
|
||||||
SitePermissions.ALLOW;
|
|
||||||
|
|
||||||
let perms = Services.perms;
|
|
||||||
let mediaManagerPerm = perms.testExactPermissionFromPrincipal(
|
|
||||||
aPrincipal,
|
|
||||||
"MediaManagerVideo"
|
|
||||||
);
|
|
||||||
if (mediaManagerPerm) {
|
|
||||||
perms.removeFromPrincipal(aPrincipal, "MediaManagerVideo");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Screen sharing shouldn't follow the camera permissions.
|
|
||||||
if (videoDevices.length && sharingScreen) {
|
|
||||||
camAllowed = false;
|
|
||||||
}
|
|
||||||
if (aRequest.isThirdPartyOrigin) {
|
|
||||||
camAllowed = false;
|
|
||||||
micAllowed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let activeCamera;
|
|
||||||
let activeMic;
|
|
||||||
|
|
||||||
// Always prompt for screen sharing
|
|
||||||
if (!sharingScreen) {
|
|
||||||
for (let device of videoDevices) {
|
|
||||||
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
|
|
||||||
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
|
|
||||||
activeCamera = device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let device of audioDevices) {
|
|
||||||
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
|
|
||||||
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
|
|
||||||
activeMic = device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(!audioDevices.length || micAllowed || activeMic) &&
|
|
||||||
(!videoDevices.length || camAllowed || activeCamera)
|
|
||||||
) {
|
|
||||||
let allowedDevices = [];
|
|
||||||
if (videoDevices.length) {
|
|
||||||
allowedDevices.push((activeCamera || videoDevices[0]).deviceIndex);
|
|
||||||
Services.perms.addFromPrincipal(
|
|
||||||
aPrincipal,
|
|
||||||
"MediaManagerVideo",
|
|
||||||
Services.perms.ALLOW_ACTION,
|
|
||||||
Services.perms.EXPIRE_SESSION
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (audioDevices.length) {
|
|
||||||
allowedDevices.push((activeMic || audioDevices[0]).deviceIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember on which URIs we found persistent permissions so that we
|
|
||||||
// can remove them if the user clicks 'Stop Sharing'. There's no
|
|
||||||
// other way for the stop sharing code to know the hostnames of frames
|
|
||||||
// using devices until bug 1066082 is fixed.
|
|
||||||
let browser = aBrowser;
|
|
||||||
browser._devicePermissionPrincipals =
|
|
||||||
browser._devicePermissionPrincipals || [];
|
|
||||||
browser._devicePermissionPrincipals.push(aPrincipal);
|
|
||||||
|
|
||||||
let camNeeded = !!videoDevices.length;
|
|
||||||
let micNeeded = !!audioDevices.length;
|
|
||||||
checkOSPermission(camNeeded, micNeeded).then(havePermission => {
|
|
||||||
if (havePermission) {
|
|
||||||
let mm = browser.messageManager;
|
|
||||||
mm.sendAsyncMessage("webrtc:Allow", {
|
|
||||||
callID: aRequest.callID,
|
|
||||||
windowID: aRequest.windowID,
|
|
||||||
devices: allowedDevices,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
denyRequestNoPermission(browser, aRequest);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prompt(aBrowser, aRequest) {
|
function prompt(aBrowser, aRequest) {
|
||||||
let {
|
let {
|
||||||
audioDevices,
|
audioDevices,
|
||||||
|
@ -590,39 +481,6 @@ function prompt(aBrowser, aRequest) {
|
||||||
aRequest.origin
|
aRequest.origin
|
||||||
);
|
);
|
||||||
|
|
||||||
// For add-on principals, we immediately check for permission instead
|
|
||||||
// of waiting for the notification to focus. This allows for supporting
|
|
||||||
// cases such as browserAction popups where no prompt is shown.
|
|
||||||
if (principal.addonPolicy) {
|
|
||||||
let isPopup = false;
|
|
||||||
let isBackground = false;
|
|
||||||
|
|
||||||
for (let view of principal.addonPolicy.extension.views) {
|
|
||||||
if (view.viewType == "popup" && view.xulBrowser == aBrowser) {
|
|
||||||
isPopup = true;
|
|
||||||
}
|
|
||||||
if (view.viewType == "background" && view.xulBrowser == aBrowser) {
|
|
||||||
isBackground = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recording from background pages is considered too sensitive and will
|
|
||||||
// always be denied.
|
|
||||||
if (isBackground) {
|
|
||||||
denyRequest(aBrowser, aRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the request comes from a popup, we don't want to show the prompt,
|
|
||||||
// but we do want to allow the request if the user previously gave permission.
|
|
||||||
if (isPopup) {
|
|
||||||
if (!checkRequestAllowed(aRequest, principal, aBrowser)) {
|
|
||||||
denyRequest(aBrowser, aRequest);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user has already denied access once in this tab,
|
// If the user has already denied access once in this tab,
|
||||||
// deny again without even showing the notification icon.
|
// deny again without even showing the notification icon.
|
||||||
if (
|
if (
|
||||||
|
@ -760,10 +618,106 @@ function prompt(aBrowser, aRequest) {
|
||||||
// it is handled synchronously before we add the notification.
|
// it is handled synchronously before we add the notification.
|
||||||
// Handling of ALLOW is delayed until the popupshowing event,
|
// Handling of ALLOW is delayed until the popupshowing event,
|
||||||
// to avoid granting permissions automatically to background tabs.
|
// to avoid granting permissions automatically to background tabs.
|
||||||
if (checkRequestAllowed(aRequest, principal, aBrowser)) {
|
if (aRequest.secure) {
|
||||||
|
let micAllowed =
|
||||||
|
SitePermissions.getForPrincipal(principal, "microphone").state ==
|
||||||
|
SitePermissions.ALLOW;
|
||||||
|
let camAllowed =
|
||||||
|
SitePermissions.getForPrincipal(principal, "camera").state ==
|
||||||
|
SitePermissions.ALLOW;
|
||||||
|
|
||||||
|
let perms = Services.perms;
|
||||||
|
let mediaManagerPerm = perms.testExactPermissionFromPrincipal(
|
||||||
|
principal,
|
||||||
|
"MediaManagerVideo"
|
||||||
|
);
|
||||||
|
if (mediaManagerPerm) {
|
||||||
|
perms.removeFromPrincipal(principal, "MediaManagerVideo");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screen sharing shouldn't follow the camera permissions.
|
||||||
|
if (videoDevices.length && sharingScreen) {
|
||||||
|
camAllowed = false;
|
||||||
|
}
|
||||||
|
if (aRequest.isThirdPartyOrigin) {
|
||||||
|
camAllowed = false;
|
||||||
|
micAllowed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let activeCamera;
|
||||||
|
let activeMic;
|
||||||
|
|
||||||
|
// Always prompt for screen sharing
|
||||||
|
if (!sharingScreen) {
|
||||||
|
for (let device of videoDevices) {
|
||||||
|
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
|
||||||
|
if (
|
||||||
|
set &&
|
||||||
|
set.has(aRequest.windowID + device.mediaSource + device.id)
|
||||||
|
) {
|
||||||
|
activeCamera = device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let device of audioDevices) {
|
||||||
|
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
|
||||||
|
if (
|
||||||
|
set &&
|
||||||
|
set.has(aRequest.windowID + device.mediaSource + device.id)
|
||||||
|
) {
|
||||||
|
activeMic = device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!audioDevices.length || micAllowed || activeMic) &&
|
||||||
|
(!videoDevices.length || camAllowed || activeCamera)
|
||||||
|
) {
|
||||||
|
let allowedDevices = [];
|
||||||
|
if (videoDevices.length) {
|
||||||
|
allowedDevices.push((activeCamera || videoDevices[0]).deviceIndex);
|
||||||
|
Services.perms.addFromPrincipal(
|
||||||
|
principal,
|
||||||
|
"MediaManagerVideo",
|
||||||
|
Services.perms.ALLOW_ACTION,
|
||||||
|
Services.perms.EXPIRE_SESSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (audioDevices.length) {
|
||||||
|
allowedDevices.push((activeMic || audioDevices[0]).deviceIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember on which URIs we found persistent permissions so that we
|
||||||
|
// can remove them if the user clicks 'Stop Sharing'. There's no
|
||||||
|
// other way for the stop sharing code to know the hostnames of frames
|
||||||
|
// using devices until bug 1066082 is fixed.
|
||||||
|
let browser = this.browser;
|
||||||
|
browser._devicePermissionPrincipals =
|
||||||
|
browser._devicePermissionPrincipals || [];
|
||||||
|
browser._devicePermissionPrincipals.push(principal);
|
||||||
|
|
||||||
|
let camNeeded = !!videoDevices.length;
|
||||||
|
let micNeeded = !!audioDevices.length;
|
||||||
|
checkOSPermission(camNeeded, micNeeded).then(havePermission => {
|
||||||
|
if (havePermission) {
|
||||||
|
let mm = browser.messageManager;
|
||||||
|
mm.sendAsyncMessage("webrtc:Allow", {
|
||||||
|
callID: aRequest.callID,
|
||||||
|
windowID: aRequest.windowID,
|
||||||
|
devices: allowedDevices,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
denyRequestNoPermission(browser, aRequest);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.remove();
|
this.remove();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function listDevices(menupopup, devices) {
|
function listDevices(menupopup, devices) {
|
||||||
while (menupopup.lastChild) {
|
while (menupopup.lastChild) {
|
||||||
|
@ -1128,8 +1082,6 @@ function prompt(aBrowser, aRequest) {
|
||||||
devices: allowedDevices,
|
devices: allowedDevices,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we haven't handled the permission yet, we want to show the doorhanger.
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1156,7 +1108,6 @@ function prompt(aBrowser, aRequest) {
|
||||||
|
|
||||||
options.checkbox = {
|
options.checkbox = {
|
||||||
label: stringBundle.getString("getUserMedia.remember"),
|
label: stringBundle.getString("getUserMedia.remember"),
|
||||||
checked: principal.isAddonOrExpandedAddonPrincipal,
|
|
||||||
checkedState: reasonForNoPermanentAllow
|
checkedState: reasonForNoPermanentAllow
|
||||||
? {
|
? {
|
||||||
disableMainAction: true,
|
disableMainAction: true,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче