/* 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 * as BackupResources from "resource:///modules/backup/BackupResources.sys.mjs"; const lazy = {}; ChromeUtils.defineLazyGetter(lazy, "logConsole", function () { return console.createInstance({ prefix: "BackupService", maxLogLevel: Services.prefs.getBoolPref("browser.backup.log", false) ? "Debug" : "Warn", }); }); /** * The BackupService class orchestrates the scheduling and creation of profile * backups. It also does most of the heavy lifting for the restoration of a * profile backup. */ export class BackupService { /** * The BackupService singleton instance. * * @static * @type {BackupService|null} */ static #instance = null; /** * Map of instantiated BackupResource classes. * * @type {Map} */ #resources = new Map(); /** * Returns a reference to a BackupService singleton. If this is the first time * that this getter is accessed, this causes the BackupService singleton to be * be instantiated. * * @static * @type {BackupService} */ static init() { if (this.#instance) { return this.#instance; } this.#instance = new BackupService(BackupResources); this.#instance.takeMeasurements(); return this.#instance; } /** * Create a BackupService instance. * * @param {object} [backupResources=BackupResources] - Object containing BackupResource classes to associate with this service. */ constructor(backupResources = BackupResources) { lazy.logConsole.debug("Instantiated"); for (const resourceName in backupResources) { let resource = BackupResources[resourceName]; this.#resources.set(resource.key, resource); } } /** * Take measurements of the current profile state for Telemetry. * * @returns {Promise} */ async takeMeasurements() { lazy.logConsole.debug("Taking Telemetry measurements"); // Note: We're talking about kilobytes here, not kibibytes. That means // 1000 bytes, and not 1024 bytes. const BYTES_IN_KB = 1000; const BYTES_IN_MB = 1000000; // We'll start by measuring the available disk space on the storage // device that the profile directory is on. let profileDir = await IOUtils.getFile(PathUtils.profileDir); let profDDiskSpaceBytes = profileDir.diskSpaceAvailable; // Make the measurement fuzzier by rounding to the nearest 10MB. let profDDiskSpaceMB = Math.round(profDDiskSpaceBytes / BYTES_IN_MB / 100) * 100; // And then record the value in kilobytes, since that's what everything // else is going to be measured in. Glean.browserBackup.profDDiskSpace.set(profDDiskSpaceMB * BYTES_IN_KB); // Measure the size of each file we are going to backup. for (let resourceClass of this.#resources.values()) { await new resourceClass().measure(PathUtils.profileDir); } } }