commit 6512de7a7f6b516881ba5940ca38b40436c47575
parent c11470f66f0e49c02f44966df725cd246dbabafb
Author: Pier Angelo Vendrame <pierov@torproject.org>
Date: Tue, 7 Oct 2025 20:27:03 +0000
Bug 1987183 - Automatically check the addon PBM checkbox when in always-on PBM. r=robwu
Differential Revision: https://phabricator.services.mozilla.com/D263934
Diffstat:
3 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/browser/components/extensions/test/browser/browser-private.toml b/browser/components/extensions/test/browser/browser-private.toml
@@ -6,6 +6,8 @@ tags = "webextensions"
prefs = ["browser.privatebrowsing.autostart=true"]
support-files = ["head.js"]
+["browser_always_on_pbm_prompt.js"]
+
["browser_ext_tabs_cookieStoreId_private.js"]
["browser_ext_tabs_newtab_private.js"]
diff --git a/browser/components/extensions/test/browser/browser_always_on_pbm_prompt.js b/browser/components/extensions/test/browser/browser_always_on_pbm_prompt.js
@@ -0,0 +1,95 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { AddonTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/AddonTestUtils.sys.mjs"
+);
+
+AddonTestUtils.initMochitest(this);
+
+const addonId = "test@pbm-checkbox";
+let xpi;
+
+async function testCheckbox(allowPbm, expectedCheckboxValue) {
+ const readyPromise = AddonTestUtils.promiseWebExtensionStartup(addonId);
+
+ window.gURLBar.value = xpi.path;
+ window.gURLBar.focus();
+ EventUtils.synthesizeKey("KEY_Enter", {}, window);
+
+ const panel = await promisePopupNotificationShown("addon-webext-permissions");
+ const checkbox = panel.querySelector(
+ "li.webext-perm-privatebrowsing > moz-checkbox"
+ );
+ ok(checkbox, "We found the PBM checkbox");
+
+ is(
+ checkbox.checked,
+ expectedCheckboxValue,
+ `We expected the PBM checkbox ${expectedCheckboxValue ? "" : "not "}to be checked for this test case.`
+ );
+
+ if (checkbox.checked != allowPbm) {
+ let { promise, resolve } = Promise.withResolvers();
+ checkbox.addEventListener("change", resolve, { once: true });
+ checkbox.click();
+ await promise;
+ }
+
+ is(checkbox.checked, allowPbm, "The checkbox matches allowPbm.");
+
+ // Accept the installation
+ panel.button.click();
+
+ await readyPromise;
+
+ let policy = WebExtensionPolicy.getByID(addonId);
+ is(
+ policy.privateBrowsingAllowed,
+ allowPbm,
+ `Private browsing permission has ${allowPbm ? "" : "not "}been granted`
+ );
+}
+
+async function uninstall() {
+ const addon = await AddonManager.getAddonByID(addonId);
+ await addon.uninstall();
+}
+
+add_task(async function () {
+ is(
+ PrivateBrowsingUtils.permanentPrivateBrowsing,
+ true,
+ "We are in permanent PBM for this test"
+ );
+
+ xpi = AddonTestUtils.createTempWebExtensionFile({
+ manifest: {
+ browser_specific_settings: { gecko: { id: addonId } },
+ },
+ });
+
+ await BrowserTestUtils.withNewTab({ gBrowser: window.gBrowser }, async () => {
+ // First run: install the addon for the first time. We do not let it run in
+ // PBM.
+ await testCheckbox(false, true);
+ // Second run: reinstall the already installed addon, to check the
+ // permission denial prevails on being in always-on PBM.
+ await testCheckbox(false, false);
+ });
+
+ await uninstall();
+
+ await BrowserTestUtils.withNewTab({ gBrowser: window.gBrowser }, async () => {
+ // Third run: install the addon for the first time, and let it run also in
+ // PBM.
+ await testCheckbox(true, true);
+ // Fourth run: reinstall the already installed addon, to check permission
+ // approval is persisted.
+ await testCheckbox(true, true);
+ });
+
+ await uninstall();
+});
diff --git a/browser/modules/ExtensionsUI.sys.mjs b/browser/modules/ExtensionsUI.sys.mjs
@@ -16,6 +16,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.sys.mjs",
ExtensionData: "resource://gre/modules/Extension.sys.mjs",
ExtensionPermissions: "resource://gre/modules/ExtensionPermissions.sys.mjs",
+ PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
OriginControls: "resource://gre/modules/ExtensionPermissions.sys.mjs",
QuarantinedDomains: "resource://gre/modules/ExtensionPermissions.sys.mjs",
});
@@ -420,7 +421,8 @@ export var ExtensionsUI = {
!!strings.dataCollectionPermissions?.collectsTechnicalAndInteractionData;
const incognitoPermissionName = "internal:privateBrowsingAllowed";
- let grantPrivateBrowsingAllowed = false;
+ let grantPrivateBrowsingAllowed =
+ lazy.PrivateBrowsingUtils.permanentPrivateBrowsing;
if (
showIncognitoCheckbox &&
// Usually false, unless the user tries to install a XPI file whose ID