1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
// Copyright 2024 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_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_
#define CHROME_BROWSER_ASH_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_
#include <memory>
#include <optional>
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/timer/wall_clock_timer.h"
#include "chrome/browser/ash/policy/skyvault/local_user_files_policy_observer.h"
#include "chrome/browser/ash/policy/skyvault/migration_coordinator.h"
#include "chrome/browser/ash/policy/skyvault/migration_notification_manager.h"
#include "chrome/browser/ash/policy/skyvault/policy_utils.h"
#include "chrome/browser/chromeos/extensions/login_screen/login/cleanup/files_cleanup_handler.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
#include "chromeos/ash/components/dbus/cryptohome/UserDataAuth.pb.h"
#include "components/keyed_service/core/keyed_service.h"
namespace base {
template <typename T>
class NoDestructor;
} // namespace base
namespace content {
class BrowserContext;
} // namespace content
namespace policy::local_user_files {
// Manages the migration of local files to the cloud when SkyVault is enabled.
// Handles starting, monitoring, and completing the migration process.
class LocalFilesMigrationManager : public LocalUserFilesPolicyObserver,
public KeyedService {
public:
class Observer {
public:
// Called when the migration of files to the cloud has completed
// successfully.
virtual void OnMigrationSucceeded() = 0;
// Called when the migration of files to the cloud has been reset.
virtual void OnMigrationReset() = 0;
};
// Creates an instance of LocalFilesMigrationManager with overridden
// dependencies.
static LocalFilesMigrationManager* CreateForTesting(
content::BrowserContext* context,
MigrationNotificationManager* notification_manager,
std::unique_ptr<MigrationCoordinator> coordinator);
// Creates an instance of LocalFilesMigrationManager.
explicit LocalFilesMigrationManager(content::BrowserContext* context);
LocalFilesMigrationManager(const LocalFilesMigrationManager&) = delete;
LocalFilesMigrationManager& operator=(const LocalFilesMigrationManager&) =
delete;
~LocalFilesMigrationManager() override;
// Initializes this instance.
void Initialize();
// KeyedService overrides:
void Shutdown() override;
// Adds an observer to receive notifications about migration events.
void AddObserver(Observer* observer);
// Removes an observer.
void RemoveObserver(Observer* observer);
// Injects a mock MigrationNotificationManager for tests.
void SetNotificationManagerForTesting(
MigrationNotificationManager* notification_manager);
// Injects a mock MigrationCoordinator for tests.
void SetCoordinatorForTesting(
std::unique_ptr<MigrationCoordinator> coordinator);
// Injects a mock FilesCleanupHandler for tests.
void SetCleanupHandlerForTesting(
base::WeakPtr<chromeos::FilesCleanupHandler> cleanup_handler);
private:
// Called after the preferences have been loaded.
void OnPrefsInitialized(bool success);
// Initializes this instance, after the preferences have been loaded.
void InitializeFromPrefs();
// policy::local_user_files::Observer overrides:
void OnLocalUserFilesPolicyChanged() override;
// Called after migration is stopped and can be started again.
void OnMigrationStopped(bool log_file_deleted);
// Called after contents of MyFiles are checked. If empty, removes the volume
// and restricts write access, otherwise initiates the migration based on the
// current state.
void OnMyFilesChecked(bool is_empty);
// Informs the user about the upcoming migration. Schedules another dialog to
// appear closer to the start. From the dialog, the user can also choose to
// start the migration immediately.
void InformUser();
// After initial delay, informs the user again and schedules the migration to
// start automatically. From the dialog, the user can also choose to start the
// migration immediately.
void ScheduleMigrationAndInformUser(const base::Time scheduled_start_time);
// Bypasses the migration delay and initiates the upload process immediately.
// Called when the user clicks the "Upload now" button in the info dialog.
void SkipMigrationDelay();
// Called after the full migration timeout elapses. Closes the dialog if
// opened, and starts migration.
void OnTimeoutExpired();
// Gathers all file paths that need to be uploaded.
void GetPathsToUpload();
// Starts the migration process by uploading `files` to `cloud_provider_`.
void StartMigration(std::vector<base::FilePath> files);
// Handles the completion of the migration process (success or failure).
// If the migration was successful, starts the cleanup process, and handles
// the errors otherwise.
void OnMigrationDone(std::map<base::FilePath, MigrationUploadError> errors,
base::FilePath upload_root_path,
base::FilePath error_log_path);
// Completes the migration process, taking into account any errors that
// occurred during the migration.
void ProcessErrors(std::map<base::FilePath, MigrationUploadError> errors,
base::FilePath error_log_path);
// Cleans up any remaining files from the device after a successful migration.
void CleanupLocalFiles();
// Handles the completion of the local files cleanup process.
void OnCleanupDone(
std::unique_ptr<chromeos::FilesCleanupHandler> cleanup_handler,
const std::optional<std::string>& error_message);
// Sends a D-Bus call to enable or disable write access to MyFiles.
void SetLocalUserFilesWriteEnabled(bool enabled);
// Handles the response of the SetUserDataStorageWriteEnabled D-Bus call.
void OnFilesWriteRestricted(
std::optional<user_data_auth::SetUserDataStorageWriteEnabledReply> reply);
// Stops the migration if currently ongoing.
void MaybeStopMigration(MigrationDestination previous_destination,
bool close_dialog = true,
MigrationStoppedCallback = base::DoNothing());
// Sets and stores the state on the device.
void SetState(State new_state);
// Resets all stored prefs, like the state and start time, in case migration
// is stopped.
void ResetMigrationPrefs();
// Notifies the observers that migration succeeded.
void NotifySuccess();
// Notifies the observers that migration was reset.
void NotifyReset();
// Observers for migration events.
base::ObserverList<Observer>::Unchecked observers_;
// Indicates the migration state.
State state_ = State::kUninitialized;
// Indicates if local files cleanup is currently running.
bool cleanup_in_progress_ = false;
// Whether local user files are allowed by policy.
bool local_user_files_allowed_ = true;
// Indicates how local files should be handled (upload to the cloud or
// delete). If not specified, no migration happens.
MigrationDestination migration_destination_ =
MigrationDestination::kNotSpecified;
// The name of the device-unique upload root folder on Drive
std::string upload_root_;
// Context for which this instance is created.
raw_ptr<content::BrowserContext> context_;
// Shows and manages migration notifications and dialogs.
raw_ptr<MigrationNotificationManager> notification_manager_;
// Manages the upload of local files to the cloud.
std::unique_ptr<MigrationCoordinator> coordinator_;
// Timer for delaying the start of migration and showing dialogs.
std::unique_ptr<base::WallClockTimer> scheduling_timer_;
// Number of times the entire upload failed and was retried.
int current_retry_count_;
base::WeakPtr<chromeos::FilesCleanupHandler> cleanup_handler_for_testing_ =
nullptr;
base::WeakPtrFactory<LocalFilesMigrationManager> weak_factory_{this};
};
// Manages all LocalFilesMigrationManager instances and associates them with
// Profiles.
class LocalFilesMigrationManagerFactory : public ProfileKeyedServiceFactory {
public:
LocalFilesMigrationManagerFactory(const LocalFilesMigrationManagerFactory&) =
delete;
LocalFilesMigrationManagerFactory& operator=(
const LocalFilesMigrationManagerFactory&) = delete;
// Gets the singleton instance of the factory.
static LocalFilesMigrationManagerFactory* GetInstance();
// Gets the LocalFilesMigrationManager instance associated with the given
// BrowserContext. If `create` is true, an instance is created if it doesn't
// exist.
static LocalFilesMigrationManager* GetForBrowserContext(
content::BrowserContext* context,
bool create = true);
private:
friend base::NoDestructor<LocalFilesMigrationManagerFactory>;
LocalFilesMigrationManagerFactory();
~LocalFilesMigrationManagerFactory() override;
// BrowserContextKeyedServiceFactory overrides:
bool ServiceIsNULLWhileTesting() const override;
std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
content::BrowserContext* context) const override;
};
} // namespace policy::local_user_files
#endif // CHROME_BROWSER_ASH_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_
|