commit e93c6d84bd469982d3adc588767cbca3b449db7e
parent d731e585dcd76b8aa314fcf28f456921c27ce26e
Author: Fred Chasen <fchasen@mozilla.com>
Date: Wed, 22 Oct 2025 16:02:25 +0000
Bug 1993605 - Prevent re-adding IP Protection toolbar when it has been removed by the user. r=ip-protection-reviewers,Gijs
Adds a `browser.ipProtection.added` pref to track when the toolbar item has been added and prevent changing the location after it has been set.
Differential Revision: https://phabricator.services.mozilla.com/D269507
Diffstat:
4 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
@@ -3502,6 +3502,7 @@ pref("browser.ipProtection.domainExclusions", "");
pref("browser.ipProtection.domainInclusions", "");
pref("browser.ipProtection.log", false);
pref("browser.ipProtection.guardian.endpoint", "https://vpn.mozilla.org/");
+pref("browser.ipProtection.added", false);
// Pref to enable aboug:glean redesign.
pref("about.glean.redesign.enabled", false);
diff --git a/browser/components/ipprotection/IPProtection.sys.mjs b/browser/components/ipprotection/IPProtection.sys.mjs
@@ -39,6 +39,7 @@ class IPProtectionWidget {
static ENABLED_PREF = "browser.ipProtection.enabled";
static VARIANT_PREF = "browser.ipProtection.variant";
+ static ADDED_PREF = "browser.ipProtection.added";
#inited = false;
created = false;
@@ -121,7 +122,7 @@ class IPProtectionWidget {
const onBeforeCreated = this.#onBeforeCreated.bind(this);
const onCreated = this.#onCreated.bind(this);
const onDestroyed = this.#onDestroyed.bind(this);
- lazy.CustomizableUI.createWidget({
+ const item = {
id: IPProtectionWidget.WIDGET_ID,
l10nId: "ipprotection-button",
type: "view",
@@ -131,7 +132,8 @@ class IPProtectionWidget {
onBeforeCreated,
onCreated,
onDestroyed,
- });
+ };
+ lazy.CustomizableUI.createWidget(item);
this.#placeWidget();
@@ -142,12 +144,16 @@ class IPProtectionWidget {
* Places the widget in the nav bar, next to the FxA widget.
*/
#placeWidget() {
+ let wasAddedToToolbar = Services.prefs.getBoolPref(
+ IPProtectionWidget.ADDED_PREF,
+ false
+ );
let alreadyPlaced = lazy.CustomizableUI.getPlacementOfWidget(
IPProtectionWidget.WIDGET_ID,
false,
true
);
- if (alreadyPlaced) {
+ if (wasAddedToToolbar || alreadyPlaced) {
return;
}
@@ -161,6 +167,7 @@ class IPProtectionWidget {
lazy.CustomizableUI.AREA_NAVBAR,
pos
);
+ Services.prefs.setBoolPref(IPProtectionWidget.ADDED_PREF, true);
}
/**
diff --git a/browser/components/ipprotection/tests/browser/browser_ipprotection_toolbar.js b/browser/components/ipprotection/tests/browser/browser_ipprotection_toolbar.js
@@ -259,3 +259,52 @@ add_task(async function toolbar_placement_customized() {
start.position
);
});
+
+/**
+ * Tests that toolbar widget can be removed and will not be re-added.
+ */
+add_task(async function toolbar_removed() {
+ setupService({
+ isSignedIn: true,
+ isEnrolled: true,
+ });
+
+ let start = CustomizableUI.getPlacementOfWidget(IPProtectionWidget.WIDGET_ID);
+ Assert.equal(
+ start.area,
+ CustomizableUI.AREA_NAVBAR,
+ "IP Protection widget is initially added to the nav bar"
+ );
+
+ // Remove from the toolbar
+ CustomizableUI.removeWidgetFromArea(IPProtectionWidget.WIDGET_ID);
+
+ let end = CustomizableUI.getPlacementOfWidget(IPProtectionWidget.WIDGET_ID);
+ Assert.equal(end, null, "IP Protection widget is removed");
+
+ // Disable the feature
+ await cleanupExperiment();
+
+ const waitForStateChange = BrowserTestUtils.waitForEvent(
+ lazy.IPProtectionService,
+ "IPProtectionService:StateChanged",
+ false,
+ () => lazy.IPProtectionService.state === lazy.IPProtectionStates.READY
+ );
+
+ // Reenable the feature
+ await setupExperiment();
+
+ await waitForStateChange;
+
+ let restored = CustomizableUI.getPlacementOfWidget(
+ IPProtectionWidget.WIDGET_ID
+ );
+ Assert.equal(restored, null, "IP Protection widget is still removed");
+
+ CustomizableUI.addWidgetToArea(
+ IPProtectionWidget.WIDGET_ID,
+ start.area,
+ start.position
+ );
+});
diff --git a/browser/components/ipprotection/tests/browser/head.js b/browser/components/ipprotection/tests/browser/head.js
@@ -265,6 +265,7 @@ add_setup(async function setupVPN() {
setupSandbox.restore();
cleanupExperiment();
CustomizableUI.reset();
+ Services.prefs.clearUserPref(IPProtectionWidget.ADDED_PREF);
});
});