commit 553d79eebb106ea693faaea1ad30493310147225
parent 2960b00b8ff9c65df18fa61ba23020d696894cdd
Author: kpatenio <kpatenio@mozilla.com>
Date: Sat, 18 Oct 2025 02:57:06 +0000
Bug 1993031 - Create section for Firefox VPN in about:settings - r=ip-protection-reviewers,fluent-reviewers,bolsson,mstriemer,fchasen
Differential Revision: https://phabricator.services.mozilla.com/D267966
Diffstat:
9 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
@@ -1479,6 +1479,21 @@ let SETTINGS_CONFIG = {
},
],
},
+ ipprotection: {
+ l10nId: "ip-protection-description",
+ headingLevel: 2,
+ // TODO: Replace support url with finalized link (Bug 1993266)
+ supportPage: "ip-protection",
+ items: [
+ {
+ id: "ipProtectionPlaceholderMessage",
+ control: "moz-message-bar",
+ controlAttrs: {
+ message: "This is a placeholder for the IP Protection section",
+ },
+ },
+ ],
+ },
cookiesAndSiteData: {
l10nId: "sitedata-label",
items: [
diff --git a/browser/components/preferences/preferences.xhtml b/browser/components/preferences/preferences.xhtml
@@ -57,6 +57,7 @@
<!-- Temporary until localization is done -->
<link rel="localization" href="preview/smartTabGroups.ftl"/>
<link rel="localization" href="preview/privacyPreferences.ftl"/>
+ <link rel="localization" href="preview/ipProtection.ftl"/>
<!-- Links below are only used for search-l10n-ids into subdialogs -->
<link rel="localization" href="browser/aboutDialog.ftl"/>
diff --git a/browser/components/preferences/privacy.inc.xhtml b/browser/components/preferences/privacy.inc.xhtml
@@ -395,6 +395,12 @@
<html:setting-group groupid="nonTechnicalPrivacy"/>
</groupbox>
+<!-- Firefox VPN - IP Protection -->
+<groupbox id="dataIPProtectionGroup" data-category="panePrivacy" hidden="true">
+ <html:setting-group groupid="ipprotection"></html:setting-group>
+</groupbox>
+
+
<groupbox id="siteDataGroup" data-category="panePrivacy" hidden="true" aria-describedby="totalSiteDataSize">
<label><html:h2 data-l10n-id="sitedata-header"/></label>
<html:setting-group groupid="cookiesAndSiteData"/>
diff --git a/browser/components/preferences/privacy.js b/browser/components/preferences/privacy.js
@@ -210,6 +210,9 @@ Preferences.addAll([
// Global Privacy Control
{ id: "privacy.globalprivacycontrol.enabled", type: "bool" },
+ // Firefox VPN
+ { id: "browser.ipProtection.variant", type: "string" },
+
// Media
{ id: "media.autoplay.default", type: "int" },
@@ -1252,6 +1255,17 @@ Preferences.addSetting({
],
});
+Preferences.addSetting({
+ id: "ipProtectionVisible",
+ pref: "browser.ipProtection.variant",
+ get: prefVal => prefVal == "beta",
+});
+Preferences.addSetting({
+ id: "ipProtectionPlaceholderMessage",
+ deps: ["ipProtectionVisible"],
+ visible: ({ ipProtectionVisible }) => ipProtectionVisible.value,
+});
+
// Study opt out
if (AppConstants.MOZ_DATA_REPORTING) {
Preferences.addAll([
@@ -2367,6 +2381,7 @@ var gPrivacyPane = {
initSettingGroup("browsingProtection");
initSettingGroup("cookiesAndSiteData");
initSettingGroup("certificates");
+ initSettingGroup("ipprotection");
this._updateSanitizeSettingsButton();
this.initializeHistoryMode();
diff --git a/browser/components/preferences/tests/browser.toml b/browser/components/preferences/tests/browser.toml
@@ -197,6 +197,8 @@ skip-if = ["os == 'linux' && os_version == '24.04' && processor == 'x86_64' && t
["browser_privacy_gpc.js"]
+["browser_privacy_ipprotection.js"]
+
["browser_privacy_passwordGenerationAndAutofill.js"]
["browser_privacy_relayIntegration.js"]
diff --git a/browser/components/preferences/tests/browser_bug731866.js b/browser/components/preferences/tests/browser_bug731866.js
@@ -10,6 +10,9 @@ const cookieBannerHandlingDisabled = !SpecialPowers.getBoolPref(
const backupSectionDisabled = !SpecialPowers.getBoolPref(
"browser.backup.preferences.ui.enabled"
);
+const ipProtectionExperiment = SpecialPowers.getStringPref(
+ "browser.ipProtection.variant"
+);
const profilesGroupDisabled = !SelectableProfileService.isEnabled;
const updatePrefContainers = ["updatesCategory", "updateApp"];
const updateContainersGroupDisabled =
@@ -75,6 +78,14 @@ function checkElements(expectedPane) {
continue;
}
+ // IP Protection is only enabled by browser.ipProtection.variant = beta
+ if (
+ element.id === "dataIPProtectionGroup" &&
+ ipProtectionExperiment !== "beta"
+ ) {
+ continue;
+ }
+
let attributeValue = element.getAttribute("data-category");
let suffix = " (id=" + element.id + ")";
if (attributeValue == "pane" + expectedPane) {
diff --git a/browser/components/preferences/tests/browser_bug795764_cachedisabled.js b/browser/components/preferences/tests/browser_bug795764_cachedisabled.js
@@ -25,6 +25,9 @@ function test() {
}
async function runTest(win) {
+ const ipProtectionExperiment = SpecialPowers.getStringPref(
+ "browser.ipProtection.variant"
+ );
is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
let tab = win.document;
@@ -41,6 +44,14 @@ async function runTest(win) {
continue;
}
+ // IP Protection is only enabled by browser.ipProtection.variant = beta
+ if (
+ element.id === "dataIPProtectionGroup" &&
+ ipProtectionExperiment !== "beta"
+ ) {
+ continue;
+ }
+
if (attributeValue == "panePrivacy") {
is_element_visible(element, "HTTPSOnly should be visible");
diff --git a/browser/components/preferences/tests/browser_privacy_ipprotection.js b/browser/components/preferences/tests/browser_privacy_ipprotection.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This file tests the Privacy pane's Firefox VPN UI.
+
+"use strict";
+
+const FEATURE_PREF = "browser.ipProtection.variant";
+
+const SECTION_ID = "dataIPProtectionGroup";
+
+// Test the section is hidden on page load if the variant pref is set to an ineligible experiment.
+add_task(
+ async function test_section_removed_when_set_to_ineligible_experiment_pref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [[FEATURE_PREF, "alpha"]],
+ });
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:preferences#privacy" },
+ async function (browser) {
+ let section = browser.contentDocument.getElementById(SECTION_ID);
+ is_element_hidden(section, "#dataIPProtectionGroup is hidden");
+ }
+ );
+
+ await SpecialPowers.popPrefEnv();
+ }
+);
+
+// Test the section is shown on page load if the variant pref is set to an eligible experiment
+add_task(
+ async function test_section_shown_when_set_to_eligible_experiment_pref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [[FEATURE_PREF, "beta"]],
+ });
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:preferences#privacy" },
+ async function (browser) {
+ let section = browser.contentDocument.getElementById(SECTION_ID);
+ is_element_visible(section, "#dataIPProtectionGroup is shown");
+ }
+ );
+
+ await SpecialPowers.popPrefEnv();
+ }
+);
diff --git a/browser/locales-preview/ipProtection.ftl b/browser/locales-preview/ipProtection.ftl
@@ -76,4 +76,11 @@ ipprotection-message-generic-error =
.heading = Couldn’t connect to VPN
.message = Try again in a few minutes.
+## IP Protection Settings
+
+ip-protection-description =
+ .label = { -firefox-vpn-brand-name }
+ .description = Hides your location and adds extra encryption to your browsing in { -brand-short-name }.
+ip-protection-learn-more = Learn more
+
##