tor-browser

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

commit f58038979749b7bb225c931a870d73dd8ed947e0
parent 0e3ebebbc4800a65a9908ada3577e180f9c34a3a
Author: Chris H-C <chutten@mozilla.com>
Date:   Mon,  8 Dec 2025 21:42:50 +0000

Bug 1999541 - Implement Nimbus-controlled shutoff switch for "main" ping scalars r=TravisLong

Even if scalars are completely disabled, we leave the two that fuel top-line
KPIs intact. This is out of an abundance of caution, should this feature be
accidentally enabled.

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

Diffstat:
Mtoolkit/components/nimbus/FeatureManifest.yaml | 9+++++++++
Mtoolkit/components/telemetry/pings/TelemetrySession.sys.mjs | 26++++++++++++++++++++++++++
Atoolkit/components/telemetry/tests/unit/test_MainPingDisablement.js | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/components/telemetry/tests/unit/xpcshell.toml | 5+++++
4 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/toolkit/components/nimbus/FeatureManifest.yaml b/toolkit/components/nimbus/FeatureManifest.yaml @@ -2754,6 +2754,15 @@ legacyTelemetry: Code that collects to and submits the ping will still operate as normal. Cannot be used to disable the "main", "first-shutdown", "new-profile", or "deletion-request" pings. + disableMainPingScalars: + type: boolean + description: | + If true, scalars will not be included in "main" pings. + Exceptions are made for two important engagement measures: + `browser.engagement.total_uri_count_normal_and_private_mode` and + `browser.engagement.active_ticks`. + These scalars will continue to be reported as normal, even if all + others are disabled by this variable. browserLowMemoryPrefs: description: Prefs which control the browser's behaviour under low memory. diff --git a/toolkit/components/telemetry/pings/TelemetrySession.sys.mjs b/toolkit/components/telemetry/pings/TelemetrySession.sys.mjs @@ -11,6 +11,7 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { AddonManagerPrivate: "resource://gre/modules/AddonManager.sys.mjs", + NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs", TelemetryController: "resource://gre/modules/TelemetryController.sys.mjs", TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs", TelemetryReportingPolicy: @@ -507,6 +508,31 @@ var Impl = { !this._testing ); + if ( + lazy.NimbusFeatures.legacyTelemetry.getVariable("disableMainPingScalars") + ) { + this._log.trace("getScalars - Main ping scalars are disabled."); + if (keyed) { + // We don't need to preserve any keyed scalars. + scalarsSnapshot = {}; + } else { + let filteredSnapshot = {}; + const scalarsToKeep = [ + "browser.engagement.total_uri_count_normal_and_private_mode", + "browser.engagement.active_ticks", + ]; + for (let scalar of scalarsToKeep) { + if ("parent" in scalarsSnapshot && scalar in scalarsSnapshot.parent) { + if (!("parent" in filteredSnapshot)) { + filteredSnapshot.parent = {}; + } + filteredSnapshot.parent[scalar] = scalarsSnapshot.parent[scalar]; + } + } + scalarsSnapshot = filteredSnapshot; + } + } + return scalarsSnapshot; }, diff --git a/toolkit/components/telemetry/tests/unit/test_MainPingDisablement.js b/toolkit/components/telemetry/tests/unit/test_MainPingDisablement.js @@ -0,0 +1,77 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +*/ +/** + * Tests for disabling pieces of the "main" ping. + */ + +const { NimbusFeatures } = ChromeUtils.importESModule( + "resource://nimbus/ExperimentAPI.sys.mjs" +); +const { NimbusTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/NimbusTestUtils.sys.mjs" +); +const { TelemetrySession } = ChromeUtils.importESModule( + "resource://gre/modules/TelemetrySession.sys.mjs" +); + +NimbusTestUtils.init(this); + +add_setup(async function () { + // FOG needs a profile directory + do_get_profile(); + Services.fog.initializeFOG(); + + // Make sure we don't generate unexpected pings due to pref changes. + await setEmptyPrefWatchlist(); + + Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true); + + await TelemetryController.testSetup(); +}); + +add_task(async function test_scalarDisablement() { + const URI_COUNT_SCALAR = + "browser.engagement.total_uri_count_normal_and_private_mode"; + const ACTIVE_TICKS_SCALAR = "browser.engagement.active_ticks"; + const LAST_SHUTDOWN_SCALAR = "browser.timings.last_shutdown"; + + // Ensure there's data to be snapshotted. + // Both some that shouldn't be filtered... + Glean.browserEngagement.uriCount.add(1); + Glean.browserEngagement.activeTicks.add(1); + // ...and some that should be. + Glean.browserTimings.lastShutdown.set(42); + + info("1. Ensure things begin by storing and reporting as expected."); + let payload = TelemetrySession.getPayload( + "reason", + /*clearSubsession*/ false + ); + + Assert.greater(payload.processes.parent.scalars[URI_COUNT_SCALAR], 0); + Assert.greater(payload.processes.parent.scalars[ACTIVE_TICKS_SCALAR], 0); + Assert.greater(payload.processes.parent.scalars[LAST_SHUTDOWN_SCALAR], 0); + + info("2. Ensure we can disable scalars, leaving important ones intact."); + const { cleanup } = await NimbusTestUtils.setupTest(); + registerCleanupFunction(cleanup); + + let nimbusCleanup = await NimbusTestUtils.enrollWithFeatureConfig({ + featureId: NimbusFeatures.legacyTelemetry.featureId, + value: { + disableMainPingScalars: true, + }, + }); + + let filtered = TelemetrySession.getPayload( + "reason", + /*clearSubsession*/ false + ); + + Assert.greater(filtered.processes.parent.scalars[URI_COUNT_SCALAR], 0); + Assert.greater(filtered.processes.parent.scalars[ACTIVE_TICKS_SCALAR], 0); + Assert.ok(!(LAST_SHUTDOWN_SCALAR in filtered.processes.parent.scalars)); + + await nimbusCleanup(); +}); diff --git a/toolkit/components/telemetry/tests/unit/xpcshell.toml b/toolkit/components/telemetry/tests/unit/xpcshell.toml @@ -40,6 +40,11 @@ skip-if = [ ] tags = "addons" +["test_MainPingDisablement.js"] +run-if = [ + "os != 'android'", # Legacy telemetry is always disabled on Android +] + ["test_MigratePendingPings.js"] run-if = [ "os != 'android'", # Legacy telemetry is a lways disabled on Android