Bug 1459613 - Show extension name in PermissionUI / webrtcUI doorhangers and menus items.
MozReview-Commit-ID: 2NbbsWkxDHm
--- a/browser/base/content/test/popupNotifications/browser_displayURI.js
+++ b/browser/base/content/test/popupNotifications/browser_displayURI.js
@@ -1,13 +1,13 @@
/*
* Make sure that the correct origin is shown for permission prompts.
*/
-async function check(contentTask) {
+async function check(contentTask, options = {}) {
await BrowserTestUtils.withNewTab("https://test1.example.com/", async function(browser) {
let popupShownPromise = waitForNotificationPanel();
await ContentTask.spawn(browser, null, contentTask);
let panel = await popupShownPromise;
let notification = panel.children[0];
let body = document.getAnonymousElementByAttribute(notification,
"class",
"popup-notification-body");
@@ -15,30 +15,65 @@ async function check(contentTask) {
});
let channel = NetUtil.newChannel({
uri: getRootDirectory(gTestPath),
loadUsingSystemPrincipal: true,
});
channel = channel.QueryInterface(Ci.nsIFileChannel);
- return BrowserTestUtils.withNewTab(channel.file.path, async function(browser) {
+ await BrowserTestUtils.withNewTab(channel.file.path, async function(browser) {
let popupShownPromise = waitForNotificationPanel();
await ContentTask.spawn(browser, null, contentTask);
let panel = await popupShownPromise;
let notification = panel.children[0];
let body = document.getAnonymousElementByAttribute(notification,
"class",
"popup-notification-body");
if (notification.id == "geolocation-notification") {
ok(body.innerHTML.includes("local file"), `file:// URIs should be displayed as local file.`);
} else {
ok(body.innerHTML.includes("Unknown origin"), "file:// URIs should be displayed as unknown origin.");
}
});
+
+ if (!options.skipOnExtension) {
+ // Test the scenario also on the extension page if not explicitly unsupported
+ // (e.g. an extension page can't be navigated on a blob URL).
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ name: "Test Extension Name",
+ },
+ background() {
+ let {browser} = this;
+ browser.test.sendMessage("extension-tab-url",
+ browser.extension.getURL("extension-tab-page.html"));
+ },
+ files: {
+ "extension-tab-page.html": `<!DOCTYPE html><html><body></body></html>`,
+ },
+ });
+
+ await extension.startup();
+ let extensionURI = await extension.awaitMessage("extension-tab-url");
+
+ await BrowserTestUtils.withNewTab(extensionURI, async function(browser) {
+ let popupShownPromise = waitForNotificationPanel();
+ await ContentTask.spawn(browser, null, contentTask);
+ let panel = await popupShownPromise;
+ let notification = panel.children[0];
+ let body = document.getAnonymousElementByAttribute(notification,
+ "class",
+ "popup-notification-body");
+ ok(body.innerHTML.includes("Test Extension Name"),
+ "Check the the extension name is present in the markup");
+ });
+
+ await extension.unload();
+ }
}
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({set: [
["media.navigator.permission.fake", true],
["media.navigator.permission.force", true],
]});
});
@@ -56,20 +91,20 @@ add_task(async function test_displayURI_
});
add_task(async function test_displayURI_geo_blob() {
await check(async function() {
let text = "<script>navigator.geolocation.getCurrentPosition(() => {})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);
content.location.href = url;
- });
+ }, {skipOnExtension: true});
});
add_task(async function test_displayURI_camera_blob() {
await check(async function() {
let text = "<script>navigator.mediaDevices.getUserMedia({video: true, fake: true})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);
content.location.href = url;
- });
+ }, {skipOnExtension: true});
});
--- a/browser/modules/PermissionUI.jsm
+++ b/browser/modules/PermissionUI.jsm
@@ -104,16 +104,30 @@ var PermissionPromptPrototype = {
*
* @return {nsIPrincipal}
*/
get principal() {
throw new Error("Not implemented.");
},
/**
+ * Provides the preferred name to use in the permission popups,
+ * based on the principal URI (the URI.hostPort for any URI scheme
+ * besides the moz-extension one which should default to the
+ * extension name).
+ */
+ get principalName() {
+ if (this.principal.addonPolicy) {
+ return this.principal.addonPolicy.name;
+ }
+
+ return this.principal.URI.hostPort;
+ },
+
+ /**
* If the nsIPermissionManager is being queried and written
* to for this permission request, set this to the key to be
* used. If this is undefined, user permissions will not be
* read from or written to.
*
* Note that if a permission is set, in any follow-up
* prompting within the expiry window of that permission,
* the prompt will be skipped and the allow or deny choice
@@ -422,17 +436,17 @@ GeolocationPermissionPrompt.prototype =
return "geo";
},
get popupOptions() {
let pref = "browser.geolocation.warning.infoURL";
let options = {
learnMoreURL: Services.urlFormatter.formatURLPref(pref),
displayURI: false,
- name: this.principal.URI.hostPort,
+ name: this.principalName,
};
if (this.principal.URI.schemeIs("file")) {
options.checkbox = { show: false };
} else {
// Don't offer "always remember" action in PB mode
options.checkbox = {
show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal)
@@ -455,17 +469,17 @@ GeolocationPermissionPrompt.prototype =
},
get message() {
if (this.principal.URI.schemeIs("file")) {
return gBrowserBundle.GetStringFromName("geolocation.shareWithFile3");
}
return gBrowserBundle.formatStringFromName("geolocation.shareWithSite3",
- ["<>"], 1);
+ ["<>"], 1);
},
get promptActions() {
// We collect Telemetry data on Geolocation prompts and how users
// respond to them. The probe keys are a bit verbose, so let's alias them.
const SHARE_LOCATION =
Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION;
const ALWAYS_SHARE =
@@ -530,17 +544,17 @@ DesktopNotificationPermissionPrompt.prot
get popupOptions() {
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
return {
learnMoreURL,
displayURI: false,
- name: this.principal.URI.hostPort,
+ name: this.principalName,
};
},
get notificationID() {
return "web-notifications";
},
get anchorID() {
@@ -612,17 +626,17 @@ PersistentStoragePermissionPrompt.protot
checkbox.label = gBrowserBundle.GetStringFromName("persistentStorage.remember");
}
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
return {
checkbox,
learnMoreURL,
displayURI: false,
- name: this.principal.URI.hostPort,
+ name: this.principalName,
};
},
get notificationID() {
return "persistent-storage";
},
get anchorID() {
@@ -679,17 +693,17 @@ MIDIPermissionPrompt.prototype = {
get permissionKey() {
return this.permName;
},
get popupOptions() {
// TODO (bug 1433235) We need a security/permissions explanation URL for this
let options = {
displayURI: false,
- name: this.principal.URI.hostPort,
+ name: this.principalName,
};
if (this.principal.URI.schemeIs("file")) {
options.checkbox = { show: false };
} else {
// Don't offer "always remember" action in PB mode
options.checkbox = {
show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal)
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -295,24 +295,27 @@ var webrtcUI = {
};
function denyRequest(aBrowser, aRequest) {
aBrowser.messageManager.sendAsyncMessage("webrtc:Deny",
{callID: aRequest.callID,
windowID: aRequest.windowID});
}
-function getHost(uri, href) {
+function getHostOrExtensionName(uri, href) {
let host;
try {
if (!uri) {
uri = Services.io.newURI(href);
}
- host = uri.host;
+
+ let addonPolicy = WebExtensionPolicy.getByURI(uri);
+ host = addonPolicy ? addonPolicy.name : uri.host;
} catch (ex) {}
+
if (!host) {
if (uri && uri.scheme.toLowerCase() == "about") {
// For about URIs, just use the full spec, without any #hash parts.
host = uri.specIgnoringRef;
} else {
// This is unfortunate, but we should display *something*...
const kBundleURI = "chrome://browser/locale/browser.properties";
let bundle = Services.strings.createBundle(kBundleURI);
@@ -414,17 +417,17 @@ function prompt(aBrowser, aRequest) {
SitePermissions.BLOCK, scope, notification.browser);
}
}
];
let productName = gBrandBundle.GetStringFromName("brandShortName");
let options = {
- name: getHost(uri),
+ name: getHostOrExtensionName(uri),
persistent: true,
hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
eventCallback(aTopic, aNewBrowser) {
if (aTopic == "swapping")
return true;
let doc = this.browser.ownerDocument;
@@ -1002,17 +1005,17 @@ function onTabSharingMenuPopupShowing(e)
if (types.microphone)
stringName += "Microphone";
if (types.screen)
stringName += types.screen;
let doc = e.target.ownerDocument;
let bundle = doc.defaultView.gNavigatorBundle;
- let origin = getHost(null, streamInfo.uri);
+ let origin = getHostOrExtensionName(null, streamInfo.uri);
let menuitem = doc.createElement("menuitem");
menuitem.setAttribute("label", bundle.getFormattedString(stringName, [origin]));
menuitem.stream = streamInfo;
menuitem.addEventListener("command", onTabSharingMenuPopupCommand);
e.target.appendChild(menuitem);
}
}