tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit ef6d47f01dadd7a13f3e6add1eecb9c271289df3
parent b816837e56eb521aece170d928923de0b0403460
Author: Harsheet <hsohaney@mozilla.com>
Date:   Sun, 16 Nov 2025 21:14:12 +0000

Bug 1996070 - (part 1) Move backup enable status states and error codes to the BackupService internal state and remove privileged instances from the backup UI. r=cdupuis

Differential Revision: https://phabricator.services.mozilla.com/D272692

Diffstat:
Mbrowser/components/DesktopActorRegistry.sys.mjs | 1+
Mbrowser/components/backup/BackupService.sys.mjs | 38+++++++++++++++++++++++++++++++++++++-
Mbrowser/components/backup/actors/BackupUIChild.sys.mjs | 2++
Mbrowser/components/backup/actors/BackupUIParent.sys.mjs | 13+++++++++++++
Mbrowser/components/backup/content/backup-settings.mjs | 60+++++++++++++++---------------------------------------------
Mbrowser/components/backup/content/backup-settings.stories.mjs | 12++++++++++++
Mbrowser/components/storybook/component-status/components.json | 2+-
7 files changed, 81 insertions(+), 47 deletions(-)

diff --git a/browser/components/DesktopActorRegistry.sys.mjs b/browser/components/DesktopActorRegistry.sys.mjs @@ -238,6 +238,7 @@ let JSWINDOWACTORS = { "BackupUI:RerunEncryption": { wantUntrusted: true }, "BackupUI:ShowBackupLocation": { wantUntrusted: true }, "BackupUI:EditBackupLocation": { wantUntrusted: true }, + "BackupUI:ErrorBarDismissed": { wantUntrusted: true }, }, }, includeChrome: true, diff --git a/browser/components/backup/BackupService.sys.mjs b/browser/components/backup/BackupService.sys.mjs @@ -189,6 +189,19 @@ XPCOMUtils.defineLazyPreferenceGetter( 5 ); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "backupErrorCode", + BACKUP_ERROR_CODE_PREF_NAME, + ERRORS.NONE, + function onUpdateBackupErrorCode(_pref, _prevVal, newVal) { + let bs = BackupService.init(); + if (bs) { + bs.onUpdateBackupErrorCode(newVal); + } + } +); + XPCOMUtils.defineLazyServiceGetter( lazy, "idleService", @@ -782,7 +795,6 @@ export class BackupService extends EventTarget { lastBackupFileName: "", supportBaseLink: Services.urlFormatter.formatURLPref("app.support.baseURL"), recoveryInProgress: false, - recoveryErrorCode: 0, /** * Every file we load successfully is going to get a restore ID which is * basically the identifier for that profile restore event. If we actually @@ -791,6 +803,10 @@ export class BackupService extends EventTarget { * restored. */ restoreID: null, + recoveryErrorCode: ERRORS.NONE, + backupErrorCode: lazy.backupErrorCode, + archiveEnabledStatus: this.archiveEnabledStatus.enabled, + restoreEnabledStatus: this.restoreEnabledStatus.enabled, }; /** @@ -1696,6 +1712,7 @@ export class BackupService extends EventTarget { }) ); + this.stateUpdate(); throw e; } finally { this.#backupInProgress = false; @@ -3525,6 +3542,20 @@ export class BackupService extends EventTarget { } /** + * Updates backupErrorCode in the backup service state. Should be called every time + * the value for browser.backup.errorCode changes. + * + * @param {number} newErrorCode + * Any of the ERROR code's from backup-constants.mjs + */ + onUpdateBackupErrorCode(newErrorCode) { + lazy.logConsole.debug(`Updating backup error code to ${newErrorCode}`); + + this.#_state.backupErrorCode = newErrorCode; + this.stateUpdate(); + } + + /** * Returns the moz-icon URL of a file. To get the moz-icon URL, the * file path is convered to a fileURI. If there is a problem retreiving * the moz-icon due to an invalid file path, return null instead. @@ -4090,6 +4121,11 @@ export class BackupService extends EventTarget { * 2. If archive is disabled, clean up any backup files */ #handleStatusChange() { + // Update the BackupService state before notifying observers about the + // state change + this.#_state.archiveEnabledStatus = this.archiveEnabledStatus.enabled; + this.#_state.restoreEnabledStatus = this.restoreEnabledStatus.enabled; + this.#notifyStatusObservers(); if (!this.archiveEnabledStatus.enabled) { diff --git a/browser/components/backup/actors/BackupUIChild.sys.mjs b/browser/components/backup/actors/BackupUIChild.sys.mjs @@ -138,6 +138,8 @@ export class BackupUIChild extends JSWindowActorChild { this.sendAsyncMessage("ShowBackupLocation"); } else if (event.type == "BackupUI:EditBackupLocation") { this.sendAsyncMessage("EditBackupLocation"); + } else if (event.type == "BackupUI:ErrorBarDismissed") { + this.sendAsyncMessage("ErrorBarDismissed"); } } diff --git a/browser/components/backup/actors/BackupUIParent.sys.mjs b/browser/components/backup/actors/BackupUIParent.sys.mjs @@ -18,6 +18,8 @@ ChromeUtils.defineLazyGetter(lazy, "logConsole", function () { }); }); +const BACKUP_ERROR_CODE_PREF_NAME = "browser.backup.errorCode"; + /** * A JSWindowActor that is responsible for marshalling information between * the BackupService singleton and any registered UI widgets that need to @@ -49,6 +51,7 @@ export class BackupUIParent extends JSWindowActorParent { */ actorCreated() { this.#bs.addEventListener("BackupService:StateUpdate", this); + Services.obs.addObserver(this.sendState, "backup-service-status-updated"); // Note that loadEncryptionState is an async function. // This function is no-op if the encryption state was already loaded. this.#bs.loadEncryptionState(); @@ -59,6 +62,10 @@ export class BackupUIParent extends JSWindowActorParent { */ didDestroy() { this.#bs.removeEventListener("BackupService:StateUpdate", this); + Services.obs.removeObserver( + this.sendState, + "backup-service-status-updated" + ); } /** @@ -263,6 +270,12 @@ export class BackupUIParent extends JSWindowActorParent { e ); } + } else if (message.name == "ErrorBarDismissed") { + Services.prefs.setIntPref(BACKUP_ERROR_CODE_PREF_NAME, lazy.ERRORS.NONE); + } else if (message.name == "SetEmbeddedComponentPersistentData") { + this.#bs.setEmbeddedComponentPersistentData(message.data); + } else if (message.name == "FlushEmbeddedComponentPersistentData") { + this.#bs.setEmbeddedComponentPersistentData({}); } return null; diff --git a/browser/components/backup/content/backup-settings.mjs b/browser/components/backup/content/backup-settings.mjs @@ -7,12 +7,6 @@ import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; import { getErrorL10nId } from "chrome://browser/content/backup/backup-errors.mjs"; import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs"; -const lazy = {}; - -ChromeUtils.defineESModuleGetters(lazy, { - BackupService: "resource:///modules/backup/BackupService.sys.mjs", -}); - // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/turn-on-scheduled-backups.mjs"; // eslint-disable-next-line import/no-unassigned-import @@ -24,15 +18,12 @@ import "chrome://browser/content/backup/enable-backup-encryption.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/disable-backup-encryption.mjs"; -const BACKUP_ERROR_CODE_PREF_NAME = "browser.backup.errorCode"; - /** * The widget for managing the BackupService that is embedded within the main * document of about:settings / about:preferences. */ export default class BackupSettings extends MozLitElement { #placeholderIconURL = "chrome://global/skin/icons/page-portrait.svg"; - #backupService = lazy.BackupService.init(); inProgressTimeout = null; showInProgress = false; @@ -41,10 +32,7 @@ export default class BackupSettings extends MozLitElement { static properties = { backupServiceState: { type: Object }, - backupErrorCode: { type: Number }, _enableEncryptionTypeAttr: { type: String }, - _archiveEnabled: { type: Boolean }, - _restoreEnabled: { type: Boolean }, }; static get queries() { @@ -111,18 +99,14 @@ export default class BackupSettings extends MozLitElement { supportBaseLink: "", backupInProgress: false, recoveryInProgress: false, - recoveryErrorCode: 0, + recoveryErrorCode: ERRORS.NONE, + backupErrorCode: ERRORS.NONE, + archiveEnabledStatus: false, + restoreEnabledStatus: false, }; - this.backupErrorCode = this.#readBackupErrorPref(); this._enableEncryptionTypeAttr = ""; - this.updateArchiveAndRestoreState(); } - updateArchiveAndRestoreState = () => { - this._archiveEnabled = this.#backupService.archiveEnabledStatus.enabled; - this._restoreEnabled = this.#backupService.restoreEnabledStatus.enabled; - }; - /** * Dispatches the BackupUI:InitWidget custom event upon being attached to the * DOM, which registers with BackupUIChild for BackupService state updates. @@ -133,34 +117,16 @@ export default class BackupSettings extends MozLitElement { new CustomEvent("BackupUI:InitWidget", { bubbles: true }) ); - Services.obs.addObserver( - this.updateArchiveAndRestoreState, - "backup-service-status-updated" - ); - - this._cleanupObs = () => { - Services.obs.removeObserver( - this.updateArchiveAndRestoreState, - "backup-service-status-updated" - ); - window.removeEventListener("unload", this._cleanupObs); - }; - - window.addEventListener("unload", this._cleanupObs, { once: true }); - this.addEventListener("dialogCancel", this); this.addEventListener("restoreFromBackupConfirm", this); this.addEventListener("restoreFromBackupChooseFile", this); } - #readBackupErrorPref() { - return Services.prefs.getIntPref(BACKUP_ERROR_CODE_PREF_NAME); - } - handleErrorBarDismiss = () => { // Reset the pref and reactive state; Lit will re-render without the bar. - Services.prefs.setIntPref(BACKUP_ERROR_CODE_PREF_NAME, ERRORS.NONE); - this.backupErrorCode = 0; + this.dispatchEvent( + new CustomEvent("BackupUI:ErrorBarDismissed", { bubbles: true }) + ); }; handleEvent(event) { @@ -476,7 +442,7 @@ export default class BackupSettings extends MozLitElement { } errorBarTemplate() { - const l10nId = getErrorL10nId(this.backupErrorCode); + const l10nId = getErrorL10nId(this.backupServiceState.backupErrorCode); return html` <moz-message-bar type="error" @@ -536,13 +502,15 @@ export default class BackupSettings extends MozLitElement { rel="stylesheet" href="chrome://browser/content/backup/backup-settings.css" /> - ${this.backupErrorCode ? this.errorBarTemplate() : null} + ${this.backupServiceState.backupErrorCode + ? this.errorBarTemplate() + : null} ${this.showInProgress ? this.inProgressMessageBarTemplate() : null} ${this.turnOnScheduledBackupsDialogTemplate()} ${this.turnOffScheduledBackupsDialogTemplate()} ${this.enableBackupEncryptionDialogTemplate()} ${this.disableBackupEncryptionDialogTemplate()} - ${this._archiveEnabled + ${this.backupServiceState.archiveEnabledStatus ? html` <section id="scheduled-backups"> <div class="backups-control"> <span @@ -584,7 +552,9 @@ export default class BackupSettings extends MozLitElement { : null} </section>` : null} - ${this._restoreEnabled ? this.restoreFromBackupTemplate() : null} `; + ${this.backupServiceState.restoreEnabledStatus + ? this.restoreFromBackupTemplate() + : null} `; } } diff --git a/browser/components/backup/content/backup-settings.stories.mjs b/browser/components/backup/content/backup-settings.stories.mjs @@ -28,6 +28,9 @@ ScheduledBackupsDisabled.args = { fileName: "Documents", }, scheduledBackupsEnabled: false, + backupErrorCode: 0, + archiveEnabledStatus: true, + restoreEnabledStatus: true, }, }; @@ -40,6 +43,9 @@ ScheduledBackupsEnabled.args = { fileName: "Documents", }, scheduledBackupsEnabled: true, + backupErrorCode: 0, + archiveEnabledStatus: true, + restoreEnabledStatus: true, }, }; @@ -54,6 +60,9 @@ ExistingBackup.args = { scheduledBackupsEnabled: true, lastBackupDate: 1719625747, lastBackupFileName: "FirefoxBackup_default_123123123.html", + backupErrorCode: 0, + archiveEnabledStatus: true, + restoreEnabledStatus: true, }, }; @@ -69,5 +78,8 @@ EncryptionEnabled.args = { encryptionEnabled: true, lastBackupDate: 1719625747, lastBackupFileName: "FirefoxBackup_default_123123123.html", + backupErrorCode: 0, + archiveEnabledStatus: true, + restoreEnabledStatus: true, }, }; diff --git a/browser/components/storybook/component-status/components.json b/browser/components/storybook/component-status/components.json @@ -1,5 +1,5 @@ { - "generatedAt": "2025-11-12T19:18:35.085Z", + "generatedAt": "2025-11-14T18:02:05.239Z", "count": 29, "items": [ {