| // 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)>; |
| |
| // 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}; |
| }; |
| |
| // 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}; |
| }; |
| |
| // 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_ |