Skip to content

Commit

Permalink
Bug 1898361 - Add ability to disable WNP via whatsNewPage nimbus feat…
Browse files Browse the repository at this point in the history
…ure r=aminomancer,omc-reviewers,firefox-desktop-core-reviewers CLOSED TREE

Differential Revision: https://phabricator.services.mozilla.com/D212492
  • Loading branch information
halemu committed Jul 2, 2024
1 parent ece439e commit 75fae2d
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 17 deletions.
2 changes: 2 additions & 0 deletions browser/app/profile/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3139,6 +3139,8 @@ pref("startup.homepage_override_url_nimbus", "");
// These prefs are referring to the Fx update version
pref("startup.homepage_override_nimbus_maxVersion", "");
pref("startup.homepage_override_nimbus_minVersion", "");
// Pref to disable all What's New pages
pref("startup.homepage_override_nimbus_disable_wnp", false);

// Pref to enable the content relevancy feature.
pref("toolkit.contentRelevancy.enabled", false);
Expand Down
50 changes: 33 additions & 17 deletions browser/components/BrowserContentHandler.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,20 @@ function needHomepageOverride(updateMilestones = true) {
* The default override page
* @param nimbusOverridePage
* Nimbus provided URL
* @param disableWnp
* Boolean, disables all WNPs if true
* @return The override page.
*/
function getPostUpdateOverridePage(
update,
defaultOverridePage,
nimbusOverridePage
nimbusOverridePage,
disableWnp
) {
if (disableWnp) {
return "";
}

update = update.QueryInterface(Ci.nsIWritablePropertyBag);
let actions = update.getProperty("actions");
// When the update doesn't specify actions fallback to the original behavior
Expand Down Expand Up @@ -784,15 +791,22 @@ nsBrowserContentHandler.prototype = {
"startup.homepage_override_nimbus_minVersion",
""
);
// Pref used to disable all WNPs
const disableWNP = Services.prefs.getBoolPref(
"startup.homepage_override_nimbus_disable_wnp",
false
);
let nimbusWNP;
// minVersion and maxVersion optional variables
const versionMatch =
(!maxVersion ||
Services.vc.compare(update.appVersion, maxVersion) <= 0) &&
(!minVersion ||
Services.vc.compare(update.appVersion, minVersion) >= 0);

// The update version should be less than or equal to maxVersion and
// greater or equal to minVersion set by the experiment.
if (
nimbusOverrideUrl &&
Services.vc.compare(update.appVersion, maxVersion) <= 0 &&
Services.vc.compare(update.appVersion, minVersion) >= 0
) {
if (nimbusOverrideUrl && versionMatch) {
try {
let uri = Services.io.newURI(nimbusOverrideUrl);
// Only allow https://www.mozilla.org and https://www.mozilla.com
Expand All @@ -816,19 +830,21 @@ nsBrowserContentHandler.prototype = {
overridePage = getPostUpdateOverridePage(
update,
overridePage,
nimbusWNP
nimbusWNP,
disableWNP
);
// Record a Nimbus exposure event for the whatsNewPage feature.
// The override page could be set in 3 ways: 1. set by Nimbus 2.
// set by the update file(openURL) 3. The default evergreen page(Set by the
// startup.homepage_override_url pref, could be different
// depending on the Fx channel). This is done to record that the
// control cohort could have seen the experimental What's New Page
// (and will instead see the default What's New Page).
// recordExposureEvent only records an event if the user is
// enrolled in an experiment or rollout on the whatsNewPage
// feature, so it's safe to call it unconditionally.
if (overridePage) {
// The override page could be set in 3 ways: 1. set by Nimbus; 2.
// set by the update file (openURL); 3. defaulting to the
// evergreen page (set by the startup.homepage_override_url pref,
// value depends on the Fx channel). This is done to record that
// the control cohort could have seen the experimental What's New
// Page (and will instead see the default What's New Page, or
// won't see a WNP if the experiment disabled it by setting
// disable_wnp). `recordExposureEvent` only records an event if
// the user is enrolled in an experiment or rollout on the
// whatsNewPage feature, so it's safe to call it unconditionally.
if (overridePage || (versionMatch && disableWNP)) {
let nimbusWNPFeature = lazy.NimbusFeatures.whatsNewPage;
nimbusWNPFeature
.ready()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ prefs = [
["browser_whats_new_page.js"]

["include:./browser_whats_new_page_nimbus.toml"]
["include:./browser_whats_new_page_nimbus_disable.toml"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

add_task(async function nimbus_whats_new_page_disable() {
// The test harness will use the current tab and remove the tab's history.
gBrowser.selectedTab = gBrowser.tabs[0];
await TestUtils.waitForCondition(
() =>
gBrowser.selectedBrowser &&
gBrowser.selectedBrowser.currentURI &&
gBrowser.selectedBrowser.currentURI.spec == "about:blank",
`Expected about:blank but got ${gBrowser.selectedBrowser.currentURI.spec}`
);
is(
gBrowser.selectedBrowser.currentURI.spec,
"about:blank",
"What's New pages should be disabled"
);

let um = Cc["@mozilla.org/updates/update-manager;1"].getService(
Ci.nsIUpdateManager
);
await TestUtils.waitForCondition(
async () => !(await um.getReadyUpdate()),
"Waiting for the ready update to be removed"
);
ok(!(await um.getReadyUpdate()), "There should not be a ready update");
let history;
await TestUtils.waitForCondition(async () => {
history = await um.getHistory();
return !!history[0];
}, "Waiting for the ready update to be moved to the update history");
ok(!!history[0], "There should be an update in the update history");

// Leave no trace. Since this test modifies its support files put them back in
// their original state.
let alternatePath = Services.prefs.getCharPref("app.update.altUpdateDirPath");
let testRoot = Services.prefs.getCharPref("mochitest.testRoot");
let relativePath = alternatePath.substring("<test-root>".length);
if (AppConstants.platform == "win") {
relativePath = relativePath.replace(/\//g, "\\");
}
alternatePath = testRoot + relativePath;
let updateDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
updateDir.initWithPath(alternatePath);

let activeUpdateFile = updateDir.clone();
activeUpdateFile.append("active-update.xml");
await TestUtils.waitForCondition(
() => !activeUpdateFile.exists(),
"Waiting until the active-update.xml file does not exist"
);

let updatesFile = updateDir.clone();
updatesFile.append("updates.xml");
await TestUtils.waitForCondition(
() => updatesFile.exists(),
"Waiting until the updates.xml file exists"
);

let fos = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
Ci.nsIFileOutputStream
);
let flags =
FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;

let stateSucceeded = "succeeded\n";
let updateStatusFile = updateDir.clone();
updateStatusFile.append("updates");
updateStatusFile.append("0");
updateStatusFile.append("update.status");
updateStatusFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
fos.init(updateStatusFile, flags, FileUtils.PERMS_FILE, 0);
fos.write(stateSucceeded, stateSucceeded.length);
fos.close();

let xmlContents =
'<?xml version="1.0"?><updates xmlns="http://www.mozilla.org/2005/' +
'app-update"><update xmlns="http://www.mozilla.org/2005/app-update" ' +
'appVersion="61.0" buildID="20990101111111" channel="test" ' +
'detailsURL="https://127.0.0.1/" displayVersion="1.0" installDate="' +
'1555716429454" isCompleteUpdate="true" name="What\'s New Page Test" ' +
'previousAppVersion="60.0" serviceURL="https://127.0.0.1/update.xml" ' +
'type="minor" platformVersion="99999999.0" actions="showURL" ' +
'openURL="https://example.com/|https://example.com/"><patch size="1" ' +
'type="complete" URL="https://127.0.0.1/complete.mar" ' +
'selected="true" state="pending"/></update></updates>\n';
activeUpdateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
fos.init(activeUpdateFile, flags, FileUtils.PERMS_FILE, 0);
fos.write(xmlContents, xmlContents.length);
fos.close();

updatesFile.remove(false);
Cc["@mozilla.org/updates/update-manager;1"]
.getService(Ci.nsIUpdateManager)
.internal.reload(false);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[DEFAULT]

["browser_whats_new_page_nimbus_disable.js"]
# These are prefs set by nimbus to be used for What's new pages
prefs = ["startup.homepage_override_url_nimbus='https://www.mozilla.org/en-US/projects/firefox/whatsnew/|https://www.mozilla.org/en-US/projects/firefox/whatsnew/'",
"startup.homepage_override_nimbus_maxVersion='99999999.0'", "startup.homepage_override_nimbus_disable_wnp=true"]
8 changes: 8 additions & 0 deletions toolkit/components/nimbus/FeatureManifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,14 @@ whatsNewPage:
setPref:
branch: user
pref: startup.homepage_override_nimbus_minVersion
disableWNP:
description: >-
Block all What's New Pages. Used to compare no-WNP control branches to
WNP treatment branches.
type: boolean
setPref:
branch: user
pref: startup.homepage_override_nimbus_disable_wnp

pbNewtab:
description: "A Firefox Messaging System message for the pbNewtab message channel"
Expand Down

0 comments on commit 75fae2d

Please sign in to comment.