| // 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. |
| |
| #include "chrome/browser/ash/file_manager/io_task.h" |
| |
| #include <type_traits> |
| #include <vector> |
| |
| #include "base/files/file_path.h" |
| #include "base/functional/callback.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "chrome/browser/ash/file_manager/path_util.h" |
| #include "chrome/browser/ash/file_manager/volume_manager.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "storage/browser/file_system/file_system_url.h" |
| |
| namespace file_manager::io_task { |
| |
| std::ostream& operator<<(std::ostream& out, const State state) { |
| switch (state) { |
| #define PRINT(s) \ |
| case State::k##s: \ |
| return out << #s; |
| PRINT(Queued) |
| PRINT(Scanning) |
| PRINT(InProgress) |
| PRINT(Paused) |
| PRINT(Success) |
| PRINT(Error) |
| PRINT(NeedPassword) |
| PRINT(Cancelled) |
| #undef PRINT |
| } |
| |
| return out << "State(" << static_cast<std::underlying_type_t<State>>(state) |
| << ")"; |
| } |
| |
| std::ostream& operator<<(std::ostream& out, OperationType op) { |
| switch (op) { |
| #define PRINT(s) \ |
| case OperationType::k##s: \ |
| return out << #s; |
| PRINT(Copy) |
| PRINT(Delete) |
| PRINT(EmptyTrash) |
| PRINT(Extract) |
| PRINT(Move) |
| PRINT(Restore) |
| PRINT(RestoreToDestination) |
| PRINT(Trash) |
| PRINT(Zip) |
| #undef PRINT |
| } |
| |
| return out << "OperationType(" |
| << static_cast<std::underlying_type_t<OperationType>>(op) << ")"; |
| } |
| |
| void IOTask::Pause(PauseParams params) {} |
| |
| void IOTask::Resume(ResumeParams) {} |
| |
| void IOTask::CompleteWithError(PolicyError policy_error) {} |
| |
| bool PolicyError::operator==(const PolicyError& other) const = default; |
| |
| bool ConflictPauseParams::operator==(const ConflictPauseParams& other) const = |
| default; |
| |
| bool PolicyPauseParams::operator==(const PolicyPauseParams& other) const = |
| default; |
| |
| PauseParams::PauseParams() = default; |
| |
| PauseParams::PauseParams(const PauseParams& other) = default; |
| |
| PauseParams& PauseParams::operator=(const PauseParams& other) = default; |
| |
| PauseParams::PauseParams(PauseParams&& other) = default; |
| |
| PauseParams& PauseParams::operator=(PauseParams&& other) = default; |
| |
| bool PauseParams::operator==(const PauseParams& other) const { |
| return (conflict_params == other.conflict_params) && |
| (policy_params == other.policy_params); |
| } |
| |
| PauseParams::~PauseParams() = default; |
| |
| ResumeParams::ResumeParams() = default; |
| |
| ResumeParams::ResumeParams(const ResumeParams& other) = default; |
| |
| ResumeParams& ResumeParams::operator=(const ResumeParams& other) = default; |
| |
| ResumeParams::ResumeParams(ResumeParams&& other) = default; |
| |
| ResumeParams& ResumeParams::operator=(ResumeParams&& other) = default; |
| |
| ResumeParams::~ResumeParams() = default; |
| |
| EntryStatus::EntryStatus(storage::FileSystemURL file_url, |
| std::optional<base::File::Error> file_error, |
| std::optional<storage::FileSystemURL> source_url) |
| : url(file_url), error(file_error), source_url(source_url) {} |
| |
| EntryStatus::~EntryStatus() = default; |
| |
| EntryStatus::EntryStatus(EntryStatus&& other) = default; |
| EntryStatus& EntryStatus::operator=(EntryStatus&& other) = default; |
| |
| ProgressStatus::ProgressStatus() = default; |
| ProgressStatus::~ProgressStatus() = default; |
| |
| ProgressStatus::ProgressStatus(ProgressStatus&& other) = default; |
| ProgressStatus& ProgressStatus::operator=(ProgressStatus&& other) = default; |
| |
| bool ProgressStatus::IsPaused() const { |
| return state == State::kPaused; |
| } |
| |
| bool ProgressStatus::IsCompleted() const { |
| return state == State::kSuccess || state == State::kError || |
| state == State::kCancelled; |
| } |
| |
| bool ProgressStatus::HasWarning() const { |
| // We should show a warning if the task is paused because of policy. |
| return IsPaused() && pause_params.policy_params.has_value(); |
| } |
| |
| bool ProgressStatus::HasPolicyError() const { |
| return state == State::kError && policy_error.has_value(); |
| } |
| |
| bool ProgressStatus::IsScanning() const { |
| return state == State::kScanning; |
| } |
| |
| std::string ProgressStatus::GetSourceName(Profile* profile) const { |
| if (!source_name.empty()) { |
| return source_name; |
| } |
| |
| if (sources.size() == 0) { |
| return {}; |
| } |
| |
| return util::GetDisplayablePath(profile, sources.front().url) |
| .value_or(base::FilePath()) |
| .BaseName() |
| .value(); |
| } |
| |
| void ProgressStatus::SetDestinationFolder(storage::FileSystemURL folder, |
| Profile* const profile) { |
| destination_folder_ = std::move(folder); |
| destination_volume_id_.clear(); |
| if (profile) { |
| if (VolumeManager* const volume_manager = VolumeManager::Get(profile)) { |
| if (const base::WeakPtr<const Volume> volume = |
| volume_manager->FindVolumeFromPath(destination_folder_.path())) { |
| destination_volume_id_ = volume->volume_id(); |
| } |
| } |
| } |
| } |
| |
| DummyIOTask::DummyIOTask(std::vector<storage::FileSystemURL> source_urls, |
| storage::FileSystemURL destination_folder, |
| OperationType type, |
| bool show_notifications, |
| bool progress_succeeds) |
| : IOTask(show_notifications), progress_succeeds_(progress_succeeds) { |
| progress_.state = State::kQueued; |
| progress_.type = type; |
| progress_.SetDestinationFolder(std::move(destination_folder)); |
| progress_.bytes_transferred = 0; |
| progress_.total_bytes = 2; |
| |
| for (auto& url : source_urls) { |
| progress_.sources.emplace_back(url, std::nullopt); |
| } |
| } |
| |
| DummyIOTask::~DummyIOTask() = default; |
| |
| void DummyIOTask::Execute(IOTask::ProgressCallback progress_callback, |
| IOTask::CompleteCallback complete_callback) { |
| progress_callback_ = std::move(progress_callback); |
| complete_callback_ = std::move(complete_callback); |
| |
| progress_.state = State::kInProgress; |
| progress_callback_.Run(progress_); |
| |
| base::SequencedTaskRunner::GetCurrentDefault()->PostTask( |
| FROM_HERE, |
| base::BindOnce(&DummyIOTask::DoProgress, weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void DummyIOTask::Pause(PauseParams pause_params) { |
| progress_.state = State::kPaused; |
| progress_.pause_params = pause_params; |
| } |
| |
| void DummyIOTask::Resume(ResumeParams resume_params) { |
| progress_.state = State::kInProgress; |
| } |
| |
| void DummyIOTask::Cancel() { |
| progress_.state = State::kCancelled; |
| } |
| |
| void DummyIOTask::CompleteWithError(PolicyError policy_error) { |
| progress_.state = State::kError; |
| progress_.policy_error.emplace(std::move(policy_error)); |
| } |
| |
| void DummyIOTask::DoProgress() { |
| if (progress_.IsPaused()) { |
| return; |
| } |
| |
| progress_.bytes_transferred = 1; |
| progress_callback_.Run(progress_); |
| |
| if (progress_succeeds_) { |
| base::SequencedTaskRunner::GetCurrentDefault()->PostTask( |
| FROM_HERE, base::BindOnce(&DummyIOTask::DoComplete, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| } |
| |
| void DummyIOTask::DoComplete() { |
| progress_.state = State::kSuccess; |
| progress_.bytes_transferred = 2; |
| for (auto& source : progress_.sources) { |
| source.error.emplace(base::File::FILE_OK); |
| } |
| std::move(complete_callback_).Run(std::move(progress_)); |
| } |
| |
| } // namespace file_manager::io_task |