Files
tubestation/browser/components/ProfileDataUpgrader.sys.mjs
Jonathan Sudiaman 0905650fec Bug 1963549 - Add profile migration to remove outdated sidebar attrs from XULStore. r=Gijs,sidebar-reviewers,firefox-desktop-core-reviewers ,sessionstore-reviewers,sthompson
There was some discussion on whether the XULStore data should be written back into Session Store or Prefs. My concern there is that since we no longer *write* to XULStore, there is a good chance that this data is outdated anyways, and we'd be overwriting data in other places that *are* up-to-date. My vote is to simply discard this data, it seems that users were already comfortable with clearing their xulstore.json, so it doesn't seem like an issue to do the same programmatically.

Differential Revision: https://phabricator.services.mozilla.com/D248476
2025-05-09 20:35:47 +00:00

904 lines
34 KiB
JavaScript

/* 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/. */
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
FirefoxBridgeExtensionUtils:
"resource:///modules/FirefoxBridgeExtensionUtils.sys.mjs",
LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs",
PlacesUIUtils: "resource:///modules/PlacesUIUtils.sys.mjs",
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
UsageReporting: "resource://gre/modules/UsageReporting.sys.mjs",
});
export let ProfileDataUpgrader = {
_migrateXULStoreForDocument(fromURL, toURL) {
Array.from(Services.xulStore.getIDsEnumerator(fromURL)).forEach(id => {
Array.from(Services.xulStore.getAttributeEnumerator(fromURL, id)).forEach(
attr => {
let value = Services.xulStore.getValue(fromURL, id, attr);
Services.xulStore.setValue(toURL, id, attr, value);
}
);
});
},
_migrateHashedKeysForXULStoreForDocument(docUrl) {
Array.from(Services.xulStore.getIDsEnumerator(docUrl))
.filter(id => id.startsWith("place:"))
.forEach(id => {
Services.xulStore.removeValue(docUrl, id, "open");
let hashedId = lazy.PlacesUIUtils.obfuscateUrlForXulStore(id);
Services.xulStore.setValue(docUrl, hashedId, "open", "true");
});
},
/**
* This method transforms data in the profile directory so that it can be
* used in the current version of Firefox. It is organized similar to
* typical database version upgrades: we are invoked with the version of the
* profile data on disk (`existingDataVersion`) and the version we expect/need
* (`newVersion`), and execute any necessary migrations.
*
* In practice, most of the migrations move user choices from one preference
* to another, or ensure that other mechanical file moves (e.g. of document
* URLs like browser.xhtml).
*
* If you're adding a new migration, you will need to increment
* APP_DATA_VERSION in BrowserGlue.sys.mjs' _migrateUI. That version is not
* in this module so that we can avoid loading this module entirely in common
* cases (Firefox startups where a profile is not upgraded).
*
* Note that this is invoked very early on startup and should try to avoid
* doing very expensive things immediately unless absolutely necessary. Some
* of the migrations will therefore set a pref or otherwise flag that their
* component needs to do more work later, perhaps during idle tasks or
* similar, to avoid front-loading the component initialization into this
* early part of startup. Of course, some of these migrations (e.g. to ensure
* that browser windows remember their sizes if the URL to browser.xhtml has
* changed) _need_ to run very early, and that is OK.
*
* @param {integer} existingDataVersion
* The version of the data in the profile.
* @param {integer} newVersion
* The version that the application expects/needs.
*/
// eslint-disable-next-line complexity
upgrade(existingDataVersion, newVersion) {
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
let xulStore = Services.xulStore;
if (existingDataVersion < 90) {
this._migrateXULStoreForDocument(
"chrome://browser/content/places/historySidebar.xul",
"chrome://browser/content/places/historySidebar.xhtml"
);
this._migrateXULStoreForDocument(
"chrome://browser/content/places/places.xul",
"chrome://browser/content/places/places.xhtml"
);
this._migrateXULStoreForDocument(
"chrome://browser/content/places/bookmarksSidebar.xul",
"chrome://browser/content/places/bookmarksSidebar.xhtml"
);
}
// Clear socks proxy values if they were shared from http, to prevent
// websocket breakage after bug 1577862 (see bug 969282).
if (
existingDataVersion < 91 &&
Services.prefs.getBoolPref("network.proxy.share_proxy_settings", false) &&
Services.prefs.getIntPref("network.proxy.type", 0) == 1
) {
let httpProxy = Services.prefs.getCharPref("network.proxy.http", "");
let httpPort = Services.prefs.getIntPref("network.proxy.http_port", 0);
let socksProxy = Services.prefs.getCharPref("network.proxy.socks", "");
let socksPort = Services.prefs.getIntPref("network.proxy.socks_port", 0);
if (httpProxy && httpProxy == socksProxy && httpPort == socksPort) {
Services.prefs.setCharPref(
"network.proxy.socks",
Services.prefs.getCharPref("network.proxy.backup.socks", "")
);
Services.prefs.setIntPref(
"network.proxy.socks_port",
Services.prefs.getIntPref("network.proxy.backup.socks_port", 0)
);
}
}
if (existingDataVersion < 92) {
// privacy.userContext.longPressBehavior pref was renamed and changed to a boolean
let longpress = Services.prefs.getIntPref(
"privacy.userContext.longPressBehavior",
0
);
if (longpress == 1) {
Services.prefs.setBoolPref(
"privacy.userContext.newTabContainerOnLeftClick.enabled",
true
);
}
}
if (existingDataVersion < 93) {
// The Gecko Profiler Addon is now an internal component. Remove the old
// addon, and enable the new UI.
function enableProfilerButton(wasAddonActive) {
// Enable the feature pref. This will add it to the customization palette,
// but not to the the navbar.
Services.prefs.setBoolPref(
"devtools.performance.popup.feature-flag",
true
);
if (wasAddonActive) {
const { ProfilerMenuButton } = ChromeUtils.importESModule(
"resource://devtools/client/performance-new/popup/menu-button.sys.mjs"
);
if (!ProfilerMenuButton.isInNavbar()) {
ProfilerMenuButton.addToNavbar();
}
}
}
let addonPromise;
try {
addonPromise = lazy.AddonManager.getAddonByID(
"geckoprofiler@mozilla.com"
);
} catch (error) {
console.error(
"Could not access the AddonManager to upgrade the profile. This is most " +
"likely because the upgrader is being run from an xpcshell test where " +
"the AddonManager is not initialized."
);
}
Promise.resolve(addonPromise).then(addon => {
if (!addon) {
// Either the addon wasn't installed, or the call to getAddonByID failed.
return;
}
// Remove the old addon.
const wasAddonActive = addon.isActive;
addon
.uninstall()
.catch(console.error)
.then(() => enableProfilerButton(wasAddonActive))
.catch(console.error);
}, console.error);
}
// Clear unused socks proxy backup values - see bug 1625773.
if (existingDataVersion < 94) {
let backup = Services.prefs.getCharPref("network.proxy.backup.socks", "");
let backupPort = Services.prefs.getIntPref(
"network.proxy.backup.socks_port",
0
);
let socksProxy = Services.prefs.getCharPref("network.proxy.socks", "");
let socksPort = Services.prefs.getIntPref("network.proxy.socks_port", 0);
if (backup == socksProxy) {
Services.prefs.clearUserPref("network.proxy.backup.socks");
}
if (backupPort == socksPort) {
Services.prefs.clearUserPref("network.proxy.backup.socks_port");
}
}
if (existingDataVersion < 95) {
const oldPrefName = "media.autoplay.enabled.user-gestures-needed";
const oldPrefValue = Services.prefs.getBoolPref(oldPrefName, true);
const newPrefValue = oldPrefValue ? 0 : 1;
Services.prefs.setIntPref("media.autoplay.blocking_policy", newPrefValue);
Services.prefs.clearUserPref(oldPrefName);
}
if (existingDataVersion < 96) {
const oldPrefName = "browser.urlbar.openViewOnFocus";
const oldPrefValue = Services.prefs.getBoolPref(oldPrefName, true);
Services.prefs.setBoolPref(
"browser.urlbar.suggest.topsites",
oldPrefValue
);
Services.prefs.clearUserPref(oldPrefName);
}
if (existingDataVersion < 97) {
let userCustomizedWheelMax = Services.prefs.prefHasUserValue(
"general.smoothScroll.mouseWheel.durationMaxMS"
);
let userCustomizedWheelMin = Services.prefs.prefHasUserValue(
"general.smoothScroll.mouseWheel.durationMinMS"
);
if (!userCustomizedWheelMin && !userCustomizedWheelMax) {
// If the user has an existing profile but hasn't customized the wheel
// animation duration, they will now get the new default values. This
// condition used to set a migrationPercent pref to 0, so that users
// upgrading an older profile would gradually have their wheel animation
// speed migrated to the new values. However, that "gradual migration"
// was phased out by FF 86, so we don't need to set that pref anymore.
} else if (userCustomizedWheelMin && !userCustomizedWheelMax) {
// If they customized just one of the two, save the old value for the
// other one as well, because the two values go hand-in-hand and we
// don't want to move just one to a new value and leave the other one
// at a customized value. In both of these cases, we leave the "migration
// complete" percentage at 100, because they have customized this and
// don't need any further migration.
Services.prefs.setIntPref(
"general.smoothScroll.mouseWheel.durationMaxMS",
400
);
} else if (!userCustomizedWheelMin && userCustomizedWheelMax) {
// Same as above case, but for the other pref.
Services.prefs.setIntPref(
"general.smoothScroll.mouseWheel.durationMinMS",
200
);
} else {
// The last remaining case is if they customized both values, in which
// case also don't need to do anything; the user's customized values
// will be retained and respected.
}
}
if (existingDataVersion < 98) {
Services.prefs.clearUserPref("browser.search.cohort");
}
if (existingDataVersion < 99) {
Services.prefs.clearUserPref("security.tls.version.enable-deprecated");
}
if (existingDataVersion < 102) {
// In Firefox 83, we moved to a dynamic button, so it needs to be removed
// from default placement. This is done early enough that it doesn't
// impact adding new managed bookmarks.
const { CustomizableUI } = ChromeUtils.importESModule(
"resource:///modules/CustomizableUI.sys.mjs"
);
CustomizableUI.removeWidgetFromArea("managed-bookmarks");
}
// We have to rerun these because we had to use 102 on beta.
// They were 101 and 102 before.
if (existingDataVersion < 103) {
// Set a pref if the bookmarks toolbar was already visible,
// so we can keep it visible when navigating away from newtab
let bookmarksToolbarWasVisible =
Services.xulStore.getValue(
BROWSER_DOCURL,
"PersonalToolbar",
"collapsed"
) == "false";
if (bookmarksToolbarWasVisible) {
// Migrate the user to the "always visible" value. See firefox.js for
// the other possible states.
Services.prefs.setCharPref(
"browser.toolbars.bookmarks.visibility",
"always"
);
}
Services.xulStore.removeValue(
BROWSER_DOCURL,
"PersonalToolbar",
"collapsed"
);
Services.prefs.clearUserPref(
"browser.livebookmarks.migrationAttemptsLeft"
);
}
// For existing profiles, continue putting bookmarks in the
// "other bookmarks" folder.
if (existingDataVersion < 104) {
Services.prefs.setCharPref(
"browser.bookmarks.defaultLocation",
"unfiled"
);
}
// Renamed and flipped the logic of a pref to make its purpose more clear.
if (existingDataVersion < 105) {
const oldPrefName = "browser.urlbar.imeCompositionClosesPanel";
const oldPrefValue = Services.prefs.getBoolPref(oldPrefName, true);
Services.prefs.setBoolPref(
"browser.urlbar.keepPanelOpenDuringImeComposition",
!oldPrefValue
);
Services.prefs.clearUserPref(oldPrefName);
}
// Initialize the new browser.urlbar.showSuggestionsBeforeGeneral pref.
if (existingDataVersion < 106) {
lazy.UrlbarPrefs.initializeShowSearchSuggestionsFirstPref();
}
if (existingDataVersion < 107) {
// Migrate old http URIs for mailto handlers to their https equivalents.
// The handler service will do this. We need to wait with migrating
// until the handler service has started up, so just set a pref here.
const kPref = "browser.handlers.migrations";
// We might have set up another migration further up. Create an array,
// and drop empty strings resulting from the `split`:
let migrations = Services.prefs
.getCharPref(kPref, "")
.split(",")
.filter(x => !!x);
migrations.push("secure-mail");
Services.prefs.setCharPref(kPref, migrations.join(","));
}
if (existingDataVersion < 108) {
// Migrate old ctrlTab pref to new ctrlTab pref
let defaultValue = false;
let oldPrefName = "browser.ctrlTab.recentlyUsedOrder";
let oldPrefDefault = true;
// Use old pref value if the user used Ctrl+Tab before, elsewise use new default value
if (Services.prefs.getBoolPref("browser.engagement.ctrlTab.has-used")) {
let newPrefValue = Services.prefs.getBoolPref(
oldPrefName,
oldPrefDefault
);
Services.prefs.setBoolPref(
"browser.ctrlTab.sortByRecentlyUsed",
newPrefValue
);
} else {
Services.prefs.setBoolPref(
"browser.ctrlTab.sortByRecentlyUsed",
defaultValue
);
}
}
if (existingDataVersion < 109) {
// Migrate old pref to new pref
if (
Services.prefs.prefHasUserValue("signon.recipes.remoteRecipesEnabled")
) {
// Fetch the previous value of signon.recipes.remoteRecipesEnabled and assign it to signon.recipes.remoteRecipes.enabled.
Services.prefs.setBoolPref(
"signon.recipes.remoteRecipes.enabled",
Services.prefs.getBoolPref(
"signon.recipes.remoteRecipesEnabled",
true
)
);
//Then clear user pref
Services.prefs.clearUserPref("signon.recipes.remoteRecipesEnabled");
}
}
if (existingDataVersion < 120) {
// Migrate old titlebar bool pref to new int-based one.
const oldPref = "browser.tabs.drawInTitlebar";
const newPref = "browser.tabs.inTitlebar";
if (Services.prefs.prefHasUserValue(oldPref)) {
// We may have int prefs for builds between bug 1736518 and bug 1739539.
const oldPrefType = Services.prefs.getPrefType(oldPref);
if (oldPrefType == Services.prefs.PREF_BOOL) {
Services.prefs.setIntPref(
newPref,
Services.prefs.getBoolPref(oldPref) ? 1 : 0
);
} else {
Services.prefs.setIntPref(
newPref,
Services.prefs.getIntPref(oldPref)
);
}
Services.prefs.clearUserPref(oldPref);
}
}
if (existingDataVersion < 121) {
// Migrate stored uris and convert them to use hashed keys
this._migrateHashedKeysForXULStoreForDocument(BROWSER_DOCURL);
this._migrateHashedKeysForXULStoreForDocument(
"chrome://browser/content/places/bookmarksSidebar.xhtml"
);
this._migrateHashedKeysForXULStoreForDocument(
"chrome://browser/content/places/historySidebar.xhtml"
);
}
if (existingDataVersion < 122) {
// Migrate xdg-desktop-portal pref from old to new prefs.
try {
const oldPref = "widget.use-xdg-desktop-portal";
if (Services.prefs.getBoolPref(oldPref)) {
Services.prefs.setIntPref(
"widget.use-xdg-desktop-portal.file-picker",
1
);
Services.prefs.setIntPref(
"widget.use-xdg-desktop-portal.mime-handler",
1
);
}
Services.prefs.clearUserPref(oldPref);
} catch (ex) {}
}
// Bug 1745248: Due to multiple backouts, do not use UI Version 123
// as this version is most likely set for the Nightly channel
if (existingDataVersion < 124) {
// Migrate "extensions.formautofill.available" and
// "extensions.formautofill.creditCards.available" from old to new prefs
const oldFormAutofillModule = "extensions.formautofill.available";
const oldCreditCardsAvailable =
"extensions.formautofill.creditCards.available";
const newCreditCardsAvailable =
"extensions.formautofill.creditCards.supported";
const newAddressesAvailable =
"extensions.formautofill.addresses.supported";
if (Services.prefs.prefHasUserValue(oldFormAutofillModule)) {
let moduleAvailability = Services.prefs.getCharPref(
oldFormAutofillModule
);
if (moduleAvailability == "on") {
Services.prefs.setCharPref(newAddressesAvailable, moduleAvailability);
Services.prefs.setCharPref(
newCreditCardsAvailable,
Services.prefs.getBoolPref(oldCreditCardsAvailable) ? "on" : "off"
);
}
if (moduleAvailability == "off") {
Services.prefs.setCharPref(
newCreditCardsAvailable,
moduleAvailability
);
Services.prefs.setCharPref(newAddressesAvailable, moduleAvailability);
}
}
// after migrating, clear old prefs so we can remove them later.
Services.prefs.clearUserPref(oldFormAutofillModule);
Services.prefs.clearUserPref(oldCreditCardsAvailable);
}
if (existingDataVersion < 125) {
// Bug 1756243 - Clear PiP cached coordinates since we changed their
// coordinate space.
const PIP_PLAYER_URI =
"chrome://global/content/pictureinpicture/player.xhtml";
try {
for (let value of ["left", "top", "width", "height"]) {
Services.xulStore.removeValue(
PIP_PLAYER_URI,
"picture-in-picture",
value
);
}
} catch (ex) {
console.error("Failed to clear XULStore PiP values: ", ex);
}
}
function migrateXULAttributeToStyle(url, id, attr) {
try {
let value = Services.xulStore.getValue(url, id, attr);
if (value) {
Services.xulStore.setValue(url, id, "style", `${attr}: ${value}px;`);
}
} catch (ex) {
console.error(`Error migrating ${id}'s ${attr} value: `, ex);
}
}
// Bug 1792748 used version 129 with a buggy variant of the sidebar width
// migration. This version is already in use in the nightly channel, so it
// shouldn't be used.
// Bug 1793366: migrate sidebar persisted attribute from width to style.
if (existingDataVersion < 130) {
migrateXULAttributeToStyle(BROWSER_DOCURL, "sidebar-box", "width");
}
// Migration 131 was moved to 133 to allow for an uplift.
if (existingDataVersion < 132) {
// These attributes are no longer persisted, thus remove them from xulstore.
for (let url of [
"chrome://browser/content/places/bookmarkProperties.xhtml",
"chrome://browser/content/places/bookmarkProperties2.xhtml",
]) {
for (let attr of ["width", "screenX", "screenY"]) {
xulStore.removeValue(url, "bookmarkproperties", attr);
}
}
}
if (existingDataVersion < 133) {
xulStore.removeValue(BROWSER_DOCURL, "urlbar-container", "width");
}
// Migration 134 was removed because it was no longer necessary.
if (existingDataVersion < 135 && AppConstants.platform == "linux") {
// Avoid changing titlebar setting for users that used to had it off.
try {
if (!Services.prefs.prefHasUserValue("browser.tabs.inTitlebar")) {
let de = Services.appinfo.desktopEnvironment;
let oldDefault = de.includes("gnome") || de.includes("pantheon");
if (!oldDefault) {
Services.prefs.setIntPref("browser.tabs.inTitlebar", 0);
}
}
} catch (e) {
console.error("Error migrating tabsInTitlebar setting", e);
}
}
if (existingDataVersion < 136) {
migrateXULAttributeToStyle(
"chrome://browser/content/places/places.xhtml",
"placesList",
"width"
);
}
if (existingDataVersion < 137) {
// The default value for enabling smooth scrolls is now false if the
// user prefers reduced motion. If the value was previously set, do
// not reset it, but if it was not explicitly set preserve the old
// default value.
if (
!Services.prefs.prefHasUserValue("general.smoothScroll") &&
Services.appinfo.prefersReducedMotion
) {
Services.prefs.setBoolPref("general.smoothScroll", true);
}
}
if (existingDataVersion < 138) {
// Bug 1757297: Change scheme of all existing 'https-only-load-insecure'
// permissions with https scheme to http scheme.
try {
Services.perms
.getAllByTypes(["https-only-load-insecure"])
.filter(permission => permission.principal.schemeIs("https"))
.forEach(permission => {
const capability = permission.capability;
const uri = permission.principal.URI.mutate()
.setScheme("http")
.finalize();
const principal =
Services.scriptSecurityManager.createContentPrincipal(uri, {});
Services.perms.removePermission(permission);
Services.perms.addFromPrincipal(
principal,
"https-only-load-insecure",
capability
);
});
} catch (e) {
console.error("Error migrating https-only-load-insecure permission", e);
}
}
if (existingDataVersion < 139) {
// Reset the default permissions to ALLOW_ACTION to rollback issues for
// affected users, see Bug 1579517
// originInfo in the format [origin, type]
[
["https://www.mozilla.org", "uitour"],
["https://support.mozilla.org", "uitour"],
["about:home", "uitour"],
["about:newtab", "uitour"],
["https://addons.mozilla.org", "install"],
["https://support.mozilla.org", "remote-troubleshooting"],
["about:welcome", "autoplay-media"],
].forEach(originInfo => {
// Reset permission on the condition that it is set to
// UNKNOWN_ACTION, we want to prevent resetting user
// manipulated permissions
if (
Services.perms.UNKNOWN_ACTION ==
Services.perms.testPermissionFromPrincipal(
Services.scriptSecurityManager.createContentPrincipalFromOrigin(
originInfo[0]
),
originInfo[1]
)
) {
// Adding permissions which have default values does not create
// new permissions, but rather remove the UNKNOWN_ACTION permission
// overrides. User's not affected by Bug 1579517 will not be affected by this addition.
Services.perms.addFromPrincipal(
Services.scriptSecurityManager.createContentPrincipalFromOrigin(
originInfo[0]
),
originInfo[1],
Services.perms.ALLOW_ACTION
);
}
});
}
if (existingDataVersion < 140) {
// Remove browser.fixup.alternate.enabled pref in Bug 1850902.
Services.prefs.clearUserPref("browser.fixup.alternate.enabled");
}
if (existingDataVersion < 141) {
for (const filename of ["signons.sqlite", "signons.sqlite.corrupt"]) {
const filePath = PathUtils.join(PathUtils.profileDir, filename);
IOUtils.remove(filePath, { ignoreAbsent: true }).catch(console.error);
}
}
if (existingDataVersion < 142) {
// Bug 1860392 - Remove incorrectly persisted theming values from sidebar style.
try {
let value = xulStore.getValue(BROWSER_DOCURL, "sidebar-box", "style");
if (value) {
// Remove custom properties.
value = value
.split(";")
.filter(v => !v.trim().startsWith("--"))
.join(";");
xulStore.setValue(BROWSER_DOCURL, "sidebar-box", "style", value);
}
} catch (ex) {
console.error(ex);
}
}
if (existingDataVersion < 143) {
// Version 143 has been superseded by version 145 below.
}
if (existingDataVersion < 144) {
// TerminatorTelemetry was removed in bug 1879136. Before it was removed,
// the ShutdownDuration.json file would be written to disk at shutdown
// so that the next launch of the browser could read it in and send
// shutdown performance measurements.
//
// Unfortunately, this mechanism and its measurements were fairly
// unreliable, so they were removed.
for (const filename of [
"ShutdownDuration.json",
"ShutdownDuration.json.tmp",
]) {
const filePath = PathUtils.join(PathUtils.profileDir, filename);
IOUtils.remove(filePath, { ignoreAbsent: true }).catch(console.error);
}
}
if (existingDataVersion < 145) {
if (AppConstants.platform == "win") {
// In Firefox 122, we enabled the firefox and firefox-private protocols.
// We switched over to using firefox-bridge and firefox-private-bridge,
// but we want to clean up the use of the other protocols.
lazy.FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
lazy.FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL,
lazy.FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL
);
// Clean up the old user prefs from FX 122
Services.prefs.clearUserPref(
"network.protocol-handler.external.firefox"
);
Services.prefs.clearUserPref(
"network.protocol-handler.external.firefox-private"
);
// In Firefox 126, we switched over to using native messaging so the
// protocols are no longer necessary even in firefox-bridge and
// firefox-private-bridge form
lazy.FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries(
lazy.FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL,
lazy.FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL
);
Services.prefs.clearUserPref(
"network.protocol-handler.external.firefox-bridge"
);
Services.prefs.clearUserPref(
"network.protocol-handler.external.firefox-private-bridge"
);
Services.prefs.clearUserPref("browser.shell.customProtocolsRegistered");
}
}
// Version 146 had a typo issue and thus it has been replaced by 147.
if (existingDataVersion < 147) {
// We're securing the boolean prefs for OS Authentication.
// This is achieved by converting them into a string pref and encrypting the values
// stored inside it.
// Note: we don't run this on nightly builds and we also do not run this
// for users with primary password enabled. That means both these sets of
// users will have the features turned on by default. For Nightly this is
// an intentional product decision; for primary password this is because
// we cannot encrypt the opt-out value without asking for the primary
// password, which in turn means we cannot migrate without doing so. It
// is also very difficult to postpone this migration because there is no
// way to know when the user has put in the primary password. We will
// probably reconsider some of this architecture in future, but for now
// this is the least-painful method considering the alternatives, cf.
// bug 1901899.
if (
!AppConstants.NIGHTLY_BUILD &&
!lazy.LoginHelper.isPrimaryPasswordSet()
) {
const hasRunBetaMigration = Services.prefs
.getCharPref("browser.startup.homepage_override.mstone", "")
.startsWith("127.0");
// Version 146 UI migration wrote to a wrong `creditcards` pref when
// the feature was disabled, instead it should have used `creditCards`.
// The correct pref name is in AUTOFILL_CREDITCARDS_REAUTH_PREF.
// Note that we only wrote prefs if the feature was disabled.
let ccTypoDisabled = !lazy.FormAutofillUtils.getOSAuthEnabled(
"extensions.formautofill.creditcards.reauth.optout"
);
let ccCorrectPrefDisabled = !lazy.FormAutofillUtils.getOSAuthEnabled(
lazy.FormAutofillUtils.AUTOFILL_CREDITCARDS_REAUTH_PREF
);
let ccPrevReauthPrefValue = Services.prefs.getBoolPref(
"extensions.formautofill.reauth.enabled",
false
);
let userHadEnabledCreditCardReauth =
// If we've run beta migration, and neither typo nor correct pref
// indicate disablement, the user enabled the pref:
(hasRunBetaMigration && !ccTypoDisabled && !ccCorrectPrefDisabled) ||
// Or if we never ran beta migration and the bool pref is set:
ccPrevReauthPrefValue;
lazy.FormAutofillUtils.setOSAuthEnabled(
lazy.FormAutofillUtils.AUTOFILL_CREDITCARDS_REAUTH_PREF,
userHadEnabledCreditCardReauth
);
if (!hasRunBetaMigration) {
const passwordsPrevReauthPrefValue = Services.prefs.getBoolPref(
"signon.management.page.os-auth.enabled",
false
);
lazy.LoginHelper.setOSAuthEnabled(
lazy.LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF,
passwordsPrevReauthPrefValue
);
}
}
Services.prefs.clearUserPref("extensions.formautofill.reauth.enabled");
Services.prefs.clearUserPref("signon.management.page.os-auth.enabled");
Services.prefs.clearUserPref(
"extensions.formautofill.creditcards.reauth.optout"
);
}
if (existingDataVersion < 148) {
// The Firefox Translations addon is now a built-in Firefox feature.
let addonPromise;
try {
addonPromise = lazy.AddonManager.getAddonByID(
"firefox-translations-addon@mozilla.org"
);
} catch (error) {
// This always throws in xpcshell as the AddonManager is not initialized.
if (!Services.env.exists("XPCSHELL_TEST_PROFILE_DIR")) {
console.error(
"Could not access the AddonManager to upgrade the profile."
);
}
}
addonPromise?.then(addon => addon?.uninstall()).catch(console.error);
}
if (existingDataVersion < 149) {
// remove permissions used by deleted nsContentManager
[
"other",
"script",
"image",
"stylesheet",
"object",
"document",
"subdocument",
"refresh",
"xbl",
"ping",
"xmlhttprequest",
"objectsubrequest",
"dtd",
"font",
"websocket",
"csp_report",
"xslt",
"beacon",
"fetch",
"manifest",
"speculative",
].forEach(type => {
Services.perms.removeByType(type);
});
}
if (existingDataVersion < 150) {
Services.prefs.clearUserPref("toolkit.telemetry.pioneerId");
}
if (existingDataVersion < 151) {
// Existing Firefox users should have the usage reporting upload
// preference "inherit" the general data reporting preference.
lazy.UsageReporting.adoptDataReportingPreference();
}
if (
existingDataVersion < 152 &&
Services.prefs.getBoolPref("sidebar.revamp") &&
!Services.prefs.getBoolPref("browser.ml.chat.enabled")
) {
let tools = Services.prefs.getCharPref("sidebar.main.tools");
if (tools?.includes("aichat")) {
let updatedTools = tools
.split(",")
.filter(t => t != "aichat")
.join(",");
Services.prefs.setCharPref("sidebar.main.tools", updatedTools);
}
}
if (
existingDataVersion < 153 &&
Services.prefs.getBoolPref("sidebar.revamp") &&
!Services.prefs.prefHasUserValue("sidebar.main.tools")
) {
// This pref will now be a user set branch but we want to preserve the previous
// default value for existing sidebar.revamp users who hadn't changed it.
Services.prefs.setCharPref(
"sidebar.main.tools",
"aichat,syncedtabs,history"
);
}
if (existingDataVersion < 154) {
// Remove mibbit handler.
// The handler service will do this. We need to wait with migrating
// until the handler service has started up, so just set a pref here.
const kPref = "browser.handlers.migrations";
// We might have set up another migration further up. Create an array,
// and drop empty strings resulting from the `split`:
let migrations = Services.prefs
.getCharPref(kPref, "")
.split(",")
.filter(x => !!x);
migrations.push("mibbit");
Services.prefs.setCharPref(kPref, migrations.join(","));
}
if (existingDataVersion < 155) {
// Remove outdated sidebar info from XULStore.
for (const attr of [
"checked",
"positionend",
"sidebarcommand",
"style",
]) {
Services.xulStore.removeValue(BROWSER_DOCURL, "sidebar-box", attr);
}
}
// Update the migration version.
Services.prefs.setIntPref("browser.migration.version", newVersion);
},
};