tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 43c55af65c60a2cfedeb45275256536a12937839
parent cd1586e5cf72d8c948d8d74d66a8a696ec07eb40
Author: Beth Rennie <beth@brennie.ca>
Date:   Sat,  1 Nov 2025 12:50:15 +0000

Bug 1972647 - Don't hide Firefox Labs when studies or telemetry are disabled r=mkaply,akulyk

The UserMessaging:FirefoxLabs policy no longer has to set the
"browser.preferences.experimental" pref because whether or not the
Firefox Labs pane is registered is determined by the "FirefoxLabs"
policy feature.

Differential Revision: https://phabricator.services.mozilla.com/D269922

Diffstat:
Mbrowser/app/profile/firefox.js | 2--
Mbrowser/components/enterprisepolicies/Policies.sys.mjs | 12++----------
Mbrowser/components/preferences/experimental.js | 21---------------------
Mbrowser/components/preferences/preferences.js | 6++++--
Mbrowser/components/preferences/tests/browser_experimental_features.js | 23-----------------------
Mbrowser/components/preferences/tests/browser_experimental_features_filter.js | 4----
Mbrowser/components/preferences/tests/browser_experimental_features_hidden_when_not_public.js | 10+---------
Mbrowser/components/preferences/tests/browser_experimental_features_studies_disabled.js | 165++++++++++++-------------------------------------------------------------------
8 files changed, 31 insertions(+), 212 deletions(-)

diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js @@ -1354,8 +1354,6 @@ pref("accessibility.typeaheadfind.timeout", 5000); pref("accessibility.typeaheadfind.linksonly", false); pref("accessibility.typeaheadfind.flashBar", 1); -// Whether we can show the "Firefox Labs" section. -pref("browser.preferences.experimental", true); // Whether we had to hide the "Firefox Labs" section because it would be empty. pref("browser.preferences.experimental.hidden", false); // Whether we show the "More from Mozilla" section. diff --git a/browser/components/enterprisepolicies/Policies.sys.mjs b/browser/components/enterprisepolicies/Policies.sys.mjs @@ -2923,16 +2923,8 @@ export var Policies = { param.Locked ); } - if ("FirefoxLabs" in param) { - if (!param.FirefoxLabs) { - manager.disallowFeature("FirefoxLabs"); - } - - PoliciesUtils.setDefaultPref( - "browser.preferences.experimental", - param.FirefoxLabs, - param.Locked - ); + if ("FirefoxLabs" in param && !param.FirefoxLabs) { + manager.disallowFeature("FirefoxLabs"); } }, }, diff --git a/browser/components/preferences/experimental.js b/browser/components/preferences/experimental.js @@ -26,7 +26,6 @@ const gExperimentalPane = { this._onCheckboxChanged = this._onCheckboxChanged.bind(this); this._onNimbusUpdate = this._onNimbusUpdate.bind(this); - this._onStudiesEnabledChanged = this._onStudiesEnabledChanged.bind(this); this._resetAllFeatures = this._resetAllFeatures.bind(this); setEventListener( @@ -35,10 +34,6 @@ const gExperimentalPane = { this._resetAllFeatures ); - Services.obs.addObserver( - this._onStudiesEnabledChanged, - ExperimentAPI.STUDIES_ENABLED_CHANGED - ); window.addEventListener("unload", () => this._removeObservers()); await this._maybeRenderLabsRecipes(); @@ -169,24 +164,8 @@ const gExperimentalPane = { } }, - async _onStudiesEnabledChanged() { - const studiesEnabled = ExperimentAPI.studiesEnabled; - - if (studiesEnabled) { - await this._maybeRenderLabsRecipes(); - } else { - this._setCategoryVisibility(true); - this._removeLabsRecipes(); - this._firefoxLabs = null; - } - }, - _removeObservers() { ExperimentAPI.manager.store.off("update", this._onNimbusUpdate); - Services.obs.removeObserver( - this._onStudiesEnabledChanged, - ExperimentAPI.STUDIES_ENABLED_CHANGED - ); }, // Reset the features to their default values diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js @@ -81,6 +81,7 @@ ChromeUtils.defineESModuleGetters(this, { ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.sys.mjs", DownloadUtils: "resource://gre/modules/DownloadUtils.sys.mjs", + ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs", ExtensionPreferencesManager: "resource://gre/modules/ExtensionPreferencesManager.sys.mjs", ExtensionSettingsStore: @@ -242,16 +243,17 @@ function init_all() { if (Services.prefs.getBoolPref("browser.translations.newSettingsUI.enable")) { register_module("paneTranslations", gTranslationsPane); } - if (Services.prefs.getBoolPref("browser.preferences.experimental")) { + if (ExperimentAPI.labsEnabled) { // Set hidden based on previous load's hidden value or if Nimbus is // disabled. document.getElementById("category-experimental").hidden = - !ExperimentAPI.studiesEnabled || Services.prefs.getBoolPref( "browser.preferences.experimental.hidden", false ); register_module("paneExperimental", gExperimentalPane); + } else { + document.getElementById("category-experimental").hidden = true; } NimbusFeatures.moreFromMozilla.recordExposureEvent({ once: true }); diff --git a/browser/components/preferences/tests/browser_experimental_features.js b/browser/components/preferences/tests/browser_experimental_features.js @@ -8,23 +8,6 @@ add_setup(async function setup() { registerCleanupFunction(cleanup); }); -add_task(async function testPrefRequired() { - await SpecialPowers.pushPrefEnv({ - set: [["browser.preferences.experimental", false]], - }); - - await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true }); - let doc = gBrowser.contentDocument; - - let experimentalCategory = doc.getElementById("category-experimental"); - ok(experimentalCategory, "The category exists"); - ok(experimentalCategory.hidden, "The category is hidden"); - - BrowserTestUtils.removeTab(gBrowser.selectedTab); - - await SpecialPowers.popPrefEnv(); -}); - add_task(async function testCanOpenWithPref() { await SpecialPowers.pushPrefEnv({ set: [["browser.preferences.experimental", true]], @@ -58,10 +41,6 @@ add_task(async function testCanOpenWithPref() { }); add_task(async function testSearchFindsExperiments() { - await SpecialPowers.pushPrefEnv({ - set: [["browser.preferences.experimental", true]], - }); - await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true }); let doc = gBrowser.contentDocument; @@ -80,6 +59,4 @@ add_task(async function testSearchFindsExperiments() { ); BrowserTestUtils.removeTab(gBrowser.selectedTab); - - await SpecialPowers.popPrefEnv(); }); diff --git a/browser/components/preferences/tests/browser_experimental_features_filter.js b/browser/components/preferences/tests/browser_experimental_features_filter.js @@ -36,10 +36,6 @@ add_task(async function testFilterFeatures() { ]; const cleanup = await setupLabsTest(recipes); - await SpecialPowers.pushPrefEnv({ - set: [["browser.preferences.experimental", true]], - }); - await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:preferences#paneExperimental" diff --git a/browser/components/preferences/tests/browser_experimental_features_hidden_when_not_public.js b/browser/components/preferences/tests/browser_experimental_features_hidden_when_not_public.js @@ -6,10 +6,6 @@ add_task(async function testNonPublicFeaturesShouldntGetDisplayed() { const cleanup = await setupLabsTest(); - await SpecialPowers.pushPrefEnv({ - set: [["browser.preferences.experimental", true]], - }); - await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:preferences#paneExperimental" @@ -42,7 +38,6 @@ add_task(async function testNonPublicFeaturesShouldntGetDisplayed() { BrowserTestUtils.removeTab(gBrowser.selectedTab); await cleanup(); - await SpecialPowers.popPrefEnv(); }); add_task(async function testNonPublicFeaturesShouldntGetDisplayed() { @@ -50,10 +45,7 @@ add_task(async function testNonPublicFeaturesShouldntGetDisplayed() { const cleanup = await setupLabsTest(DEFAULT_LABS_RECIPES.slice(2)); await SpecialPowers.pushPrefEnv({ - set: [ - ["browser.preferences.experimental", true], - ["browser.preferences.experimental.hidden", false], - ], + set: [["browser.preferences.experimental.hidden", false]], }); await BrowserTestUtils.openNewForegroundTab( diff --git a/browser/components/preferences/tests/browser_experimental_features_studies_disabled.js b/browser/components/preferences/tests/browser_experimental_features_studies_disabled.js @@ -3,13 +3,20 @@ "use strict"; -add_task(async function testHiddenWhenStudiesDisabled() { +const { EnterprisePolicyTesting } = ChromeUtils.importESModule( + "resource://testing-common/EnterprisePolicyTesting.sys.mjs" +); + +add_task(async function testHiddenWhenLabsDisabled() { const cleanup = await setupLabsTest(); await SpecialPowers.pushPrefEnv({ - set: [ - ["browser.preferences.experimental", true], - ["browser.preferences.experimental.hidden", false], - ], + set: [["browser.preferences.experimental.hidden", false]], + }); + + await EnterprisePolicyTesting.setupPolicyEngineWithJson({ + policies: { + UserMessaging: { FirefoxLabs: false }, + }, }); await BrowserTestUtils.openNewForegroundTab( @@ -19,151 +26,27 @@ add_task(async function testHiddenWhenStudiesDisabled() { const doc = gBrowser.contentDocument; - await waitForExperimentalFeaturesShown(doc); - - const enrollPromises = [ - promiseNimbusStoreUpdate("nimbus-qa-1", true), - promiseNimbusStoreUpdate("nimbus-qa-2", true), - ]; - - await enrollByClick(doc.getElementById("nimbus-qa-1"), true); - await enrollByClick(doc.getElementById("nimbus-qa-2"), true); - - await enrollPromises; - - const unenrollPromises = [ - promiseNimbusStoreUpdate("nimbus-qa-1", false), - promiseNimbusStoreUpdate("nimbus-qa-2", false), - ]; - - // Disabling studies should remove the experimental pane. - await SpecialPowers.pushPrefEnv({ - set: [["app.shield.optoutstudies.enabled", false]], - }); - - await waitForExperimentalFeaturesHidden(doc); - await unenrollPromises; - - ok( - !ExperimentAPI._manager.store.get("nimbus-qa-1")?.active, - "Should unenroll from nimbus-qa-1" - ); - ok( - !ExperimentAPI._manager.store.get("nimbus-qa-2")?.active, - "Should unenroll from nimbus-qa-2" + await TestUtils.waitForCondition( + () => doc.getElementById("category-experimental").hidden, + "Wait for Experimental Features section label to become hidden" ); - // Re-enabling studies should re-add it. - await SpecialPowers.popPrefEnv(); - await waitForExperimentalFeaturesShown(doc); - - // Navigate back to the experimental tab. - EventUtils.synthesizeMouseAtCenter( - doc.getElementById("category-experimental"), - {}, - gBrowser.contentWindow + is( + doc.getElementById("pane-experimental-featureGates"), + null, + "Experimental Features section not added to the DOM" ); - await waitForPageFlush(); - is( doc.querySelector(".category[selected]").id, - "category-experimental", - "Experimental category selected" - ); - - ok( - !doc.getElementById("nimbus-qa-1").checked, - "nimbus-qa-1 checkbox unchecked" - ); - ok( - !doc.getElementById("nimbus-qa-2").checked, - "nimbus-qa-2 checkbox unchecked" - ); - - await enrollByClick(doc.getElementById("nimbus-qa-1"), true); - await enrollByClick(doc.getElementById("nimbus-qa-2"), true); - - // Likewise, disabling telemetry should remove the experimental pane. - await SpecialPowers.pushPrefEnv({ - set: [["datareporting.healthreport.uploadEnabled", false]], - }); - - await waitForExperimentalFeaturesHidden(doc); - - ok( - !ExperimentAPI._manager.store.get("nimbus-qa-1")?.active, - "Should unenroll from nimbus-qa-1" - ); - ok( - !ExperimentAPI._manager.store.get("nimbus-qa-2")?.active, - "Should unenroll from nimbus-qa-2" - ); - - await SpecialPowers.popPrefEnv(); - - // Re-enabling studies should re-add it. - await waitForExperimentalFeaturesShown(doc); - - ok( - !doc.getElementById("nimbus-qa-1").checked, - "nimbus-qa-1 checkbox unchecked" - ); - ok( - !doc.getElementById("nimbus-qa-2").checked, - "nimbus-qa-2 checkbox unchecked" + "category-general", + "When the experimental features section is hidden, navigating to #experimental should redirect to #general" ); BrowserTestUtils.removeTab(gBrowser.selectedTab); - await cleanup(); await SpecialPowers.popPrefEnv(); -}); - -async function waitForExperimentalFeaturesShown(doc) { - await TestUtils.waitForCondition( - () => doc.querySelector(".featureGate"), - "Wait for features to be added to the DOM" - ); - - ok( - !doc.getElementById("category-experimental").hidden, - "Experimental Features section should not be hidden" - ); - - ok( - !Services.prefs.getBoolPref("browser.preferences.experimental.hidden"), - "Hidden pref should be false" - ); -} - -async function waitForExperimentalFeaturesHidden(doc) { - await TestUtils.waitForCondition( - () => doc.getElementById("category-experimental").hidden, - "Wait for Experimental Features section to get hidden" - ); - - ok( - doc.getElementById("category-experimental").hidden, - "Experimental Features section should be hidden when all features are hidden" - ); - ok( - doc.getElementById("firefoxExperimentalCategory").hidden, - "Experimental Features header should be hidden when all features are hidden" - ); - is( - doc.querySelector(".category[selected]").id, - "category-general", - "When the experimental features section is hidden, navigating to #experimental should redirect to #general" - ); - ok( - Services.prefs.getBoolPref("browser.preferences.experimental.hidden"), - "Hidden pref should be true" - ); -} + await cleanup(); -function waitForPageFlush() { - return new Promise(resolve => - requestAnimationFrame(() => requestAnimationFrame(resolve)) - ); -} + await EnterprisePolicyTesting.setupPolicyEngineWithJson({}); +});