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
|
// 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_MIGRATION_COORDINATOR_H_
#define CHROME_BROWSER_ASH_POLICY_SKYVAULT_MIGRATION_COORDINATOR_H_
#include <map>
#include <memory>
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/ash/policy/skyvault/drive_skyvault_uploader.h"
#include "chrome/browser/ash/policy/skyvault/odfs_skyvault_uploader.h"
#include "chrome/browser/ash/policy/skyvault/policy_utils.h"
#include "storage/browser/file_system/file_system_url.h"
namespace policy::local_user_files {
// Callback used to signal that all uploads completed (successfully or not).
// Parameters:
// errors: Map of source file paths to upload errors (empty if no errors).
// upload_root_path: Path to the upload root, or empty on early failure.
// error_log_path: Path to the error log file (empty if no errors).
using MigrationDoneCallback =
base::OnceCallback<void(std::map<base::FilePath, MigrationUploadError>,
base::FilePath,
base::FilePath)>;
// Callback to signal that migration has completely stopped and can be
// restarted.
using MigrationStoppedCallback = base::OnceCallback<void(bool)>;
class MigrationCloudUploader;
// Handles the upload of local files to a specified cloud storage destination.
// This class provides a generic interface for initiating, stopping, and
// monitoring uploads. The specific implementation for each cloud provider is
// handled by derived classes of MigrationCloudUploader.
class MigrationCoordinator {
public:
explicit MigrationCoordinator(Profile* profile);
MigrationCoordinator(const MigrationCoordinator&) = delete;
MigrationCoordinator& operator=(const MigrationCoordinator&) = delete;
virtual ~MigrationCoordinator();
// Starts the upload of files specified by `source_urls` to the
// `upload_root` directory on `destination`. Invokes `callback` upon
// completion, passing any errors that occurred and the absolute path to the
// root upload directory. Fails if a migration is already in progress.
virtual void Run(MigrationDestination destination,
std::vector<base::FilePath> files,
const std::string& upload_root,
MigrationDoneCallback callback);
// Cancels any ongoing file uploads.
virtual void Cancel(MigrationStoppedCallback callback);
// Returns whether any file uploads are currently in progress.
virtual bool IsRunning() const;
// Sets the `cb` to be invoked when all the uploads are stopped.
void SetCancelledCallbackForTesting(base::OnceClosure cb);
void SetErrorLogPathForTesting(const base::FilePath& path);
private:
// Called after underlying upload operation completes.
virtual void OnMigrationDone(
MigrationDoneCallback callback,
std::map<base::FilePath, MigrationUploadError> errors,
base::FilePath upload_root_path,
base::FilePath error_log_path);
// Profile for which this instance was created.
raw_ptr<Profile> profile_;
base::FilePath error_log_path_;
// The implementation of the upload process, specific to the
// `destination` argument passed to the `Run` method.
std::unique_ptr<MigrationCloudUploader> uploader_ = nullptr;
// If set, invoked when all the uploaders are stopped. Used in tests.
base::OnceClosure cancelled_cb_for_testing_;
base::WeakPtrFactory<MigrationCoordinator> weak_ptr_factory_{this};
};
// Abstract class for the implementation of file uploads to a specific cloud
// storage destination. Derived classes provide the concrete logic for
// interacting with the respective cloud provider.
class MigrationCloudUploader {
public:
MigrationCloudUploader(Profile* profile,
std::vector<base::FilePath> files,
const std::string& upload_root,
const base::FilePath& error_log_path,
MigrationDoneCallback callback);
MigrationCloudUploader(const MigrationCloudUploader&) = delete;
MigrationCloudUploader& operator=(const MigrationCloudUploader&) = delete;
virtual ~MigrationCloudUploader();
// Starts the upload of files to the relevant cloud location. Invokes
// `callback_` upon completion.
void Run();
// Cancels any ongoing file uploads.
virtual void Cancel(base::OnceClosure cancelled_callback) = 0;
protected:
// Called after opening the log file.
virtual void OnLogFileReady(base::File log_file) = 0;
// Called after the error for `file_path` was logged.
virtual void OnErrorLogged(const base::FilePath& file_path) = 0;
// Maps file to their upload errors, if any.
std::map<base::FilePath, MigrationUploadError> errors_;
// Profile for which this instance was created.
const raw_ptr<Profile> profile_;
// The paths of the files or directories to be uploaded.
const std::vector<base::FilePath> files_;
// The name of the device-unique upload root folder on Drive
const std::string upload_root_;
// Absolute path to the device's upload root folder on Drive. This is
// populated after the first successful upload.
base::FilePath upload_root_path_;
// Callback to run after all uploads finish.
MigrationDoneCallback done_callback_;
// Callback to run after all uploads are cancelled.
base::OnceClosure cancelled_callback_;
// Indicates that the upload was cancelled, e.g. by a policy change.
bool cancelled_ = false;
// Error logging:
base::FilePath error_log_path_;
// This file is created/destructed and accessed only on `log_tast_runner_`.
base::File error_log_file_;
scoped_refptr<base::SequencedTaskRunner> log_task_runner_;
base::WeakPtrFactory<MigrationCloudUploader> weak_ptr_factory_{this};
};
// Migration file uploader for uploads to Microsoft OneDrive.
class OneDriveMigrationUploader : public MigrationCloudUploader {
public:
OneDriveMigrationUploader(Profile* profile,
std::vector<base::FilePath> files,
const std::string& upload_root,
const base::FilePath& error_log_path,
MigrationDoneCallback callback);
OneDriveMigrationUploader(const OneDriveMigrationUploader&) = delete;
OneDriveMigrationUploader& operator=(const OneDriveMigrationUploader&) =
delete;
~OneDriveMigrationUploader() override;
// MigrationCloudUploader overrides:
void Cancel(base::OnceClosure cancelled_callback) override;
private:
// Called when one upload operation completes.
void OnUploadDone(const base::FilePath& file_path,
storage::FileSystemURL url,
std::optional<MigrationUploadError> error,
base::FilePath upload_root_path);
// MigrationCloudUploader overrides:
void OnLogFileReady(base::File log_file) override;
void OnErrorLogged(const base::FilePath& file_path) override;
// Maps source urls of files being uploaded to corresponding
// OdfsSkyvaultUploader instances. Keeps a weak reference as lifetime of
// OdfsSkyvaultUploader is managed by its action.
std::map<base::FilePath,
base::WeakPtr<ash::cloud_upload::OdfsSkyvaultUploader>>
uploaders_;
base::WeakPtrFactory<OneDriveMigrationUploader> weak_ptr_factory_{this};
};
// Migration file uploader for uploads to Google Drive.
class GoogleDriveMigrationUploader : public MigrationCloudUploader {
public:
GoogleDriveMigrationUploader(Profile* profile,
std::vector<base::FilePath> files,
const std::string& upload_root,
const base::FilePath& error_log_path,
MigrationDoneCallback callback);
GoogleDriveMigrationUploader(const GoogleDriveMigrationUploader&) = delete;
GoogleDriveMigrationUploader& operator=(const GoogleDriveMigrationUploader&) =
delete;
~GoogleDriveMigrationUploader() override;
// MigrationCloudUploader overrides:
void Cancel(base::OnceClosure cancelled_callback) override;
private:
void OnUploadDone(const base::FilePath& file_path,
std::optional<MigrationUploadError> error,
base::FilePath upload_root_path);
// MigrationCloudUploader overrides:
void OnLogFileReady(base::File log_file) override;
void OnErrorLogged(const base::FilePath& file_path) override;
// Maps source urls of files being uploaded to corresponding
// DriveSkyvaultUploader instances.
std::map<base::FilePath, std::unique_ptr<DriveSkyvaultUploader>> uploaders_;
base::WeakPtrFactory<GoogleDriveMigrationUploader> weak_ptr_factory_{this};
};
} // namespace policy::local_user_files
#endif // CHROME_BROWSER_ASH_POLICY_SKYVAULT_MIGRATION_COORDINATOR_H_
|