| // Copyright 2022 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_FILE_MANAGER_EXTRACT_IO_TASK_H_ |
| #define CHROME_BROWSER_ASH_FILE_MANAGER_EXTRACT_IO_TASK_H_ |
| |
| #include <optional> |
| #include <vector> |
| |
| #include "base/files/file_error_or.h" |
| #include "base/files/file_path.h" |
| #include "base/functional/callback.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ash/drive/drive_integration_service.h" |
| #include "chrome/browser/ash/drive/file_system_util.h" |
| #include "chrome/browser/ash/file_manager/io_task.h" |
| #include "chromeos/ash/components/file_manager/speedometer.h" |
| #include "components/file_access/scoped_file_access.h" |
| #include "components/services/unzip/public/cpp/unzip.h" |
| #include "storage/browser/file_system/file_system_context.h" |
| #include "storage/browser/file_system/file_system_url.h" |
| |
| namespace file_manager::io_task { |
| |
| // Histogram name for FileBrowser.ExtractTask. |
| inline constexpr char kExtractTaskStatusHistogramName[] = |
| "FileBrowser.ExtractTask.Status"; |
| |
| // Extract archive status. These values are persisted to logs. Entries should |
| // not be renumbered and numeric values should never be reused. |
| // See enum FileManagerExtractStatus in enums.xml. |
| enum class ExtractStatus { |
| kSuccess = 0, |
| kUnknownError = 1, |
| kCancelled = 2, |
| kInsufficientDiskSpace = 3, |
| kPasswordError = 4, |
| kAesEncrypted = 5, |
| kMaxValue = kAesEncrypted, |
| }; |
| |
| class ExtractIOTask : public IOTask { |
| public: |
| // Create a task to extract any ZIP files in |source_urls|. These |
| // must be under the |parent_folder| directory, and the resulting extraction |
| // will be created there. |
| ExtractIOTask(std::vector<storage::FileSystemURL> source_urls, |
| std::string password, |
| storage::FileSystemURL parent_folder, |
| Profile* profile, |
| scoped_refptr<storage::FileSystemContext> file_system_context, |
| bool show_notification = true); |
| ~ExtractIOTask() override; |
| |
| void Execute(ProgressCallback progress_callback, |
| CompleteCallback complete_callback) override; |
| |
| // Cancels ongoing unzips. Must be called on the same sequence as |
| // ExtractIntoNewDirectory and FinishedExtraction. |
| void Cancel() override; |
| |
| private: |
| void Complete(); |
| |
| void FinishedExtraction(base::FilePath directory, bool success); |
| |
| void ZipExtractCallback(base::FilePath destination_directory, bool success); |
| |
| void ZipListenerCallback(uint64_t bytes); |
| |
| void ExtractIntoNewDirectory(base::FilePath destination_directory, |
| base::FilePath source_file, |
| bool created_ok); |
| |
| void ExtractArchive( |
| size_t index, |
| base::FileErrorOr<storage::FileSystemURL> destination_result); |
| |
| void ExtractAllSources(); |
| |
| void ZipInfoCallback(unzip::mojom::InfoPtr info); |
| |
| void GetExtractedSize(base::FilePath source_file); |
| |
| void GotFreeDiskSpace(int64_t free_space); |
| |
| void CheckSizeThenExtract(); |
| |
| // Stores the file access object and begins the actual extraction. This object |
| // needs to survive for the all extraction time, otherwise when Data Leak |
| // Prevention features are enabled, managed archives cannot be opened. |
| void GotScopedFileAccess(file_access::ScopedFileAccess file_access); |
| |
| // Retrieves a scoped file access object for the zip files under examination |
| // and calls `GotScopedFileAccess`. This is required to open the zip files |
| // when Data Leak Prevention features are enabled. When these features are not |
| // enabled, `GotScopedFileAccess` is directly called with a default |
| // always-allow file access object. |
| void GetScopedFileAccess(); |
| |
| // URLs of the files that have archives in them for extraction. |
| const std::vector<storage::FileSystemURL> source_urls_; |
| |
| // Password for decrypting encrypted source_urls_ (one only). |
| const std::string password_; |
| |
| // Parent folder of the files in 'source_urls_'. |
| const storage::FileSystemURL parent_folder_; |
| |
| // Raw pointer not owned by this. |
| raw_ptr<Profile> profile_; |
| const scoped_refptr<storage::FileSystemContext> file_system_context_; |
| |
| // Speedometer used to calculate the remaining time to finish the operation. |
| Speedometer speedometer_; |
| |
| ProgressCallback progress_callback_; |
| CompleteCallback complete_callback_; |
| |
| // Counter of the number of archives needing extracted size retrieved. |
| size_t sizingCount_; |
| |
| // Boolean set to true if we find archives that are encrypted. |
| bool have_encrypted_content_ = false; |
| |
| // Boolean set to true if the encryption scheme is AES. |
| bool uses_aes_encryption_ = false; |
| |
| // Boolean set to true if any archive extraction fails. |
| bool any_archive_failed_ = false; |
| |
| // Counter of the number of archives needing extraction. |
| size_t extractCount_; |
| |
| // A closure that triggers a chain of cancellation callbacks, cancelling all |
| // ongoing unzipping operations. |
| base::OnceClosure cancellation_chain_ = base::DoNothing(); |
| |
| // Scoped file access object required to open the zipped files when Data Leak |
| // Prevention features are enabled. |
| std::optional<file_access::ScopedFileAccess> file_access_; |
| |
| base::WeakPtrFactory<ExtractIOTask> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace file_manager::io_task |
| |
| #endif // CHROME_BROWSER_ASH_FILE_MANAGER_EXTRACT_IO_TASK_H_ |