Bug 1831906 - Add release notes link to update modal prompts. r=bytesized,omc-reviewers,application-update-reviewers,jprickett

Differential Revision: https://phabricator.services.mozilla.com/D177410
This commit is contained in:
Shane Hughes 2023-06-08 15:48:01 +00:00
Родитель fcc5b10abb
Коммит 52d6ffecf9
8 изменённых файлов: 125 добавлений и 24 удалений

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

@ -19,6 +19,7 @@ pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/aurora/
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%beta/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
pref("app.releaseNotesURL.aboutDialog", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%beta/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-desktop&utm_campaign=about-dialog");
pref("app.releaseNotesURL.prompt", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=updateprompt");
// The number of days a binary is permitted to be old
// without checking for an update. This assumes that

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

@ -20,6 +20,7 @@ pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/nightly
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
pref("app.releaseNotesURL.aboutDialog", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-desktop&utm_campaign=about-dialog");
pref("app.releaseNotesURL.prompt", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=updateprompt");
// The number of days a binary is permitted to be old
// without checking for an update. This assumes that

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

@ -32,6 +32,7 @@ pref("app.update.promptWaitTime", 691200);
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
pref("app.releaseNotesURL.aboutDialog", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-desktop&utm_campaign=about-dialog");
#endif
pref("app.releaseNotesURL.prompt", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=updateprompt");
// The number of days a binary is permitted to be old
// without checking for an update. This assumes that

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

@ -936,6 +936,12 @@ const PanelUI = {
popupnotification.setAttribute("icon", notification.options.popupIconURL);
popupnotification.setAttribute("hasicon", true);
}
if (notification.options.learnMoreURL) {
popupnotification.setAttribute(
"learnmoreurl",
notification.options.learnMoreURL
);
}
popupnotification.notification = notification;
popupnotification.show();

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

@ -1564,3 +1564,24 @@ opaqueResponseBlocking:
description: Whether filtering of internal responses in the parent ORB is enabled
type: int
setPref: "browser.opaqueResponseBlocking.filterFetchResponse"
updatePrompt:
description: Prefs to control content and behavior of update notifications
owner: omc@mozilla.com
hasExposure: true
exposureDescription: >-
Exposure is sent at most once per browsing session when an update
notification prompt is displayed.
isEarlyStartup: true
variables:
showReleaseNotesLink:
type: boolean
description: >-
If true, the "Learn More" link will be shown in the update prompt. If
false or omitted, the link will only be shown for supported locales.
releaseNotesURL:
type: string
fallbackPref: app.releaseNotesURL.prompt
description: >-
Template for the URL opened when the user clicks the "Learn More" link
in the update prompt. If an empty string, the link will not be shown.

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

@ -10,6 +10,7 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.sys.mjs",
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
});
XPCOMUtils.defineLazyServiceGetter(
@ -121,8 +122,11 @@ export var UpdateListener = {
// update is found this pref is cleared and the notification won't be shown.
let url = Services.prefs.getCharPref(PREF_APP_UPDATE_UNSUPPORTED_URL, null);
if (url) {
this.showUpdateNotification("unsupported", true, true, win =>
this.openUnsupportedUpdateUrl(win, url)
this.showUpdateNotification(
"unsupported",
win => this.openUnsupportedUpdateUrl(win, url),
true,
{ dismissed: true }
);
}
},
@ -181,13 +185,38 @@ export var UpdateListener = {
win.openURL(detailsURL);
},
showUpdateNotification(
type,
mainActionDismiss,
dismissed,
mainAction,
beforeShowDoorhanger
) {
getReleaseNotesUrl(update) {
try {
// Release notes are enabled by default for EN locales only, but can be
// enabled for other locales within an experiment.
if (
!Services.locale.appLocaleAsBCP47.startsWith("en") &&
!lazy.NimbusFeatures.updatePrompt.getVariable("showReleaseNotesLink")
) {
return null;
}
// The release notes URL is set in the pref app.releaseNotesURL.prompt,
// but can also be overridden by an experiment.
let url = lazy.NimbusFeatures.updatePrompt.getVariable("releaseNotesURL");
if (url) {
let versionString = update.appVersion;
switch (update.channel) {
case "aurora":
case "beta":
versionString += "beta";
break;
}
url = Services.urlFormatter.formatURL(
url.replace("%VERSION%", versionString)
);
}
return url || null;
} catch (error) {
return null;
}
},
showUpdateNotification(type, mainAction, mainActionDismiss, options = {}) {
const addTelemetry = id => {
// No telemetry for the "downloading" state.
if (type !== "downloading") {
@ -218,9 +247,9 @@ export var UpdateListener = {
"update-" + type,
action,
secondaryAction,
{ dismissed, beforeShowDoorhanger }
options
);
if (dismissed) {
if (options.dismissed) {
addTelemetry("UPDATE_NOTIFICATION_BADGE_SHOWN");
} else {
addTelemetry("UPDATE_NOTIFICATION_SHOWN");
@ -234,22 +263,35 @@ export var UpdateListener = {
if (!dismissed) {
this.restartDoorhangerShown = true;
}
this.showUpdateNotification(notification, true, dismissed, () =>
this.requestRestart()
this.showUpdateNotification(
notification,
() => this.requestRestart(),
true,
{ dismissed }
);
},
showUpdateAvailableNotification(update, dismissed) {
this.showUpdateNotification("available", false, dismissed, () => {
let learnMoreURL = this.getReleaseNotesUrl(update);
this.showUpdateNotification(
"available",
// This is asynchronous, but we are just going to kick it off.
lazy.AppUpdateService.downloadUpdate(update, true);
});
() => lazy.AppUpdateService.downloadUpdate(update, true),
false,
{ dismissed, learnMoreURL }
);
lazy.NimbusFeatures.updatePrompt.recordExposureEvent({ once: true });
},
showManualUpdateNotification(update, dismissed) {
this.showUpdateNotification("manual", false, dismissed, win =>
this.openManualUpdateUrl(win)
let learnMoreURL = this.getReleaseNotesUrl(update);
this.showUpdateNotification(
"manual",
win => this.openManualUpdateUrl(win),
false,
{ dismissed, learnMoreURL }
);
lazy.NimbusFeatures.updatePrompt.recordExposureEvent({ once: true });
},
showUnsupportedUpdateNotification(update, dismissed) {
@ -265,19 +307,25 @@ export var UpdateListener = {
url != Services.prefs.getCharPref(PREF_APP_UPDATE_UNSUPPORTED_URL, null)
) {
Services.prefs.setCharPref(PREF_APP_UPDATE_UNSUPPORTED_URL, url);
this.showUpdateNotification("unsupported", true, dismissed, win =>
this.openUnsupportedUpdateUrl(win, url)
this.showUpdateNotification(
"unsupported",
win => this.openUnsupportedUpdateUrl(win, url),
true,
{ dismissed }
);
}
},
showUpdateDownloadingNotification() {
this.showUpdateNotification("downloading", true, true, () => {
this.showUpdateNotification(
"downloading",
// The user clicked on the "Downloading update" app menu item.
// Code in browser/components/customizableui/content/panelUI.js
// receives the following notification and opens the about dialog.
Services.obs.notifyObservers(null, "show-update-progress");
});
() => Services.obs.notifyObservers(null, "show-update-progress"),
true,
{ dismissed: true }
);
},
scheduleUpdateAvailableNotification(update) {

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

@ -4,17 +4,37 @@
"use strict";
add_task(async function doorhanger_bc_downloadOptIn() {
await SpecialPowers.pushPrefEnv({
set: [
[
"app.releaseNotesURL.prompt",
`${URL_HOST}/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=updateprompt`,
],
],
});
await UpdateUtils.setAppUpdateAutoEnabled(false);
let version = "9999999.0";
let params = {
checkAttempts: 1,
queryString: "&invalidCompleteSize=1&promptWaitTime=0",
version,
};
await runDoorhangerUpdateTest(params, [
{
notificationId: "update-available",
button: n => n.querySelector(".popup-notification-learnmore-link"),
checkActiveUpdate: null,
pageURLs: {
manual: `${URL_HOST}/${Services.locale.appLocaleAsBCP47}/firefox/${version}/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=updateprompt`,
},
},
{
notificationId: "update-available",
button: "button",
checkActiveUpdate: null,
popupShown: true,
},
{
notificationId: "update-restart",

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

@ -263,7 +263,7 @@ async function setAppUpdateAutoEnabledHelper(enabled) {
* @param notificationId
* The ID of the notification to get the button for.
* @param button
* The anonid of the button to get.
* The anonid of the button to get, or a function to find it.
* @return The button element.
*/
function getNotificationButton(win, notificationId, button) {
@ -271,6 +271,9 @@ function getNotificationButton(win, notificationId, button) {
`appMenu-${notificationId}-notification`
);
ok(!notification.hidden, `${notificationId} notification is showing`);
if (typeof button === "function") {
return button(notification);
}
return notification[button];
}