Bug 1381401 - Add location, camera and microphone permissions along with their settings under the 'Permissions' heading in Firefox Preferences. r=johannh
authorPrathiksha <prathikshaprasadsuman@gmail.com>
Sun, 30 Jul 2017 13:06:49 +0530
changeset 374311 75509cda693e05bf003b074e08734de730f4338e
parent 374310 ee15ce19465519e44f58dcc2891402c4a83fbf6f
child 374312 1dcdc22d4919cca28f1b83ace94d4b476deb4c88
push id32320
push userarchaeopteryx@coole-files.de
push dateSat, 12 Aug 2017 21:35:10 +0000
treeherdermozilla-central@6062341662fc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1381401
milestone57.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 1381401 - Add location, camera and microphone permissions along with their settings under the 'Permissions' heading in Firefox Preferences. r=johannh MozReview-Commit-ID: PdcUyUKAcN
browser/components/preferences/in-content-new/preferences.xul
browser/components/preferences/in-content-new/privacy.js
browser/components/preferences/in-content-new/privacy.xul
browser/components/preferences/in-content-new/tests/browser_permissions_dialog.js
browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_2.js
browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_4.js
browser/locales/en-US/chrome/browser/preferences/content.dtd
browser/locales/en-US/chrome/browser/preferences/preferences.properties
browser/themes/shared/incontentprefs/privacy.css
browser/themes/shared/jar.inc.mn
--- a/browser/components/preferences/in-content-new/preferences.xul
+++ b/browser/components/preferences/in-content-new/preferences.xul
@@ -9,16 +9,17 @@
 <?xml-stylesheet href="chrome://global/skin/in-content/common.css"?>
 <?xml-stylesheet
   href="chrome://browser/skin/preferences/in-content-new/preferences.css"?>
 <?xml-stylesheet
   href="chrome://browser/content/preferences/handlers.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/in-content-new/search.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/in-content-new/containers.css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/in-content-new/privacy.css"?>
 
 <!DOCTYPE page [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % globalPreferencesDTD SYSTEM "chrome://global/locale/preferences.dtd">
 <!ENTITY % preferencesDTD SYSTEM
   "chrome://browser/locale/preferences/preferences.dtd">
 <!ENTITY % selectBookmarkDTD SYSTEM
   "chrome://browser/locale/preferences/selectBookmark.dtd">
--- a/browser/components/preferences/in-content-new/privacy.js
+++ b/browser/components/preferences/in-content-new/privacy.js
@@ -155,18 +155,24 @@ var gPrivacyPane = {
                      gPrivacyPane.clearCache);
 
     this._pane = document.getElementById("panePrivacy");
     this._initMasterPasswordUI();
     this._initSafeBrowsing();
     this.updateCacheSizeInputField();
     this.updateActualCacheSize();
 
-    setEventListener("notificationsPolicyButton", "command",
+    setEventListener("notificationSettingsButton", "command",
       gPrivacyPane.showNotificationExceptions);
+    setEventListener("locationSettingsButton", "command",
+      gPrivacyPane.showLocationExceptions);
+    setEventListener("cameraSettingsButton", "command",
+      gPrivacyPane.showCameraExceptions);
+    setEventListener("microphoneSettingsButton", "command",
+      gPrivacyPane.showMicrophoneExceptions);
     setEventListener("popupPolicyButton", "command",
       gPrivacyPane.showPopupExceptions);
     setEventListener("notificationsDoNotDisturb", "command",
       gPrivacyPane.toggleDoNotDisturbNotifications);
 
     if (AlertsServiceDND) {
       let notificationsDoNotDisturbBox =
         document.getElementById("notificationsDoNotDisturbBox");
@@ -216,17 +222,17 @@ var gPrivacyPane = {
       let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
       document.getElementById("siteDataLearnMoreLink").setAttribute("href", url);
       let siteDataGroup = document.getElementById("siteDataGroup");
       siteDataGroup.removeAttribute("data-hidden-from-search");
     }
 
     let notificationInfoURL =
       Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
-    document.getElementById("notificationsPolicyLearnMore").setAttribute("href",
+    document.getElementById("notificationPermissionsLearnMore").setAttribute("href",
                                                                          notificationInfoURL);
     let drmInfoURL =
       Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content";
     document.getElementById("playDRMContentLink").setAttribute("href", drmInfoURL);
     let emeUIEnabled = Services.prefs.getBoolPref("browser.eme.ui.enabled");
     // Force-disable/hide on WinXP:
     if (navigator.platform.toLowerCase().startsWith("win")) {
       emeUIEnabled = emeUIEnabled && parseFloat(Services.sysinfo.get("version")) >= 6;
@@ -262,20 +268,32 @@ var gPrivacyPane = {
     appendSearchKeywords("changeBlockList", [
       bundlePrefs.getString("blockliststitle"),
       bundlePrefs.getString("blockliststext"),
     ]);
     appendSearchKeywords("popupPolicyButton", [
       bundlePrefs.getString("popuppermissionstitle2"),
       bundlePrefs.getString("popuppermissionstext"),
     ]);
-    appendSearchKeywords("notificationsPolicyButton", [
+    appendSearchKeywords("notificationSettingsButton", [
       bundlePrefs.getString("notificationspermissionstitle2"),
       bundlePrefs.getString("notificationspermissionstext5"),
     ]);
+    appendSearchKeywords("locationSettingsButton", [
+      bundlePrefs.getString("locationpermissionstitle"),
+      bundlePrefs.getString("locationpermissionstext"),
+    ]);
+    appendSearchKeywords("cameraSettingsButton", [
+      bundlePrefs.getString("camerapermissionstitle"),
+      bundlePrefs.getString("camerapermissionstext"),
+    ]);
+    appendSearchKeywords("microphoneSettingsButton", [
+      bundlePrefs.getString("microphonepermissionstitle"),
+      bundlePrefs.getString("microphonepermissionstext"),
+    ]);
     appendSearchKeywords("addonExceptions", [
       bundlePrefs.getString("addons_permissions_title2"),
       bundlePrefs.getString("addonspermissionstext"),
     ]);
     appendSearchKeywords("viewSecurityDevicesButton", [
       pkiBundle.getString("enable_fips"),
     ]);
     appendSearchKeywords("siteDataSettings", [
@@ -793,16 +811,64 @@ var gPrivacyPane = {
 
      settings.disabled = !pref.value;
    },
 
    toggleDoNotDisturbNotifications(event) {
      AlertsServiceDND.manualDoNotDisturb = event.target.checked;
    },
 
+  // GEOLOCATION
+
+  /**
+   * 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");
+
+    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");
+
+    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");
+
+    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");
--- a/browser/components/preferences/in-content-new/privacy.xul
+++ b/browser/components/preferences/in-content-new/privacy.xul
@@ -535,35 +535,94 @@
 <!-- Permissions -->
 <groupbox id="permissionsGroup" data-category="panePrivacy" hidden="true">
   <grid>
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows>
-      <row id="notificationsPolicyRow" align="center">
+      <row id="locationSettingsRow" align="center">
         <description flex="1">
-          <label id="notificationsPolicy">&notificationsPolicyDesc4.label;</label>
-          <label id="notificationsPolicyLearnMore"
-                 class="learnMore text-link">&notificationsPolicyLearnMore.label;</label>
+          <image class="geo-icon permission-icon" />
+          <separator orient="vertical" class="thin"/>
+          <label id="locationPermissionsLabel">&locationPermissions.label;</label>
+        </description>
+        <hbox pack="end">
+          <button id="locationSettingsButton"
+                  class="accessory-button"
+                  label="&permissionSettingsButton.label;"
+                  accesskey="&locationSettingsButton.accesskey;"
+                  searchkeywords="&removepermission2.label;
+                                  &removeallpermissions2.label;
+                                  &button.cancel.label;
+                                  &button.ok.label;"/>
+        </hbox>
+      </row>
+
+      <row id="cameraSettingsRow" align="center">
+        <description flex="1">
+          <image class="camera-icon permission-icon" />
+          <separator orient="vertical" class="thin"/>
+          <label id="cameraPermissionsLabel">&cameraPermissions.label;</label>
         </description>
         <hbox pack="end">
-          <button id="notificationsPolicyButton"
+          <button id="cameraSettingsButton"
+                  class="accessory-button"
+                  label="&permissionSettingsButton.label;"
+                  accesskey="&cameraSettingsButton.accesskey;"
+                  searchkeywords="&removepermission2.label;
+                                  &removeallpermissions2.label;
+                                  &button.cancel.label;
+                                  &button.ok.label;"/>
+        </hbox>
+      </row>
+
+      <row id="microphoneSettingsRow" align="center">
+        <description flex="1">
+          <image class="microphone-icon permission-icon" />
+          <separator orient="vertical" class="thin"/>
+          <label id="microphonePermissionsLabel">&microphonePermissions.label;</label>
+        </description>
+        <hbox pack="end">
+          <button id="microphoneSettingsButton"
                   class="accessory-button"
-                  label="&notificationsPolicyButton.label;"
-                  accesskey="&notificationsPolicyButton.accesskey;"
+                  label="&permissionSettingsButton.label;"
+                  accesskey="&microphoneSettingsButton.accesskey;"
+                  searchkeywords="&removepermission2.label;
+                                  &removeallpermissions2.label;
+                                  &button.cancel.label;
+                                  &button.ok.label;"/>
+        </hbox>
+      </row>
+
+      <row id="notificationSettingsRow" align="center">
+        <description flex="1">
+          <image class="desktop-notification-icon permission-icon" />
+          <separator orient="vertical" class="thin"/>
+          <label id="notificationPermissionsLabel">&notificationPermissions.label;</label>
+          <label id="notificationPermissionsLearnMore"
+                 class="learnMore text-link">&notificationPermissionsLearnMore.label;</label>
+        </description>
+        <hbox pack="end">
+          <button id="notificationSettingsButton"
+                  class="accessory-button"
+                  label="&permissionSettingsButton.label;"
+                  accesskey="&notificationSettingsButton.accesskey;"
                   searchkeywords="&removepermission2.label;
                                   &removeallpermissions2.label;
                                   &button.cancel.label;
                                   &button.ok.label;"/>
         </hbox>
       </row>
     </rows>
   </grid>
+
+  <separator flex="1"/>
+
   <vbox id="notificationsDoNotDisturbBox" hidden="true">
     <checkbox id="notificationsDoNotDisturb" label="&notificationsDoNotDisturb.label;"
               accesskey="&notificationsDoNotDisturb.accesskey;"/>
     <label id="notificationsDoNotDisturbDetails"
            class="indent">&notificationsDoNotDisturbDetails.value;</label>
   </vbox>
 
   <hbox align="start">
--- a/browser/components/preferences/in-content-new/tests/browser_permissions_dialog.js
+++ b/browser/components/preferences/in-content-new/tests/browser_permissions_dialog.js
@@ -22,17 +22,17 @@ function checkPermissionItem(origin, sta
   Assert.equal(menulist.label, state);
 }
 
 async function openPermissionsDialog() {
   let dialogOpened = promiseLoadSubDialog(PERMISSIONS_URL);
 
   await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
     let doc = content.document;
-    let settingsButton = doc.getElementById("notificationsPolicyButton");
+    let settingsButton = doc.getElementById("notificationSettingsButton");
     settingsButton.click();
   });
 
   sitePermissionsDialog = await dialogOpened;
 }
 
 add_task(async function openSitePermissionsDialog() {
   await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
--- a/browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_2.js
+++ b/browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_2.js
@@ -40,17 +40,8 @@ add_task(async function() {
 /**
  * Test for searching for the "Allowed Sites - Pop-ups" subdialog.
  */
 add_task(async function() {
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
   evaluateSearchResults("open pop-up windows", "permissionsGroup");
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
-
-/**
- * Test for searching for the "Notification Permissions" subdialog.
- */
-add_task(async function() {
-  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
-  evaluateSearchResults("send notifications", "permissionsGroup");
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
--- a/browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_4.js
+++ b/browser/components/preferences/in-content-new/tests/browser_search_subdialogs_within_preferences_4.js
@@ -10,8 +10,44 @@ add_task(async function() {
 /**
  * Test for searching for the "Update History" subdialog.
  */
 add_task(async function() {
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
   evaluateSearchResults("updates have been installed", "updateApp");
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
+
+/**
+ * Test for searching for the "Location Permissions" subdialog.
+ */
+add_task(async function() {
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  evaluateSearchResults("set location permissions", "permissionsGroup");
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+/**
+ * Test for searching for the "Camera Permissions" subdialog.
+ */
+add_task(async function() {
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  evaluateSearchResults("set camera permissions", "permissionsGroup");
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+/**
+ * Test for searching for the "Microphone Permissions" subdialog.
+ */
+add_task(async function() {
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  evaluateSearchResults("set microphone permissions", "permissionsGroup");
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+/**
+ * Test for searching for the "Notification Permissions" subdialog.
+ */
+add_task(async function() {
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  evaluateSearchResults("set notifications permissions", "permissionsGroup");
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
--- a/browser/locales/en-US/chrome/browser/preferences/content.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/content.dtd
@@ -2,26 +2,37 @@
    - 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/. -->
 
 <!ENTITY  permissions.label           "Permissions">
 
 <!ENTITY  blockPopups.label           "Block pop-up windows">
 <!ENTITY  blockPopups.accesskey       "B">
 
-<!ENTITY  notificationsPolicyLearnMore.label   "Learn more">
-<!ENTITY  notificationsPolicyDesc4.label       "Choose which websites are allowed to send you notifications">
-<!ENTITY  notificationsPolicyButton.accesskey  "h">
-<!ENTITY  notificationsPolicyButton.label      "Choose…">
 <!ENTITY  notificationsDoNotDisturb.label      "Do not disturb me">
 <!ENTITY  notificationsDoNotDisturb.accesskey  "n">
 <!ENTITY  notificationsDoNotDisturbDetails.value "No notification will be shown until you restart &brandShortName;">
 
-<!ENTITY  popupExceptions.label       "Exceptions…">
-<!ENTITY  popupExceptions.accesskey   "E">
+<!ENTITY  popupExceptions.label                                 "Exceptions…">
+<!ENTITY  popupExceptions.accesskey                             "E">
+
+<!ENTITY  permissionSettingsButton.label                        "Settings">
+
+<!ENTITY  notificationPermissions.label                         "Notifications">
+<!ENTITY  notificationSettingsButton.accesskey                  "n">
+<!ENTITY  notificationPermissionsLearnMore.label                "Learn more">
+
+<!ENTITY  locationPermissions.label                             "Location">
+<!ENTITY  locationSettingsButton.accesskey                      "l">
+
+<!ENTITY  cameraPermissions.label                               "Camera">
+<!ENTITY  cameraSettingsButton.accesskey                        "c">
+
+<!ENTITY  microphonePermissions.label                           "Microphone">
+<!ENTITY  microphoneSettingsButton.accesskey                    "m">
 
 <!ENTITY  fontsAndColors.label        "Fonts &amp; Colors">
 
 <!ENTITY  defaultFont2.label          "Default font">
 <!ENTITY  defaultFont2.accesskey      "D">
 <!ENTITY  defaultSize2.label          "Size">
 <!ENTITY  defaultSize2.accesskey      "S">
 
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -24,16 +24,22 @@ trackingprotectionpermissionstitle=Excep
 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.
 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.
+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.
+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.
+microphonepermissionstitle=Settings - Microphone Permissions
 invalidURI=Please enter a valid hostname
 invalidURITitle=Invalid Hostname Entered
 savedLoginsExceptions_title=Exceptions - Saved Logins
 savedLoginsExceptions_desc2=Logins for the following websites will not be saved
 
 #### Block List Manager
 
 blockliststext=You can choose which list Firefox will use to block Web elements that may track your browsing activity.
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/incontentprefs/privacy.css
@@ -0,0 +1,27 @@
+/* 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/. */
+
+.permission-icon {
+  max-height: 20px;
+  max-width: 20px;
+  vertical-align: middle;
+  -moz-context-properties: fill;
+  fill: currentColor;
+}
+
+.geo-icon {
+  list-style-image: url(chrome://browser/skin/notification-icons.svg#geo-linux);
+}
+
+.camera-icon {
+  list-style-image: url(chrome://browser/skin/notification-icons.svg#camera);
+}
+
+.microphone-icon {
+  list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone);
+}
+
+.desktop-notification-icon {
+  list-style-image: url(chrome://browser/skin/notification-icons.svg#desktop-notification);
+}
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -80,16 +80,17 @@
   skin/classic/browser/preferences/in-content-new/logo-android.svg (../shared/incontentprefs/logo-android.svg)
   skin/classic/browser/preferences/in-content-new/logo-ios.svg     (../shared/incontentprefs/logo-ios.svg)
   skin/classic/browser/preferences/in-content-new/no-search-results.svg       (../shared/incontentprefs/no-search-results.svg)
   skin/classic/browser/preferences/in-content-new/privacy-security.svg        (../shared/incontentprefs/privacy-security.svg)
   skin/classic/browser/preferences/in-content-new/search-arrow-indicator.svg  (../shared/incontentprefs/search-arrow-indicator.svg)
   skin/classic/browser/preferences/in-content-new/search.css       (../shared/incontentprefs/search.css)
   skin/classic/browser/preferences/in-content-new/search.svg       (../shared/incontentprefs/search.svg)
   skin/classic/browser/preferences/in-content-new/siteDataSettings.css (../shared/incontentprefs/siteDataSettings.css)
+  skin/classic/browser/preferences/in-content-new/privacy.css      (../shared/incontentprefs/privacy.css)
   skin/classic/browser/preferences/in-content-new/sync.svg         (../shared/incontentprefs/sync.svg)
 * skin/classic/browser/preferences/in-content-new/containers.css   (../shared/incontentprefs/containers.css)
   skin/classic/browser/preferences/in-content/icons.svg        (../shared/incontentprefs-old/icons.svg)
   skin/classic/browser/preferences/in-content/search.css       (../shared/incontentprefs-old/search.css)
 * skin/classic/browser/preferences/in-content/containers.css   (../shared/incontentprefs-old/containers.css)
 * skin/classic/browser/preferences/containers.css              (../shared/preferences/containers.css)
   skin/classic/browser/fxa/default-avatar.svg                  (../shared/fxa/default-avatar.svg)
   skin/classic/browser/fxa/logo.png                            (../shared/fxa/logo.png)