Bug 1368744 - Provide a way for users to deny permission prompts by default in about:preferences. r=johannh
authorPrathiksha <prathikshaprasadsuman@gmail.com>
Wed, 20 Dec 2017 22:32:20 +0530
changeset 397999 25d72de8349834612ba5ff06ce4dcf62801fa595
parent 397998 28009c663a1d10cac6d86eac554b656a5b8d3e4d
child 398000 a32acea9d091d3bc3aa9476f2a1ee3e565c2a211
push id57604
push userryanvm@gmail.com
push dateFri, 05 Jan 2018 17:43:55 +0000
treeherderautoland@25d72de83498 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1368744
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1368744 - Provide a way for users to deny permission prompts by default in about:preferences. r=johannh MozReview-Commit-ID: 3k3LRi7N8PX
browser/components/preferences/in-content/privacy.js
browser/components/preferences/in-content/tests/browser_permissions_dialog.js
browser/components/preferences/sitePermissions.css
browser/components/preferences/sitePermissions.js
browser/components/preferences/sitePermissions.xul
browser/locales/en-US/chrome/browser/preferences/preferences.properties
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -365,29 +365,37 @@ var gPrivacyPane = {
       bundlePrefs.getString("blockliststext"),
     ]);
     appendSearchKeywords("popupPolicyButton", [
       bundlePrefs.getString("popuppermissionstitle2"),
       bundlePrefs.getString("popuppermissionstext"),
     ]);
     appendSearchKeywords("notificationSettingsButton", [
       bundlePrefs.getString("notificationspermissionstitle2"),
-      bundlePrefs.getString("notificationspermissionstext5"),
+      bundlePrefs.getString("notificationspermissionstext6"),
+      bundlePrefs.getString("notificationspermissionsdisablelabel"),
+      bundlePrefs.getString("notificationspermissionsdisabledescription"),
     ]);
     appendSearchKeywords("locationSettingsButton", [
       bundlePrefs.getString("locationpermissionstitle"),
-      bundlePrefs.getString("locationpermissionstext"),
+      bundlePrefs.getString("locationpermissionstext2"),
+      bundlePrefs.getString("locationpermissionsdisablelabel"),
+      bundlePrefs.getString("locationpermissionsdisabledescription"),
     ]);
     appendSearchKeywords("cameraSettingsButton", [
       bundlePrefs.getString("camerapermissionstitle"),
-      bundlePrefs.getString("camerapermissionstext"),
+      bundlePrefs.getString("camerapermissionstext2"),
+      bundlePrefs.getString("camerapermissionsdisablelabel"),
+      bundlePrefs.getString("camerapermissionsdisabledescription"),
     ]);
     appendSearchKeywords("microphoneSettingsButton", [
       bundlePrefs.getString("microphonepermissionstitle"),
-      bundlePrefs.getString("microphonepermissionstext"),
+      bundlePrefs.getString("microphonepermissionstext2"),
+      bundlePrefs.getString("microphonepermissionsdisablelabel"),
+      bundlePrefs.getString("microphonepermissionsdisabledescription"),
     ]);
     appendSearchKeywords("addonExceptions", [
       bundlePrefs.getString("addons_permissions_title2"),
       bundlePrefs.getString("addonspermissionstext"),
     ]);
     appendSearchKeywords("viewSecurityDevicesButton", [
       pkiBundle.getString("enable_fips"),
     ]);
@@ -889,65 +897,73 @@ var gPrivacyPane = {
   /**
    * Displays the location exceptions dialog where specific site location
    * preferences can be set.
    */
   showLocationExceptions() {
     let bundlePreferences = document.getElementById("bundlePreferences");
     let params = { permissionType: "geo" };
     params.windowTitle = bundlePreferences.getString("locationpermissionstitle");
-    params.introText = bundlePreferences.getString("locationpermissionstext");
+    params.introText = bundlePreferences.getString("locationpermissionstext2");
+    params.disablePermissionsLabel = bundlePreferences.getString("locationpermissionsdisablelabel");
+    params.disablePermissionsDescription = bundlePreferences.getString("locationpermissionsdisabledescription");
 
     gSubDialog.open("chrome://browser/content/preferences/sitePermissions.xul",
       "resizable=yes", params);
   },
 
   // CAMERA
 
   /**
    * Displays the camera exceptions dialog where specific site camera
    * preferences can be set.
    */
   showCameraExceptions() {
     let bundlePreferences = document.getElementById("bundlePreferences");
     let params = { permissionType: "camera" };
     params.windowTitle = bundlePreferences.getString("camerapermissionstitle");
-    params.introText = bundlePreferences.getString("camerapermissionstext");
+    params.introText = bundlePreferences.getString("camerapermissionstext2");
+    params.disablePermissionsLabel = bundlePreferences.getString("camerapermissionsdisablelabel");
+    params.disablePermissionsDescription = bundlePreferences.getString("camerapermissionsdisabledescription");
 
     gSubDialog.open("chrome://browser/content/preferences/sitePermissions.xul",
       "resizable=yes", params);
   },
 
   // MICROPHONE
 
   /**
    * Displays the microphone exceptions dialog where specific site microphone
    * preferences can be set.
    */
   showMicrophoneExceptions() {
     let bundlePreferences = document.getElementById("bundlePreferences");
     let params = { permissionType: "microphone" };
     params.windowTitle = bundlePreferences.getString("microphonepermissionstitle");
-    params.introText = bundlePreferences.getString("microphonepermissionstext");
+    params.introText = bundlePreferences.getString("microphonepermissionstext2");
+    params.disablePermissionsLabel = bundlePreferences.getString("microphonepermissionsdisablelabel");
+    params.disablePermissionsDescription = bundlePreferences.getString("microphonepermissionsdisabledescription");
 
     gSubDialog.open("chrome://browser/content/preferences/sitePermissions.xul",
       "resizable=yes", params);
   },
 
   // NOTIFICATIONS
 
   /**
    * Displays the notifications exceptions dialog where specific site notification
    * preferences can be set.
    */
   showNotificationExceptions() {
     let bundlePreferences = document.getElementById("bundlePreferences");
     let params = { permissionType: "desktop-notification" };
     params.windowTitle = bundlePreferences.getString("notificationspermissionstitle2");
-    params.introText = bundlePreferences.getString("notificationspermissionstext5");
+    params.introText = bundlePreferences.getString("notificationspermissionstext6");
+    params.disablePermissionsLabel = bundlePreferences.getString("notificationspermissionsdisablelabel");
+    params.disablePermissionsDescription = bundlePreferences.getString("notificationspermissionsdisabledescription");
 
     gSubDialog.open("chrome://browser/content/preferences/sitePermissions.xul",
       "resizable=yes", params);
 
     try {
       Services.telemetry
         .getHistogramById("WEB_NOTIFICATION_EXCEPTIONS_OPENED").add();
     } catch (e) { }
--- a/browser/components/preferences/in-content/tests/browser_permissions_dialog.js
+++ b/browser/components/preferences/in-content/tests/browser_permissions_dialog.js
@@ -266,11 +266,76 @@ add_task(async function onPermissionsSor
   Assert.equal(richlistbox.getItemAtIndex(1).getAttribute("origin"), "http://www.example.com");
 
   SitePermissions.remove(URI, "desktop-notification");
   SitePermissions.remove(u, "desktop-notification");
 
   doc.getElementById("cancel").click();
 });
 
+add_task(async function onPermissionDisable() {
+  // Enable desktop-notification permission prompts.
+  Services.prefs.setIntPref("permissions.default.desktop-notification", SitePermissions.UNKNOWN);
+
+  await openPermissionsDialog();
+  let doc = sitePermissionsDialog.document;
+
+  // Check if the enabled state is reflected in the checkbox.
+  let checkbox = doc.getElementById("permissionsDisableCheckbox");
+  Assert.equal(checkbox.checked, false);
+
+  // Disable permission and click on "Cancel".
+  checkbox.checked = true;
+  doc.getElementById("cancel").click();
+
+  // Check that the permission is not disabled yet.
+  let perm = Services.prefs.getIntPref("permissions.default.desktop-notification");
+  Assert.equal(perm, SitePermissions.UNKNOWN);
+
+  // Open the dialog once again.
+  await openPermissionsDialog();
+  doc = sitePermissionsDialog.document;
+
+  // Disable permission and save changes.
+  checkbox = doc.getElementById("permissionsDisableCheckbox");
+  checkbox.checked = true;
+  doc.getElementById("btnApplyChanges").click();
+
+  // Check if the permission is now disabled.
+  perm = Services.prefs.getIntPref("permissions.default.desktop-notification");
+  Assert.equal(perm, SitePermissions.BLOCK);
+
+  // Open the dialog once again and check if the disabled state is still reflected in the checkbox.
+  await openPermissionsDialog();
+  doc = sitePermissionsDialog.document;
+  checkbox = doc.getElementById("permissionsDisableCheckbox");
+  Assert.equal(checkbox.checked, true);
+
+  // Close the dialog.
+  doc.getElementById("cancel").click();
+});
+
+add_task(async function checkDefaultPermissionState() {
+  // Set default permission state to ALLOW.
+  Services.prefs.setIntPref("permissions.default.desktop-notification", SitePermissions.ALLOW);
+
+  await openPermissionsDialog();
+  let doc = sitePermissionsDialog.document;
+
+  // Check if the enabled state is reflected in the checkbox.
+  let checkbox = doc.getElementById("permissionsDisableCheckbox");
+  Assert.equal(checkbox.checked, false);
+
+  // Check the checkbox and then uncheck it.
+  checkbox.checked = true;
+  checkbox.checked = false;
+
+  // Save changes.
+  doc.getElementById("btnApplyChanges").click();
+
+  // Check if the default permission state is retained (and not automatically set to SitePermissions.UNKNOWN).
+  let state = Services.prefs.getIntPref("permissions.default.desktop-notification");
+  Assert.equal(state, SitePermissions.ALLOW);
+});
+
 add_task(async function removeTab() {
   gBrowser.removeCurrentTab();
 });
--- a/browser/components/preferences/sitePermissions.css
+++ b/browser/components/preferences/sitePermissions.css
@@ -16,8 +16,24 @@
 #permissionsBox > richlistitem {
   min-height: 35px;
 }
 
 .website-status {
   margin: 1px;
   margin-inline-end: 5px;
 }
+
+#permissionsDisableLabel {
+  padding-top: 14px;
+  font-weight: bold;
+}
+
+#permissionsDisableDescription {
+  margin-inline-start: 37px;
+  color: #737373;
+  line-height: 110%;
+}
+
+#permissionsDisableCheckbox {
+  margin-inline-start: 4px;
+  padding-top: 10px;
+}
--- a/browser/components/preferences/sitePermissions.js
+++ b/browser/components/preferences/sitePermissions.js
@@ -22,16 +22,19 @@ var gSitePermissionsManager = {
   _permissions: new Map(),
   _permissionsToChange: new Map(),
   _permissionsToDelete: new Map(),
   _list: null,
   _bundle: null,
   _removeButton: null,
   _removeAllButton: null,
   _searchBox: null,
+  _checkbox: null,
+  _currentDefaultPermissionsState: null,
+  _defaultPermissionStatePrefName: null,
 
   onLoad() {
     let params = window.arguments[0];
     this.init(params);
   },
 
   init(params) {
     if (!this._isObserving) {
@@ -40,24 +43,48 @@ var gSitePermissionsManager = {
     }
 
     this._bundle = document.getElementById("bundlePreferences");
     this._type = params.permissionType;
     this._list = document.getElementById("permissionsBox");
     this._removeButton = document.getElementById("removePermission");
     this._removeAllButton = document.getElementById("removeAllPermissions");
     this._searchBox = document.getElementById("searchBox");
+    this._checkbox = document.getElementById("permissionsDisableCheckbox");
 
     let permissionsText = document.getElementById("permissionsText");
     while (permissionsText.hasChildNodes())
       permissionsText.firstChild.remove();
     permissionsText.appendChild(document.createTextNode(params.introText));
 
+    let permissionsDisableLabel = document.getElementById("permissionsDisableLabel");
+    permissionsDisableLabel.value = params.disablePermissionsLabel;
+
+    let permissionsDisableDescription = document.getElementById("permissionsDisableDescription");
+    permissionsDisableDescription.appendChild(document.createTextNode(params.disablePermissionsDescription));
+
     document.title = params.windowTitle;
 
+    // Initialize the checkbox state.
+    this._defaultPermissionStatePrefName = "permissions.default." + this._type;
+    let pref = Services.prefs.getPrefType(this._defaultPermissionStatePrefName);
+    if (pref != Services.prefs.PREF_INVALID) {
+      this._currentDefaultPermissionsState = Services.prefs.getIntPref(this._defaultPermissionStatePrefName);
+    }
+
+    if (this._currentDefaultPermissionsState === null) {
+      this._checkbox.setAttribute("hidden", true);
+      permissionsDisableLabel.setAttribute("hidden", true);
+      permissionsDisableDescription.setAttribute("hidden", true);
+    } else if (this._currentDefaultPermissionsState == SitePermissions.BLOCK) {
+      this._checkbox.checked = true;
+    } else {
+      this._checkbox.checked = false;
+    }
+
     this._loadPermissions();
     this.buildPermissionsList();
 
     this._searchBox.focus();
   },
 
   uninit() {
     if (this._isObserving) {
@@ -259,16 +286,23 @@ var gSitePermissionsManager = {
       let uri = Services.io.newURI(p.origin);
       SitePermissions.set(uri, p.type, p.capability);
     }
 
     for (let p of this._permissionsToDelete.values()) {
       let uri = Services.io.newURI(p.origin);
       SitePermissions.remove(uri, p.type);
     }
+
+    if (this._checkbox.checked) {
+      Services.prefs.setIntPref(this._defaultPermissionStatePrefName, SitePermissions.BLOCK);
+    } else if (this._currentDefaultPermissionsState == SitePermissions.BLOCK) {
+      Services.prefs.setIntPref(this._defaultPermissionStatePrefName, SitePermissions.UNKNOWN);
+    }
+
     window.close();
   },
 
   buildPermissionsList(sortCol) {
     // Clear old entries.
     let oldItems = this._list.querySelectorAll("richlistitem");
     for (let item of oldItems) {
       item.remove();
--- a/browser/components/preferences/sitePermissions.xul
+++ b/browser/components/preferences/sitePermissions.xul
@@ -57,16 +57,24 @@
               icon="remove" label="&removepermission2.label;"
               oncommand="gSitePermissionsManager.onPermissionDelete();"/>
       <button id="removeAllPermissions"
               icon="clear" label="&removeallpermissions2.label;"
               accesskey="&removeallpermissions2.accesskey;"
               oncommand="gSitePermissionsManager.onAllPermissionsDelete();"/>
     </hbox>
     <spacer flex="1"/>
+    <vbox align="start">
+      <hbox align="start">
+        <checkbox id="permissionsDisableCheckbox"/>
+        <label for="permissionsDisableCheckbox" id="permissionsDisableLabel"/>
+      </hbox>
+      <description id="permissionsDisableDescription"/>
+    </vbox>
+    <spacer flex="1"/>
     <hbox class="actionButtons" align="right" flex="1">
       <button oncommand="close();" icon="close" id="cancel"
               label="&button.cancel.label;" accesskey="&button.cancel.accesskey;" />
       <button id="btnApplyChanges" oncommand="gSitePermissionsManager.onApplyChanges();" icon="save"
               label="&button.ok.label;" accesskey="&button.ok.accesskey;"/>
     </hbox>
   </vbox>
 </window>
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -23,24 +23,32 @@ acceptVeryLargeMinimumFont=Keep my chang
 trackingprotectionpermissionstext2=You have disabled Tracking Protection on these websites.
 trackingprotectionpermissionstitle=Exceptions - Tracking Protection
 cookiepermissionstext=You can specify which websites are always or never allowed to use cookies.  Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow.
 cookiepermissionstitle=Exceptions - Cookies
 addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow.
 addons_permissions_title2=Allowed Websites - Add-ons Installation
 popuppermissionstext=You can specify which websites are allowed to open pop-up windows. Type the exact address of the site you want to allow and then click Allow.
 popuppermissionstitle2=Allowed Websites - Pop-ups
-notificationspermissionstext5=The following websites have requested to send you notifications. You can specify which websites are allowed to send you notifications.
+notificationspermissionstext6=The following websites have requested to send you notifications. You can specify which websites are allowed to send you notifications. You can also block new requests asking to allow notifications.
 notificationspermissionstitle2=Settings - Notification Permissions
-locationpermissionstext=The following websites have requested to access your location. You can specify which websites are allowed to access your location.
+notificationspermissionsdisablelabel=Block new requests asking to allow notifications
+notificationspermissionsdisabledescription=This will prevent any websites not listed above from requesting permission to send notifications. Blocking notifications may break some website features.
+locationpermissionstext2=The following websites have requested to access your location. You can specify which websites are allowed to access your location. You can also block new requests asking to access your location.
 locationpermissionstitle=Settings - Location Permissions
-camerapermissionstext=The following websites have requested to access your camera. You can specify which websites are allowed to access your camera.
+locationpermissionsdisablelabel=Block new requests asking to access your location
+locationpermissionsdisabledescription=This will prevent any websites not listed above from requesting permission to access your location. Blocking access to your location may break some website features.
+camerapermissionstext2=The following websites have requested to access your camera. You can specify which websites are allowed to access your camera. You can also block new requests asking to access your camera.
 camerapermissionstitle=Settings - Camera Permissions
-microphonepermissionstext=The following websites have requested to access your microphone. You can specify which websites are allowed to access your microphone.
+camerapermissionsdisablelabel=Block new requests asking to access your camera
+camerapermissionsdisabledescription=This will prevent any websites not listed above from requesting permission to access your camera. Blocking access to your camera may break some website features.
+microphonepermissionstext2=The following websites have requested to access your microphone. You can specify which websites are allowed to access your microphone. You can also block new requests asking to access your microphone.
 microphonepermissionstitle=Settings - Microphone Permissions
+microphonepermissionsdisablelabel=Block new requests asking to access your microphone
+microphonepermissionsdisabledescription=This will prevent any websites not listed above from requesting permission to access your microphone. Blocking access to your microphone may break some website features.
 invalidURI=Please enter a valid hostname
 invalidURITitle=Invalid Hostname Entered
 savedLoginsExceptions_title=Exceptions - Saved Logins
 savedLoginsExceptions_desc3=Logins for the following websites will not be saved
 
 # LOCALIZATION NOTE(pauseNotifications.label): %S is replaced with the
 # brandShortName of the application.
 pauseNotifications.label=Pause notifications until %S restarts