Bug 1815898 - Inform users about Colorway theme removal - part 1 - notification bar, r=fluent-reviewers,bolsson,rpl
Differential Revision: https://phabricator.services.mozilla.com/D243441
This commit is contained in:
@@ -47,6 +47,7 @@ category browser-idle-startup resource:///modules/UrlbarSearchTermsPersistence.s
|
||||
category browser-idle-startup resource:///modules/ShoppingUtils.sys.mjs ShoppingUtils.init
|
||||
category browser-idle-startup moz-src:///browser/components/search/SERPCategorization.sys.mjs SERPCategorization.init
|
||||
category browser-idle-startup resource://gre/modules/ContentRelevancyManager.sys.mjs ContentRelevancyManager.init
|
||||
category browser-idle-startup resource://gre/modules/ColorwayThemeMigration.sys.mjs ColorwayThemeMigration.maybeWarn
|
||||
#ifdef MOZ_UPDATER
|
||||
category browser-idle-startup resource://gre/modules/UpdateListener.sys.mjs UpdateListener.maybeShowUnsupportedNotification
|
||||
#endif
|
||||
|
||||
@@ -108,3 +108,8 @@ webext-site-perms-header-unsigned-with-perms = Add { $extension }? This extensio
|
||||
|
||||
webext-site-perms-midi = Access MIDI devices
|
||||
webext-site-perms-midi-sysex = Access MIDI devices with SysEx support
|
||||
|
||||
## Colorway theme migration
|
||||
|
||||
webext-colorway-theme-migration-notification-message = <b>Your colorway theme was removed.</b> { -brand-shorter-name } updated its colorways collection. You can find the latest versions on the add-ons site.
|
||||
webext-colorway-theme-migration-notification-button = Get updated colorways
|
||||
|
||||
102
toolkit/mozapps/extensions/ColorwayThemeMigration.sys.mjs
Normal file
102
toolkit/mozapps/extensions/ColorwayThemeMigration.sys.mjs
Normal file
@@ -0,0 +1,102 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
|
||||
AddonSettings: "resource://gre/modules/addons/AddonSettings.sys.mjs",
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
||||
});
|
||||
|
||||
const CLEANUP_UNKNOWN = 0;
|
||||
const CLEANUP_COMPLETED = 1;
|
||||
const CLEANUP_COMPLETED_WITH_BUILTIN = 2;
|
||||
|
||||
// Cleanup any colorway builtin theme that may still be installed.
|
||||
async function uninstallAllColorwayBuiltinThemes(activeThemeID) {
|
||||
const CLEANUP_PREF = "extensions.colorway-builtin-themes-cleanup";
|
||||
|
||||
if (
|
||||
Services.prefs.getIntPref(CLEANUP_PREF, CLEANUP_UNKNOWN) != CLEANUP_UNKNOWN
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let builtinColorwayThemeFound = false;
|
||||
let activeThemeUninstalling = false;
|
||||
|
||||
const themes = await lazy.AddonManager.getAddonsByTypes(["theme"]);
|
||||
for (const theme of themes) {
|
||||
if (theme.isBuiltinColorwayTheme) {
|
||||
builtinColorwayThemeFound = true;
|
||||
if (theme.id === activeThemeID) {
|
||||
activeThemeUninstalling = true;
|
||||
}
|
||||
|
||||
theme.uninstall();
|
||||
}
|
||||
}
|
||||
|
||||
Services.prefs.setIntPref(
|
||||
CLEANUP_PREF,
|
||||
builtinColorwayThemeFound
|
||||
? CLEANUP_COMPLETED_WITH_BUILTIN
|
||||
: CLEANUP_COMPLETED
|
||||
);
|
||||
|
||||
return activeThemeUninstalling;
|
||||
}
|
||||
|
||||
export const ColorwayThemeMigration = {
|
||||
maybeWarn: async () => {
|
||||
const activeThemeID = Services.prefs.getCharPref(
|
||||
"extensions.activeThemeID",
|
||||
""
|
||||
);
|
||||
|
||||
// Let's remove all the existing colorwy builtin themes.
|
||||
const activeThemeUninstalled = await uninstallAllColorwayBuiltinThemes(
|
||||
activeThemeID
|
||||
).catch(err => {
|
||||
console.warn("Error on uninstalling all colorways builtin themes", err);
|
||||
});
|
||||
|
||||
if (!activeThemeUninstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This can go async.
|
||||
lazy.AddonManager.getAddonByID(lazy.AddonSettings.DEFAULT_THEME_ID).then(
|
||||
addon => addon.enable()
|
||||
);
|
||||
|
||||
const win = lazy.BrowserWindowTracker.getTopWindow();
|
||||
win.MozXULElement.insertFTLIfNeeded("toolkit/global/extensions.ftl");
|
||||
|
||||
win.gNotificationBox.appendNotification(
|
||||
"colorway-theme-migration",
|
||||
{
|
||||
label: {
|
||||
"l10n-id": "webext-colorway-theme-migration-notification-message",
|
||||
},
|
||||
priority: win.gNotificationBox.PRIORITY_INFO_MEDIUM,
|
||||
},
|
||||
[
|
||||
{
|
||||
supportPage: "colorways",
|
||||
},
|
||||
{
|
||||
"l10n-id": "webext-colorway-theme-migration-notification-button",
|
||||
callback: () => {
|
||||
win.openTrustedLinkIn(
|
||||
"https://addons.mozilla.org/firefox/collections/4757633/colorways/",
|
||||
"tab"
|
||||
);
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -71,6 +71,7 @@ EXTRA_JS_MODULES += [
|
||||
"amManager.sys.mjs",
|
||||
"amWebAPI.sys.mjs",
|
||||
"Blocklist.sys.mjs",
|
||||
"ColorwayThemeMigration.sys.mjs",
|
||||
"LightweightThemeManager.sys.mjs",
|
||||
]
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ support-files = ["head_abuse_report.js"]
|
||||
["browser_colorwaybuiltins_migration.js"]
|
||||
run-if = ["appname == 'firefox'"]
|
||||
|
||||
["browser_colorwaybuiltins_notification.js"]
|
||||
run-if = ["appname == 'firefox'"]
|
||||
|
||||
["browser_dragdrop.js"]
|
||||
skip-if = ["true"] # Bug 1626824
|
||||
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
"use strict";
|
||||
|
||||
const { AddonTestUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/AddonTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
const { ColorwayThemeMigration } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/ColorwayThemeMigration.sys.mjs"
|
||||
);
|
||||
|
||||
AddonTestUtils.initMochitest(this);
|
||||
|
||||
const CLEANUP_PREF = "extensions.colorway-builtin-themes-cleanup";
|
||||
const NON_COLORWAY_THEME_ID = "test-non@colorway.org";
|
||||
const COLORWAY_THEME_ID = "test-colorway@mozilla.org";
|
||||
|
||||
function mockAsyncUninstallMethod(mockProviderAddon) {
|
||||
// Override the MockAddon uninstall method to mock the behavior
|
||||
// of uninstalling an XPIProvider add-on, for which uninstalling
|
||||
// is asynchonous and the add-on may not be gone right away
|
||||
// (unlike the MockProvider uninstall method which synchonously remove
|
||||
// the addon from the MockProvider).
|
||||
const mockUninstall = mockProviderAddon.uninstall.bind(mockProviderAddon);
|
||||
mockProviderAddon.uninstall = async () => {
|
||||
//
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
return mockUninstall();
|
||||
};
|
||||
}
|
||||
|
||||
function hasNotification() {
|
||||
return !!window.gNotificationBox.getNotificationWithValue(
|
||||
"colorway-theme-migration"
|
||||
);
|
||||
}
|
||||
|
||||
function closeNotification() {
|
||||
const notification = window.gNotificationBox.getNotificationWithValue(
|
||||
"colorway-theme-migration"
|
||||
);
|
||||
if (notification) {
|
||||
window.gNotificationBox.removeNotification(notification);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkColorwayBuiltinTheme(colorwayThemeExists) {
|
||||
const colorwayTheme = await AddonManager.getAddonByID(COLORWAY_THEME_ID);
|
||||
is(!!colorwayTheme, colorwayThemeExists, "The colorway theme exists");
|
||||
}
|
||||
|
||||
async function checkNonBuiltinTheme(nonColorwayThemeExists) {
|
||||
const nonColorwayTheme = await AddonManager.getAddonByID(
|
||||
NON_COLORWAY_THEME_ID
|
||||
);
|
||||
is(
|
||||
!!nonColorwayTheme,
|
||||
nonColorwayThemeExists,
|
||||
"The non colorway theme exists"
|
||||
);
|
||||
}
|
||||
|
||||
let gProvider;
|
||||
async function installThemes() {
|
||||
if (!gProvider) {
|
||||
gProvider = new MockProvider(["extension"]);
|
||||
}
|
||||
|
||||
const [mockNonColorwayTheme, mockColorwayTheme] = gProvider.createAddons([
|
||||
{
|
||||
id: NON_COLORWAY_THEME_ID,
|
||||
name: "Test Non Colorway theme",
|
||||
creator: { name: "Artist", url: "https://example.com/artist" },
|
||||
description: "A nice tree",
|
||||
type: "theme",
|
||||
isBuiltinColorwayTheme: false,
|
||||
isBuiltin: true,
|
||||
screenshots: [],
|
||||
},
|
||||
{
|
||||
id: COLORWAY_THEME_ID,
|
||||
name: "Test Colorway theme",
|
||||
creator: { name: "Artist", url: "https://example.com/artist" },
|
||||
description: "A nice tree",
|
||||
type: "theme",
|
||||
isBuiltinColorwayTheme: true,
|
||||
isBuiltin: true,
|
||||
screenshots: [],
|
||||
},
|
||||
]);
|
||||
|
||||
mockAsyncUninstallMethod(mockNonColorwayTheme);
|
||||
mockAsyncUninstallMethod(mockColorwayTheme);
|
||||
|
||||
await checkColorwayBuiltinTheme(true);
|
||||
await checkNonBuiltinTheme(true);
|
||||
}
|
||||
|
||||
add_setup(() => {
|
||||
// Make sure we do close the notificationbox when this test file has been fully run
|
||||
// (prevents the notificationbox to stay open when other mochitests may run on the
|
||||
// same application instance and trigger unexpected failures).
|
||||
registerCleanupFunction(closeNotification);
|
||||
});
|
||||
|
||||
add_task(async function no_colorway_themes() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:blank",
|
||||
},
|
||||
async function () {
|
||||
// Before running the test, let's close existing notifications.
|
||||
closeNotification();
|
||||
ok(!hasNotification(), "No notification found when the test is starting");
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CLEANUP_PREF, 0]],
|
||||
});
|
||||
|
||||
await ColorwayThemeMigration.maybeWarn();
|
||||
ok(!hasNotification(), "No notification shown with the default theme");
|
||||
|
||||
is(SpecialPowers.getIntPref(CLEANUP_PREF), 1, "The cleanup pref is set");
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function default_theme_no_notification() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:blank",
|
||||
},
|
||||
async function () {
|
||||
// Before running the test, let's close existing notifications.
|
||||
closeNotification();
|
||||
ok(!hasNotification(), "No notification found when the test is starting");
|
||||
|
||||
await installThemes();
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CLEANUP_PREF, 0]],
|
||||
});
|
||||
|
||||
// Default theme should not trigger the notification.
|
||||
const defaultTheme = await AddonManager.getAddonByID(
|
||||
"default-theme@mozilla.org"
|
||||
);
|
||||
ok(!!defaultTheme, "The default theme exists");
|
||||
await defaultTheme.enable();
|
||||
|
||||
const promiseUninstalled =
|
||||
AddonTestUtils.promiseAddonEvent("onUninstalled");
|
||||
|
||||
await ColorwayThemeMigration.maybeWarn();
|
||||
ok(!hasNotification(), "No notification shown with the default theme");
|
||||
|
||||
// No notification shown, but the colorway themes are gone.
|
||||
await promiseUninstalled;
|
||||
await checkColorwayBuiltinTheme(false);
|
||||
await checkNonBuiltinTheme(true);
|
||||
|
||||
is(
|
||||
SpecialPowers.getIntPref(CLEANUP_PREF),
|
||||
2,
|
||||
"The cleanup pref is set (builtin add-ons found)"
|
||||
);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function non_colorway_theme_no_notification() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:blank",
|
||||
},
|
||||
async function () {
|
||||
// Before running the test, let's close existing notifications.
|
||||
closeNotification();
|
||||
ok(!hasNotification(), "No notification found when the test is starting");
|
||||
|
||||
await installThemes();
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CLEANUP_PREF, 0]],
|
||||
});
|
||||
|
||||
// Let's force a non-colorway theme.
|
||||
await (await AddonManager.getAddonByID(NON_COLORWAY_THEME_ID)).enable();
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["extensions.activeThemeID", NON_COLORWAY_THEME_ID]],
|
||||
});
|
||||
|
||||
const promiseUninstalled =
|
||||
AddonTestUtils.promiseAddonEvent("onUninstalled");
|
||||
|
||||
await ColorwayThemeMigration.maybeWarn();
|
||||
ok(
|
||||
!hasNotification(),
|
||||
"No notification shown with a non-existing theme != colorway"
|
||||
);
|
||||
|
||||
// No notification shown, but the colorway themes are gone.
|
||||
await promiseUninstalled;
|
||||
await checkColorwayBuiltinTheme(false);
|
||||
await checkNonBuiltinTheme(true);
|
||||
|
||||
is(
|
||||
SpecialPowers.getIntPref(CLEANUP_PREF),
|
||||
2,
|
||||
"The cleanup pref is set (builtin add-ons found)"
|
||||
);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function colorway_theme_notification() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:blank",
|
||||
},
|
||||
async function () {
|
||||
// Before running the test, let's close existing notifications.
|
||||
closeNotification();
|
||||
ok(!hasNotification(), "No notification found when the test is starting");
|
||||
|
||||
await installThemes();
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[CLEANUP_PREF, 0]],
|
||||
});
|
||||
|
||||
// Mock an active colorway builtin theme.
|
||||
const mockColorwayTheme =
|
||||
await AddonManager.getAddonByID(COLORWAY_THEME_ID);
|
||||
await mockColorwayTheme.enable();
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["extensions.activeThemeID", COLORWAY_THEME_ID]],
|
||||
});
|
||||
|
||||
const promiseUninstalled =
|
||||
AddonTestUtils.promiseAddonEvent("onUninstalled");
|
||||
|
||||
await ColorwayThemeMigration.maybeWarn();
|
||||
ok(
|
||||
hasNotification(),
|
||||
"Notification shown with an active colorway builtin theme"
|
||||
);
|
||||
|
||||
await promiseUninstalled;
|
||||
await checkColorwayBuiltinTheme(false);
|
||||
await checkNonBuiltinTheme(true);
|
||||
|
||||
is(
|
||||
SpecialPowers.getIntPref(CLEANUP_PREF),
|
||||
2,
|
||||
"The cleanup pref is set (builtin add-ons found)"
|
||||
);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user