|  | // Copyright 2021 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef CHROME_BROWSER_ASH_CROSAPI_BROWSER_DATA_MIGRATOR_UTIL_H_ | 
|  | #define CHROME_BROWSER_ASH_CROSAPI_BROWSER_DATA_MIGRATOR_UTIL_H_ | 
|  |  | 
|  | #include <atomic> | 
|  | #include <map> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/files/file_path.h" | 
|  | #include "base/synchronization/atomic_flag.h" | 
|  | #include "base/values.h" | 
|  | #include "chrome/browser/ash/crosapi/migration_progress_tracker.h" | 
|  | #include "components/sync/base/model_type.h" | 
|  | #include "third_party/abseil-cpp/absl/types/optional.h" | 
|  | #include "third_party/leveldatabase/env_chromium.h" | 
|  |  | 
|  | namespace base { | 
|  | class FilePath; | 
|  | } | 
|  |  | 
|  | namespace ash::browser_data_migrator_util { | 
|  |  | 
|  | // User data directory name for lacros. | 
|  | constexpr char kLacrosDir[] = "lacros"; | 
|  |  | 
|  | // Profile data directory name for lacros. | 
|  | constexpr char kLacrosProfilePath[] = "Default"; | 
|  |  | 
|  | // The name of temporary directory that will store copies of files from the | 
|  | // original user data directory. At the end of the migration, it will be moved | 
|  | // to the appropriate destination. | 
|  | constexpr char kTmpDir[] = "browser_data_migrator"; | 
|  |  | 
|  | // `MoveMigrator` migrates user data to this directory first then moves it to | 
|  | // the correct location as its final step. | 
|  | constexpr char kMoveTmpDir[] = "move_migrator"; | 
|  |  | 
|  | // `MoveMigrator` splits user data that needs to remain Ash into this directory | 
|  | // first, then moves it to the correct location as its final step. | 
|  | constexpr char kSplitTmpDir[] = "move_migrator_split"; | 
|  |  | 
|  | // Directory for `MoveMigrator` to move hard links for lacros file/dirs in ash | 
|  | // directory so that they become inaccessible from ash. This directory should be | 
|  | // cleaned up after the migraton. | 
|  | constexpr char kRemoveDir[] = "move_migrator_trash"; | 
|  |  | 
|  | // The following UMAs are recorded from | 
|  | // `DryRunToCollectUMA()`. | 
|  | constexpr char kDryRunNoCopyDataSize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunNoCopyDataSizeMB"; | 
|  | constexpr char kDryRunAshDataSize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunAshDataSizeMB"; | 
|  | constexpr char kDryRunLacrosDataSize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunLacrosDataSizeMB"; | 
|  | constexpr char kDryRunCommonDataSize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunCommonDataSizeMB"; | 
|  | constexpr char kDryRunCopyMigrationTotalCopySize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunTotalCopySizeMB.Copy"; | 
|  | constexpr char kDryRunMoveMigrationTotalCopySize[] = | 
|  | "Ash.BrowserDataMigrator.DryRunTotalCopySizeMB.Move"; | 
|  | constexpr char kDryRunMoveMigrationExtraSpaceReserved[] = | 
|  | "Ash.BrowserDataMigrator.DryRunExtraSizeReservedMB.Move"; | 
|  | constexpr char kDryRunMoveMigrationExtraSpaceRequired[] = | 
|  | "Ash.BrowserDataMigrator.DryRunExtraSizeRequiredMB.Move"; | 
|  |  | 
|  | constexpr char kDryRunCopyMigrationHasEnoughDiskSpace[] = | 
|  | "Ash.BrowserDataMigrator.DryRunHasEnoughDiskSpace.Copy"; | 
|  | constexpr char kDryRunMoveMigrationHasEnoughDiskSpace[] = | 
|  | "Ash.BrowserDataMigrator.DryRunHasEnoughDiskSpace.Move"; | 
|  | constexpr char kDryRunDeleteAndCopyMigrationHasEnoughDiskSpace[] = | 
|  | "Ash.BrowserDataMigrator.DryRunHasEnoughDiskSpace.DeleteAndCopy"; | 
|  | constexpr char kDryRunDeleteAndMoveMigrationHasEnoughDiskSpace[] = | 
|  | "Ash.BrowserDataMigrator.DryRunHasEnoughDiskSpace.DeleteAndMove"; | 
|  |  | 
|  | // The base names of files/dirs directly under the original profile | 
|  | // data directory that can be deleted if needed because they are temporary | 
|  | // storages. | 
|  | constexpr const char* const kDeletablePaths[] = { | 
|  | kTmpDir, | 
|  | kMoveTmpDir, | 
|  | "blob_storage", | 
|  | "Cache", | 
|  | "Code Cache", | 
|  | "coupon_db", | 
|  | "crash", | 
|  | "Download Service", | 
|  | "GPUCache", | 
|  | "heavy_ad_intervention_opt_out.db", | 
|  | "merchant_signal_db", | 
|  | "Network Action Predictor", | 
|  | "Network Persistent State", | 
|  | "previews_opt_out.db", | 
|  | "Reporting and NEL", | 
|  | "Site Characteristics Database", | 
|  | "Translate Ranker Model", | 
|  | "TransportSecurity"}; | 
|  |  | 
|  | // The base names of files/dirs that should remain in ash data | 
|  | // directory. | 
|  | constexpr const char* const kRemainInAshDataPaths[] = { | 
|  | "AccountManagerTokens.bin", | 
|  | "Accounts", | 
|  | "app_ranker.pb", | 
|  | "arc.apps", | 
|  | "autobrightness", | 
|  | "BudgetDatabase", | 
|  | "crostini.icons", | 
|  | "data_reduction_proxy_leveldb", | 
|  | "Downloads", | 
|  | "extension_install_log", | 
|  | "Feature Engagement Tracker", | 
|  | "FullRestoreData", | 
|  | "GCM Store", | 
|  | "google-assistant-library", | 
|  | "input_methods", | 
|  | "launcher_ranking", | 
|  | "LOCK", | 
|  | "LOG", | 
|  | "LOG.old", | 
|  | "login-times", | 
|  | "logout-times", | 
|  | "MyFiles", | 
|  | "NearbySharePublicCertificateDatabase", | 
|  | "PPDCache", | 
|  | "PreferredApps", | 
|  | "PrintJobDatabase", | 
|  | "README", | 
|  | "RLZ Data", | 
|  | "smartcharging", | 
|  | "structured_metrics", | 
|  | "Sync Data", | 
|  | "Trusted Vault", | 
|  | "trusted_vault.pb", | 
|  | "WebRTC Logs", | 
|  | "webrtc_event_logs", | 
|  | "zero_state_group_ranker.pb", | 
|  | "zero_state_local_files.pb"}; | 
|  |  | 
|  | // The base names of files/dirs that are required for browsing and should be | 
|  | // moved to lacros data dir. | 
|  | constexpr const char* const kLacrosDataPaths[]{ | 
|  | "Affiliation Database", | 
|  | "AutofillStrikeDatabase", | 
|  | "Bookmarks", | 
|  | "chrome_cart_db", | 
|  | "commerce_subscription_db", | 
|  | "Cookies", | 
|  | "databases", | 
|  | "Extension Rules", | 
|  | "Extension Scripts", | 
|  | "Extension State", | 
|  | "Extensions", | 
|  | "Favicons", | 
|  | "File System", | 
|  | "History", | 
|  | "IndexedDB", | 
|  | "Local App Settings", | 
|  | "Local Extension Settings", | 
|  | "Local Storage", | 
|  | "Login Data", | 
|  | "Login Data For Account", | 
|  | "optimization_guide_hint_cache_store", | 
|  | "optimization_guide_model_and_features_store", | 
|  | "Managed Extension Settings", | 
|  | "persisted_state_db", | 
|  | "Platform Notifications", | 
|  | "QuotaManager", | 
|  | "Safe Browsing Cookies", | 
|  | "Safe Browsing Network", | 
|  | "Service Worker", | 
|  | "Session Storage", | 
|  | "Sessions", | 
|  | "SharedStorage", | 
|  | "Shortcuts", | 
|  | "Storage", | 
|  | "Sync App Settings", | 
|  | "Sync Extension Settings", | 
|  | "Top Sites", | 
|  | "Visited Links", | 
|  | "Web Applications", | 
|  | "Web Data", | 
|  | "WebStorage"}; | 
|  |  | 
|  | // The base names of files/dirs that are required by both ash and lacros and | 
|  | // thus should be copied to lacros while keeping the original files/dirs in ash | 
|  | // data dir. | 
|  | constexpr const char* const kNeedCopyForMoveDataPaths[]{ | 
|  | "DNR Extension Rules", "Extension Cookies", "shared_proto_db"}; | 
|  |  | 
|  | // The same as `kNeedCopyDataPathsForMove` + "Preferences". | 
|  | constexpr const char* const kNeedCopyForCopyDataPaths[]{ | 
|  | "DNR Extension Rules", "Extension Cookies", "Preferences", | 
|  | "shared_proto_db"}; | 
|  |  | 
|  | // List of extension ids to be kept in Ash. | 
|  | // TODO(crbug.com/1302613): make sure this is the complete list. | 
|  | constexpr const char* const kExtensionsAshOnly[] = { | 
|  | "gjjabgpgjpampikjhjpfhneeoapjbjaf",  // Google Speech Synthesis Ext. (patts) | 
|  | "dakbfdmgjiabojdgbiljlhgjbokobjpg",  // ESpeak Speech Synthesis Extension | 
|  | "jacnkoglebceckolkoapelihnglgaicd",  // Enhanced Network Tts Extension | 
|  | "klbcgckkldhdhonijdbnhhaiedfkllef",  // Select to Speak Extension | 
|  | "egfdjlfmgnehecnclamagfafdccgfndp",  // Accessibility Common Extension | 
|  | "mndnfokpggljbaajbnioimlmbfngpief",  // Chrome Vox Extension | 
|  | "pmehocpgjmkenlokgjfkaichfjdhpeol",  // Switch Access Extension | 
|  | "jddehjeebkoimngcbdkaahpobgicbffp",  // Braille IME (in IME allowlist) | 
|  | "mppnpdlheglhdfmldimlhpnegondlapf",  // Keyboard App Extension | 
|  | "mecfefiddjlmabpeilblgegnbioikfmp",  // sign in profile testing extension | 
|  | "behllobkkfkfnphdnhnkndlbkcpglgmj",  // guest mode test extension | 
|  | "honijodknafkokifofgiaalefdiedpko",  // Help App | 
|  | "pmfjbimdmchhbnneeidfognadeopoehp",  // Image Loader Extension | 
|  | "cnbgggchhmkkdmeppjobngjoejnihlei",  // Arc Support (Play Store) | 
|  | }; | 
|  |  | 
|  | // List of extension ids to be kept in both Ash and Lacros. | 
|  | constexpr const char* const kExtensionsBothChromes[] = { | 
|  | "cfmgaohenjcikllcgjpepfadgbflcjof",  // GCSE (Google Corp SSH Extension) | 
|  | "lfboplenmmjcmpbkeemecobbadnmpfhi",  // gnubbyd-v3 (new Gnubby extension) | 
|  | "beknehfpfkghjoafdifaflglpjkojoco",  // gnubbyd | 
|  | }; | 
|  |  | 
|  | // Extensions path. | 
|  | constexpr char kExtensionsFilePath[] = "Extensions"; | 
|  |  | 
|  | // IndexedDB path. | 
|  | constexpr char kIndexedDBFilePath[] = "IndexedDB"; | 
|  |  | 
|  | // `Local Storage` paths. | 
|  | constexpr char kLocalStorageFilePath[] = "Local Storage"; | 
|  | constexpr char kLocalStorageLeveldbName[] = "leveldb"; | 
|  |  | 
|  | // `Sync Data` path. | 
|  | constexpr char kSyncDataFilePath[] = "Sync Data"; | 
|  | constexpr char kSyncDataLeveldbName[] = "LevelDB"; | 
|  | constexpr char kSyncDataNigoriFileName[] = "Nigori.bin"; | 
|  |  | 
|  | // State Store paths. | 
|  | constexpr const char* const kStateStorePaths[] = { | 
|  | "Extension Rules", | 
|  | "Extension Scripts", | 
|  | "Extension State", | 
|  | }; | 
|  |  | 
|  | // `Storage` path. | 
|  | constexpr char kStorageFilePath[] = "Storage"; | 
|  | constexpr char kStorageExtFilePath[] = "ext"; | 
|  |  | 
|  | // Values used for the kBrowserDataMigrationMode flag. | 
|  | constexpr char kCopySwitchValue[] = "copy";  // Corresponds to kCopy. | 
|  | constexpr char kMoveSwitchValue[] = "move";  // Corresponds to KMove. | 
|  |  | 
|  | // The type of LevelDB schema. | 
|  | enum class LevelDBType { | 
|  | kLocalStorage = 0, | 
|  | kStateStore = 1, | 
|  | }; | 
|  |  | 
|  | // Map from ExtensionID -> { leveldb keys..}. | 
|  | using ExtensionKeys = std::map<std::string, std::vector<std::string>>; | 
|  |  | 
|  | // Structure containing both IndexedDB paths for an extension. | 
|  | struct IndexedDBPaths { | 
|  | base::FilePath blob_path; | 
|  | base::FilePath leveldb_path; | 
|  | }; | 
|  |  | 
|  | // Structure containing Ash and Lacros's version of Preferences. | 
|  | struct PreferencesContents { | 
|  | std::string ash; | 
|  | std::string lacros; | 
|  | }; | 
|  |  | 
|  | // Chrome instance type (Ash or Lacros). | 
|  | enum class ChromeType { | 
|  | kAsh, | 
|  | kLacros, | 
|  | }; | 
|  |  | 
|  | // Preferences's keys that have to be split between Ash and Lacros | 
|  | // based on extension id. | 
|  | constexpr const char* kSplitPreferencesKeys[] = { | 
|  | "extensions.pinned_extensions", "extensions.settings", | 
|  | "extensions.toolbar",           "updateclientdata.apps", | 
|  | "web_apps.web_app_ids", | 
|  | }; | 
|  | // Preferences's keys that should not be migrated to Lacros. | 
|  | constexpr const char* kAshOnlyPreferencesKeys[] = { | 
|  | "app_list.local_state", | 
|  | "invalidation.per_sender_active_registration_tokens", | 
|  | "invalidation.per_sender_client_id_cache", | 
|  | "invalidation.per_sender_registered_for_invalidation", | 
|  | "invalidation.per_sender_topics_to_handler", | 
|  | "invalidation.topics_to_handler", | 
|  | }; | 
|  | // Preferences's key that has to be moved to Lacros, and cleared in Ash. | 
|  | constexpr const char* kLacrosOnlyPreferencesKeys[] = { | 
|  | "sync.cache_guid", | 
|  | }; | 
|  |  | 
|  | // List of data types in Sync Data that have to stay in Ash and Ash only. | 
|  | static_assert(46 == syncer::GetNumModelTypes(), | 
|  | "If adding a new sync data type, update the lists below if" | 
|  | " you want to keep the new data type in Ash only."); | 
|  | constexpr syncer::ModelType kAshOnlySyncDataTypes[] = { | 
|  | syncer::ModelType::APP_LIST, | 
|  | syncer::ModelType::ARC_PACKAGE, | 
|  | syncer::ModelType::OS_PREFERENCES, | 
|  | syncer::ModelType::OS_PRIORITY_PREFERENCES, | 
|  | syncer::ModelType::PRINTERS, | 
|  | syncer::ModelType::PRINTERS_AUTHORIZATION_SERVERS, | 
|  | syncer::ModelType::WIFI_CONFIGURATIONS, | 
|  | syncer::ModelType::WORKSPACE_DESK, | 
|  | }; | 
|  |  | 
|  | constexpr char kTotalSize[] = "Ash.UserDataStatsRecorder.DataSize.TotalSize"; | 
|  |  | 
|  | // UMA name prefix to record sizes of files/dirs in profile data directory. The | 
|  | // name unique to each file/dir is appended to the end to create a full UMA name | 
|  | // as follows `Ash.UserDataStatsRecorder.DataSize.{ItemName}`. | 
|  | constexpr char kUserDataStatsRecorderDataSize[] = | 
|  | "Ash.UserDataStatsRecorder.DataSize."; | 
|  |  | 
|  | // Files/dirs that is not assigned a unique uma name is given this name. | 
|  | constexpr char kUnknownUMAName[] = "Unknown"; | 
|  |  | 
|  | constexpr int64_t kBytesInOneMB = 1024 * 1024; | 
|  |  | 
|  | // The size of disk space that should be kept free after migration. This is | 
|  | // important since crypotohome conducts an aggressive disk cleanup if free disk | 
|  | // space becomes less than 768MB. The buffer is rounded up to 1GB. | 
|  | constexpr uint64_t kBuffer = 1024LL * 1024 * 1024; | 
|  |  | 
|  | // CancelFlag | 
|  | class CancelFlag : public base::RefCountedThreadSafe<CancelFlag> { | 
|  | public: | 
|  | CancelFlag(); | 
|  | CancelFlag(const CancelFlag&) = delete; | 
|  | CancelFlag& operator=(const CancelFlag&) = delete; | 
|  |  | 
|  | void Set() { cancelled_ = true; } | 
|  | bool IsSet() const { return cancelled_; } | 
|  |  | 
|  | private: | 
|  | friend base::RefCountedThreadSafe<CancelFlag>; | 
|  |  | 
|  | ~CancelFlag(); | 
|  | std::atomic_bool cancelled_; | 
|  | }; | 
|  |  | 
|  | // This is used to describe top level entries inside ash-chrome's profile data | 
|  | // directory. | 
|  | struct TargetItem { | 
|  | enum class ItemType { kFile, kDirectory }; | 
|  | TargetItem(base::FilePath path, int64_t size, ItemType item_type); | 
|  | ~TargetItem() = default; | 
|  | bool operator==(const TargetItem& rhs) const; | 
|  |  | 
|  | base::FilePath path; | 
|  | // The size of the TargetItem. If TargetItem is a directory, it is the sum | 
|  | // of all files under the directory. | 
|  | int64_t size; | 
|  | bool is_directory; | 
|  | }; | 
|  |  | 
|  | // `TargetItems` should hold `TargetItem`s of the same `ItemType`. | 
|  | struct TargetItems { | 
|  | TargetItems(); | 
|  | ~TargetItems(); | 
|  | TargetItems(TargetItems&&); | 
|  |  | 
|  | std::vector<TargetItem> items; | 
|  | // The sum of the sizes of `TargetItem`s in `items`. | 
|  | int64_t total_size = 0; | 
|  | }; | 
|  |  | 
|  | // Specifies the type of `TargetItem` | 
|  | enum class ItemType { | 
|  | kLacros = 0,       // Item that should be moved to lacros profile directory. | 
|  | kRemainInAsh = 1,  // Item that should remain in ash. | 
|  | kNeedCopyForMove = | 
|  | 2,  // Item that should be copied to lacros during move migration. | 
|  | kNeedCopyForCopy = 3,  // Item that should be copied to lacros during copy | 
|  | // migration. This is kNeedCopyForMove + "Preferences". | 
|  | kDeletable = 4,  // Item that can be deleted to free up space i.e. cache. | 
|  | }; | 
|  |  | 
|  | // It enumerates the file/dirs in the given directory and returns items of | 
|  | // `type`. E.g. `GetTargetItems(path, ItemType::kLacros)` will get all items | 
|  | // that should be moved to lacros. | 
|  | TargetItems GetTargetItems(const base::FilePath& original_profile_dir, | 
|  | ItemType type); | 
|  |  | 
|  | // Checks if there is enough disk space to migration to be carried out safely. | 
|  | // that needs to be copied. | 
|  | bool HasEnoughDiskSpace(int64_t total_copy_size, | 
|  | const base::FilePath& original_profile_dir); | 
|  |  | 
|  | // Returns extra bytes that has to be freed for the migration to be carried out | 
|  | // if there are `total_copy_size` bytes of copying to be done. Returns 0 if no | 
|  | // extra space needs to be freed. | 
|  | uint64_t ExtraBytesRequiredToBeFreed( | 
|  | int64_t total_copy_size, | 
|  | const base::FilePath& original_profile_dir); | 
|  |  | 
|  | // Returns an estimate of the total of file sizes created during profile | 
|  | // migration in bytes. Note that this underestimates the total because some | 
|  | // smaller files that are being created during the migration. | 
|  | int64_t EstimatedExtraBytesCreated(const base::FilePath& original_profile_dir); | 
|  |  | 
|  | // Injects the bytes to be returned by ExtraBytesRequiredToBeFreed above | 
|  | // in RAII manner. | 
|  | class ScopedExtraBytesRequiredToBeFreedForTesting { | 
|  | public: | 
|  | explicit ScopedExtraBytesRequiredToBeFreedForTesting(uint64_t bytes); | 
|  | ~ScopedExtraBytesRequiredToBeFreedForTesting(); | 
|  | }; | 
|  |  | 
|  | // Copies `items` to `to_dir`. | 
|  | bool CopyTargetItems(const base::FilePath& to_dir, | 
|  | const TargetItems& items, | 
|  | CancelFlag* cancel_flag, | 
|  | MigrationProgressTracker* progress_tracker); | 
|  |  | 
|  | // Copies `item` to location pointed by `dest`. Returns true on success and | 
|  | // false on failure. | 
|  | bool CopyTargetItem(const TargetItem& item, | 
|  | const base::FilePath& dest, | 
|  | CancelFlag* cancel_flag, | 
|  | MigrationProgressTracker* progress_tracker); | 
|  |  | 
|  | // Copies the contents of `from_path` to `to_path` recursively. Unlike | 
|  | // `base::CopyDirectory()` it skips symlinks. | 
|  | bool CopyDirectory(const base::FilePath& from_path, | 
|  | const base::FilePath& to_path, | 
|  | CancelFlag* cancel_flag, | 
|  | MigrationProgressTracker* progress_tracker); | 
|  |  | 
|  | // Creates a hard link from `from_file` to `to_file`. Use it on a file and not a | 
|  | // directory. Any parent directory of `to_file` should already exist. This will | 
|  | // fail if `to_dir` already exists. | 
|  | bool CreateHardLink(const base::FilePath& from_file, | 
|  | const base::FilePath& to_file); | 
|  |  | 
|  | // Copies the content of `from_dir` to `to_dir` recursively similar to | 
|  | // `CopyDirectory` while skipping symlinks. Unlike `CopyDirectory` it creates | 
|  | // hard links for the files from `from_dir` to `to_dir`. If `to_dir` | 
|  | // already exists, then this will fail. | 
|  | bool CopyDirectoryByHardLinks(const base::FilePath& from_dir, | 
|  | const base::FilePath& to_dir); | 
|  |  | 
|  | // Copies `items` to `to_dir` by calling `CreateHardLink()` for files and | 
|  | // `CopyDirectoryBeHardLinks()` for directories. | 
|  | bool CopyTargetItemsByHardLinks(const base::FilePath& to_dir, | 
|  | const TargetItems& items, | 
|  | CancelFlag* cancel_flag); | 
|  |  | 
|  | // Records the sizes of `TargetItem`s. | 
|  | void RecordTargetItemSizes(const std::vector<TargetItem>& items); | 
|  |  | 
|  | // Records `size` of the file/dir pointed by `path`. If it is a directory, the | 
|  | // size is the recursively accumulated sizes of contents inside. | 
|  | void RecordUserDataSize(const base::FilePath& path, int64_t size); | 
|  |  | 
|  | // Collects migration specific UMAs without actually running the migration. It | 
|  | // does not check if lacros is enabled. | 
|  | void DryRunToCollectUMA(const base::FilePath& profile_data_dir); | 
|  |  | 
|  | // Given a leveldb instance and its type, output a map from | 
|  | // ExtensionID -> { keys associated with the extension... }. | 
|  | leveldb::Status GetExtensionKeys(leveldb::DB* db, | 
|  | LevelDBType leveldb_type, | 
|  | ExtensionKeys* result); | 
|  |  | 
|  | // Returns UMA name for `path`. Returns `kUnknownUMAName` if `path` is not in | 
|  | // `kPathNamePairs`. | 
|  | std::string GetUMAItemName(const base::FilePath& path); | 
|  |  | 
|  | // Similar to `base::ComputeDirectorySize()` this computes the sum of all files | 
|  | // under `dir_path` recursively while skipping symlinks. | 
|  | int64_t ComputeDirectorySizeWithoutLinks(const base::FilePath& dir_path); | 
|  |  | 
|  | // Record the total size of the user's profile data directory in MB. | 
|  | void RecordTotalSize(int64_t size); | 
|  |  | 
|  | // Given a key in Sync Data's leveldb, returns true if (based on its prefix) its | 
|  | // data type has to stay in Ash and Ash only, false otherwise. | 
|  | bool IsAshOnlySyncDataType(base::StringPiece key); | 
|  |  | 
|  | // Given an extension id, return the paths of the associated blob | 
|  | // and leveldb directories inside IndexedDB. | 
|  | IndexedDBPaths GetIndexedDBPaths(const base::FilePath& profile_path, | 
|  | const char* extension_id); | 
|  |  | 
|  | // Migrate the LevelDB instance at `original_path` to `target_path`, | 
|  | // Filter out all the extensions that are not in `kExtensionsAshOnly`. | 
|  | // `leveldb_type` determines the schema type. | 
|  | bool MigrateLevelDB(const base::FilePath& original_path, | 
|  | const base::FilePath& target_path, | 
|  | const LevelDBType leveldb_type); | 
|  |  | 
|  | // Migrate Sync Data's LevelDB instance at `original_path` to Ash and Lacros. | 
|  | // For Ash, filter out the data types that are not meant to be ported to Lacros. | 
|  | // For Lacros, filter out the data types that are meant to stay in Ash. | 
|  | bool MigrateSyncDataLevelDB(const base::FilePath& original_path, | 
|  | const base::FilePath& ash_target_path, | 
|  | const base::FilePath& lacros_target_path); | 
|  |  | 
|  | // Manipulates the given representation of Preferences (`root_dict`) | 
|  | // so that the given key only contains values relevant to Ash or | 
|  | // Lacros, depending on `chrome_type`. | 
|  | // | 
|  | // If the entry in `root_dict` at `key` is a dict in the format | 
|  | // { <AppId> : { ... }, ... }, it will change the dict to contain only | 
|  | // AppIds of extensions meant to be in `chrome_type` (Ash or Lacros). | 
|  | // | 
|  | // If the entry is a list in the format [ <AppId>, ... ], it will | 
|  | // change the list to contain only AppIds of extensions meant to be | 
|  | // in `chrome_type` (Ash or Lacros). | 
|  | // | 
|  | // If the entry is a list in any other format, if it doesn't exist, | 
|  | // or if it's not container type, no changes will be performed. | 
|  | void UpdatePreferencesKeyByType(base::Value::Dict* root_dict, | 
|  | const base::StringPiece key, | 
|  | ChromeType chrome_type); | 
|  |  | 
|  | // Given a `original_contents` string containing the original Preferences | 
|  | // file, return the migrated Ash and Lacros versions of Preferences. | 
|  | absl::optional<PreferencesContents> MigratePreferencesContents( | 
|  | const base::StringPiece original_contents); | 
|  |  | 
|  | // Migrate Preferences to Ash and Lacros. | 
|  | bool MigratePreferences(const base::FilePath& original_path, | 
|  | const base::FilePath& ash_target_path, | 
|  | const base::FilePath& lacros_target_path); | 
|  |  | 
|  | // Copy or move IndexedDB objects to Ash's profile directory. | 
|  | bool MigrateAshIndexedDB(const base::FilePath& src_profile_dir, | 
|  | const base::FilePath& target_indexed_db_dir, | 
|  | const char* extension_id, | 
|  | bool copy); | 
|  |  | 
|  | }  // namespace ash::browser_data_migrator_util | 
|  |  | 
|  | #endif  // CHROME_BROWSER_ASH_CROSAPI_BROWSER_DATA_MIGRATOR_UTIL_H_ |