summaryrefslogtreecommitdiffstats
path: root/browser/components/backup/resources/BackupResource.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/backup/resources/BackupResource.sys.mjs')
-rw-r--r--browser/components/backup/resources/BackupResource.sys.mjs109
1 files changed, 109 insertions, 0 deletions
diff --git a/browser/components/backup/resources/BackupResource.sys.mjs b/browser/components/backup/resources/BackupResource.sys.mjs
new file mode 100644
index 0000000000..bde3f0669c
--- /dev/null
+++ b/browser/components/backup/resources/BackupResource.sys.mjs
@@ -0,0 +1,109 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+// Convert from bytes to kilobytes (not kibibytes).
+const BYTES_IN_KB = 1000;
+
+/**
+ * An abstract class representing a set of data within a user profile
+ * that can be persisted to a separate backup archive file, and restored
+ * to a new user profile from that backup archive file.
+ */
+export class BackupResource {
+ /**
+ * This must be overridden to return a simple string identifier for the
+ * resource, for example "places" or "extensions". This key is used as
+ * a unique identifier for the resource.
+ *
+ * @type {string}
+ */
+ static get key() {
+ throw new Error("BackupResource::key needs to be overridden.");
+ }
+
+ /**
+ * Get the size of a file.
+ *
+ * @param {string} filePath - path to a file.
+ * @returns {Promise<number|null>} - the size of the file in kilobytes, or null if the
+ * file does not exist, the path is a directory or the size is unknown.
+ */
+ static async getFileSize(filePath) {
+ if (!(await IOUtils.exists(filePath))) {
+ return null;
+ }
+
+ let { size } = await IOUtils.stat(filePath);
+
+ if (size < 0) {
+ return null;
+ }
+
+ let sizeInKb = Math.ceil(size / BYTES_IN_KB);
+ // Make the measurement fuzzier by rounding to the nearest 10kb.
+ let nearestTenthKb = Math.round(sizeInKb / 10) * 10;
+
+ return Math.max(nearestTenthKb, 1);
+ }
+
+ /**
+ * Get the total size of a directory.
+ *
+ * @param {string} directoryPath - path to a directory.
+ * @returns {Promise<number|null>} - the size of all descendants of the directory in kilobytes, or null if the
+ * directory does not exist, the path is not a directory or the size is unknown.
+ */
+ static async getDirectorySize(directoryPath) {
+ if (!(await IOUtils.exists(directoryPath))) {
+ return null;
+ }
+
+ let { type } = await IOUtils.stat(directoryPath);
+
+ if (type != "directory") {
+ return null;
+ }
+
+ let children = await IOUtils.getChildren(directoryPath, {
+ ignoreAbsent: true,
+ });
+
+ let size = 0;
+ for (const childFilePath of children) {
+ let { size: childSize, type: childType } = await IOUtils.stat(
+ childFilePath
+ );
+
+ if (childSize >= 0) {
+ let sizeInKb = Math.ceil(childSize / BYTES_IN_KB);
+ // Make the measurement fuzzier by rounding to the nearest 10kb.
+ let nearestTenthKb = Math.round(sizeInKb / 10) * 10;
+ size += Math.max(nearestTenthKb, 1);
+ }
+
+ if (childType == "directory") {
+ let childDirectorySize = await this.getDirectorySize(childFilePath);
+ if (Number.isInteger(childDirectorySize)) {
+ size += childDirectorySize;
+ }
+ }
+ }
+
+ return size;
+ }
+
+ constructor() {}
+
+ /**
+ * This must be overridden to record telemetry on the size of any
+ * data associated with this BackupResource.
+ *
+ * @param {string} profilePath - path to a profile directory.
+ * @returns {Promise<undefined>}
+ */
+ // eslint-disable-next-line no-unused-vars
+ async measure(profilePath) {
+ throw new Error("BackupResource::measure needs to be overridden.");
+ }
+}