diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_dfpi_rollout.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_dfpi_rollout.js index 7089ba69c0dd..c6fa45291001 100644 --- a/browser/base/content/test/protectionsUI/browser_protectionsUI_dfpi_rollout.js +++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_dfpi_rollout.js @@ -1,6 +1,10 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +const { TelemetryTestUtils } = ChromeUtils.import( + "resource://testing-common/TelemetryTestUtils.jsm" +); + const PREF_DFPI_ENABLED_BY_DEFAULT = "privacy.restrict3rdpartystorage.rollout.enabledByDefault"; const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior"; @@ -33,36 +37,44 @@ function testSearchPrefState(optIn) { let expectedPrefs = optIn ? SEARCH_PREFS_OPT_IN : SEARCH_PREFS_OPT_OUT; expectedPrefs.forEach(([key, value]) => { - ok(Services.prefs.prefHasUserValue(key)); + ok( + Services.prefs.prefHasUserValue(key), + `Pref '${key}' should have user value.'` + ); is( Services.prefs.getStringPref(key), value, - `Pref '${key}' is set by the action` + `Pref '${key}' should have correct value.` ); }); } -// Tests that the dFPI rollout pref updates the default cookieBehavior to 5 and -// sets the correct search prefs. +function testTelemetryState(optIn) { + let expectedValue; + if (optIn == null) { + expectedValue = 2; + } else { + expectedValue = optIn ? 1 : 0; + } + + TelemetryTestUtils.assertScalar( + TelemetryTestUtils.getProcessScalars("parent"), + "privacy.dfpi_rollout_enabledByDefault", + expectedValue, + "Scalar should have correct value" + ); +} + +// Tests that the dFPI rollout pref updates the default cookieBehavior to 5, +// sets the correct search prefs and records telemetry. add_task(async function testdFPIRolloutPref() { defaultPrefs.setIntPref( COOKIE_BEHAVIOR_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ); - Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, false); - is( - defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF), - Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER - ); - testSearchPrefState(false); - - Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, true); - is( - defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF), - Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN - ); - testSearchPrefState(true); + // Test the unset state of the pref. + testTelemetryState(null); Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, false); is( @@ -70,6 +82,7 @@ add_task(async function testdFPIRolloutPref() { Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ); testSearchPrefState(false); + testTelemetryState(false); Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, true); is( @@ -77,4 +90,21 @@ add_task(async function testdFPIRolloutPref() { Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN ); testSearchPrefState(true); + testTelemetryState(true); + + Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, false); + is( + defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF), + Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER + ); + testSearchPrefState(false); + testTelemetryState(false); + + Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, true); + is( + defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF), + Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN + ); + testSearchPrefState(true); + testTelemetryState(true); }); diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 44ae9c891aa1..ee3fec90c2f4 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -1722,6 +1722,7 @@ BrowserGlue.prototype = { // set during onboarding when the user chooses to enable protections or not. _setDefaultCookieBehavior() { if (!Services.prefs.prefHasUserValue(PREF_DFPI_ENABLED_BY_DEFAULT)) { + Services.telemetry.scalarSet("privacy.dfpi_rollout_enabledByDefault", 2); return; } let dFPIEnabled = Services.prefs.getBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT); @@ -1734,6 +1735,11 @@ BrowserGlue.prototype = { : Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ); + Services.telemetry.scalarSet( + "privacy.dfpi_rollout_enabledByDefault", + dFPIEnabled ? 1 : 0 + ); + if (dFPIEnabled) { Services.prefs.setStringPref( "browser.search.param.google_channel_us", diff --git a/browser/components/preferences/tests/browser_contentblocking_standard_tcp_toggle.js b/browser/components/preferences/tests/browser_contentblocking_standard_tcp_toggle.js index ed3fc06ff798..b8eed1269f53 100644 --- a/browser/components/preferences/tests/browser_contentblocking_standard_tcp_toggle.js +++ b/browser/components/preferences/tests/browser_contentblocking_standard_tcp_toggle.js @@ -10,6 +10,9 @@ ChromeUtils.defineModuleGetter( const { ExperimentFakes } = ChromeUtils.import( "resource://testing-common/NimbusTestUtils.jsm" ); +const { TelemetryTestUtils } = ChromeUtils.import( + "resource://testing-common/TelemetryTestUtils.jsm" +); const PREF_DFPI_ENABLED_BY_DEFAULT = "privacy.restrict3rdpartystorage.rollout.enabledByDefault"; @@ -29,6 +32,22 @@ const { BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN, } = Ci.nsICookieService; +function testTelemetryState(optIn) { + let expectedValue; + if (optIn == null) { + expectedValue = 2; + } else { + expectedValue = optIn ? 1 : 0; + } + + TelemetryTestUtils.assertScalar( + TelemetryTestUtils.getProcessScalars("parent"), + "privacy.dfpi_rollout_enabledByDefault", + expectedValue, + "Scalar should have correct value" + ); +} + /** * Waits for preference to be set and asserts the value. * @param {string} pref - Preference key. @@ -68,6 +87,10 @@ async function testRolloutUI({ JSON.stringify({ dFPIEnabledByDefault, rolloutUIEnabled }) ); + // Initially the rollout pref is not set. Telemetry should record this unset + // state. + testTelemetryState(null); + // Setting to standard category explicitly, since changing the default cookie // behavior still switches us to custom initially. let set = [[CAT_PREF, "standard"]]; @@ -79,6 +102,9 @@ async function testRolloutUI({ } await SpecialPowers.pushPrefEnv({ set }); + // At this point the pref can only be enabled or unset. + testTelemetryState(dFPIEnabledByDefault || null); + const uiEnabled = rolloutUIEnabled || rolloutUIEnabledByExperiment || @@ -182,11 +208,11 @@ async function testRolloutUI({ "standard", "Should still be in standard category" ); - ok( BrowserTestUtils.is_visible(reloadWarning), "Reload warning should be visible." ); + testTelemetryState(true); } // Un-check checkbox and assert pref state. @@ -208,11 +234,11 @@ async function testRolloutUI({ "standard", "Should still be in standard category" ); - ok( BrowserTestUtils.is_visible(reloadWarning), "Reload warning should be visible." ); + testTelemetryState(false); } let categoryPrefChange = waitForAndAssertPrefState(CAT_PREF, "strict"); @@ -246,6 +272,8 @@ async function testRolloutUI({ Services.prefs.setStringPref(CAT_PREF, "standard"); Services.prefs.clearUserPref(PREF_DFPI_ENABLED_BY_DEFAULT); Services.prefs.clearUserPref(PREF_DFPI_ROLLOUT_UI_ENABLED); + + testTelemetryState(null); } // Clients which are not part of the rollout. They should not see the diff --git a/toolkit/components/telemetry/Scalars.yaml b/toolkit/components/telemetry/Scalars.yaml index c413dfe3a209..ee29e6ad5888 100644 --- a/toolkit/components/telemetry/Scalars.yaml +++ b/toolkit/components/telemetry/Scalars.yaml @@ -1372,6 +1372,24 @@ contentblocking: record_in_processes: - main +privacy: + dfpi_rollout_enabledByDefault: + bug_numbers: + - 1740232 + description: > + Records if a client is opted into dFPI in standard ETP mode as part of the + rollout experiment. 0: opted out, 1: opted in, 2: not part of the + experiment + expires: "101" + kind: uint + notification_emails: + - pbz@mozilla.com + release_channel_collection: opt-out + products: + - 'firefox' + record_in_processes: + - main + datasanitization: network_cookie_lifetimePolicy: bug_numbers: