From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- toolkit/components/nimbus/FeatureManifest.yaml | 119 +++++++++++- .../nimbus/generate/generate_feature_manifest.py | 2 - .../nimbus/lib/ExperimentManager.sys.mjs | 21 ++- .../test/unit/test_ExperimentManager_prefs.js | 204 +++++++++++++++++++++ 4 files changed, 330 insertions(+), 16 deletions(-) (limited to 'toolkit/components/nimbus') diff --git a/toolkit/components/nimbus/FeatureManifest.yaml b/toolkit/components/nimbus/FeatureManifest.yaml index 7612ef2dc2..c540e0e387 100644 --- a/toolkit/components/nimbus/FeatureManifest.yaml +++ b/toolkit/components/nimbus/FeatureManifest.yaml @@ -136,6 +136,14 @@ search: branch: default pref: browser.urlbar.trending.maxResultsNoSearchMode description: The maximum number of trending results mode outside search mode. + newSearchConfigEnabled: + type: boolean + setPref: + branch: user + pref: browser.search.newSearchConfig.enabled + description: >- + Whether search-config-v2 is enabled for the user. This will only take + effect when the user restarts. # `searchConfiguration` is for search experiment features for items that require # isEarlyStartup to be true. These items may require a reload of the search @@ -256,6 +264,13 @@ urlbar: will be able to click the "Show less frequently" command for Pocket suggestions. If undefined or zero, the user will be able to click the command without any limit. + potentialExposureKeywords: + type: json + fallbackPref: browser.urlbar.potentialExposureKeywords + description: >- + An array of keyword strings that will trigger the + `urlbar-potential-exposure` ping when the user types one during a urlbar + session. quickSuggestAllowPositionInSuggestions: type: boolean fallbackPref: browser.urlbar.quicksuggest.allowPositionInSuggestions @@ -825,6 +840,13 @@ pocketNewtab: browser.newtabpage.activity-stream.discoverystream.sendToPocket.enabled description: >- Decides what to do when a logged out user click "Save to Pocket" from a Pocket card. + wallpapers: + type: boolean + setPref: + branch: user + pref: browser.newtabpage.activity-stream.newtabWallpapers.enabled + description: >- + Turns on and off wallpaper support. recsPersonalized: type: boolean fallbackPref: >- @@ -926,27 +948,36 @@ saveToPocket: description: The save to Pocket feature owner: sdowne@getpocket.com hasExposure: false - isEarlyStartup: true variables: emailButton: type: boolean - fallbackPref: extensions.pocket.refresh.emailButton.enabled + setPref: + branch: user + pref: extensions.pocket.refresh.emailButton.enabled description: Just for the new Pocket panels, enables the email signup button. hideRecentSaves: type: boolean - fallbackPref: extensions.pocket.refresh.hideRecentSaves.enabled + setPref: + branch: user + pref: extensions.pocket.refresh.hideRecentSaves.enabled description: Hides the recently saved section in the home panel. bffRecentSaves: type: boolean - fallbackPref: "extensions.pocket.bffRecentSaves" + setPref: + branch: user + pref: extensions.pocket.bffRecentSaves description: Use the new BFF Proxy Service instead of the legacy Pocket Service for Recent Saves bffApi: type: string - fallbackPref: "extensions.pocket.bffApi" + setPref: + branch: user + pref: extensions.pocket.bffApi description: BFF Proxy Service domain oAuthConsumerKeyBff: type: string - fallbackPref: "extensions.pocket.oAuthConsumerKeyBff" + setPref: + branch: user + pref: extensions.pocket.oAuthConsumerKeyBff description: BFF Proxy Service OAuth Consumer Key password-autocomplete: @@ -1378,9 +1409,6 @@ gleanInternalSdk: type: int description: >- Maximum number of pings that can be sent in a 60 second interval - enableEventTimestamps: - type: "boolean" - description: "Enables precise event timestamps for Glean events" majorRelease2022: description: Major Release 2022 @@ -1543,6 +1571,12 @@ dohPrefs: setPref: branch: default pref: "network.trr_ui.show_fallback_warning_option" + nativeHTTPSRecords: + description: Whether we can perform native DNS HTTPS lookups + type: boolean + setPref: + branch: default + pref: "network.dns.native_https_query" dooh: description: "DNS over Oblivious HTTP" @@ -2295,7 +2329,6 @@ updatePrompt: exposureDescription: >- Exposure is sent at most once per browsing session when an update notification prompt is displayed. - isEarlyStartup: true variables: showReleaseNotesLink: type: boolean @@ -2647,3 +2680,69 @@ httpsFirst: setPref: branch: default pref: dom.security.https_only_fire_http_request_background_timer_ms + +contentRelevancy: + description: >- + A feature for interest-based content relevance ranking and personalization + for Firefox. + owner: disco-team@mozilla.com + hasExposure: false + variables: + enabled: + description: Enable this feature + type: boolean + fallbackPref: toolkit.contentRelevancy.enabled + maxInputUrls: + description: The maximum number of input URLs for interest classification + type: int + minInputUrls: + description: The minimal number of input URLs for interest classification + type: int + timerInterval: + description: >- + The interval (in seconds) of the background update timer for the content + relevancy manager + type: int + setPref: + branch: user + pref: toolkit.contentRelevancy.timerInterval + +tabPreview: + description: Prefs to control Tab Previews + owner: dwalker@mozilla.com + hasExposure: false + variables: + tabPreviewsEnabled: + type: boolean + setPref: + branch: default + pref: browser.tabs.cardPreview.enabled + description: >- + When true, users will see the new card preview when hovering a tab, instead of the standard tooltip + +backupService: + description: Prefs to control the profile backup service + owner: mconley@mozilla.com + hasExposure: false + variables: + enabled: + type: boolean + setPref: + branch: default + pref: browser.backup.enabled + description: >- + When true, the profile backup service will be initialized soon after + startup. + +pqcrypto: + description: Prefs that control the use of post-quantum cryptography. + owner: jschanck@mozilla.com + hasExposure: false + variables: + tlsEnableXyber: + type: boolean + setPref: + branch: default + pref: security.tls.enable_kyber + description: >- + Whether to enable Xyber768 for TLS. diff --git a/toolkit/components/nimbus/generate/generate_feature_manifest.py b/toolkit/components/nimbus/generate/generate_feature_manifest.py index 14057493c5..55e681fdf8 100644 --- a/toolkit/components/nimbus/generate/generate_feature_manifest.py +++ b/toolkit/components/nimbus/generate/generate_feature_manifest.py @@ -31,11 +31,9 @@ ALLOWED_ISEARLYSTARTUP_FEATURE_IDS = { "majorRelease2022", "newtab", "pocketNewtab", - "saveToPocket", "searchConfiguration", "shellService", "testFeature", - "updatePrompt", "upgradeDialog", } diff --git a/toolkit/components/nimbus/lib/ExperimentManager.sys.mjs b/toolkit/components/nimbus/lib/ExperimentManager.sys.mjs index d0f313a2ae..8bd847b067 100644 --- a/toolkit/components/nimbus/lib/ExperimentManager.sys.mjs +++ b/toolkit/components/nimbus/lib/ExperimentManager.sys.mjs @@ -95,8 +95,8 @@ export class _ExperimentManager { get studiesEnabled() { return ( - Services.prefs.getBoolPref(UPLOAD_ENABLED_PREF) && - Services.prefs.getBoolPref(STUDIES_OPT_OUT_PREF) + Services.prefs.getBoolPref(UPLOAD_ENABLED_PREF, false) && + Services.prefs.getBoolPref(STUDIES_OPT_OUT_PREF, false) ); } @@ -974,7 +974,7 @@ export class _ExperimentManager { // need to check if we have another enrollment for the same feature. const conflictingEnrollment = getConflictingEnrollment(featureId); - for (const [variable, value] of Object.entries(featureValue)) { + for (let [variable, value] of Object.entries(featureValue)) { const setPref = feature.getSetPref(variable); if (setPref) { @@ -1012,6 +1012,13 @@ export class _ExperimentManager { // An experiment takes precedence if there is already a pref set. if (!isRollout || !conflictingPref) { + if ( + lazy.NimbusFeatures[featureId].manifest.variables[variable] + .type === "json" + ) { + value = JSON.stringify(value); + } + prefsToSet.push({ name: prefName, value, @@ -1250,7 +1257,13 @@ export class _ExperimentManager { } } - const value = featuresById[featureId].value[variable]; + let value = featuresById[featureId].value[variable]; + if ( + lazy.NimbusFeatures[featureId].manifest.variables[variable].type === + "json" + ) { + value = JSON.stringify(value); + } if (prefBranch !== "user") { lazy.PrefUtils.setPref(name, value, { branch: prefBranch }); diff --git a/toolkit/components/nimbus/test/unit/test_ExperimentManager_prefs.js b/toolkit/components/nimbus/test/unit/test_ExperimentManager_prefs.js index 7ae0e1b76f..f2f5a25836 100644 --- a/toolkit/components/nimbus/test/unit/test_ExperimentManager_prefs.js +++ b/toolkit/components/nimbus/test/unit/test_ExperimentManager_prefs.js @@ -3348,3 +3348,207 @@ add_task(async function test_nested_prefs_enroll_both() { branch: DEFAULT, }); }); + +const TYPED_FEATURE = new ExperimentFeature("test-typed-prefs", { + description: "Test feature that sets each type of pref", + owner: "test@test.test", + hasExposure: false, + variables: { + string: { + type: "string", + description: "test string variable", + setPref: { + branch: "default", + pref: "nimbus.test-only.types.string", + }, + }, + int: { + type: "int", + description: "test int variable", + setPref: { + branch: "default", + pref: "nimbus.test-only.types.int", + }, + }, + boolean: { + type: "boolean", + description: "test boolean variable", + setPref: { + branch: "default", + pref: "nimbus.test-only.types.boolean", + }, + }, + json: { + type: "json", + description: "test json variable", + setPref: { + branch: "default", + pref: "nimbus.test-only.types.json", + }, + }, + }, +}); + +add_task(async function test_setPref_types() { + const featureCleanup = ExperimentTestUtils.addTestFeatures(TYPED_FEATURE); + + const store = ExperimentFakes.store(); + const manager = ExperimentFakes.manager(store); + + await manager.onStartup(); + await assertEmptyStore(store); + + const json = { + foo: "foo", + bar: 12345, + baz: true, + qux: null, + quux: ["corge"], + }; + + const experimentCleanup = await ExperimentFakes.enrollWithFeatureConfig( + { + featureId: TYPED_FEATURE.featureId, + value: { + string: "hello, world", + int: 12345, + boolean: true, + json, + }, + }, + { manager } + ); + + const defaultBranch = Services.prefs.getDefaultBranch(null); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.string"), + Services.prefs.PREF_STRING + ); + Assert.equal( + defaultBranch.getStringPref("nimbus.test-only.types.string"), + "hello, world" + ); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.int"), + Services.prefs.PREF_INT + ); + Assert.equal(defaultBranch.getIntPref("nimbus.test-only.types.int"), 12345); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.boolean"), + Services.prefs.PREF_BOOL + ); + Assert.equal( + defaultBranch.getBoolPref("nimbus.test-only.types.boolean"), + true + ); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.json"), + Services.prefs.PREF_STRING + ); + + const jsonPrefValue = JSON.parse( + defaultBranch.getStringPref("nimbus.test-only.types.json") + ); + + Assert.deepEqual(json, jsonPrefValue); + + await experimentCleanup(); + featureCleanup(); + + await assertEmptyStore(store, { cleanup: true }); +}); + +add_task(async function test_setPref_types_restore() { + const featureCleanup = ExperimentTestUtils.addTestFeatures(TYPED_FEATURE); + + const json = { + foo: "foo", + bar: 12345, + baz: true, + qux: null, + quux: ["corge"], + }; + + { + const store = ExperimentFakes.store(); + const manager = ExperimentFakes.manager(store); + + await manager.onStartup(); + await assertEmptyStore(store); + + await ExperimentFakes.enrollWithFeatureConfig( + { + featureId: TYPED_FEATURE.featureId, + value: { + string: "hello, world", + int: 12345, + boolean: true, + json, + }, + }, + { manager } + ); + + store._store.saveSoon(); + await store._store.finalize(); + + for (const varDef of Object.values(TYPED_FEATURE.manifest.variables)) { + Services.prefs.deleteBranch(varDef.setPref.pref); + } + + removePrefObservers(manager); + assertNoObservers(manager); + } + + const store = ExperimentFakes.store(); + const manager = ExperimentFakes.manager(store); + + await manager.onStartup(); + + const defaultBranch = Services.prefs.getDefaultBranch(null); + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.string"), + Services.prefs.PREF_STRING + ); + Assert.equal( + defaultBranch.getStringPref("nimbus.test-only.types.string"), + "hello, world" + ); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.int"), + Services.prefs.PREF_INT + ); + Assert.equal(defaultBranch.getIntPref("nimbus.test-only.types.int"), 12345); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.boolean"), + Services.prefs.PREF_BOOL + ); + Assert.equal( + defaultBranch.getBoolPref("nimbus.test-only.types.boolean"), + true + ); + + Assert.equal( + defaultBranch.getPrefType("nimbus.test-only.types.json"), + Services.prefs.PREF_STRING + ); + + const jsonPrefValue = JSON.parse( + defaultBranch.getStringPref("nimbus.test-only.types.json") + ); + + Assert.deepEqual(json, jsonPrefValue); + + const enrollment = store.getExperimentForFeature(TYPED_FEATURE.featureId); + manager.unenroll(enrollment.slug); + store._deleteForTests(enrollment.slug); + + await assertEmptyStore(store, { cleanup: true }); + featureCleanup(); +}); -- cgit v1.2.3