Bug 1536459 add messages for different private permission conditions r=flod,aswan
authorShane Caraveo <scaraveo@mozilla.com>
Wed, 27 Mar 2019 19:03:41 +0000
changeset 466420 217849cb7750831a9dd8ef637819374399650d4a
parent 466419 6960595971e59ed7c59ea4e77134f66ae1aeac57
child 466421 fde4dfc0464ab070c72ed8bd591aaea7379ca73a
push id35768
push useropoprus@mozilla.com
push dateThu, 28 Mar 2019 09:55:54 +0000
treeherdermozilla-central@c045dd97faf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflod, aswan
bugs1536459
milestone68.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 1536459 add messages for different private permission conditions r=flod,aswan Differential Revision: https://phabricator.services.mozilla.com/D24990
toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xul
toolkit/mozapps/extensions/test/browser/browser_webext_incognito.js
--- a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
+++ b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
@@ -126,16 +126,25 @@ detail-update-manual =
     .label = Off
     .tooltiptext = Don’t automatically install updates
 
 # Used as a description for the option to allow or block an add-on in private windows.
 detail-private-browsing-label = Run in Private Windows
 
 detail-private-browsing-description2 = When allowed, the extension will have access to your online activities while private browsing. <label data-l10n-name="detail-private-browsing-learn-more">Learn more</label>
 
+# Some add-ons may elect to not run in private windows by setting incognito: not_allowed in the manifest.  This
+# cannot be overriden by the user.
+detail-private-disallowed-label = Not Allowed in Private Windows
+detail-private-disallowed-description = This extension does not run while private browsing. <label data-l10n-name="detail-private-browsing-learn-more">Learn more</label>
+
+# Some special add-ons are privileged, run in private windows automatically, and this permission can't be revoked
+detail-private-required-label = Requires Access to Private Windows
+detail-private-required-description = This extension has access to your online activities while private browsing. <label data-l10n-name="detail-private-browsing-learn-more">Learn more</label>
+
 detail-private-browsing-on =
     .label = Allow
     .tooltiptext = Enable in Private Browsing
 
 detail-private-browsing-off =
     .label = Don’t Allow
     .tooltiptext = Disable in Private Browsing
 
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2804,18 +2804,19 @@ var gDetailView = {
     this.headingImage = this.node.querySelector(".card-heading-image");
 
     this._autoUpdate = document.getElementById("detail-autoUpdate");
     this._autoUpdate.addEventListener("command", () => {
       this._addon.applyBackgroundUpdates = this._autoUpdate.value;
       recordSetAddonUpdateTelemetry(this._addon);
     }, true);
 
-    document.getElementById("detail-private-browsing-learnmore-link")
-            .setAttribute("href", SUPPORT_URL + "extensions-pb");
+    for (let el of document.getElementsByClassName("private-learnmore")) {
+      el.setAttribute("href", SUPPORT_URL + "extensions-pb");
+    }
 
     this._privateBrowsing = document.getElementById("detail-privateBrowsing");
     this._privateBrowsing.addEventListener("command", async () => {
       let addon = this._addon;
       let policy = WebExtensionPolicy.getByID(addon.id);
       let extension = policy && policy.extension;
 
       let perms = {permissions: ["internal:privateBrowsingAllowed"], origins: []};
@@ -2994,31 +2995,37 @@ var gDetailView = {
       this._autoUpdate.hidden = true;
       document.getElementById("detail-findUpdates-btn").hidden = false;
     }
 
     // Only type = "extension" will ever get privateBrowsingAllowed, other types have
     // no code that would be affected by the setting.  The permission is read directly
     // from ExtensionPermissions so we can get it whether or not the extension is
     // currently active.
-    let privateBrowsingRow = document.getElementById("detail-privateBrowsing-row");
-    let privateBrowsingFooterRow = document.getElementById("detail-privateBrowsing-row-footer");
-
-    if (allowPrivateBrowsingByDefault || aAddon.type != "extension" ||
-        !(aAddon.permissions & AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS)) {
-      this._privateBrowsing.hidden = true;
-      privateBrowsingRow.hidden = true;
-      privateBrowsingFooterRow.hidden = true;
-      this._privateBrowsing.value = "0";
-    } else {
-      let perms = await ExtensionPermissions.get(aAddon.id);
-      this._privateBrowsing.hidden = false;
-      privateBrowsingRow.hidden = false;
-      privateBrowsingFooterRow.hidden = false;
-      this._privateBrowsing.value = perms.permissions.includes("internal:privateBrowsingAllowed") ? "1" : "0";
+    // Ensure that all private browsing rows are hidden by default, we'll then
+    // unhide what we want.
+    for (let el of document.getElementsByClassName("detail-privateBrowsing")) {
+      el.hidden = true;
+    }
+    if (!allowPrivateBrowsingByDefault && aAddon.type === "extension") {
+      if (aAddon.permissions & AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS) {
+        let privateBrowsingRow = document.getElementById("detail-privateBrowsing-row");
+        let privateBrowsingFooterRow = document.getElementById("detail-privateBrowsing-row-footer");
+        let perms = await ExtensionPermissions.get(aAddon.id);
+        this._privateBrowsing.hidden = false;
+        privateBrowsingRow.hidden = false;
+        privateBrowsingFooterRow.hidden = false;
+        this._privateBrowsing.value = perms.permissions.includes("internal:privateBrowsingAllowed") ? "1" : "0";
+      } else if (aAddon.incognito == "spanning") {
+        document.getElementById("detail-privateBrowsing-required").hidden = false;
+        document.getElementById("detail-privateBrowsing-required-footer").hidden = false;
+      } else if (aAddon.incognito == "not_allowed") {
+        document.getElementById("detail-privateBrowsing-disallowed").hidden = false;
+        document.getElementById("detail-privateBrowsing-disallowed-footer").hidden = false;
+      }
     }
 
     // While updating the addon details view, also check if the preferences button should be disabled because
     // we are in a private window and the addon is not allowed to access it.
     let hidePreferences = (!aIsRemote &&
       !gViewController.commands.cmd_showItemPreferences.isEnabled(aAddon)) ||
       !await isAddonAllowedInCurrentWindow(aAddon);
     document.getElementById("detail-prefs-btn").hidden = hidePreferences;
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -542,30 +542,46 @@
                         </hbox>
                       </vbox>
                       <grid id="detail-grid">
                         <columns>
                            <column flex="1"/>
                            <column flex="2"/>
                         </columns>
                         <rows id="detail-rows">
-                          <row class="detail-row-complex" id="detail-privateBrowsing-row">
+                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-row">
                             <label class="detail-row-label" data-l10n-id="detail-private-browsing-label"/>
                             <hbox align="center">
                               <radiogroup id="detail-privateBrowsing" orient="horizontal">
                                 <radio data-l10n-id="detail-private-browsing-on"
                                        value="1"/>
                                 <radio data-l10n-id="detail-private-browsing-off"
                                        value="0"/>
                               </radiogroup>
                             </hbox>
                           </row>
-                          <hbox class="detail-row-footer" id="detail-privateBrowsing-row-footer">
+                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-row-footer">
                             <description class="indent preferences-description" data-l10n-id="detail-private-browsing-description2">
-                              <label id="detail-private-browsing-learnmore-link" class="learnMore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
+                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
+                            </description>
+                          </hbox>
+                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-required">
+                            <label class="detail-row-label" data-l10n-id="detail-private-required-label"/>
+                          </row>
+                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-required-footer">
+                            <description class="indent preferences-description" data-l10n-id="detail-private-required-description">
+                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
+                            </description>
+                          </hbox>
+                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-disallowed">
+                            <label class="detail-row-label" data-l10n-id="detail-private-disallowed-label"/>
+                          </row>
+                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-disallowed-footer">
+                            <description class="indent preferences-description" data-l10n-id="detail-private-disallowed-description">
+                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
                             </description>
                           </hbox>
                           <row class="detail-row-complex" id="detail-updates-row">
                             <label class="detail-row-label" data-l10n-id="detail-update-type"/>
                             <hbox align="center">
                               <radiogroup id="detail-autoUpdate" orient="horizontal">
                                 <!-- The values here need to match the values of
                                      AddonManager.AUTOUPDATE_* -->
--- a/toolkit/mozapps/extensions/test/browser/browser_webext_incognito.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_webext_incognito.js
@@ -97,17 +97,20 @@ add_task(async function test_addon() {
 
   for (let [id, definition] of addons.entries()) {
     gManagerWindow = await open_manager("addons://detail/" + encodeURIComponent(id));
     ok(true, `==== ${id} detail opened`);
     if (definition.manifest.incognito == "not_allowed") {
       is_element_hidden(get("detail-privateBrowsing-row"), "Private browsing should be hidden");
       is_element_hidden(get("detail-privateBrowsing-row-footer"), "Private browsing footer should be hidden");
       ok(!await hasPrivateAllowed(id), "Private browsing permission not set");
+      is_element_visible(get("detail-privateBrowsing-disallowed"), "Private browsing should be hidden");
+      is_element_visible(get("detail-privateBrowsing-disallowed-footer"), "Private browsing footer should be hidden");
     } else {
+      // This assumes PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS, we test other options in a later test in this file.
       is_element_visible(get("detail-privateBrowsing-row"), "Private browsing should be visible");
       is_element_visible(get("detail-privateBrowsing-row-footer"), "Private browsing footer should be visible");
       let privateBrowsing = gManagerWindow.document.getElementById("detail-privateBrowsing");
       if (definition.incognitoOverride == "spanning") {
         is(privateBrowsing.value, "1", "Private browsing should be on");
         ok(await hasPrivateAllowed(id), "Private browsing permission set");
         EventUtils.synthesizeMouseAtCenter(privateBrowsing.lastChild, { clickCount: 1 }, gManagerWindow);
         await TestUtils.waitForCondition(() => privateBrowsing.value == "0");
@@ -351,20 +354,42 @@ add_task(async function test_addon_posti
       waitAppMenuNotificationShown("addon-installed", id, true),
       install.install().then(() => {
         Services.obs.notifyObservers({
           addon: install.addon, target: gBrowser.selectedBrowser,
         }, "webextension-install-notify");
       }),
     ]);
 
-    const {permissions} = install.addon;
+    const {addon} = install;
+    const {permissions} = addon;
     const canChangePBAccess = Boolean(permissions & AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS);
 
     if (id === "ext-incognito-default-opt-in@mozilla.com") {
       ok(canChangePBAccess, `${id} should have the PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS permission`);
     } else {
       ok(!canChangePBAccess, `${id} should not have the PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS permission`);
     }
 
-    await install.addon.uninstall();
+    // This tests the visibility of various private detail rows.
+    gManagerWindow = await open_manager("addons://detail/" + encodeURIComponent(id));
+    info(`addon ${id} detail opened`);
+    if (addon.type === "extension") {
+      is(!is_hidden(get("detail-privateBrowsing-row")), canChangePBAccess, "Private permission row visibility is correct");
+      is(!is_hidden(get("detail-privateBrowsing-row-footer")), canChangePBAccess, "Private permission footer visibility is correct");
+      let required = addon.incognito === "spanning";
+      is(!is_hidden(get("detail-privateBrowsing-required")), !canChangePBAccess && required, "Private required row visibility is correct");
+      is(!is_hidden(get("detail-privateBrowsing-required-footer")), !canChangePBAccess && required, "Private required footer visibility is correct");
+      is(!is_hidden(get("detail-privateBrowsing-disallowed")), !canChangePBAccess && !required, "Private disallowed row visibility is correct");
+      is(!is_hidden(get("detail-privateBrowsing-disallowed-footer")), !canChangePBAccess && !required, "Private disallowed footer visibility is correct");
+    } else {
+      is_element_hidden(get("detail-privateBrowsing-row"), "Private browsing should be hidden");
+      is_element_hidden(get("detail-privateBrowsing-row-footer"), "Private browsing footer should be hidden");
+      is_element_hidden(get("detail-privateBrowsing-required"), "Private required should be hidden");
+      is_element_hidden(get("detail-privateBrowsing-required-footer"), "Private required footer should be hidden");
+      is_element_hidden(get("detail-privateBrowsing-disallowed"), "Private disallowed should be hidden");
+      is_element_hidden(get("detail-privateBrowsing-disallowed-footer"), "Private disallowed footer should be hidden");
+    }
+    await close_manager(gManagerWindow);
+
+    await addon.uninstall();
   }
 });