Bug 1730618 - Allow Nimbus to enable Firefox Suggest online and override the offline default. r=mythmon,preferences-reviewers,mstriemer

This reworks the fix to bug 1729776.

Currently Nimbus doesn't have a way to force the two suggestions prefs [1] on or
off. That might seem surprising since we've run experiments already. Initially
we defaulted the two prefs to true but we defaulted the separate feature-gate
pref [2] to false, and it was the feature-gate pref we controlled via Nimbus. At
some point we changed the defaults to false and then in Firefox flipped them to
true after showing the onboarding dialog. As a result we've never needed to
override the two suggestion prefs via Nimbus.

The problem now is that we default-enable offline (for US en users), so we set
all three prefs to true. For the online rollout, we need to keep the
feature-gate pref enabled but disable the suggestion prefs, and there's no way
to do that.

My first idea was to add new Nimbus variables to override the two suggestion
prefs. The prefs would keep their default true values but be overridden by
Nimbus. But that doesn't work because there's no way for Firefox to tell whether
the prefs are true because the user has opted in (overriding Nimbus) or because
they still have their default values. Setting the prefs to true on the user
branch doesn't have any effect because they're also true on the default branch.
Or maybe there's a way I don't know about to force them to true on the user
branch, but even if there were, it seems brittle to rely on a value being set on
the user branch to distinguish between the two cases. (This is a potential
problem for any prefs that are controlled by both Nimbus and the user. So far
the prefs we've been using via Nimbus have all been hidden feature-gate-type
things and implementation details.)

We already have a `quickSuggestScenario` variable. We currently use it only to
tell what we should send in the telemetry ping (bug 1729576) and whether some
parts of the prefs UI should be shown. This revision makes it much more
important by treating it as the source of truth for the user's scenario. It now
determines the default values of related prefs, including the two suggestions
prefs.

The logic is:

```
If quickSuggestScenario is non-null:
  scenario = quickSuggestScenario
Else (e.g., there's no rollout):
  If the user is US en:
    scenario = offline
  Else:
    scenario = history
```

After determining the scenario, it's set it as
`browser.urlbar.quicksuggest.scenario` on the default branch. There's an
existing pref observer in UrlbarPrefs, and I added a case for this pref so that
when it's updated we also update all the other prefs that depend on the
scenario. This way when the pref is set -- either due to Nimbus update or by
changing it on about:config -- all the other prefs stay in sync.

I kept the default value of `browser.urlbar.quicksuggest.scenario` but removed
it as the fallback for `quickSuggestScenario`. If it still both had a default
and remained the fallback, then it would be impossible to tell when Nimbus is
trying to override it, because any fetch of the value from Nimbus would just
return the fallback pref's value if there is no override.

I considered instead removing the default value and keeping it as the fallback.
The drawback of that is that unenrollments would not take effect until restart.
I actually tried this approach first, and in tests, after mock experiments were
unenrolled, the pref values remained what they were when the experiment was
active.

It might also be possible to not have the `browser.urlbar.quicksuggest.scenario`
pref at all. We could call NimbusFeatures directly to get the scenario. However,
currently we cache and access Nimbus variables through UrlbarPrefs, as we do
with prefs, and I don't want to add an inconsistency.

This revision also fixes bug 1730596 since it was easy to do given that I needed
a way to prevent indirect recursive updates to the scenario, and I can use that
for bug 1730596 too (the `_updatingFirefoxSuggestScenario` bool).

[1] `browser.urlbar.suggest.quicksuggest` and `browser.urlbar.suggest.quicksuggest.sponsored`
[2] `browser.urlbar.quicksuggest.enabled`

Differential Revision: https://phabricator.services.mozilla.com/D125511
This commit is contained in:
Drew Willcoxon 2021-09-16 18:28:02 +00:00
Родитель 42fc576ab9
Коммит f0b457683b
9 изменённых файлов: 363 добавлений и 119 удалений

Просмотреть файл

@ -1650,7 +1650,7 @@ BrowserGlue.prototype = {
ProcessHangMonitor.init();
UrlbarPrefs.maybeEnableOfflineQuickSuggest();
UrlbarPrefs.updateFirefoxSuggestScenario();
// A channel for "remote troubleshooting" code...
let channel = new WebChannel(

Просмотреть файл

@ -1925,16 +1925,21 @@ var gPrivacyPane = {
* Initializes the address bar section.
*/
_initAddressBar() {
// Update the Firefox Suggest section on Nimbus changes. Note that
// `onUpdate` passes the Nimbus feature name as its first arg but that is
// not the arg that `_updateFirefoxSuggestSection` expects, so we do not
// want to pass it on.
this._firefoxSuggestNimbusUpdate = () =>
// Update the Firefox Suggest section when Firefox Suggest's enabled status
// or scenario changes.
this._urlbarPrefObserver = {
onPrefChanged: pref => {
if (["quicksuggest.enabled", "quicksuggest.scenario"].includes(pref)) {
this._updateFirefoxSuggestSection();
NimbusFeatures.urlbar.onUpdate(this._firefoxSuggestNimbusUpdate);
window.addEventListener("unload", () =>
NimbusFeatures.urlbar.off(this._firefoxSuggestNimbusUpdate)
);
}
},
};
UrlbarPrefs.addObserver(this._urlbarPrefObserver);
window.addEventListener("unload", () => {
// UrlbarPrefs holds a weak reference to our observer, which is why we
// don't remove it on unload.
this._urlbarPrefObserver = null;
});
// Set up the sponsored checkbox. When the main checkbox is checked, the
// sponsored checkbox should be enabled and its checked status should
@ -1989,7 +1994,7 @@ var gPrivacyPane = {
// The main checkbox description discusses data collection, which we
// perform only in the "online" scenario. Hide it otherwise.
document.getElementById("firefoxSuggestSuggestionDescription").hidden =
UrlbarPrefs.get("quickSuggestScenario") != "online";
UrlbarPrefs.get("quicksuggest.scenario") != "online";
// Show the container.
this._updateFirefoxSuggestSponsoredCheckbox();
container.removeAttribute("hidden");

Просмотреть файл

@ -6,8 +6,8 @@
/**
* This module exports the UrlbarPrefs singleton, which manages preferences for
* the urlbar. It also provides access to urlbar Nimbus features as if they are
* preferences.
* the urlbar. It also provides access to urlbar Nimbus variables as if they are
* preferences, but only for variables with fallback prefs.
*/
var EXPORTED_SYMBOLS = ["UrlbarPrefs", "UrlbarPrefsObserver"];
@ -447,6 +447,7 @@ class Preferences {
"keyword.enabled",
"suggest.searches",
];
this._updatingFirefoxSuggestScenario = false;
NimbusFeatures.urlbar.onUpdate(() => this._onNimbusUpdate());
}
@ -527,37 +528,130 @@ class Preferences {
}
/**
* Depending on certain conditions [1], possibly enables on the default prefs
* branch the Firefox Suggest "offline" scenario, which means Firefox Suggest
* (quick suggest) will be fully enabled by default without showing onboarding
* and without sending data to Mozilla [2]. Users can opt out in the prefs UI,
* which will set overriding prefs on the user branch. Note that values set
* programatically on the default branch like this do not persist across app
* restarts, so this needs to be called on every startup until these pref
* values are codified in firefox.js.
* Sets the appropriate Firefox Suggest scenario based on the current Nimbus
* rollout (if any) and "hardcoded" rollouts (if any). The possible scenarios
* are:
*
* [1] Currently the conditions are: the user's home region must be US and
* their locale must be en-*
*
* [2] In contrast, the "online" scenario sends data to Mozilla and requires
* user opt-in via onboarding before Firefox Suggest is fully enabled.
* history
* This is the scenario when the user is not in any rollouts. Firefox
* Suggest suggestions are disabled.
* offline
* This is the scenario for the "offline" rollout. Firefox Suggest
* suggestions are enabled by default. Search strings and matching keywords
* are not included in related telemetry. The onboarding dialog is not
* shown.
* online
* This is the scenario for the "online" rollout. The onboarding dialog will
* be shown and the user must opt in to enable Firefox Suggest suggestions
* and related telemetry, which will include search strings and matching
* keywords.
*/
async maybeEnableOfflineQuickSuggest() {
// `Region.home` is null before init finishes, so await it.
async updateFirefoxSuggestScenario() {
// Make sure we don't re-enter this method while updating prefs. (Updates to
// prefs that are fallbacks for Nimbus variables trigger the pref observer
// in Nimbus, which triggers our Nimbus `onUpdate` callback, which calls
// this method again.) We also want to avoid event telemetry that's recorded
// on updates to the `suggest` prefs since that telemetry is intended to
// capture toggles made by the user on about:preferences.
if (this._updatingFirefoxSuggestScenario) {
return;
}
try {
this._updatingFirefoxSuggestScenario = true;
await this._updateFirefoxSuggestScenarioHelper();
} finally {
this._updatingFirefoxSuggestScenario = false;
}
}
async _updateFirefoxSuggestScenarioHelper() {
// We need to pick a scenario. If the user is in a Nimbus rollout, then
// Nimbus will define it. Otherwise the user may be in a "hardcoded" rollout
// depending on their region and locale. Finally, if the user is not in any
// rollouts, then the scenario is "history", which means no Firefox Suggest
// suggestions should appear.
//
// IMPORTANT: This relies on the `quickSuggestScenario` variable not having
// a `fallbackPref`. If it did, and if there were no Nimbus override, then
// Nimbus would just return the pref's value. The logic here would
// incorrectly assume that the user is in a Nimbus rollout when in fact it
// would only be fetching the pref value. You might think, But wait, I can
// define a fallback as long as there's no default value for it in
// firefox.js. That would work initially, but if the user is ever unenrolled
// from a Nimbus rollout, the default value set here would persist until
// restart, meaning Firefox would effectively ignore the unenrollment until
// then.
let scenario = this._nimbus.quickSuggestScenario;
if (!scenario) {
await Region.init();
if (
Region.home == "US" &&
Services.locale.appLocaleAsBCP47.substring(0, 2) == "en"
) {
let prefs = Services.prefs.getDefaultBranch("browser.urlbar.");
prefs.setBoolPref("quicksuggest.enabled", true);
prefs.setCharPref("quicksuggest.scenario", "offline");
prefs.setBoolPref("quicksuggest.shouldShowOnboardingDialog", false);
prefs.setBoolPref("suggest.quicksuggest", true);
prefs.setBoolPref("suggest.quicksuggest.sponsored", true);
// offline rollout for en locales in the US region
scenario = "offline";
} else {
// no rollout
scenario = "history";
}
}
let defaults = Services.prefs.getDefaultBranch("browser.urlbar.");
defaults.setCharPref("quicksuggest.scenario", scenario);
// At this point, `onPrefChange` fires for the `quicksuggest.scenario`
// change and it calls `_syncFirefoxSuggestPrefsFromScenario`.
}
_syncFirefoxSuggestPrefsFromScenario() {
// Note: Setting a pref that's listed as a fallback for a Nimbus variable
// will trigger the pref observer inside Nimbus and cause all
// `Nimbus.urlbar.onUpdate` callbacks to be called. Inside this class we
// guard against that by using `_updatingFirefoxSuggestScenario`, but keep
// it in mind.
let scenario = this.get("quicksuggest.scenario");
let defaults = Services.prefs.getDefaultBranch("browser.urlbar.");
let enabled = false;
switch (scenario) {
case "history":
defaults.setBoolPref("quicksuggest.shouldShowOnboardingDialog", true);
defaults.setBoolPref("suggest.quicksuggest", false);
defaults.setBoolPref("suggest.quicksuggest.sponsored", false);
break;
case "offline":
enabled = true;
defaults.setBoolPref("quicksuggest.shouldShowOnboardingDialog", false);
defaults.setBoolPref("suggest.quicksuggest", true);
defaults.setBoolPref("suggest.quicksuggest.sponsored", true);
break;
case "online":
enabled = true;
defaults.setBoolPref("quicksuggest.shouldShowOnboardingDialog", true);
defaults.setBoolPref("suggest.quicksuggest", false);
defaults.setBoolPref("suggest.quicksuggest.sponsored", false);
break;
default:
Cu.reportError(`Unrecognized Firefox Suggest scenario "${scenario}"`);
break;
}
// Set `quicksuggest.enabled` last so that if any observers depend on it
// specifically, all prefs will have been updated when they're called.
defaults.setBoolPref("quicksuggest.enabled", enabled);
}
/**
* @returns {boolean}
* Whether the Firefox Suggest scenario is being updated. While true,
* changes to related prefs should be ignored, depending on the observer.
* Telemetry intended to capture user changes to the prefs should not be
* recorded, for example.
*/
get updatingFirefoxSuggestScenario() {
return this._updatingFirefoxSuggestScenario;
}
/**
* Adds a preference observer. Observers are held weakly.
*
@ -608,6 +702,9 @@ class Preferences {
// Some prefs may influence others.
switch (pref) {
case "quicksuggest.scenario":
this._syncFirefoxSuggestPrefsFromScenario();
return;
case "showSearchSuggestionsFirst":
this.set(
"resultGroups",
@ -635,6 +732,8 @@ class Preferences {
this._map.delete(key);
}
this.__nimbus = null;
this.updateFirefoxSuggestScenario();
}
get _nimbus() {

Просмотреть файл

@ -270,7 +270,7 @@ class ProviderQuickSuggest extends UrlbarProvider {
let searchQuery = "";
let matchedKeywords = "";
let scenario = UrlbarPrefs.get("quickSuggestScenario");
let scenario = UrlbarPrefs.get("quicksuggest.scenario");
// Only collect the search query and matched keywords for "online" scenario.
// For other scenarios, those fields are set as empty strings.
if (scenario === "online") {
@ -318,18 +318,22 @@ class ProviderQuickSuggest extends UrlbarProvider {
onPrefChanged(pref) {
switch (pref) {
case "suggest.quicksuggest":
if (!UrlbarPrefs.updatingFirefoxSuggestScenario) {
Services.telemetry.recordEvent(
TELEMETRY_EVENT_CATEGORY,
"enable_toggled",
UrlbarPrefs.get(pref) ? "enabled" : "disabled"
);
}
break;
case "suggest.quicksuggest.sponsored":
if (!UrlbarPrefs.updatingFirefoxSuggestScenario) {
Services.telemetry.recordEvent(
TELEMETRY_EVENT_CATEGORY,
"sponsored_toggled",
UrlbarPrefs.get(pref) ? "enabled" : "disabled"
);
}
break;
}
}

Просмотреть файл

@ -31,19 +31,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
});
// This must be kept in sync with FeatureManifest.js. UrlbarPrefs.get() will
// throw an "unknown pref" error if a test enrolls in a mock experiment and hits
// a code path that accesses a Nimbus feature variable not defined here.
const DEFAULT_EXPERIMENT_FEATURE_VARIABLES = {
merinoEnabled: false,
quickSuggestEnabled: false,
quickSuggestNonSponsoredIndex: -1,
quickSuggestScenario: "history",
quickSuggestShouldShowOnboardingDialog: true,
quickSuggestShowOnboardingDialogAfterNRestarts: 0,
quickSuggestSponsoredIndex: -1,
};
var UrlbarTestUtils = {
/**
* This maps the categories used by the FX_URLBAR_SELECTED_RESULT_METHOD and
@ -823,13 +810,7 @@ var UrlbarTestUtils = {
* Enrolls in a mock Nimbus experiment.
*
* @param {object} [valueOverrides]
* Individual feature variables to override. By default, feature variables
* take their values from DEFAULT_EXPERIMENT_FEATURE_VARIABLES. Overridden
* by `recipe`.
* @param {object} [recipe]
* If given, this recipe is used as is.
* @param {string} [name]
* The name of the experiment.
* Values for feature variables.
* @returns {function}
* The experiment cleanup function (async).
*/
@ -838,10 +819,7 @@ var UrlbarTestUtils = {
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
enabled: true,
featureId: "urlbar",
value: Object.assign(
DEFAULT_EXPERIMENT_FEATURE_VARIABLES,
valueOverrides
),
value: valueOverrides,
});
return doExperimentCleanup;
},

Просмотреть файл

@ -11,10 +11,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
UrlbarQuickSuggest: "resource:///modules/UrlbarQuickSuggest.jsm",
});
const SHOWED_ONBOARDING_DIALOG_PREF =
"browser.urlbar.quicksuggest.showedOnboardingDialog";
const SEEN_RESTART_PREF = "browser.urlbar.quicksuggest.seenRestarts";
add_task(async function init() {
await UrlbarTestUtils.ensureQuickSuggestInit();
});
@ -23,24 +19,17 @@ add_task(async function init() {
// on the first restart. This tests that we can override it by configuring the
// `showOnboardingDialogOnNthRestart`
add_task(async function test_override_wait_after_n_restarts() {
// Set up prefs so that onboarding will be shown.
// Set up non-Nimbus prefs related to showing the onboarding.
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.quicksuggest.shouldShowOnboardingDialog", true],
[
"browser.urlbar.quicksuggest.quicksuggest.showedOnboardingDialog",
false,
],
["browser.urlbar.quicksuggest.showedOnboardingDialog", false],
["browser.urlbar.quicksuggest.seenRestarts", 0],
["browser.urlbar.suggest.quicksuggest", false],
["browser.urlbar.suggest.quicksuggest.sponsored", false],
],
});
await UrlbarTestUtils.withExperiment({
valueOverrides: {
quickSuggestEnabled: true,
quickSuggestShouldShowOnboardingDialog: true,
quickSuggestScenario: "online",
// Wait for 1 browser restart
quickSuggestShowOnboardingDialogAfterNRestarts: 1,
},
@ -51,7 +40,7 @@ add_task(async function test_override_wait_after_n_restarts() {
{ isSubDialog: true }
).then(() => info("Saw dialog"));
let prefPromise = TestUtils.waitForPrefChange(
SHOWED_ONBOARDING_DIALOG_PREF,
"browser.urlbar.quicksuggest.showedOnboardingDialog",
value => value === true
).then(() => info("Saw pref change"));
@ -73,16 +62,16 @@ add_task(async function test_override_wait_after_n_restarts() {
});
add_task(async function test_skip_onboarding_dialog() {
// Set up non-Nimbus prefs related to showing the onboarding.
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.suggest.quicksuggest", false],
[SHOWED_ONBOARDING_DIALOG_PREF, false],
[SEEN_RESTART_PREF, 0],
["browser.urlbar.quicksuggest.showedOnboardingDialog", false],
["browser.urlbar.quicksuggest.seenRestarts", 0],
],
});
await UrlbarTestUtils.withExperiment({
valueOverrides: {
quickSuggestEnabled: true,
quickSuggestScenario: "online",
quickSuggestShouldShowOnboardingDialog: false,
},
callback: async () => {
@ -92,7 +81,9 @@ add_task(async function test_skip_onboarding_dialog() {
await UrlbarQuickSuggest.maybeShowOnboardingDialog();
}
Assert.ok(
!Services.prefs.getBoolPref(SHOWED_ONBOARDING_DIALOG_PREF),
!Services.prefs.getBoolPref(
"browser.urlbar.quicksuggest.showedOnboardingDialog"
),
"The showed onboarding dialog pref should not be set"
);
},
@ -151,11 +142,44 @@ add_task(async function test_scenario_online() {
quickSuggestScenario: "online",
},
callback: () => {
Assert.equal(
UrlbarPrefs.get("quickSuggestScenario"),
"online",
"quickSuggestScenario online"
);
assertScenarioPrefs({
urlbarPrefs: {
// prefs
"quicksuggest.scenario": "online",
"quicksuggest.enabled": true,
"quicksuggest.shouldShowOnboardingDialog": true,
"suggest.quicksuggest": false,
"suggest.quicksuggest.sponsored": false,
// Nimbus variables
quickSuggestScenario: "online",
quickSuggestEnabled: true,
quickSuggestShouldShowOnboardingDialog: true,
},
defaults: [
{
name: "browser.urlbar.quicksuggest.scenario",
value: "online",
getter: "getCharPref",
},
{
name: "browser.urlbar.quicksuggest.enabled",
value: true,
},
{
name: "browser.urlbar.quicksuggest.shouldShowOnboardingDialog",
value: true,
},
{
name: "browser.urlbar.suggest.quicksuggest",
value: false,
},
{
name: "browser.urlbar.suggest.quicksuggest.sponsored",
value: false,
},
],
});
},
});
});
@ -166,11 +190,44 @@ add_task(async function test_scenario_offline() {
quickSuggestScenario: "offline",
},
callback: () => {
Assert.equal(
UrlbarPrefs.get("quickSuggestScenario"),
"offline",
"quickSuggestScenario offline"
);
assertScenarioPrefs({
urlbarPrefs: {
// prefs
"quicksuggest.scenario": "offline",
"quicksuggest.enabled": true,
"quicksuggest.shouldShowOnboardingDialog": false,
"suggest.quicksuggest": true,
"suggest.quicksuggest.sponsored": true,
// Nimbus variables
quickSuggestScenario: "offline",
quickSuggestEnabled: true,
quickSuggestShouldShowOnboardingDialog: false,
},
defaults: [
{
name: "browser.urlbar.quicksuggest.scenario",
value: "offline",
getter: "getCharPref",
},
{
name: "browser.urlbar.quicksuggest.enabled",
value: true,
},
{
name: "browser.urlbar.quicksuggest.shouldShowOnboardingDialog",
value: false,
},
{
name: "browser.urlbar.suggest.quicksuggest",
value: true,
},
{
name: "browser.urlbar.suggest.quicksuggest.sponsored",
value: true,
},
],
});
},
});
});
@ -181,15 +238,63 @@ add_task(async function test_scenario_history() {
quickSuggestScenario: "history",
},
callback: () => {
Assert.equal(
UrlbarPrefs.get("quickSuggestScenario"),
"history",
"quickSuggestScenario history"
);
assertScenarioPrefs({
urlbarPrefs: {
// prefs
"quicksuggest.scenario": "history",
"quicksuggest.enabled": false,
"quicksuggest.shouldShowOnboardingDialog": true,
"suggest.quicksuggest": false,
"suggest.quicksuggest.sponsored": false,
// Nimbus variables
quickSuggestScenario: "history",
quickSuggestEnabled: false,
quickSuggestShouldShowOnboardingDialog: true,
},
defaults: [
{
name: "browser.urlbar.quicksuggest.scenario",
value: "history",
getter: "getCharPref",
},
{
name: "browser.urlbar.quicksuggest.enabled",
value: false,
},
{
name: "browser.urlbar.quicksuggest.shouldShowOnboardingDialog",
value: true,
},
{
name: "browser.urlbar.suggest.quicksuggest",
value: false,
},
{
name: "browser.urlbar.suggest.quicksuggest.sponsored",
value: false,
},
],
});
},
});
});
function assertScenarioPrefs({ urlbarPrefs, defaults }) {
for (let [name, value] of Object.entries(urlbarPrefs)) {
Assert.equal(UrlbarPrefs.get(name), value, `UrlbarPrefs.get("${name}")`);
}
let prefs = Services.prefs.getDefaultBranch("");
for (let { name, getter, value } of defaults) {
Assert.equal(
prefs[getter || "getBoolPref"](name),
value,
`Default branch pref: ${name}`
);
}
}
function clearOnboardingPrefs() {
UrlbarPrefs.clear("suggest.quicksuggest");
UrlbarPrefs.clear("suggest.quicksuggest.sponsored");

Просмотреть файл

@ -46,7 +46,7 @@ const TELEMETRY_EVENT_CATEGORY = "contextservices.quicksuggest";
const EXPERIMENT_PREF = "browser.urlbar.quicksuggest.enabled";
const SUGGEST_PREF = "suggest.quicksuggest";
const DEFAULT_SCENARIO = UrlbarPrefs.get("quickSuggestScenario");
const DEFAULT_SCENARIO = UrlbarPrefs.get("quicksuggest.scenario");
// Spy for the custom impression/click sender
let spy;
@ -111,11 +111,12 @@ add_task(async function impression_online() {
// Make sure Merino is disabled so we don't hit the network.
merinoEnabled: false,
quickSuggestScenario: "online",
quickSuggestEnabled: true,
quickSuggestShouldShowOnboardingDialog: false,
},
callback: async () => {
spy.resetHistory();
UrlbarPrefs.set("suggest.quicksuggest", true);
UrlbarPrefs.set("suggest.quicksuggest.sponsored", true);
await BrowserTestUtils.withNewTab("about:blank", async () => {
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
@ -473,6 +474,57 @@ add_task(async function nimbusExposure() {
await doExperimentCleanup();
});
// The contextservices.quicksuggest enable_toggled and sponsored_toggled events
// should not be recorded when the scenario changes.
add_task(async function updateScenarioNoEvents() {
// Make sure the prefs don't have user values that would mask the default
// values set below.
UrlbarPrefs.clear("quicksuggest.scenario");
UrlbarPrefs.clear("suggest.quicksuggest");
UrlbarPrefs.clear("suggest.quicksuggest.sponsored");
Services.telemetry.clearEvents();
// check initial defaults
let defaults = Services.prefs.getDefaultBranch("browser.urlbar.");
Assert.equal(
defaults.getCharPref("quicksuggest.scenario"),
"offline",
"Default scenario is offline initially"
);
Assert.ok(
defaults.getBoolPref("suggest.quicksuggest"),
"suggest.quicksuggest is true initially"
);
Assert.ok(
defaults.getBoolPref("suggest.quicksuggest.sponsored"),
"suggest.quicksuggest.sponsored is true initially"
);
// set online
defaults.setCharPref("quicksuggest.scenario", "online");
Assert.ok(
!defaults.getBoolPref("suggest.quicksuggest"),
"suggest.quicksuggest is false after setting online scenario"
);
Assert.ok(
!defaults.getBoolPref("suggest.quicksuggest.sponsored"),
"suggest.quicksuggest.sponsored is false after setting online scenario"
);
TelemetryTestUtils.assertEvents([]);
// set back to offline
defaults.setCharPref("quicksuggest.scenario", "offline");
Assert.ok(
defaults.getBoolPref("suggest.quicksuggest"),
"suggest.quicksuggest is true after setting offline again"
);
Assert.ok(
defaults.getBoolPref("suggest.quicksuggest.sponsored"),
"suggest.quicksuggest.sponsored is true after setting offline again"
);
TelemetryTestUtils.assertEvents([]);
});
/**
* Checks the values of all the Quick Suggest scalars.
*

Просмотреть файл

@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Tests `UrlbarPrefs.maybeEnableOfflineQuickSuggest` in isolation.
// Tests `UrlbarPrefs.updateFirefoxSuggestScenario` in isolation under the
// assumption that the offline scenario should be enabled by default for US en.
"use strict";
@ -10,8 +11,8 @@ XPCOMUtils.defineLazyModuleGetters(this, {
Region: "resource://gre/modules/Region.jsm",
});
// All the prefs that `maybeEnableOfflineQuickSuggest` sets along with
// the expected default-branch values when offline is enabled and when it's not
// All the prefs that `updateFirefoxSuggestScenario` sets along with the
// expected default-branch values when offline is enabled and when it's not
// enabled.
const PREFS = [
{
@ -69,8 +70,8 @@ add_task(async function test() {
/**
* Sets the app's locale and region, calls
* `UrlbarPrefs.maybeEnableOfflineQuickSuggest`, and asserts that the pref
* values are correct.
* `UrlbarPrefs.updateFirefoxSuggestScenario`, and asserts that the pref values
* are correct.
*
* @param {string} options.locale
* The locale to simulate.
@ -92,7 +93,7 @@ async function doTest({ locale, home, expectedOfflineDefault }) {
// Set the region and locale, call the function, check the pref values.
Region._setHomeRegion(home, false);
await withLocales([locale], async () => {
await UrlbarPrefs.maybeEnableOfflineQuickSuggest();
await UrlbarPrefs.updateFirefoxSuggestScenario();
for (let { name, get, expectedOfflineValue, expectedOtherValue } of PREFS) {
let expectedValue = expectedOfflineDefault
? expectedOfflineValue

Просмотреть файл

@ -38,8 +38,8 @@ const FeatureManifest = {
"Whether Remote Settings is enabled as a quick suggest source",
},
quickSuggestScenario: {
// IMPORTANT: This should not have a fallbackPref. See UrlbarPrefs.jsm.
type: "string",
fallbackPref: "browser.urlbar.quicksuggest.scenario",
description:
"The Firefox Suggest scenario in which the user is enrolled",
enum: ["history", "offline", "online"],