Bug 1461656 - Ask permission when site wants to autoplay media. r=johannh, r=flod
MozReview-Commit-ID: Fc2IUZK90eu
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -1051,17 +1051,19 @@ var gIdentityHandler = {
if (aPermission.state == SitePermissions.getDefault(aPermission.id)) {
menulist.value = "0";
} else {
menulist.value = aPermission.state;
}
// Avoiding listening to the "select" event on purpose. See Bug 1404262.
menulist.addEventListener("command", () => {
- SitePermissions.set(gBrowser.currentURI, "popup", menulist.selectedItem.value);
+ SitePermissions.set(gBrowser.currentURI,
+ aPermission.id,
+ menulist.selectedItem.value);
});
container.appendChild(img);
container.appendChild(nameLabel);
container.appendChild(menulist);
block.appendChild(container);
return block;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -819,32 +819,36 @@
<image data-permission-id="microphone" class="blocked-permission-icon microphone-icon" role="button"
tooltiptext="&urlbar.microphoneBlocked.tooltip;"/>
<image data-permission-id="screen" class="blocked-permission-icon screen-icon" role="button"
tooltiptext="&urlbar.screenBlocked.tooltip;"/>
<image data-permission-id="persistent-storage" class="blocked-permission-icon persistent-storage-icon" role="button"
tooltiptext="&urlbar.persistentStorageBlocked.tooltip;"/>
<image data-permission-id="popup" class="blocked-permission-icon popup-icon" role="button"
tooltiptext="&urlbar.popupBlocked.tooltip;"/>
+ <image data-permission-id="autoplay-media" class="blocked-permission-icon autoplay-media-icon" role="button"
+ tooltiptext="&urlbar.autoplayMediaBlocked.tooltip;"/>
<image data-permission-id="canvas" class="blocked-permission-icon canvas-icon" role="button"
tooltiptext="&urlbar.canvasBlocked.tooltip;"/>
<image data-permission-id="plugin:flash" class="blocked-permission-icon plugin-icon" role="button"
tooltiptext="&urlbar.flashPluginBlocked.tooltip;"/>
<image data-permission-id="midi" class="blocked-permission-icon midi-icon" role="button"
tooltiptext="&urlbar.midiBlocked.tooltip;"/>
</box>
<box id="notification-popup-box"
hidden="true"
onmouseover="document.getElementById('identity-box').classList.add('no-hover');"
onmouseout="document.getElementById('identity-box').classList.remove('no-hover');"
align="center">
<image id="default-notification-icon" class="notification-anchor-icon" role="button"
tooltiptext="&urlbar.defaultNotificationAnchor.tooltip;"/>
<image id="geo-notification-icon" class="notification-anchor-icon geo-icon" role="button"
tooltiptext="&urlbar.geolocationNotificationAnchor.tooltip;"/>
+ <image id="autoplay-media-notification-icon" class="notification-anchor-icon autoplay-media-icon" role="button"
+ tooltiptext="&urlbar.autoplayNotificationAnchor.tooltip;"/>
<image id="addons-notification-icon" class="notification-anchor-icon install-icon" role="button"
tooltiptext="&urlbar.addonsNotificationAnchor.tooltip;"/>
<image id="canvas-notification-icon" class="notification-anchor-icon" role="button"
tooltiptext="&urlbar.canvasNotificationAnchor.tooltip;"/>
<image id="indexedDB-notification-icon" class="notification-anchor-icon indexedDB-icon" role="button"
tooltiptext="&urlbar.indexedDBNotificationAnchor.tooltip;"/>
<image id="password-notification-icon" class="notification-anchor-icon login-icon" role="button"
tooltiptext="&urlbar.passwordNotificationAnchor.tooltip;"/>
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2838,16 +2838,19 @@ const ContentPermissionIntegration = {
return new PermissionUI.DesktopNotificationPermissionPrompt(request);
}
case "persistent-storage": {
return new PermissionUI.PersistentStoragePermissionPrompt(request);
}
case "midi": {
return new PermissionUI.MIDIPermissionPrompt(request);
}
+ case "autoplay-media": {
+ return new PermissionUI.AutoplayPermissionPrompt(request);
+ }
}
return undefined;
},
};
function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = {
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -208,16 +208,17 @@ These should match what Safari and other
<!ENTITY goEndCap.tooltip "Go to the address in the Location Bar">
<!ENTITY printButton.label "Print">
<!ENTITY printButton.tooltip "Print this page">
<!ENTITY urlbar.viewSiteInfo.label "View site information">
<!ENTITY urlbar.defaultNotificationAnchor.tooltip "Open message panel">
<!ENTITY urlbar.geolocationNotificationAnchor.tooltip "Open location request panel">
+<!ENTITY urlbar.autoplayNotificationAnchor.tooltip "Open autoplay panel">
<!ENTITY urlbar.addonsNotificationAnchor.tooltip "Open add-on installation message panel">
<!ENTITY urlbar.canvasNotificationAnchor.tooltip "Manage canvas extraction permission">
<!ENTITY urlbar.indexedDBNotificationAnchor.tooltip "Open offline storage message panel">
<!ENTITY urlbar.passwordNotificationAnchor.tooltip "Open save password message panel">
<!ENTITY urlbar.pluginsNotificationAnchor.tooltip "Manage plug-in use">
<!ENTITY urlbar.webNotificationAnchor.tooltip "Change whether you can receive notifications from the site">
<!ENTITY urlbar.persistentStorageNotificationAnchor.tooltip "Store data in Persistent Storage">
<!ENTITY urlbar.remoteControlNotificationAnchor.tooltip "Browser is under remote control">
@@ -235,16 +236,17 @@ These should match what Safari and other
<!ENTITY urlbar.cameraBlocked.tooltip "You have blocked your camera for this website.">
<!ENTITY urlbar.microphoneBlocked.tooltip "You have blocked your microphone for this website.">
<!ENTITY urlbar.screenBlocked.tooltip "You have blocked this website from sharing your screen.">
<!ENTITY urlbar.geolocationBlocked.tooltip "You have blocked location information for this website.">
<!ENTITY urlbar.webNotificationsBlocked.tooltip "You have blocked notifications for this website.">
<!ENTITY urlbar.persistentStorageBlocked.tooltip "You have blocked persistent storage for this website.">
<!ENTITY urlbar.popupBlocked.tooltip "You have blocked pop-ups for this website.">
+<!ENTITY urlbar.autoplayMediaBlocked.tooltip "You have blocked autoplay media with sound for this website.">
<!ENTITY urlbar.canvasBlocked.tooltip "You have blocked canvas data extraction for this website.">
<!ENTITY urlbar.flashPluginBlocked.tooltip "You have blocked this website from using the Adobe Flash plugin.">
<!ENTITY urlbar.midiBlocked.tooltip "You have blocked MIDI access for this website.">
<!ENTITY urlbar.openHistoryPopup.tooltip "Show history">
<!ENTITY searchItem.title "Search">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -946,12 +946,20 @@ midi.DontAllow.accesskey = N
midi.remember=Remember this decision
midi.shareWithFile.message = Will you allow this local file to access your MIDI Devices?
# LOCALIZATION NOTE (midi.shareWithSite.message): %S is the name of the site URL (https://...) requesting MIDI access
midi.shareWithSite.message = Will you allow %S to access your MIDI Devices?
midi.shareSysexWithFile.message = Will you allow this local file to access your MIDI devices and send/receive SysEx messages?
# LOCALIZATION NOTE (midi.shareSysexWithSite.message): %S is the name of the site URL (https://...) requesting MIDI access
midi.shareSysexWithSite.message = Will you allow %S to access your MIDI devices and send/receive SysEx messages?
+autoplay.Allow.label = Allow Autoplay
+autoplay.Allow.accesskey = A
+autoplay.DontAllow.label = Don’t Allow
+autoplay.DontAllow.accesskey = n
+autoplay.remember = Remember this decision
+# LOCALIZATION NOTE (autoplay.message): %S is the name of the site URL (https://...) trying to autoplay media
+autoplay.message = Will you allow %S to autoplay media with sound?
+autoplay.messageWithFile = Will you allow this file to autoplay media with sound?
# LOCALIZATION NOTE (panel.back):
# This is used by screen readers to label the "back" button in various browser
# popup panels, including the sliding subviews of the main menu.
panel.back = Back
--- a/browser/modules/PermissionUI.jsm
+++ b/browser/modules/PermissionUI.jsm
@@ -742,8 +742,69 @@ MIDIPermissionPrompt.prototype = {
}];
},
onBeforeShow() {
},
};
PermissionUI.MIDIPermissionPrompt = MIDIPermissionPrompt;
+
+function AutoplayPermissionPrompt(request) {
+ this.request = request;
+}
+
+AutoplayPermissionPrompt.prototype = {
+ __proto__: PermissionPromptForRequestPrototype,
+
+ get permissionKey() {
+ return "autoplay-media";
+ },
+
+ get popupOptions() {
+ let checkbox = {
+ show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal) &&
+ !this.principal.URI.schemeIs("file")
+ };
+ if (checkbox.show) {
+ checkbox.checked = true;
+ checkbox.label = gBrowserBundle.GetStringFromName("autoplay.remember");
+ }
+ return {
+ checkbox,
+ displayURI: false,
+ name: this.principal.URI.hostPort,
+ };
+ },
+
+ get notificationID() {
+ return "autoplay-media";
+ },
+
+ get anchorID() {
+ return "autoplay-media-icon";
+ },
+
+ get message() {
+ if (this.principal.URI.schemeIs("file")) {
+ return gBrowserBundle.GetStringFromName("autoplay.messageWithFile");
+ }
+ return gBrowserBundle.formatStringFromName("autoplay.message", ["<>"], 1);
+ },
+
+ get promptActions() {
+ return [{
+ label: gBrowserBundle.GetStringFromName("autoplay.Allow.label"),
+ accessKey: gBrowserBundle.GetStringFromName("autoplay.Allow.accesskey"),
+ action: Ci.nsIPermissionManager.ALLOW_ACTION,
+ },
+ {
+ label: gBrowserBundle.GetStringFromName("autoplay.DontAllow.label"),
+ accessKey: gBrowserBundle.GetStringFromName("autoplay.DontAllow.accesskey"),
+ action: Ci.nsIPermissionManager.DENY_ACTION,
+ }];
+ },
+
+ onBeforeShow() {
+ },
+};
+
+PermissionUI.AutoplayPermissionPrompt = AutoplayPermissionPrompt;
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -606,18 +606,19 @@ var gPermissionObject = {
*/
"autoplay-media": {
exactHostMatch: true,
getDefault() {
if (Services.prefs.getBoolPref("media.autoplay.enabled")) {
return SitePermissions.ALLOW;
}
- return SitePermissions.BLOCK;
- }
+ return SitePermissions.UNKNOWN;
+ },
+ labelID: "autoplay-media"
},
"image": {
states: [ SitePermissions.ALLOW, SitePermissions.BLOCK ],
},
"cookie": {
states: [ SitePermissions.ALLOW, SitePermissions.ALLOW_COOKIES_FOR_SESSION, SitePermissions.BLOCK ],
--- a/browser/modules/test/browser/browser_PermissionUI_prompts.js
+++ b/browser/modules/test/browser/browser_PermissionUI_prompts.js
@@ -25,16 +25,23 @@ add_task(async function test_persistent_
await testPrompt(PermissionUI.PersistentStoragePermissionPrompt);
});
// Tests that MidiPrompt works as expected
add_task(async function test_midi_permission_prompt() {
await testPrompt(PermissionUI.MIDIPermissionPrompt);
});
+// Tests that AutoplayPermissionPrompt works as expected
+add_task(async function test_autoplay_permission_prompt() {
+ Services.prefs.setBoolPref("media.autoplay.enabled", false);
+ await testPrompt(PermissionUI.AutoplayPermissionPrompt);
+ Services.prefs.clearUserPref("media.autoplay.enabled");
+});
+
async function testPrompt(Prompt) {
await BrowserTestUtils.withNewTab({
gBrowser,
url: "http://example.com",
}, async function(browser) {
let mockRequest = makeMockPermissionRequest(browser);
let principal = mockRequest.principal;
let TestPrompt = new Prompt(mockRequest);
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -50,16 +50,18 @@
skin/classic/browser/connection-mixed-active-loaded.svg (../shared/identity-block/connection-mixed-active-loaded.svg)
skin/classic/browser/identity-icon.svg (../shared/identity-block/identity-icon.svg)
skin/classic/browser/identity-icon-notice.svg (../shared/identity-block/identity-icon-notice.svg)
skin/classic/browser/info.svg (../shared/info.svg)
skin/classic/browser/searchReset.css (../shared/searchReset.css)
skin/classic/browser/illustrations/error-session-restore.svg (../shared/illustrations/error-session-restore.svg)
+ skin/classic/browser/notification-icons/autoplay-media.svg (../shared/notification-icons/autoplay-media.svg)
+ skin/classic/browser/notification-icons/autoplay-media-blocked.svg (../shared/notification-icons/autoplay-media-blocked.svg)
skin/classic/browser/notification-icons/camera-blocked.svg (../shared/notification-icons/camera-blocked.svg)
skin/classic/browser/notification-icons/camera.svg (../shared/notification-icons/camera.svg)
skin/classic/browser/notification-icons/canvas-blocked.svg (../shared/notification-icons/canvas-blocked.svg)
skin/classic/browser/notification-icons/canvas.svg (../shared/notification-icons/canvas.svg)
skin/classic/browser/notification-icons/default-info.svg (../shared/notification-icons/default-info.svg)
skin/classic/browser/notification-icons/desktop-notification-blocked.svg (../shared/notification-icons/desktop-notification-blocked.svg)
skin/classic/browser/notification-icons/desktop-notification.svg (../shared/notification-icons/desktop-notification.svg)
skin/classic/browser/notification-icons/focus-tab-by-prompt.svg (../shared/notification-icons/focus-tab-by-prompt.svg)
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -52,16 +52,25 @@
.geo-icon {
list-style-image: url(chrome://browser/skin/notification-icons/geo.svg);
}
.geo-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons/geo-blocked.svg);
}
+.popup-notification-icon[popupid="autoplay-media"],
+.autoplay-media-icon {
+ list-style-image: url(chrome://browser/skin/notification-icons/autoplay-media.svg);
+}
+
+.autoplay-media-icon.blocked-permission-icon {
+ list-style-image: url(chrome://browser/skin/notification-icons/autoplay-media-blocked.svg);
+}
+
.popup-notification-icon[popupid="geolocation"] {
list-style-image: url(chrome://browser/skin/notification-icons/geo-detailed.svg);
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.indexedDB-icon {
list-style-image: url(chrome://browser/skin/notification-icons/indexedDB.svg);
}
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/notification-icons/autoplay-media-blocked.svg
@@ -0,0 +1,10 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <path d="M9.94970307,6.4383516 C8.40256713,7.13481327 7.27358134,8.59523862 7.04329506,10.3390783 L5.85914977,11.0232511 C5.68193745,11.1255647 5.46360318,11.1255661 5.28638956,11.0232548 C5.10917593,10.9209434 5.0000052,10.7318625 5,10.5272353 L5,4.57046357 C5.00082111,4.36624583 5.11031415,4.17791321 5.28737873,4.0761601 C5.46444331,3.97440698 5.68229154,3.97462749 5.85914977,4.07673884 L9.94970307,6.4383516 Z" fill="#000000" fill-rule="nonzero"></path>
+ <path d="M13.5616811,5.14867232 C12.6193302,2.72101341 10.2606472,1 7.5,1 C3.91014913,1 1,3.91014913 1,7.5 C1,10.8017358 3.46176769,13.528495 6.64994254,13.9449169" stroke="#000000" stroke-width="1.5" stroke-linecap="round"></path>
+ <path d="M12,7 C9.790861,7 8,8.790861 8,11 C8,13.209139 9.790861,15 12,15 C14.209139,15 16,13.209139 16,11 C16,8.790861 14.209139,7 12,7 Z M12,8 C12.6220042,8.00091132 13.2280791,8.19675778 13.733,8.56 L9.56,12.733 C8.90610356,11.8203472 8.81838019,10.6183679 9.33283825,9.62044577 C9.8472963,8.62252365 10.8772778,7.99675388 12,8 Z M12,14 C11.3779958,13.9990887 10.7719209,13.8032422 10.267,13.44 L14.44,9.267 C15.0938964,10.1796528 15.1816198,11.3816321 14.6671618,12.3795542 C14.1527037,13.3774764 13.1227222,14.0032461 12,14 Z" fill="#000000" fill-rule="nonzero"></path>
+ </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/notification-icons/autoplay-media.svg
@@ -0,0 +1,7 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
+ <path d="M8 2a6 6 0 1 0 6 6 6.007 6.007 0 0 0-6-6zm0 11a5 5 0 1 1 5-5 5.006 5.006 0 0 1-5 5z"></path>
+ <path d="M6.75 4.969A.5.5 0 0 0 6 5.4v5.2a.5.5 0 0 0 .75.433l4.5-2.6a.5.5 0 0 0 0-.866z"></path>
+</svg>