Bug 1536459 add messages for different private permission conditions r=flod,aswan a=pascalc
authorShane Caraveo <scaraveo@mozilla.com>
Wed, 27 Mar 2019 19:03:41 +0000
changeset 522828 2a43c0f29c287054b941988970db92a64e5519be
parent 522827 f36792ee434476ad27f215563b2fda30f6b7298b
child 522829 0f768a9686b19f26c36483fe67fbe6fb913c8499
push id10956
push usercbrindusan@mozilla.com
push dateSat, 30 Mar 2019 18:55:26 +0000
treeherdermozilla-beta@0f768a9686b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflod, aswan, pascalc
bugs1536459
milestone67.0
Bug 1536459 add messages for different private permission conditions r=flod,aswan a=pascalc 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();
   }
 });