diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-09-03 13:32:17 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-01 14:31:55 +0200 |
commit | 21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (patch) | |
tree | 91be119f694044dfc1ff9fdc054459e925de9df0 /chromium/storage | |
parent | 03c549e0392f92c02536d3f86d5e1d8dfa3435ac (diff) | |
download | qtwebengine-chromium-21ba0c5d4bf8fba15dddd97cd693bad2358b77fd.tar.gz |
BASELINE: Update Chromium to 92.0.4515.166
Change-Id: I42a050486714e9e54fc271f2a8939223a02ae364
Diffstat (limited to 'chromium/storage')
112 files changed, 2736 insertions, 2368 deletions
diff --git a/chromium/storage/BUILD.gn b/chromium/storage/BUILD.gn index d6208ef440c..23789543889 100644 --- a/chromium/storage/BUILD.gn +++ b/chromium/storage/BUILD.gn @@ -8,4 +8,6 @@ test("storage_unittests") { "//storage/browser:unittests", "//storage/common:unittests", ] + + data = [ "//storage/test/data/" ] } diff --git a/chromium/storage/browser/BUILD.gn b/chromium/storage/browser/BUILD.gn index 56f3b131eb4..025683c50d7 100644 --- a/chromium/storage/browser/BUILD.gn +++ b/chromium/storage/browser/BUILD.gn @@ -91,8 +91,6 @@ component("browser") { "file_system/file_system_context.h", "file_system/file_system_features.cc", "file_system/file_system_features.h", - "file_system/file_system_file_stream_reader.cc", - "file_system/file_system_file_stream_reader.h", "file_system/file_system_file_util.cc", "file_system/file_system_file_util.h", "file_system/file_system_operation.h", @@ -162,20 +160,18 @@ component("browser") { "file_system/remove_operation_delegate.h", "file_system/sandbox_directory_database.cc", "file_system/sandbox_directory_database.h", + "file_system/sandbox_file_stream_reader.cc", + "file_system/sandbox_file_stream_reader.h", "file_system/sandbox_file_stream_writer.cc", "file_system/sandbox_file_stream_writer.h", "file_system/sandbox_file_system_backend.cc", "file_system/sandbox_file_system_backend.h", "file_system/sandbox_file_system_backend_delegate.cc", "file_system/sandbox_file_system_backend_delegate.h", - "file_system/sandbox_isolated_origin_database.cc", - "file_system/sandbox_isolated_origin_database.h", "file_system/sandbox_origin_database.cc", "file_system/sandbox_origin_database.h", "file_system/sandbox_origin_database_interface.cc", "file_system/sandbox_origin_database_interface.h", - "file_system/sandbox_prioritized_origin_database.cc", - "file_system/sandbox_prioritized_origin_database.h", "file_system/sandbox_quota_observer.cc", "file_system/sandbox_quota_observer.h", "file_system/task_runner_bound_observer_list.h", @@ -192,6 +188,8 @@ component("browser") { "quota/quota_client_type.h", "quota/quota_database.cc", "quota/quota_database.h", + "quota/quota_database_migrations.cc", + "quota/quota_database_migrations.h", "quota/quota_device_info_helper.cc", "quota/quota_device_info_helper.h", "quota/quota_features.cc", @@ -235,7 +233,7 @@ component("browser") { "//base:i18n", "//base/third_party/dynamic_annotations", "//build:chromeos_buildflags", - "//components/services/storage/public/cpp/filesystem", + "//components/services/storage/public/cpp", "//mojo/public/cpp/bindings", "//net", "//services/network:network_service", @@ -295,7 +293,6 @@ source_set("unittests") { "file_system/file_stream_writer_test.cc", "file_system/file_stream_writer_test.h", "file_system/file_system_context_unittest.cc", - "file_system/file_system_file_stream_reader_unittest.cc", "file_system/file_system_operation_impl_unittest.cc", "file_system/file_system_operation_impl_write_unittest.cc", "file_system/file_system_quota_client_unittest.cc", @@ -317,13 +314,13 @@ source_set("unittests") { "file_system/quota/quota_reservation_manager_unittest.cc", "file_system/recursive_operation_delegate_unittest.cc", "file_system/sandbox_directory_database_unittest.cc", + "file_system/sandbox_file_stream_reader_unittest.cc", "file_system/sandbox_file_stream_writer_unittest.cc", "file_system/sandbox_file_system_backend_delegate_unittest.cc", "file_system/sandbox_file_system_backend_unittest.cc", - "file_system/sandbox_isolated_origin_database_unittest.cc", "file_system/sandbox_origin_database_unittest.cc", - "file_system/sandbox_prioritized_origin_database_unittest.cc", "file_system/transient_file_util_unittest.cc", + "quota/quota_database_migrations_unittest.cc", "quota/quota_database_unittest.cc", "quota/quota_manager_unittest.cc", "quota/quota_settings_unittest.cc", @@ -338,7 +335,7 @@ source_set("unittests") { "//base/test:test_support", "//build:chromeos_buildflags", "//components/services/filesystem/public/mojom", - "//components/services/storage/public/cpp/filesystem", + "//components/services/storage/public/cpp", "//mojo/public/cpp/system", "//net:test_support", "//services/network/public/cpp", diff --git a/chromium/storage/browser/blob/DIR_METADATA b/chromium/storage/browser/blob/DIR_METADATA index 433b3a9e88c..19266882c43 100644 --- a/chromium/storage/browser/blob/DIR_METADATA +++ b/chromium/storage/browser/blob/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>FileAPI" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/browser/blob/blob_builder_from_stream.h b/chromium/storage/browser/blob/blob_builder_from_stream.h index 56199f06ebe..d4ecc17c609 100644 --- a/chromium/storage/browser/blob/blob_builder_from_stream.h +++ b/chromium/storage/browser/blob/blob_builder_from_stream.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H -#define STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H +#ifndef STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H_ +#define STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H_ #include "base/component_export.h" #include "base/containers/queue.h" @@ -168,4 +168,4 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobBuilderFromStream { } // namespace storage -#endif // STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H +#endif // STORAGE_BROWSER_BLOB_BLOB_BUILDER_FROM_STREAM_H_ diff --git a/chromium/storage/browser/blob/blob_entry.h b/chromium/storage/browser/blob/blob_entry.h index 4f8eb163368..317e4050c8e 100644 --- a/chromium/storage/browser/blob/blob_entry.h +++ b/chromium/storage/browser/blob/blob_entry.h @@ -16,8 +16,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "base/optional.h" #include "storage/browser/blob/blob_memory_controller.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace storage { class BlobDataHandle; diff --git a/chromium/storage/browser/blob/blob_impl.cc b/chromium/storage/browser/blob/blob_impl.cc index 2d66abcc8a3..d366316e02b 100644 --- a/chromium/storage/browser/blob/blob_impl.cc +++ b/chromium/storage/browser/blob/blob_impl.cc @@ -143,7 +143,7 @@ void BlobImpl::ReadSideData(ReadSideDataCallback callback) { BlobStatus status) { if (status != BlobStatus::DONE) { DCHECK(BlobStatusIsError(status)); - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); return; } @@ -151,26 +151,26 @@ void BlobImpl::ReadSideData(ReadSideDataCallback callback) { // Currently side data is supported only for blobs with a single entry. const auto& items = snapshot->items(); if (items.size() != 1) { - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); return; } const auto& item = items[0]; if (item->type() != BlobDataItem::Type::kReadableDataHandle) { - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); return; } int32_t body_size = item->data_handle()->GetSideDataSize(); if (body_size == 0) { - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); return; } item->data_handle()->ReadSideData(base::BindOnce( [](ReadSideDataCallback callback, int result, mojo_base::BigBuffer buffer) { if (result < 0) { - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); return; } std::move(callback).Run(std::move(buffer)); @@ -194,7 +194,7 @@ void BlobImpl::CaptureSnapshot(CaptureSnapshotCallback callback) { if (status != BlobStatus::DONE) { DCHECK(BlobStatusIsError(status)); - std::move(callback).Run(0, base::nullopt); + std::move(callback).Run(0, absl::nullopt); return; } @@ -203,13 +203,13 @@ void BlobImpl::CaptureSnapshot(CaptureSnapshotCallback callback) { // time. const auto& items = snapshot->items(); if (items.size() != 1) { - std::move(callback).Run(handle->size(), base::nullopt); + std::move(callback).Run(handle->size(), absl::nullopt); return; } const auto& item = items[0]; if (item->type() != BlobDataItem::Type::kFile) { - std::move(callback).Run(handle->size(), base::nullopt); + std::move(callback).Run(handle->size(), absl::nullopt); return; } @@ -222,7 +222,7 @@ void BlobImpl::CaptureSnapshot(CaptureSnapshotCallback callback) { struct SizeAndTime { uint64_t size; - base::Optional<base::Time> time; + absl::optional<base::Time> time; }; base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, @@ -230,7 +230,7 @@ void BlobImpl::CaptureSnapshot(CaptureSnapshotCallback callback) { [](const base::FilePath& path) { base::File::Info info; if (!base::GetFileInfo(path, &info)) - return SizeAndTime{0, base::nullopt}; + return SizeAndTime{0, absl::nullopt}; return SizeAndTime{info.size, info.last_modified}; }, item->path()), diff --git a/chromium/storage/browser/blob/blob_memory_controller.cc b/chromium/storage/browser/blob/blob_memory_controller.cc index 1c8cbfe80ae..e070b09c27d 100644 --- a/chromium/storage/browser/blob/blob_memory_controller.cc +++ b/chromium/storage/browser/blob/blob_memory_controller.cc @@ -82,7 +82,7 @@ File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { BlobStorageLimits CalculateBlobStorageLimitsImpl( const FilePath& storage_dir, bool disk_enabled, - base::Optional<int64_t> optional_memory_size_for_testing) { + absl::optional<int64_t> optional_memory_size_for_testing) { int64_t disk_size = 0ull; int64_t memory_size = optional_memory_size_for_testing ? optional_memory_size_for_testing.value() diff --git a/chromium/storage/browser/blob/blob_memory_controller.h b/chromium/storage/browser/blob/blob_memory_controller.h index 1293e42af10..85971d5951d 100644 --- a/chromium/storage/browser/blob/blob_memory_controller.h +++ b/chromium/storage/browser/blob/blob_memory_controller.h @@ -11,7 +11,6 @@ #include <map> #include <memory> #include <string> -#include <unordered_map> #include <unordered_set> #include <utility> #include <vector> @@ -28,9 +27,9 @@ #include "base/memory/memory_pressure_listener.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "base/optional.h" #include "base/time/time.h" #include "storage/browser/blob/blob_storage_constants.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace base { class TaskRunner; @@ -281,7 +280,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobMemoryController { bool did_calculate_storage_limits_ = false; std::vector<base::OnceClosure> on_calculate_limits_callbacks_; - base::Optional<int64_t> amount_of_memory_for_testing_; + absl::optional<int64_t> amount_of_memory_for_testing_; // Memory bookkeeping. These numbers are all disjoint. // This is the amount of memory we're using for blobs in RAM, including the diff --git a/chromium/storage/browser/blob/blob_memory_controller_unittest.cc b/chromium/storage/browser/blob/blob_memory_controller_unittest.cc index 320d505e7cb..324d44990b2 100644 --- a/chromium/storage/browser/blob/blob_memory_controller_unittest.cc +++ b/chromium/storage/browser/blob/blob_memory_controller_unittest.cc @@ -170,7 +170,7 @@ class BlobMemoryControllerTest : public base::test::WithFeatureOverride, scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); - base::test::SingleThreadTaskEnvironment task_environment_; + base::test::TaskEnvironment task_environment_; }; TEST_P(BlobMemoryControllerTest, Strategy) { diff --git a/chromium/storage/browser/blob/blob_reader.cc b/chromium/storage/browser/blob/blob_reader.cc index 8cf4623ed7a..b004bf3a26f 100644 --- a/chromium/storage/browser/blob/blob_reader.cc +++ b/chromium/storage/browser/blob/blob_reader.cc @@ -137,7 +137,7 @@ void BlobReader::ReadSideData(StatusCallback done) { std::move(done), side_data_size)); } -base::Optional<mojo_base::BigBuffer> BlobReader::TakeSideData() { +absl::optional<mojo_base::BigBuffer> BlobReader::TakeSideData() { return std::move(side_data_); } diff --git a/chromium/storage/browser/blob/blob_reader.h b/chromium/storage/browser/blob/blob_reader.h index 754bb0cbc4f..b8c71d5a3cb 100644 --- a/chromium/storage/browser/blob/blob_reader.h +++ b/chromium/storage/browser/blob/blob_reader.h @@ -102,7 +102,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader { void ReadSideData(StatusCallback done); // Passes the side data (if any) from ReadSideData() to the caller. - base::Optional<mojo_base::BigBuffer> TakeSideData(); + absl::optional<mojo_base::BigBuffer> TakeSideData(); // Used to set the read position. // * This should be called after CalculateSize and before Read. @@ -244,7 +244,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader { std::unique_ptr<BlobDataSnapshot> blob_data_; std::unique_ptr<FileStreamReaderProvider> file_stream_provider_for_testing_; scoped_refptr<base::TaskRunner> file_task_runner_; - base::Optional<mojo_base::BigBuffer> side_data_; + absl::optional<mojo_base::BigBuffer> side_data_; int net_error_; bool item_list_populated_ = false; diff --git a/chromium/storage/browser/blob/blob_registry_impl.cc b/chromium/storage/browser/blob/blob_registry_impl.cc index 34e736e80de..90753d9337a 100644 --- a/chromium/storage/browser/blob/blob_registry_impl.cc +++ b/chromium/storage/browser/blob/blob_registry_impl.cc @@ -277,7 +277,7 @@ void BlobRegistryImpl::BlobUnderConstruction::StartTransportation( // requested asynchronously later again anyway. for (auto& entry : elements_) { if (entry.element->is_bytes()) - entry.element->get_bytes()->embedded_data = base::nullopt; + entry.element->get_bytes()->embedded_data = absl::nullopt; } } diff --git a/chromium/storage/browser/blob/blob_registry_impl_unittest.cc b/chromium/storage/browser/blob/blob_registry_impl_unittest.cc index 64ed3dff9f3..6a4431d68fd 100644 --- a/chromium/storage/browser/blob/blob_registry_impl_unittest.cc +++ b/chromium/storage/browser/blob/blob_registry_impl_unittest.cc @@ -302,7 +302,7 @@ TEST_F(BlobRegistryImplTest, Register_EmptyBytesBlob) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - 0, base::nullopt, CreateBytesProvider("")))); + 0, absl::nullopt, CreateBytesProvider("")))); mojo::Remote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.BindNewPipeAndPassReceiver(), kId, @@ -533,7 +533,7 @@ TEST_F(BlobRegistryImplTest, Register_UnreadableFile) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewFile(blink::mojom::DataElementFile::New( - base::FilePath(FILE_PATH_LITERAL("foobar")), 0, 16, base::nullopt))); + base::FilePath(FILE_PATH_LITERAL("foobar")), 0, 16, absl::nullopt))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -557,7 +557,7 @@ TEST_F(BlobRegistryImplTest, Register_ValidFile) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back(blink::mojom::DataElement::NewFile( - blink::mojom::DataElementFile::New(path, 0, 16, base::nullopt))); + blink::mojom::DataElementFile::New(path, 0, 16, absl::nullopt))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -583,7 +583,7 @@ TEST_F(BlobRegistryImplTest, Register_FileSystemFile_InvalidScheme) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back(blink::mojom::DataElement::NewFileFilesystem( blink::mojom::DataElementFilesystemURL::New(GURL("http://foobar.com/"), 0, - 16, base::nullopt))); + 16, absl::nullopt))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -607,7 +607,7 @@ TEST_F(BlobRegistryImplTest, Register_FileSystemFile_UnreadablFile) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back(blink::mojom::DataElement::NewFileFilesystem( - blink::mojom::DataElementFilesystemURL::New(url, 0, 16, base::nullopt))); + blink::mojom::DataElementFilesystemURL::New(url, 0, 16, absl::nullopt))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -631,7 +631,7 @@ TEST_F(BlobRegistryImplTest, Register_FileSystemFile_Valid) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back(blink::mojom::DataElement::NewFileFilesystem( - blink::mojom::DataElementFilesystemURL::New(url, 0, 16, base::nullopt))); + blink::mojom::DataElementFilesystemURL::New(url, 0, 16, absl::nullopt))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -689,10 +689,10 @@ TEST_F(BlobRegistryImplTest, Register_BytesInvalidDataSize) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - 8, base::nullopt, CreateBytesProvider("")))); + 8, absl::nullopt, CreateBytesProvider("")))); elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - std::numeric_limits<uint64_t>::max() - 4, base::nullopt, + std::numeric_limits<uint64_t>::max() - 4, absl::nullopt, CreateBytesProvider("")))); mojo::PendingRemote<blink::mojom::Blob> blob; @@ -723,11 +723,11 @@ TEST_F(BlobRegistryImplTest, Register_BytesOutOfMemory) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kTestBlobStorageMaxDiskSpace, base::nullopt, + kTestBlobStorageMaxDiskSpace, absl::nullopt, CreateBytesProvider("")))); elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kTestBlobStorageMaxDiskSpace, base::nullopt, + kTestBlobStorageMaxDiskSpace, absl::nullopt, CreateBytesProvider("")))); mojo::PendingRemote<blink::mojom::Blob> blob; @@ -784,7 +784,7 @@ TEST_F(BlobRegistryImplTest, Register_ValidBytesAsReply) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, CreateBytesProvider(kData)))); + kData.size(), absl::nullopt, CreateBytesProvider(kData)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -814,7 +814,7 @@ TEST_F(BlobRegistryImplTest, Register_InvalidBytesAsReply) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, CreateBytesProvider("")))); + kData.size(), absl::nullopt, CreateBytesProvider("")))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -845,7 +845,7 @@ TEST_F(BlobRegistryImplTest, Register_ValidBytesAsStream) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, CreateBytesProvider(kData)))); + kData.size(), absl::nullopt, CreateBytesProvider(kData)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -881,7 +881,7 @@ TEST_F(BlobRegistryImplTest, Register_ValidBytesAsFile) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, CreateBytesProvider(kData)))); + kData.size(), absl::nullopt, CreateBytesProvider(kData)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -927,7 +927,7 @@ TEST_F(BlobRegistryImplTest, Register_BytesProviderClosedPipe) { std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - 32, base::nullopt, std::move(bytes_provider_remote)))); + 32, absl::nullopt, std::move(bytes_provider_remote)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -952,7 +952,7 @@ TEST_F(BlobRegistryImplTest, std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - 32, base::nullopt, std::move(bytes_provider_remote)))); + 32, absl::nullopt, std::move(bytes_provider_remote)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -1031,7 +1031,7 @@ TEST_F(BlobRegistryImplTest, std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, std::move(bytes_provider_remote)))); + kData.size(), absl::nullopt, std::move(bytes_provider_remote)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, @@ -1067,7 +1067,7 @@ TEST_F(BlobRegistryImplTest, std::vector<blink::mojom::DataElementPtr> elements; elements.push_back( blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New( - kData.size(), base::nullopt, std::move(bytes_provider_remote)))); + kData.size(), absl::nullopt, std::move(bytes_provider_remote)))); mojo::PendingRemote<blink::mojom::Blob> blob; EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId, diff --git a/chromium/storage/browser/blob/blob_storage_context.cc b/chromium/storage/browser/blob/blob_storage_context.cc index 91a6ba5abde..7c0cd2d3006 100644 --- a/chromium/storage/browser/blob/blob_storage_context.cc +++ b/chromium/storage/browser/blob/blob_storage_context.cc @@ -728,7 +728,7 @@ void BlobStorageContext::WriteBlobToFile( mojo::PendingRemote<::blink::mojom::Blob> pending_blob, const base::FilePath& file_path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, BlobStorageContext::WriteBlobToFileCallback callback) { DCHECK(!last_modified || !last_modified.value().is_null()); if (profile_directory_.empty()) { @@ -749,7 +749,7 @@ void BlobStorageContext::WriteBlobToFile( base::BindOnce( [](base::WeakPtr<BlobStorageContext> blob_context, const base::FilePath& file_path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, BlobStorageContext::WriteBlobToFileCallback callback, std::unique_ptr<BlobDataHandle> handle) { if (!handle || !blob_context) { diff --git a/chromium/storage/browser/blob/blob_storage_context.h b/chromium/storage/browser/blob/blob_storage_context.h index 0b6044066d9..1f7436ab34d 100644 --- a/chromium/storage/browser/blob/blob_storage_context.h +++ b/chromium/storage/browser/blob/blob_storage_context.h @@ -251,7 +251,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobStorageContext void WriteBlobToFile(mojo::PendingRemote<::blink::mojom::Blob> blob, const base::FilePath& path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, WriteBlobToFileCallback callback) override; base::FilePath profile_directory_; diff --git a/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc b/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc index effedb22b2d..4f373a6af20 100644 --- a/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc +++ b/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc @@ -120,7 +120,7 @@ class BlobStorageContextMojoTest : public testing::Test { void CreateFile(base::FilePath path, std::string data, - base::Optional<base::Time> modification_time) { + absl::optional<base::Time> modification_time) { base::ScopedAllowBlockingForTesting allow_blocking; EXPECT_TRUE(base::WriteFile(path, data)); if (modification_time) { @@ -211,7 +211,7 @@ TEST_F(BlobStorageContextMojoTest, SaveBlobToFileNoDate) { base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt"); context->WriteBlobToFile( - blob.Unbind(), file_path, true, base::nullopt, + blob.Unbind(), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kSuccess); loop.Quit(); @@ -491,7 +491,7 @@ TEST_F(BlobStorageContextMojoTest, InvalidInputFileTimeModified) { base::FilePath file_path = temp_dir_.GetPath().AppendASCII("DestinationFile.txt"); context->WriteBlobToFile( - blob.Unbind(), file_path, true, base::nullopt, + blob.Unbind(), file_path, true, absl::nullopt, base::BindLambdaForTesting([&loop](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kInvalidBlob); loop.Quit(); @@ -516,7 +516,7 @@ TEST_F(BlobStorageContextMojoTest, NoProfileDirectory) { base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt"); context->WriteBlobToFile( - blob.Unbind(), file_path, true, base::nullopt, + blob.Unbind(), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath); loop.Quit(); @@ -538,7 +538,7 @@ TEST_F(BlobStorageContextMojoTest, PathWithReferences) { base::FilePath file_path = temp_dir_.GetPath().AppendASCII("..").AppendASCII("UnaccessibleFile.txt"); context->WriteBlobToFile( - blob.Unbind(), file_path, true, base::nullopt, + blob.Unbind(), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath); loop.Quit(); @@ -559,7 +559,7 @@ TEST_F(BlobStorageContextMojoTest, InvalidPath) { base::RunLoop loop; base::FilePath file_path = base::FilePath::FromUTF8Unsafe("/etc/passwd"); context->WriteBlobToFile( - blob.Unbind(), file_path, true, base::nullopt, + blob.Unbind(), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath); loop.Quit(); @@ -606,7 +606,7 @@ TEST_F(BlobStorageContextMojoTest, SaveOptimizedBlobToFileNoDirectory) { temp_dir_.GetPath().AppendASCII("SourceFile.txt"); // Create a file to copy from. - CreateFile(copy_from_file, kData, base::nullopt); + CreateFile(copy_from_file, kData, absl::nullopt); std::unique_ptr<BlobDataBuilder> builder = std::make_unique<BlobDataBuilder>("1234"); @@ -625,7 +625,7 @@ TEST_F(BlobStorageContextMojoTest, SaveOptimizedBlobToFileNoDirectory) { .AppendASCII("NotCreatedDirectory") .AppendASCII("TestFile.txt"); context->WriteBlobToFile( - std::move(blob), file_path, true, base::nullopt, + std::move(blob), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kIOError); loop.Quit(); @@ -645,7 +645,7 @@ TEST_F(BlobStorageContextMojoTest, SaveOptimizedBlobNoFileSize) { temp_dir_.GetPath().AppendASCII("SourceFile.txt"); // Create a file to copy from. - CreateFile(copy_from_file, kData, base::nullopt); + CreateFile(copy_from_file, kData, absl::nullopt); std::unique_ptr<BlobDataBuilder> builder = std::make_unique<BlobDataBuilder>("1234"); @@ -663,7 +663,7 @@ TEST_F(BlobStorageContextMojoTest, SaveOptimizedBlobNoFileSize) { base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt"); context->WriteBlobToFile( - std::move(blob), file_path, true, base::nullopt, + std::move(blob), file_path, true, absl::nullopt, base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) { EXPECT_EQ(result, mojom::WriteBlobToFileResult::kSuccess); loop.Quit(); diff --git a/chromium/storage/browser/blob/blob_storage_registry.h b/chromium/storage/browser/blob/blob_storage_registry.h index a0723456413..dd3963e47af 100644 --- a/chromium/storage/browser/blob/blob_storage_registry.h +++ b/chromium/storage/browser/blob/blob_storage_registry.h @@ -13,7 +13,6 @@ #include <unordered_map> #include <vector> -#include "base/callback_forward.h" #include "base/component_export.h" #include "base/macros.h" #include "storage/browser/blob/blob_storage_constants.h" diff --git a/chromium/storage/browser/blob/blob_transport_strategy.cc b/chromium/storage/browser/blob/blob_transport_strategy.cc index 05827b6748e..c86c700fd0f 100644 --- a/chromium/storage/browser/blob/blob_transport_strategy.cc +++ b/chromium/storage/browser/blob/blob_transport_strategy.cc @@ -321,7 +321,7 @@ class FileTransportStrategy : public BlobTransportStrategy { private: void OnReply(BlobDataBuilder::FutureFile future_file, scoped_refptr<ShareableFileReference> file_reference, - base::Optional<base::Time> time_file_modified) { + absl::optional<base::Time> time_file_modified) { if (!time_file_modified) { // Writing to the file failed in the renderer. std::move(result_callback_).Run(BlobStatus::ERR_FILE_WRITE_FAILED); diff --git a/chromium/storage/browser/blob/blob_transport_strategy_unittest.cc b/chromium/storage/browser/blob/blob_transport_strategy_unittest.cc index 409042178da..9a08c025b74 100644 --- a/chromium/storage/browser/blob/blob_transport_strategy_unittest.cc +++ b/chromium/storage/browser/blob/blob_transport_strategy_unittest.cc @@ -88,7 +88,7 @@ class BlobTransportStrategyTest : public testing::Test { mojo::PendingRemote<blink::mojom::BytesProvider> CreateBytesProvider( const std::string& bytes, - base::Optional<base::Time> time) { + absl::optional<base::Time> time) { mojo::PendingRemote<blink::mojom::BytesProvider> result; auto provider = std::make_unique<MockBytesProvider>( std::vector<uint8_t>(bytes.begin(), bytes.end()), &reply_request_count_, @@ -179,7 +179,7 @@ TEST_P(BasicTests, WithBytes) { expected.AppendData(data); data = base::RandBytesAsString(10); - blink::mojom::DataElementBytes bytes3(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes3(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider3( CreateBytesProvider(data, mock_time_)); @@ -240,7 +240,7 @@ TEST_P(BasicErrorTests, NotEnoughBytesInProvider) { limits_); std::string data = base::RandBytesAsString(7); - blink::mojom::DataElementBytes bytes(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider( CreateBytesProvider(data.substr(0, 4), mock_time_)); @@ -270,7 +270,7 @@ TEST_P(BasicErrorTests, TooManyBytesInProvider) { limits_); std::string data = base::RandBytesAsString(4); - blink::mojom::DataElementBytes bytes(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider( CreateBytesProvider(data + "foobar", mock_time_)); @@ -312,7 +312,7 @@ TEST_F(BlobTransportStrategyTest, DataStreamChunksData) { std::string data = base::RandBytesAsString(kTestBlobStorageMaxSharedMemoryBytes * 3 + 13); - blink::mojom::DataElementBytes bytes(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider( CreateBytesProvider(data, mock_time_)); @@ -380,10 +380,10 @@ TEST_F(BlobTransportStrategyTest, Files_WriteFailed) { limits_); std::string data = base::RandBytesAsString(kTestBlobStorageMaxFileSizeBytes); - blink::mojom::DataElementBytes bytes(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider( - CreateBytesProvider(data, base::nullopt)); + CreateBytesProvider(data, absl::nullopt)); strategy->AddBytesElement(&bytes, bytes_provider); FileInfoVector files(1); @@ -424,7 +424,7 @@ TEST_F(BlobTransportStrategyTest, Files_ValidBytesOneElement) { std::string data = base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize + 42); - blink::mojom::DataElementBytes bytes(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider( CreateBytesProvider(data, mock_time_)); @@ -480,22 +480,22 @@ TEST_F(BlobTransportStrategyTest, Files_ValidBytesMultipleElements) { std::string data = base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize / 3); - blink::mojom::DataElementBytes bytes1(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes1(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider1( CreateBytesProvider(data, mock_time_)); strategy->AddBytesElement(&bytes1, bytes_provider1); - blink::mojom::DataElementBytes bytes2(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes2(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider2( CreateBytesProvider(data, mock_time_)); strategy->AddBytesElement(&bytes2, bytes_provider2); - blink::mojom::DataElementBytes bytes3(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes3(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider3( CreateBytesProvider(data, mock_time_)); strategy->AddBytesElement(&bytes3, bytes_provider3); - blink::mojom::DataElementBytes bytes4(data.size(), base::nullopt, + blink::mojom::DataElementBytes bytes4(data.size(), absl::nullopt, mojo::NullRemote()); mojo::Remote<blink::mojom::BytesProvider> bytes_provider4( CreateBytesProvider(data, mock_time_)); diff --git a/chromium/storage/browser/blob/blob_url_loader.cc b/chromium/storage/browser/blob/blob_url_loader.cc index 072337a8d7c..72325e7cc96 100644 --- a/chromium/storage/browser/blob/blob_url_loader.cc +++ b/chromium/storage/browser/blob/blob_url_loader.cc @@ -171,7 +171,7 @@ void BlobURLLoader::FollowRedirect( const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_headers, const net::HttpRequestHeaders& modified_cors_exempt_headers, - const base::Optional<GURL>& new_url) { + const absl::optional<GURL>& new_url) { NOTREACHED(); } @@ -192,11 +192,11 @@ MojoBlobReader::Delegate::RequestSideData BlobURLLoader::DidCalculateSize( return REQUEST_SIDE_DATA; } - HeadersCompleted(status_code, content_size, base::nullopt); + HeadersCompleted(status_code, content_size, absl::nullopt); return DONT_REQUEST_SIDE_DATA; } -void BlobURLLoader::DidReadSideData(base::Optional<mojo_base::BigBuffer> data) { +void BlobURLLoader::DidReadSideData(absl::optional<mojo_base::BigBuffer> data) { HeadersCompleted(net::HTTP_OK, total_size_, std::move(data)); } @@ -213,7 +213,7 @@ void BlobURLLoader::OnComplete(net::Error error_code, void BlobURLLoader::HeadersCompleted( net::HttpStatusCode status_code, uint64_t content_size, - base::Optional<mojo_base::BigBuffer> metadata) { + absl::optional<mojo_base::BigBuffer> metadata) { auto response = network::mojom::URLResponseHead::New(); response->content_length = 0; if (status_code == net::HTTP_OK || status_code == net::HTTP_PARTIAL_CONTENT) diff --git a/chromium/storage/browser/blob/blob_url_loader.h b/chromium/storage/browser/blob/blob_url_loader.h index 59ab6e9acce..1ea8a497875 100644 --- a/chromium/storage/browser/blob/blob_url_loader.h +++ b/chromium/storage/browser/blob/blob_url_loader.h @@ -64,7 +64,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLLoader const std::vector<std::string>& removed_headers, const net::HttpRequestHeaders& modified_request_headers, const net::HttpRequestHeaders& modified_cors_exempt_request_headers, - const base::Optional<GURL>& new_url) override; + const absl::optional<GURL>& new_url) override; void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override {} void PauseReadingBodyFromNet() override {} @@ -73,12 +73,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLLoader // MojoBlobReader::Delegate implementation: RequestSideData DidCalculateSize(uint64_t total_size, uint64_t content_size) override; - void DidReadSideData(base::Optional<mojo_base::BigBuffer> data) override; + void DidReadSideData(absl::optional<mojo_base::BigBuffer> data) override; void OnComplete(net::Error error_code, uint64_t total_written_bytes) override; void HeadersCompleted(net::HttpStatusCode status_code, uint64_t content_size, - base::Optional<mojo_base::BigBuffer> metadata); + absl::optional<mojo_base::BigBuffer> metadata); mojo::Receiver<network::mojom::URLLoader> receiver_; mojo::Remote<network::mojom::URLLoaderClient> client_; diff --git a/chromium/storage/browser/blob/blob_url_registry.h b/chromium/storage/browser/blob/blob_url_registry.h index c74eb3f00c4..e2ba6707019 100644 --- a/chromium/storage/browser/blob/blob_url_registry.h +++ b/chromium/storage/browser/blob/blob_url_registry.h @@ -7,7 +7,6 @@ #include <map> -#include "base/callback_forward.h" #include "base/component_export.h" #include "base/macros.h" #include "base/sequence_checker.h" diff --git a/chromium/storage/browser/blob/mojo_blob_reader.h b/chromium/storage/browser/blob/mojo_blob_reader.h index 32901036ae1..96b3b0e08e9 100644 --- a/chromium/storage/browser/blob/mojo_blob_reader.h +++ b/chromium/storage/browser/blob/mojo_blob_reader.h @@ -52,7 +52,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MojoBlobReader { // Called if DidCalculateSize returned |REQUEST_SIDE_DATA|, with the side // data associated with the blob being read, if any. - virtual void DidReadSideData(base::Optional<mojo_base::BigBuffer> data) {} + virtual void DidReadSideData(absl::optional<mojo_base::BigBuffer> data) {} // Called whenever some amount of data is read from the blob and about to be // written to the data pipe. @@ -135,4 +135,4 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MojoBlobReader { } // namespace storage -#endif +#endif // STORAGE_BROWSER_BLOB_MOJO_BLOB_READER_H_ diff --git a/chromium/storage/browser/blob/view_blob_internals_job.cc b/chromium/storage/browser/blob/view_blob_internals_job.cc index 10c7ba69778..2849cd6bfa2 100644 --- a/chromium/storage/browser/blob/view_blob_internals_job.cc +++ b/chromium/storage/browser/blob/view_blob_internals_job.cc @@ -18,7 +18,6 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "net/base/escape.h" diff --git a/chromium/storage/browser/blob/write_blob_to_file.cc b/chromium/storage/browser/blob/write_blob_to_file.cc index b41269b38f8..4fd0c3d3137 100644 --- a/chromium/storage/browser/blob/write_blob_to_file.cc +++ b/chromium/storage/browser/blob/write_blob_to_file.cc @@ -139,8 +139,8 @@ mojom::WriteBlobToFileResult CopyFileAndMaybeWriteTimeModified( base::Time expected_last_modified_copy_from, const base::FilePath& copy_to, int64_t offset, - base::Optional<int64_t> size, - base::Optional<base::Time> last_modified, + absl::optional<int64_t> size, + absl::optional<base::Time> last_modified, bool flush_on_close) { // Do a full file copy if the sizes match and there is no offset. if (offset == 0) { @@ -201,7 +201,7 @@ mojom::WriteBlobToFileResult CopyFileAndMaybeWriteTimeModified( mojom::WriteBlobToFileResult CreateEmptyFileAndMaybeSetModifiedTime( base::FilePath file_path, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, bool flush_on_write) { base::File file(file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); @@ -224,7 +224,7 @@ mojom::WriteBlobToFileResult CreateEmptyFileAndMaybeSetModifiedTime( void HandleModifiedTimeOnBlobFileWriteComplete( base::FilePath file_path, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, bool flush_on_write, mojom::BlobStorageContext::WriteBlobToFileCallback callback, base::File::Error rv, @@ -252,7 +252,7 @@ void HandleModifiedTimeOnBlobFileWriteComplete( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce( [](int64_t bytes_written, base::FilePath file_path, - base::Optional<base::Time> last_modified) { + absl::optional<base::Time> last_modified) { if (!base::TouchFile(file_path, last_modified.value(), last_modified.value())) { // If the file modification time isn't set correctly, then @@ -273,7 +273,7 @@ void WriteConstructedBlobToFile( std::unique_ptr<BlobDataHandle> blob_handle, const base::FilePath& file_path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, mojom::BlobStorageContext::WriteBlobToFileCallback callback, BlobStatus status) { DCHECK(!last_modified || !last_modified.value().is_null()); @@ -291,11 +291,11 @@ void WriteConstructedBlobToFile( const BlobDataItem& item = *items[0]; if (item.type() == BlobDataItem::Type::kFile) { // The File API cannot handle uint64_t. - base::Optional<int64_t> optional_size = item.length(); + absl::optional<int64_t> optional_size = item.length(); if (item.length() == blink::BlobUtils::kUnknownSize) { // The blob system uses a special value (max uint64_t) to denote an // unknown file size. This means the whole file should be copied. - optional_size = base::nullopt; + optional_size = absl::nullopt; } else if (item.length() > std::numeric_limits<int64_t>::max()) { std::move(callback).Run(mojom::WriteBlobToFileResult::kError); return; @@ -347,7 +347,7 @@ void WriteBlobToFile( std::unique_ptr<BlobDataHandle> blob_handle, const base::FilePath& file_path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, mojom::BlobStorageContext::WriteBlobToFileCallback callback) { auto* blob_handle_ptr = blob_handle.get(); blob_handle_ptr->RunOnConstructionComplete(base::BindOnce( diff --git a/chromium/storage/browser/blob/write_blob_to_file.h b/chromium/storage/browser/blob/write_blob_to_file.h index 2e1e8af3edc..92a52e3097e 100644 --- a/chromium/storage/browser/blob/write_blob_to_file.h +++ b/chromium/storage/browser/blob/write_blob_to_file.h @@ -6,12 +6,12 @@ #define STORAGE_BROWSER_BLOB_WRITE_BLOB_TO_FILE_H_ #include "base/files/file_path.h" -#include "base/optional.h" #include "base/time/time.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom.h" #include "mojo/public/cpp/bindings/remote.h" #include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_entry.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace storage { @@ -26,7 +26,7 @@ void WriteBlobToFile( std::unique_ptr<BlobDataHandle> blob_handle, const base::FilePath& file_path, bool flush_on_write, - base::Optional<base::Time> last_modified, + absl::optional<base::Time> last_modified, mojom::BlobStorageContext::WriteBlobToFileCallback callback); } // namespace storage diff --git a/chromium/storage/browser/database/DIR_METADATA b/chromium/storage/browser/database/DIR_METADATA index f337a384213..67bdd01e3be 100644 --- a/chromium/storage/browser/database/DIR_METADATA +++ b/chromium/storage/browser/database/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>WebSQL" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/browser/database/database_tracker.cc b/chromium/storage/browser/database/database_tracker.cc index 806e42d4941..2bdd932ceb3 100644 --- a/chromium/storage/browser/database/database_tracker.cc +++ b/chromium/storage/browser/database/database_tracker.cc @@ -13,6 +13,7 @@ #include "base/callback_helpers.h" #include "base/files/file_enumerator.h" #include "base/files/file_util.h" +#include "base/metrics/user_metrics.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -81,7 +82,7 @@ DatabaseTracker::DatabaseTracker(const base::FilePath& profile_path, db_dir_(is_incognito_ ? profile_path_.Append(kIncognitoDatabaseDirectoryName) : profile_path_.Append(kDatabaseDirectoryName)), - db_(new sql::Database()), + db_(std::make_unique<sql::Database>()), special_storage_policy_(special_storage_policy), quota_manager_proxy_(quota_manager_proxy), task_runner_(base::ThreadPool::CreateSequencedTaskRunner( @@ -810,6 +811,7 @@ const base::File* DatabaseTracker::SaveIncognitoFile( auto rv = incognito_file_handles_.insert(std::make_pair(vfs_file_name, to_insert)); DCHECK(rv.second); + base::RecordAction(base::UserMetricsAction("IncognitoWebSQL_Created")); return rv.first->second; } @@ -825,6 +827,7 @@ void DatabaseTracker::CloseIncognitoFileHandle( delete it->second; incognito_file_handles_.erase(it); } + base::RecordAction(base::UserMetricsAction("IncognitoWebSQL_Released")); } bool DatabaseTracker::HasSavedIncognitoFileHandle( diff --git a/chromium/storage/browser/database/vfs_backend.h b/chromium/storage/browser/database/vfs_backend.h index 11609c72b34..16277273364 100644 --- a/chromium/storage/browser/database/vfs_backend.h +++ b/chromium/storage/browser/database/vfs_backend.h @@ -7,8 +7,6 @@ #include <stdint.h> -#include <string> - #include "base/component_export.h" #include "base/files/file.h" #include "base/process/process.h" diff --git a/chromium/storage/browser/file_system/DIR_METADATA b/chromium/storage/browser/file_system/DIR_METADATA index e704db93ca3..a32478d8fb0 100644 --- a/chromium/storage/browser/file_system/DIR_METADATA +++ b/chromium/storage/browser/file_system/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>FileSystem" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/browser/file_system/README.md b/chromium/storage/browser/file_system/README.md index 53460ee93ef..ed65fa5bb4e 100644 --- a/chromium/storage/browser/file_system/README.md +++ b/chromium/storage/browser/file_system/README.md @@ -7,7 +7,7 @@ underlying implementation. ## Related directories -[`//content/browser/fileapi/`](../../../content/browser/fileapi) contains the +[`//content/browser/file_system/`](../../../content/browser/file_system) contains the rest of the browser side implementation, while [`blink/renderer/modules/filesystem`](../../../third_party/blink/renderer/modules/filesystem) contains the renderer side implementation and diff --git a/chromium/storage/browser/file_system/copy_or_move_operation_delegate.cc b/chromium/storage/browser/file_system/copy_or_move_operation_delegate.cc index 86cbd036681..581c1ea4373 100644 --- a/chromium/storage/browser/file_system/copy_or_move_operation_delegate.cc +++ b/chromium/storage/browser/file_system/copy_or_move_operation_delegate.cc @@ -37,41 +37,136 @@ class CopyOrMoveOperationDelegate::CopyOrMoveImpl { virtual void Cancel() = 0; protected: - CopyOrMoveImpl() = default; + CopyOrMoveImpl( + FileSystemOperationRunner* operation_runner, + const CopyOrMoveOperationDelegate::OperationType operation_type, + const FileSystemURL& src_url, + const FileSystemURL& dest_url, + const CopyOrMoveOperationDelegate::CopyOrMoveOption option, + FileSystemOperation::CopyOrMoveProgressCallback progress_callback) + : operation_runner_(operation_runner), + operation_type_(operation_type), + src_url_(src_url), + dest_url_(dest_url), + option_(option), + progress_callback_(std::move(progress_callback)) {} + + // Callback for sending progress events with the current number of processed + // bytes. + void OnCopyOrMoveFileProgress(int64_t size) { + if (!progress_callback_.is_null()) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kProgress, src_url_, + dest_url_, size); + } + } + + // Callback for sending progress events notifying the end of a copy, for a + // copy operation or a cross-filesystem move. + void DidEndCopy(CopyOrMoveOperationDelegate::StatusCallback callback, + base::File::Error error) { + if (!progress_callback_.is_null()) { + if (error == base::File::FILE_OK) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kEndCopy, src_url_, + dest_url_, 0); + } else if (error != base::File::FILE_ERROR_NOT_A_FILE) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kError, src_url_, + dest_url_, 0); + } + } + + // The callback should be called in case of copy or error. The callback is + // null if the operation type is OPERATION_MOVE (implemented as copy + + // delete) and no error occurred. + if (!callback.is_null()) + std::move(callback).Run(error); + } + + // Callback for sending progress events notifying the end of a move operation + // in the case of a local (same-filesystem) move. + void DidEndMove(CopyOrMoveOperationDelegate::StatusCallback callback, + base::File::Error error) { + if (!progress_callback_.is_null()) { + if (error == base::File::FILE_OK) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kEndMove, src_url_, + dest_url_, 0); + } else { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kError, src_url_, + dest_url_, 0); + } + } + std::move(callback).Run(error); + } + + // Callback for sending progress events notifying that the source entry has + // been deleted in the case of a cross-filesystem move. + void DidEndRemoveSourceForMove( + CopyOrMoveOperationDelegate::StatusCallback callback, + base::File::Error error) { + if (!progress_callback_.is_null()) { + if (error == base::File::FILE_OK) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource, + src_url_, FileSystemURL(), 0); + } else { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kError, src_url_, + dest_url_, 0); + } + } + std::move(callback).Run(error); + } + + FileSystemOperationRunner* const operation_runner_; + const CopyOrMoveOperationDelegate::OperationType operation_type_; + const FileSystemURL src_url_; + const FileSystemURL dest_url_; + const CopyOrMoveOperationDelegate::CopyOrMoveOption option_; private: + const FileSystemOperation::CopyOrMoveProgressCallback progress_callback_; DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl); }; namespace { -// Copies a file on a (same) file system. Just delegate the operation to -// |operation_runner|. +// Copies or moves a file on a (same) file system. Just delegate the operation +// to |operation_runner|. class CopyOrMoveOnSameFileSystemImpl : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { public: CopyOrMoveOnSameFileSystemImpl( FileSystemOperationRunner* operation_runner, - CopyOrMoveOperationDelegate::OperationType operation_type, + const CopyOrMoveOperationDelegate::OperationType operation_type, const FileSystemURL& src_url, const FileSystemURL& dest_url, - CopyOrMoveOperationDelegate::CopyOrMoveOption option, - FileSystemOperation::CopyFileProgressCallback file_progress_callback) - : operation_runner_(operation_runner), - operation_type_(operation_type), - src_url_(src_url), - dest_url_(dest_url), - option_(option), - file_progress_callback_(std::move(file_progress_callback)) {} + const CopyOrMoveOperationDelegate::CopyOrMoveOption option, + FileSystemOperation::CopyOrMoveProgressCallback progress_callback) + : CopyOrMoveImpl(operation_runner, + operation_type, + src_url, + dest_url, + option, + progress_callback) {} void Run(CopyOrMoveOperationDelegate::StatusCallback callback) override { if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) { - operation_runner_->MoveFileLocal(src_url_, dest_url_, option_, - std::move(callback)); + operation_runner_->MoveFileLocal( + src_url_, dest_url_, option_, + base::BindOnce(&CopyOrMoveOnSameFileSystemImpl::DidEndMove, + weak_factory_.GetWeakPtr(), std::move(callback))); } else { - operation_runner_->CopyFileLocal(src_url_, dest_url_, option_, - file_progress_callback_, - std::move(callback)); + operation_runner_->CopyFileLocal( + src_url_, dest_url_, option_, + base::BindRepeating( + &CopyOrMoveOnSameFileSystemImpl::OnCopyOrMoveFileProgress, + weak_factory_.GetWeakPtr()), + base::BindOnce(&CopyOrMoveOnSameFileSystemImpl::DidEndCopy, + weak_factory_.GetWeakPtr(), std::move(callback))); } } @@ -82,12 +177,7 @@ class CopyOrMoveOnSameFileSystemImpl } private: - FileSystemOperationRunner* operation_runner_; - CopyOrMoveOperationDelegate::OperationType operation_type_; - FileSystemURL src_url_; - FileSystemURL dest_url_; - CopyOrMoveOperationDelegate::CopyOrMoveOption option_; - FileSystemOperation::CopyFileProgressCallback file_progress_callback_; + base::WeakPtrFactory<CopyOrMoveOnSameFileSystemImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl); }; @@ -105,19 +195,19 @@ class SnapshotCopyOrMoveImpl const FileSystemURL& dest_url, CopyOrMoveOperationDelegate::CopyOrMoveOption option, CopyOrMoveFileValidatorFactory* validator_factory, - const FileSystemOperation::CopyFileProgressCallback& - file_progress_callback) - : operation_runner_(operation_runner), - operation_type_(operation_type), - src_url_(src_url), - dest_url_(dest_url), - option_(option), + FileSystemOperation::CopyOrMoveProgressCallback progress_callback) + : CopyOrMoveImpl(operation_runner, + operation_type, + src_url, + dest_url, + option, + progress_callback), + validator_factory_(validator_factory), - file_progress_callback_(file_progress_callback), cancel_requested_(false) {} void Run(CopyOrMoveOperationDelegate::StatusCallback callback) override { - file_progress_callback_.Run(0); + OnCopyOrMoveFileProgress(0); operation_runner_->CreateSnapshotFile( src_url_, base::BindOnce(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot, @@ -137,7 +227,7 @@ class SnapshotCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -170,7 +260,7 @@ class SnapshotCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -192,11 +282,11 @@ class SnapshotCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } - file_progress_callback_.Run(file_info.size); + OnCopyOrMoveFileProgress(file_info.size); if (option_ == FileSystemOperation::OPTION_NONE) { RunAfterTouchFile(std::move(callback), base::File::FILE_OK); @@ -214,7 +304,7 @@ class SnapshotCopyOrMoveImpl // Even if TouchFile is failed, just ignore it. if (cancel_requested_) { - std::move(callback).Run(base::File::FILE_ERROR_ABORT); + DidEndCopy(std::move(callback), base::File::FILE_ERROR_ABORT); return; } @@ -235,7 +325,7 @@ class SnapshotCopyOrMoveImpl CopyOrMoveOperationDelegate::StatusCallback callback, base::File::Error error) { if (cancel_requested_) { - std::move(callback).Run(base::File::FILE_ERROR_ABORT); + DidEndCopy(std::move(callback), base::File::FILE_ERROR_ABORT); return; } @@ -250,8 +340,11 @@ class SnapshotCopyOrMoveImpl } if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { - std::move(callback).Run(base::File::FILE_OK); + DidEndCopy(std::move(callback), base::File::FILE_OK); return; + } else { + DidEndCopy(CopyOrMoveOperationDelegate::StatusCallback(), + base::File::FILE_OK); } DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); @@ -271,7 +364,7 @@ class SnapshotCopyOrMoveImpl if (error == base::File::FILE_ERROR_NOT_FOUND) error = base::File::FILE_OK; - std::move(callback).Run(error); + DidEndRemoveSourceForMove(std::move(callback), error); } void DidRemoveDestForError( @@ -282,7 +375,7 @@ class SnapshotCopyOrMoveImpl VLOG(1) << "Error removing destination file after validation error: " << error; } - std::move(callback).Run(prior_error); + DidEndCopy(std::move(callback), prior_error); } // Runs pre-write validation. @@ -292,9 +385,7 @@ class SnapshotCopyOrMoveImpl DCHECK(validator_factory_); validator_.reset(validator_factory_->CreateCopyOrMoveFileValidator( src_url_, platform_path)); - // TODO(mek): Update CopyOrMoveFileValidator to use OnceCallback. - validator_->StartPreWriteValidation( - base::AdaptCallbackForRepeating(std::move(callback))); + validator_->StartPreWriteValidation(std::move(callback)); } // Runs post-write validation. @@ -324,12 +415,11 @@ class SnapshotCopyOrMoveImpl DCHECK(validator_); // Note: file_ref passed here to keep the file alive until after // the StartPostWriteValidation operation finishes. - // TODO(mek): Update CopyOrMoveFileValidator to use OnceCallback. validator_->StartPostWriteValidation( - platform_path, base::AdaptCallbackForRepeating(base::BindOnce( - &SnapshotCopyOrMoveImpl::DidPostWriteValidation, - weak_factory_.GetWeakPtr(), std::move(file_ref), - std::move(callback)))); + platform_path, + base::BindOnce(&SnapshotCopyOrMoveImpl::DidPostWriteValidation, + weak_factory_.GetWeakPtr(), std::move(file_ref), + std::move(callback))); } // |file_ref| is unused; it is passed here to make sure the reference is @@ -341,15 +431,8 @@ class SnapshotCopyOrMoveImpl std::move(callback).Run(error); } - FileSystemOperationRunner* operation_runner_; - CopyOrMoveOperationDelegate::OperationType operation_type_; - FileSystemURL src_url_; - FileSystemURL dest_url_; - - CopyOrMoveOperationDelegate::CopyOrMoveOption option_; CopyOrMoveFileValidatorFactory* validator_factory_; std::unique_ptr<CopyOrMoveFileValidator> validator_; - FileSystemOperation::CopyFileProgressCallback file_progress_callback_; bool cancel_requested_; base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl); @@ -377,17 +460,16 @@ class StreamCopyOrMoveImpl CopyOrMoveOperationDelegate::CopyOrMoveOption option, std::unique_ptr<FileStreamReader> reader, std::unique_ptr<FileStreamWriter> writer, - const FileSystemOperation::CopyFileProgressCallback& - file_progress_callback) - : operation_runner_(operation_runner), + FileSystemOperation::CopyOrMoveProgressCallback progress_callback) + : CopyOrMoveImpl(operation_runner, + operation_type, + src_url, + dest_url, + option, + progress_callback), file_system_context_(file_system_context), - operation_type_(operation_type), - src_url_(src_url), - dest_url_(dest_url), - option_(option), reader_(std::move(reader)), writer_(std::move(writer)), - file_progress_callback_(file_progress_callback), cancel_requested_(false) {} void Run(CopyOrMoveOperationDelegate::StatusCallback callback) override { @@ -438,7 +520,7 @@ class StreamCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -469,7 +551,7 @@ class StreamCopyOrMoveImpl if (error != base::File::FILE_OK && error != base::File::FILE_ERROR_EXISTS) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -493,7 +575,7 @@ class StreamCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -503,7 +585,8 @@ class StreamCopyOrMoveImpl std::make_unique<CopyOrMoveOperationDelegate::StreamCopyHelper>( std::move(reader_), std::move(writer_), dest_url_.mount_option().flush_policy(), kReadBufferSize, - file_progress_callback_, + base::BindRepeating(&StreamCopyOrMoveImpl::OnCopyOrMoveFileProgress, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds( kMinProgressCallbackInvocationSpanInMilliseconds)); copy_helper_->Run(base::BindOnce(&StreamCopyOrMoveImpl::RunAfterStreamCopy, @@ -526,7 +609,7 @@ class StreamCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error != base::File::FILE_OK) { - std::move(callback).Run(error); + DidEndCopy(std::move(callback), error); return; } @@ -545,15 +628,19 @@ class StreamCopyOrMoveImpl base::File::Error error) { // Even if TouchFile is failed, just ignore it. if (cancel_requested_) { - std::move(callback).Run(base::File::FILE_ERROR_ABORT); + DidEndCopy(std::move(callback), base::File::FILE_ERROR_ABORT); return; } - if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { - std::move(callback).Run(base::File::FILE_OK); + if (error != base::File::FILE_OK || + operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { + DidEndCopy(std::move(callback), base::File::FILE_OK); return; } + DidEndCopy(CopyOrMoveOperationDelegate::StatusCallback(), + base::File::FILE_OK); + DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); // Remove the source for finalizing move operation. @@ -570,18 +657,12 @@ class StreamCopyOrMoveImpl error = base::File::FILE_ERROR_ABORT; if (error == base::File::FILE_ERROR_NOT_FOUND) error = base::File::FILE_OK; - std::move(callback).Run(error); + DidEndRemoveSourceForMove(std::move(callback), error); } - FileSystemOperationRunner* operation_runner_; scoped_refptr<FileSystemContext> file_system_context_; - CopyOrMoveOperationDelegate::OperationType operation_type_; - FileSystemURL src_url_; - FileSystemURL dest_url_; - CopyOrMoveOperationDelegate::CopyOrMoveOption option_; std::unique_ptr<FileStreamReader> reader_; std::unique_ptr<FileStreamWriter> writer_; - FileSystemOperation::CopyFileProgressCallback file_progress_callback_; std::unique_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; bool cancel_requested_; base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_{this}; @@ -734,7 +815,7 @@ CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate( OperationType operation_type, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) : RecursiveOperationDelegate(file_system_context), src_root_(src_root), @@ -784,12 +865,13 @@ void CopyOrMoveOperationDelegate::RunRecursively() { void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, StatusCallback callback) { + FileSystemURL dest_url = CreateDestURL(src_url); + if (!progress_callback_.is_null()) { - progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url, - FileSystemURL(), 0); + progress_callback_.Run(FileSystemOperation::CopyOrMoveProgressType::kBegin, + src_url, dest_url, 0); } - FileSystemURL dest_url = CreateDestURL(src_url); std::unique_ptr<CopyOrMoveImpl> impl; if (same_file_system_ && (file_system_context() @@ -798,8 +880,7 @@ void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, operation_type_ == OPERATION_MOVE)) { impl = std::make_unique<CopyOrMoveOnSameFileSystemImpl>( operation_runner(), operation_type_, src_url, dest_url, option_, - base::BindRepeating(&CopyOrMoveOperationDelegate::OnCopyFileProgress, - weak_factory_.GetWeakPtr(), src_url)); + progress_callback_); } else { // Cross filesystem case. base::File::Error error = base::File::FILE_ERROR_FAILED; @@ -808,8 +889,9 @@ void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, dest_root_.type(), &error); if (error != base::File::FILE_OK) { if (!progress_callback_.is_null()) - progress_callback_.Run(FileSystemOperation::ERROR_COPY_ENTRY, src_url, - dest_url, 0); + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kError, src_url, + dest_url, 0); std::move(callback).Run(error); return; @@ -825,18 +907,14 @@ void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, impl = std::make_unique<StreamCopyOrMoveImpl>( operation_runner(), file_system_context(), operation_type_, src_url, dest_url, option_, std::move(reader), std::move(writer), - base::BindRepeating( - &CopyOrMoveOperationDelegate::OnCopyFileProgress, - weak_factory_.GetWeakPtr(), src_url)); + progress_callback_); } } if (!impl) { impl = std::make_unique<SnapshotCopyOrMoveImpl>( operation_runner(), operation_type_, src_url, dest_url, option_, - validator_factory, - base::BindRepeating(&CopyOrMoveOperationDelegate::OnCopyFileProgress, - weak_factory_.GetWeakPtr(), src_url)); + validator_factory, progress_callback_); } } @@ -845,8 +923,8 @@ void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, CopyOrMoveImpl* impl_ptr = impl.get(); running_copy_set_[impl_ptr] = std::move(impl); impl_ptr->Run(base::BindOnce(&CopyOrMoveOperationDelegate::DidCopyOrMoveFile, - weak_factory_.GetWeakPtr(), src_url, dest_url, - std::move(callback), impl_ptr)); + weak_factory_.GetWeakPtr(), std::move(callback), + impl_ptr)); } void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url, @@ -864,13 +942,14 @@ void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url, return; } + FileSystemURL dest_url = CreateDestURL(src_url); + if (!progress_callback_.is_null()) { - progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url, - FileSystemURL(), 0); + progress_callback_.Run(FileSystemOperation::CopyOrMoveProgressType::kBegin, + src_url, dest_url, 0); } - ProcessDirectoryInternal(src_url, CreateDestURL(src_url), - std::move(callback)); + ProcessDirectoryInternal(src_url, dest_url, std::move(callback)); } void CopyOrMoveOperationDelegate::PostProcessDirectory( @@ -896,23 +975,11 @@ void CopyOrMoveOperationDelegate::OnCancel() { } void CopyOrMoveOperationDelegate::DidCopyOrMoveFile( - const FileSystemURL& src_url, - const FileSystemURL& dest_url, StatusCallback callback, CopyOrMoveImpl* impl, base::File::Error error) { running_copy_set_.erase(impl); - if (!progress_callback_.is_null() && error != base::File::FILE_OK && - error != base::File::FILE_ERROR_NOT_A_FILE) - progress_callback_.Run(FileSystemOperation::ERROR_COPY_ENTRY, src_url, - dest_url, 0); - - if (!progress_callback_.is_null() && error == base::File::FILE_OK) { - progress_callback_.Run(FileSystemOperation::END_COPY_ENTRY, src_url, - dest_url, 0); - } - std::move(callback).Run(error); } @@ -953,8 +1020,9 @@ void CopyOrMoveOperationDelegate::DidCreateDirectory( StatusCallback callback, base::File::Error error) { if (!progress_callback_.is_null() && error == base::File::FILE_OK) { - progress_callback_.Run(FileSystemOperation::END_COPY_ENTRY, src_url, - dest_url, 0); + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kEndCopy, src_url, + dest_url, 0); } std::move(callback).Run(error); @@ -998,24 +1066,26 @@ void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile( operation_runner()->Remove( src_url, false /* recursive */, base::BindOnce(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, - weak_factory_.GetWeakPtr(), std::move(callback))); + weak_factory_.GetWeakPtr(), src_url, std::move(callback))); } void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( + const FileSystemURL& src_url, StatusCallback callback, base::File::Error error) { - if (error == base::File::FILE_ERROR_NOT_FOUND) - error = base::File::FILE_OK; - std::move(callback).Run(error); -} - -void CopyOrMoveOperationDelegate::OnCopyFileProgress( - const FileSystemURL& src_url, - int64_t size) { if (!progress_callback_.is_null()) { - progress_callback_.Run(FileSystemOperation::PROGRESS, src_url, - FileSystemURL(), size); + if (error == base::File::FILE_OK || + error == base::File::FILE_ERROR_NOT_FOUND) { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource, + src_url, FileSystemURL(), 0); + } else { + progress_callback_.Run( + FileSystemOperation::CopyOrMoveProgressType::kError, src_url, + FileSystemURL(), 0); + } } + std::move(callback).Run(error); } FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( diff --git a/chromium/storage/browser/file_system/copy_or_move_operation_delegate.h b/chromium/storage/browser/file_system/copy_or_move_operation_delegate.h index 3b709d2e96d..3b630d7f099 100644 --- a/chromium/storage/browser/file_system/copy_or_move_operation_delegate.h +++ b/chromium/storage/browser/file_system/copy_or_move_operation_delegate.h @@ -31,7 +31,8 @@ enum class FlushPolicy; class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { public: class CopyOrMoveImpl; - using CopyProgressCallback = FileSystemOperation::CopyProgressCallback; + using CopyOrMoveProgressCallback = + FileSystemOperation::CopyOrMoveProgressCallback; using CopyOrMoveOption = FileSystemOperation::CopyOrMoveOption; using ErrorBehavior = FileSystemOperation::ErrorBehavior; @@ -84,14 +85,15 @@ class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper); }; - CopyOrMoveOperationDelegate(FileSystemContext* file_system_context, - const FileSystemURL& src_root, - const FileSystemURL& dest_root, - OperationType operation_type, - CopyOrMoveOption option, - ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, - StatusCallback callback); + CopyOrMoveOperationDelegate( + FileSystemContext* file_system_context, + const FileSystemURL& src_root, + const FileSystemURL& dest_root, + OperationType operation_type, + CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, + StatusCallback callback); ~CopyOrMoveOperationDelegate() override; // RecursiveOperationDelegate overrides: @@ -107,9 +109,7 @@ class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { void OnCancel() override; private: - void DidCopyOrMoveFile(const FileSystemURL& src_url, - const FileSystemURL& dest_url, - StatusCallback callback, + void DidCopyOrMoveFile(StatusCallback callback, CopyOrMoveImpl* impl, base::File::Error error); void DidTryRemoveDestRoot(StatusCallback callback, base::File::Error error); @@ -127,22 +127,23 @@ class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { void PostProcessDirectoryAfterTouchFile(const FileSystemURL& src_url, StatusCallback callback, base::File::Error error); - void DidRemoveSourceForMove(StatusCallback callback, base::File::Error error); + void DidRemoveSourceForMove(const FileSystemURL& src_url, + StatusCallback callback, + base::File::Error error); - void OnCopyFileProgress(const FileSystemURL& src_url, int64_t size); FileSystemURL CreateDestURL(const FileSystemURL& src_url) const; #if DCHECK_IS_ON() bool did_run_ = false; #endif - FileSystemURL src_root_; - FileSystemURL dest_root_; + const FileSystemURL src_root_; + const FileSystemURL dest_root_; bool same_file_system_; - OperationType operation_type_; - CopyOrMoveOption option_; - ErrorBehavior error_behavior_; - CopyProgressCallback progress_callback_; + const OperationType operation_type_; + const CopyOrMoveOption option_; + const ErrorBehavior error_behavior_; + const CopyOrMoveProgressCallback progress_callback_; StatusCallback callback_; std::map<CopyOrMoveImpl*, std::unique_ptr<CopyOrMoveImpl>> running_copy_set_; diff --git a/chromium/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc b/chromium/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc index edaf1d252f9..acfba01ef76 100644 --- a/chromium/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc +++ b/chromium/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc @@ -109,16 +109,16 @@ class TestValidatorFactory : public CopyOrMoveFileValidatorFactory { }; }; -// Records CopyProgressCallback invocations. +// Records CopyOrMoveProgressCallback invocations. struct ProgressRecord { - FileSystemOperation::CopyProgressType type; + FileSystemOperation::CopyOrMoveProgressType type; FileSystemURL source_url; FileSystemURL dest_url; int64_t size; }; void RecordProgressCallback(std::vector<ProgressRecord>* records, - FileSystemOperation::CopyProgressType type, + FileSystemOperation::CopyOrMoveProgressType type, const FileSystemURL& source_url, const FileSystemURL& dest_url, int64_t size) { @@ -259,7 +259,8 @@ class CopyOrMoveOperationTestHelper { base::File::Error CopyWithProgress( const FileSystemURL& src, const FileSystemURL& dest, - const AsyncFileTestHelper::CopyProgressCallback& progress_callback) { + const AsyncFileTestHelper::CopyOrMoveProgressCallback& + progress_callback) { return AsyncFileTestHelper::CopyWithProgress(file_system_context_.get(), src, dest, progress_callback); } @@ -268,6 +269,15 @@ class CopyOrMoveOperationTestHelper { return AsyncFileTestHelper::Move(file_system_context_.get(), src, dest); } + base::File::Error MoveWithProgress( + const FileSystemURL& src, + const FileSystemURL& dest, + const AsyncFileTestHelper::CopyOrMoveProgressCallback& + progress_callback) { + return AsyncFileTestHelper::MoveWithProgress(file_system_context_.get(), + src, dest, progress_callback); + } + base::File::Error SetUpTestCaseFiles( const FileSystemURL& root, const FileSystemTestCaseRecord* const test_cases, @@ -439,6 +449,25 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFile) { ASSERT_EQ(src_increase, dest_increase); } +TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFileLocal) { + CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypeTemporary, + kFileSystemTypeTemporary); + helper.SetUp(); + + FileSystemURL src = helper.SourceURL("a"); + FileSystemURL dest = helper.DestURL("b"); + + // Set up a source file. + ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10)); + + // Move it. + ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest)); + + // Verify. + ASSERT_FALSE(helper.FileExists(src, AsyncFileTestHelper::kDontCheckSize)); + ASSERT_TRUE(helper.FileExists(dest, 10)); +} + TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleDirectory) { CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypeTemporary, kFileSystemTypePersistent); @@ -495,6 +524,25 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectory) { ASSERT_EQ(src_increase, dest_increase); } +TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectoryLocal) { + CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypePersistent, + kFileSystemTypePersistent); + helper.SetUp(); + + FileSystemURL src = helper.SourceURL("a"); + FileSystemURL dest = helper.DestURL("b"); + + // Set up a source directory. + ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src)); + + // Move it. + ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest)); + + // Verify. + ASSERT_FALSE(helper.DirectoryExists(src)); + ASSERT_TRUE(helper.DirectoryExists(dest)); +} + TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) { CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypeTemporary, kFileSystemTypePersistent); @@ -515,7 +563,7 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) { // Copy it. ASSERT_EQ(base::File::FILE_OK, helper.CopyWithProgress( - src, dest, AsyncFileTestHelper::CopyProgressCallback())); + src, dest, AsyncFileTestHelper::CopyOrMoveProgressCallback())); // Verify. ASSERT_TRUE(helper.DirectoryExists(src)); @@ -615,7 +663,7 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFileNoValidator) { ASSERT_EQ(base::File::FILE_ERROR_SECURITY, helper.Copy(src, dest)); } -TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) { +TEST(LocalFileSystemCopyOrMoveOperationTest, CopyProgressCallback) { CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypeTemporary, kFileSystemTypePersistent); helper.SetUp(); @@ -661,29 +709,150 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) { ASSERT_NE(end_index, records.size()); ASSERT_NE(begin_index, end_index); - EXPECT_EQ(FileSystemOperation::BEGIN_COPY_ENTRY, records[begin_index].type); - EXPECT_FALSE(records[begin_index].dest_url.is_valid()); - EXPECT_EQ(FileSystemOperation::END_COPY_ENTRY, records[end_index].type); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kBegin, + records[begin_index].type); + EXPECT_EQ(dest_url, records[begin_index].dest_url); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndCopy, + records[end_index].type); EXPECT_EQ(dest_url, records[end_index].dest_url); if (test_case.is_directory) { // For directory copy, the progress shouldn't be interlaced. EXPECT_EQ(begin_index + 1, end_index); } else { - // PROGRESS event's size should be assending order. + // PROGRESS event's size should be ascending order. int64_t current_size = 0; for (size_t j = begin_index + 1; j < end_index; ++j) { if (records[j].source_url == src_url) { - EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type); - EXPECT_FALSE(records[j].dest_url.is_valid()); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kProgress, + records[j].type); + EXPECT_EQ(dest_url, records[j].dest_url); + EXPECT_GE(records[j].size, current_size); + current_size = records[j].size; + } + } + } + } +} + +TEST(LocalFileSystemCopyOrMoveOperationTest, MoveProgressCallback) { + CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypeTemporary, + kFileSystemTypePersistent); + helper.SetUp(); + + FileSystemURL src = helper.SourceURL("a"); + FileSystemURL dest = helper.DestURL("b"); + + // Set up a source directory. + ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src)); + ASSERT_EQ(base::File::FILE_OK, + helper.SetUpTestCaseFiles(src, kRegularFileSystemTestCases, + kRegularFileSystemTestCaseSize)); + + std::vector<ProgressRecord> records; + ASSERT_EQ( + base::File::FILE_OK, + helper.MoveWithProgress(src, dest, + base::BindRepeating(&RecordProgressCallback, + base::Unretained(&records)))); + + // Verify progress callback. + for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { + const FileSystemTestCaseRecord& test_case = kRegularFileSystemTestCases[i]; + + FileSystemURL src_url = helper.SourceURL( + std::string("a/") + base::FilePath(test_case.path).AsUTF8Unsafe()); + FileSystemURL dest_url = helper.DestURL( + std::string("b/") + base::FilePath(test_case.path).AsUTF8Unsafe()); + + // Find the first and last progress record. + size_t begin_index = records.size(); + size_t end_index = records.size(); + for (size_t j = 0; j < records.size(); ++j) { + if (records[j].source_url == src_url) { + if (begin_index == records.size()) + begin_index = j; + end_index = j; + } + } + + // The record should be found. + ASSERT_NE(begin_index, records.size()); + ASSERT_NE(end_index, records.size()); + ASSERT_NE(begin_index, end_index); + + if (test_case.is_directory) { + // A directory move starts with kBegin and kEndCopy. + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kBegin, + records[begin_index].type); + EXPECT_EQ(dest_url, records[begin_index].dest_url); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndCopy, + records[begin_index + 1].type); + EXPECT_EQ(dest_url, records[begin_index + 1].dest_url); + // A directory move ends with kEndRemoveSource, after the contents of the + // directory has been copied. + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource, + records[end_index].type); + EXPECT_FALSE(records[end_index].dest_url.is_valid()); + } else { + // A file move starts with kBegin. + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kBegin, + records[begin_index].type); + EXPECT_EQ(dest_url, records[begin_index].dest_url); + // PROGRESS event's size should be ascending order. + int64_t current_size = 0; + for (size_t j = begin_index + 1; j < end_index - 1; ++j) { + if (records[j].source_url == src_url) { + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kProgress, + records[j].type); + EXPECT_EQ(dest_url, records[j].dest_url); EXPECT_GE(records[j].size, current_size); current_size = records[j].size; } } + // A file move ends with kEndCopy and kEndRemoveSource. + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndCopy, + records[end_index - 1].type); + EXPECT_EQ(dest_url, records[end_index - 1].dest_url); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource, + records[end_index].type); + EXPECT_FALSE(records[end_index].dest_url.is_valid()); } } } +TEST(LocalFileSystemCopyOrMoveOperationTest, MoveFileLocalProgressCallback) { + CopyOrMoveOperationTestHelper helper("http://foo", kFileSystemTypePersistent, + kFileSystemTypePersistent); + helper.SetUp(); + + FileSystemURL src = helper.SourceURL("a"); + FileSystemURL dest = helper.DestURL("b"); + + // Set up a source file. + ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10)); + + std::vector<ProgressRecord> records; + ASSERT_EQ( + base::File::FILE_OK, + helper.MoveWithProgress(src, dest, + base::BindRepeating(&RecordProgressCallback, + base::Unretained(&records)))); + + // There should be 2 records, for kBegin and kEndMove. No progress should be + // reported. + EXPECT_EQ(records.size(), (uint64_t)2); + + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kBegin, + records[0].type); + EXPECT_EQ(src, records[0].source_url); + EXPECT_EQ(dest, records[0].dest_url); + EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndMove, + records[1].type); + EXPECT_EQ(src, records[1].source_url); + EXPECT_EQ(dest, records[1].dest_url); +} + TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper) { base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); diff --git a/chromium/storage/browser/file_system/dump_file_system.cc b/chromium/storage/browser/file_system/dump_file_system.cc index fe85f662fc9..84c25c88a96 100644 --- a/chromium/storage/browser/file_system/dump_file_system.cc +++ b/chromium/storage/browser/file_system/dump_file_system.cc @@ -9,8 +9,6 @@ // ./out/Release/dump_file_system [options] <filesystem dir> [origin]... // // If no origin is specified, this dumps all origins in the profile dir. -// For Chrome App, which has a separate storage directory, specify "primary" -// as the origin name. // // Available options: // @@ -46,7 +44,6 @@ #include "storage/browser/file_system/sandbox_directory_database.h" #include "storage/browser/file_system/sandbox_file_system_backend.h" #include "storage/browser/file_system/sandbox_origin_database.h" -#include "storage/browser/file_system/sandbox_prioritized_origin_database.h" #include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" @@ -136,11 +133,6 @@ static void DumpDirectoryTree(const std::string& origin_name, static base::FilePath GetOriginDir(const base::FilePath& file_system_dir, const std::string& origin_name) { - if (base::PathExists(file_system_dir.Append( - SandboxPrioritizedOriginDatabase::kPrimaryOriginFile))) { - return base::FilePath(SandboxPrioritizedOriginDatabase::kPrimaryDirectory); - } - SandboxOriginDatabase origin_db(file_system_dir, nullptr); base::FilePath origin_dir; if (!origin_db.HasOriginPath(origin_name)) { diff --git a/chromium/storage/browser/file_system/file_stream_reader.h b/chromium/storage/browser/file_system/file_stream_reader.h index 4f6e30af5f6..0f38d9f8ea0 100644 --- a/chromium/storage/browser/file_system/file_stream_reader.h +++ b/chromium/storage/browser/file_system/file_stream_reader.h @@ -27,9 +27,6 @@ class IOBuffer; } namespace storage { -class FileSystemContext; -class FileSystemURL; -class ObfuscatedFileUtilMemoryDelegate; // A generic interface for reading a file-like object. class FileStreamReader { @@ -71,35 +68,6 @@ class FileStreamReader { int64_t initial_offset, const base::Time& expected_modification_time); - // Creates a new FileReader for a memory file |file_path|. - // |initial_offset| specifies the offset in the file where the first read - // should start. If the given offset is out of the file range any - // read operation may error out with net::ERR_REQUEST_RANGE_NOT_SATISFIABLE. - // |expected_modification_time| specifies the expected last modification - // If the value is non-null, the reader will check the underlying file's - // actual modification time to see if the file has been modified, and if - // it does any succeeding read operations should fail with - // ERR_UPLOAD_FILE_CHANGED error. - COMPONENT_EXPORT(STORAGE_BROWSER) - static std::unique_ptr<FileStreamReader> CreateForMemoryFile( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset, - const base::Time& expected_modification_time); - - // Creates a new reader for a filesystem URL |url| form |initial_offset|. - // |expected_modification_time| specifies the expected last modification if - // the value is non-null, the reader will check the underlying file's actual - // modification time to see if the file has been modified, and if it does any - // succeeding read operations should fail with ERR_UPLOAD_FILE_CHANGED error. - COMPONENT_EXPORT(STORAGE_BROWSER) - static std::unique_ptr<FileStreamReader> CreateForFileSystemFile( - FileSystemContext* context, - const FileSystemURL& url, - int64_t initial_offset, - const base::Time& expected_modification_time); - // Verify if the underlying file has not been modified. COMPONENT_EXPORT(STORAGE_BROWSER) static bool VerifySnapshotTime(const base::Time& expected_modification_time, diff --git a/chromium/storage/browser/file_system/file_stream_reader_test.h b/chromium/storage/browser/file_system/file_stream_reader_test.h index a0c77e5ec82..e48515b60ee 100644 --- a/chromium/storage/browser/file_system/file_stream_reader_test.h +++ b/chromium/storage/browser/file_system/file_stream_reader_test.h @@ -6,7 +6,6 @@ #define STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_READER_TEST_H_ #include "base/callback_helpers.h" -#include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/single_thread_task_runner.h" #include "base/test/task_environment.h" diff --git a/chromium/storage/browser/file_system/file_stream_writer.h b/chromium/storage/browser/file_system/file_stream_writer.h index 11ce21c64d9..7c414264e34 100644 --- a/chromium/storage/browser/file_system/file_stream_writer.h +++ b/chromium/storage/browser/file_system/file_stream_writer.h @@ -23,10 +23,6 @@ class IOBuffer; } namespace storage { -class ObfuscatedFileUtilMemoryDelegate; -} - -namespace storage { // A generic interface for writing to a file-like object. class FileStreamWriter { @@ -46,15 +42,6 @@ class FileStreamWriter { int64_t initial_offset, OpenOrCreate open_or_create); - // Creates a writer for the existing memory file in the path |file_path| - // starting from |initial_offset|. - COMPONENT_EXPORT(STORAGE_BROWSER) - static std::unique_ptr<FileStreamWriter> CreateForMemoryFile( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset); - // Closes the file. If there's an in-flight operation, it is canceled (i.e., // the callback function associated with the operation is not called). virtual ~FileStreamWriter() {} diff --git a/chromium/storage/browser/file_system/file_stream_writer_test.h b/chromium/storage/browser/file_system/file_stream_writer_test.h index eb84a69b7a6..1b5b67deeb2 100644 --- a/chromium/storage/browser/file_system/file_stream_writer_test.h +++ b/chromium/storage/browser/file_system/file_stream_writer_test.h @@ -7,7 +7,6 @@ #include <cstdio> #include "base/callback_helpers.h" -#include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/single_thread_task_runner.h" @@ -234,4 +233,4 @@ REGISTER_TYPED_TEST_SUITE_P(FileStreamWriterTypedTest, } // namespace storage -#endif // STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_WRITER_TEST_H_
\ No newline at end of file +#endif // STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_WRITER_TEST_H_ diff --git a/chromium/storage/browser/file_system/file_system_context.cc b/chromium/storage/browser/file_system/file_system_context.cc index e249cc7e780..06fbf60cc1d 100644 --- a/chromium/storage/browser/file_system/file_system_context.cc +++ b/chromium/storage/browser/file_system/file_system_context.cc @@ -393,16 +393,19 @@ void FileSystemContext::AttemptAutoMountForURLRequest( const FileSystemRequestInfo& request_info, StatusCallback callback) { const FileSystemURL filesystem_url(request_info.url); - auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); if (filesystem_url.type() == kFileSystemTypeExternal) { - for (size_t i = 0; i < auto_mount_handlers_.size(); i++) { - if (auto_mount_handlers_[i].Run(request_info, filesystem_url, - copyable_callback)) { + for (auto& handler : auto_mount_handlers_) { + auto split_callback = base::SplitOnceCallback(std::move(callback)); + callback = std::move(split_callback.first); + if (handler.Run(request_info, filesystem_url, + std::move(split_callback.second))) { + // The `callback` will be run if true was returned. return; } } } - copyable_callback.Run(base::File::FILE_ERROR_NOT_FOUND); + // If every handler returned false, then `callback` was not run yet. + std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND); } void FileSystemContext::DeleteFileSystem(const url::Origin& origin, diff --git a/chromium/storage/browser/file_system/file_system_operation.h b/chromium/storage/browser/file_system/file_system_operation.h index b827d9a61ef..18e98cf2d4a 100644 --- a/chromium/storage/browser/file_system/file_system_operation.h +++ b/chromium/storage/browser/file_system/file_system_operation.h @@ -123,83 +123,111 @@ class FileSystemOperation { // fails some of the operations. enum ErrorBehavior { ERROR_BEHAVIOR_ABORT, ERROR_BEHAVIOR_SKIP }; - // Used for progress update callback for Copy(). - // - // BEGIN_COPY_ENTRY is fired for each copy creation beginning (for both - // file and directory). - // The |source_url| is the URL of the source entry. |size| should not be + // Used for progress update callback for Copy() and Move(). + // + // Note that Move() has both a same-filesystem (1) and a cross-filesystem (2) + // implementation. + // 1) Requires metadata updates. Depending on the underlying implementation: + // - we either only update the metadata of (or in other words, rename) the + // moving directory + // - or the directories are recursively copied + deleted, while the files are + // moved by having their metadata updated. + // 2) Degrades into copy + delete: each entry is copied and deleted + // recursively. + // + // kBegin is fired at the start of each copy or move operation (for + // both file and directory). The |source_url| and the |destination_url| are + // the URLs of the source and the destination entries. |size| should not be // used. // - // END_COPY_ENTRY is fired for each copy creation finishing (for both - // file and directory). - // The |source_url| is the URL of the source entry. The |destination_url| is - // the URL of the destination entry. |size| should not be used. - // - // PROGRESS is fired periodically during file copying (not fired for - // directory copy). - // The |source_url| is the URL of the source file. |size| is the number - // of cumulative copied bytes for the currently copied file. - // Both at beginning and ending of file copying, PROGRESS event should be - // called. At beginning, |size| should be 0. At ending, |size| should be - // the size of the file. - // - // Here is an example callback sequence of recursive copy. Suppose - // there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes), and trying to - // copy a to x recursively, then the progress update sequence will be: - // - // BEGIN_COPY_ENTRY a (starting create "a" directory in x/). - // END_COPY_ENTRY a x/a (creating "a" directory in x/ is finished). - // - // BEGIN_COPY_ENTRY a/b (starting create "b" directory in x/a). - // END_COPY_ENTRY a/b x/a/b (creating "b" directory in x/a/ is finished). - // - // BEGIN_COPY_ENTRY a/b/c.txt (starting to copy "c.txt" in x/a/b/). - // PROGRESS a/b/c.txt 0 (The first PROGRESS's |size| should be 0). - // PROGRESS a/b/c.txt 10 + // kProgress is fired periodically during file transfer (not fired for + // same-filesystem move and directory copy/move). + // The |source_url| and the |destination_url| are the URLs of the source and + // the destination entries. |size| is the number of cumulative copied bytes + // for the currently copied file. Both at beginning and ending of file + // transfer, PROGRESS event should be called. At beginning, |size| should be + // 0. At ending, |size| should be the size of the file. + // + // kEndCopy is fired for each destination entry that has been successfully + // copied (for both file and directory). The |source_url| and the + // |destination_url| are the URLs of the source and the destination entries. + // |size| should not be used. + // + // kEndMove is fired for each entry that has been successfully moved (for both + // file and directory), in the case of a same-filesystem move. The + // |source_url| and the |destination_url| are the URLs of the source and the + // destination entries. |size| should not be used. + // + // kEndRemoveSource, applies in the Move() case only, and is fired for each + // source entry that has been successfully removed from its source location + // (for both file and directory). The |source_url| is the URL of the source + // entry. |destination_url| and |size| should not be used. + // + // When moving files, the expected events are as follows. + // Copy: kBegin -> kProgress -> ... -> kProgress -> kEndCopy. + // Move (same-filesystem): kBegin -> kEndMove. + // Move (cross-filesystem): kBegin -> kProgress -> ... -> kProgress -> + // kEndCopy -> kEndRemoveSource. + // + // Here is an example callback sequence of for a copy or a cross-filesystem + // move. Suppose there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes), + // and trying to transfer a to x recursively, then the progress update + // sequence will be: + // + // kBegin a x/a (starting create "a" directory in x/). + // kEndCopy a x/a (creating "a" directory in x/ is finished). + // + // kBegin a/b x/a/b (starting create "b" directory in x/a). + // kEndCopy a/b x/a/b (creating "b" directory in x/a/ is + // finished). + // + // kBegin a/b/c.txt x/a/b/c.txt (starting to transfer "c.txt" in + // x/a/b/). + // kProgress a/b/c.txt x/a/b/c.txt 0 (The first kProgress's |size| + // should be 0). + // kProgress a/b/c.txt x/a/b/c.txt 10 // : - // PROGRESS a/b/c.txt 90 - // PROGRESS a/b/c.txt 100 (The last PROGRESS's |size| should be the size of - // the file). - // END_COPY_ENTRY a/b/c.txt x/a/b/c.txt (copying "c.txt" is finished). - // - // BEGIN_COPY_ENTRY a/b/d.txt (starting to copy "d.txt" in x/a/b). - // PROGRESS a/b/d.txt 0 (The first PROGRESS's |size| should be 0). - // PROGRESS a/b/d.txt 10 + // kProgress a/b/c.txt x/a/b/c.txt 90 + // kProgress a/b/c.txt x/a/b/c.txt 100 (The last kProgress's |size| should be + // the size of the file). + // kEndCopy a/b/c.txt x/a/b/c.txt (transferring "c.txt" is + // finished). + // kEndRemoveSource a/b/c.txt ("copy + delete" move case). + // + // kBegin a/b/d.txt x/a/b/d.txt (starting to transfer "d.txt" in x/a/b). + // kProgress a/b/d.txt x/a/b/d.txt 0 (The first kProgress's |size| should be + // 0). + // kProgress a/b/d.txt x/a/b/d.txt 10 // : - // PROGRESS a/b/d.txt 190 - // PROGRESS a/b/d.txt 200 (The last PROGRESS's |size| should be the size of - // the file). - // END_COPY_ENTRY a/b/d.txt x/a/b/d.txt (copy "d.txt" is finished). + // kProgress a/b/d.txt x/a/b/d.txt 190 + // kProgress a/b/d.txt x/a/b/d.txt 200 (The last kProgress's |size| should be + // the size of the file). + // kEndCopy a/b/d.txt x/a/b/d.txt (transferring "d.txt" is + // finished). + // kEndRemoveSource a/b/d.txt ("copy + delete" move case). + // + // kEndRemoveSource a/b ("copy + delete" move case). + // + // kEndRemoveSource a ("copy + delete" move case). // // Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced, - // because they can be done in parallel. Also PROGRESS events are optional, + // because they can be done in parallel. Also kProgress events are optional, // so they may not be appeared. // All the progress callback invocation should be done before StatusCallback // given to the Copy is called. Especially if an error is found before first // progres callback invocation, the progress callback may NOT invoked for the // copy. // - // Note for future extension. Currently this callback is only supported on - // Copy(). We can extend this to Move(), because Move() is sometimes - // implemented as "copy then delete." - // In more precise, Move() usually can be implemented either 1) by updating - // the metadata of resource (e.g. root of moving directory tree), or 2) by - // copying directory tree and them removing the source tree. - // For 1)'s case, we can simply add BEGIN_MOVE_ENTRY and END_MOVE_ENTRY - // for root directory. - // For 2)'s case, we can add BEGIN_DELETE_ENTRY and END_DELETE_ENTRY for each - // entry. - // For both cases, we probably won't need to use PROGRESS event because - // these operations should be done quickly (at least much faster than copying - // usually). - enum CopyProgressType { - BEGIN_COPY_ENTRY, - END_COPY_ENTRY, - PROGRESS, - ERROR_COPY_ENTRY + enum class CopyOrMoveProgressType { + kBegin = 0, + kProgress, + kEndCopy, + kEndMove, + kEndRemoveSource, + kError, }; - using CopyProgressCallback = - base::RepeatingCallback<void(CopyProgressType type, + using CopyOrMoveProgressCallback = + base::RepeatingCallback<void(CopyOrMoveProgressType type, const FileSystemURL& source_url, const FileSystemURL& destination_url, int64_t size)>; @@ -268,8 +296,8 @@ class FileSystemOperation { // |error_behavior| specifies whether this continues operation after it // failed an operation or not. // |progress_callback| is periodically called to report the progress - // update. See also the comment of CopyProgressCallback. This callback is - // optional. + // update. See also the comment of CopyOrMoveProgressCallback. This callback + // is optional. // // For recursive case this internally creates new FileSystemOperations and // calls: @@ -283,13 +311,18 @@ class FileSystemOperation { const FileSystemURL& dest_path, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) = 0; // Moves a file or directory from |src_path| to |dest_path|. A new file // or directory is created at |dest_path| as needed. // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's // comment for details. + // |error_behavior| specifies whether this continues operation after it + // failed an operation or not. + // |progress_callback| is periodically called to report the progress + // update. See also the comment of CopyProgressCallback. This callback is + // optional. // // For recursive case this internally creates new FileSystemOperations and // calls: @@ -304,6 +337,8 @@ class FileSystemOperation { virtual void Move(const FileSystemURL& src_path, const FileSystemURL& dest_path, CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) = 0; // Checks if a directory is present at |path|. diff --git a/chromium/storage/browser/file_system/file_system_operation_context.h b/chromium/storage/browser/file_system/file_system_operation_context.h index 330dea9894e..b3837f27a48 100644 --- a/chromium/storage/browser/file_system/file_system_operation_context.h +++ b/chromium/storage/browser/file_system/file_system_operation_context.h @@ -8,7 +8,6 @@ #include <stdint.h> #include "base/component_export.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "base/supports_user_data.h" #include "base/threading/thread_checker.h" diff --git a/chromium/storage/browser/file_system/file_system_operation_impl.cc b/chromium/storage/browser/file_system/file_system_operation_impl.cc index 4871ad66f8a..fa53a2e2754 100644 --- a/chromium/storage/browser/file_system/file_system_operation_impl.cc +++ b/chromium/storage/browser/file_system/file_system_operation_impl.cc @@ -68,14 +68,14 @@ void FileSystemOperationImpl::CreateFile(const FileSystemURL& url, StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationCreateFile)); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( url, base::BindOnce(&FileSystemOperationImpl::DoCreateFile, - weak_factory_.GetWeakPtr(), url, repeatable_callback, - exclusive), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + weak_factory_.GetWeakPtr(), url, + std::move(split_callback.first), exclusive), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } void FileSystemOperationImpl::CreateDirectory(const FileSystemURL& url, @@ -84,14 +84,14 @@ void FileSystemOperationImpl::CreateDirectory(const FileSystemURL& url, StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationCreateDirectory)); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( url, base::BindOnce(&FileSystemOperationImpl::DoCreateDirectory, - weak_factory_.GetWeakPtr(), url, repeatable_callback, - exclusive, recursive), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + weak_factory_.GetWeakPtr(), url, + std::move(split_callback.first), exclusive, recursive), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } void FileSystemOperationImpl::Copy( @@ -99,7 +99,7 @@ void FileSystemOperationImpl::Copy( const FileSystemURL& dest_url, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationCopy)); DCHECK(!recursive_operation_delegate_); @@ -113,16 +113,19 @@ void FileSystemOperationImpl::Copy( recursive_operation_delegate_->RunRecursively(); } -void FileSystemOperationImpl::Move(const FileSystemURL& src_url, - const FileSystemURL& dest_url, - CopyOrMoveOption option, - StatusCallback callback) { +void FileSystemOperationImpl::Move( + const FileSystemURL& src_url, + const FileSystemURL& dest_url, + CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, + StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationMove)); DCHECK(!recursive_operation_delegate_); recursive_operation_delegate_ = std::make_unique<CopyOrMoveOperationDelegate>( file_system_context(), src_url, dest_url, - CopyOrMoveOperationDelegate::OPERATION_MOVE, option, ERROR_BEHAVIOR_ABORT, - FileSystemOperation::CopyProgressCallback(), + CopyOrMoveOperationDelegate::OPERATION_MOVE, option, error_behavior, + progress_callback, base::BindOnce(&FileSystemOperationImpl::DidFinishOperation, weak_factory_.GetWeakPtr(), std::move(callback))); recursive_operation_delegate_->RunRecursively(); @@ -216,14 +219,14 @@ void FileSystemOperationImpl::Truncate(const FileSystemURL& url, StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationTruncate)); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( url, base::BindOnce(&FileSystemOperationImpl::DoTruncate, - weak_factory_.GetWeakPtr(), url, repeatable_callback, - length), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + weak_factory_.GetWeakPtr(), url, + std::move(split_callback.first), length), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } void FileSystemOperationImpl::TouchFile(const FileSystemURL& url, @@ -249,14 +252,13 @@ void FileSystemOperationImpl::OpenFile(const FileSystemURL& url, return; } - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( url, base::BindOnce(&FileSystemOperationImpl::DoOpenFile, - weak_factory_.GetWeakPtr(), url, repeatable_callback, - file_flags), - base::BindOnce(repeatable_callback, + weak_factory_.GetWeakPtr(), url, + std::move(split_callback.first), file_flags), + base::BindOnce(std::move(split_callback.second), base::File(base::File::FILE_ERROR_FAILED), base::OnceClosure())); } @@ -295,14 +297,14 @@ void FileSystemOperationImpl::CopyInForeignFile( StatusCallback callback) { DCHECK(SetPendingOperationType(kOperationCopyInForeignFile)); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( dest_url, base::BindOnce(&FileSystemOperationImpl::DoCopyInForeignFile, weak_factory_.GetWeakPtr(), src_local_disk_file_path, - dest_url, repeatable_callback), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + dest_url, std::move(split_callback.first)), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } void FileSystemOperationImpl::RemoveFile(const FileSystemURL& url, @@ -337,14 +339,14 @@ void FileSystemOperationImpl::CopyFileLocal( DCHECK_EQ(src_url.origin(), dest_url.origin()); DCHECK_EQ(src_url.type(), dest_url.type()); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( dest_url, base::BindOnce(&FileSystemOperationImpl::DoCopyFileLocal, weak_factory_.GetWeakPtr(), src_url, dest_url, option, - progress_callback, repeatable_callback), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + progress_callback, std::move(split_callback.first)), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } void FileSystemOperationImpl::MoveFileLocal(const FileSystemURL& src_url, @@ -359,14 +361,14 @@ void FileSystemOperationImpl::MoveFileLocal(const FileSystemURL& src_url, DCHECK_EQ(src_url.origin(), dest_url.origin()); DCHECK_EQ(src_url.type(), dest_url.type()); - auto repeatable_callback = - base::AdaptCallbackForRepeating(std::move(callback)); + auto split_callback = base::SplitOnceCallback(std::move(callback)); GetUsageAndQuotaThenRunTask( dest_url, base::BindOnce(&FileSystemOperationImpl::DoMoveFileLocal, weak_factory_.GetWeakPtr(), src_url, dest_url, option, - repeatable_callback), - base::BindOnce(repeatable_callback, base::File::FILE_ERROR_FAILED)); + std::move(split_callback.first)), + base::BindOnce(std::move(split_callback.second), + base::File::FILE_ERROR_FAILED)); } base::File::Error FileSystemOperationImpl::SyncGetPlatformPath( diff --git a/chromium/storage/browser/file_system/file_system_operation_impl.h b/chromium/storage/browser/file_system/file_system_operation_impl.h index c096e2a63df..ee6f52aacbc 100644 --- a/chromium/storage/browser/file_system/file_system_operation_impl.h +++ b/chromium/storage/browser/file_system/file_system_operation_impl.h @@ -45,11 +45,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationImpl const FileSystemURL& dest_url, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) override; void Move(const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) override; void DirectoryExists(const FileSystemURL& url, StatusCallback callback) override; diff --git a/chromium/storage/browser/file_system/file_system_operation_impl_unittest.cc b/chromium/storage/browser/file_system/file_system_operation_impl_unittest.cc index 8ba68dfa6d7..13f885ff576 100644 --- a/chromium/storage/browser/file_system/file_system_operation_impl_unittest.cc +++ b/chromium/storage/browser/file_system/file_system_operation_impl_unittest.cc @@ -283,7 +283,8 @@ class FileSystemOperationImplTest : public testing::Test { base::RunLoop run_loop; update_observer_.Enable(); operation_runner()->Move( - src, dest, option, + src, dest, option, storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT, + storage::FileSystemOperation::CopyOrMoveProgressCallback(), RecordStatusCallback(run_loop.QuitClosure(), &status)); run_loop.Run(); update_observer_.Disable(); @@ -298,7 +299,7 @@ class FileSystemOperationImplTest : public testing::Test { update_observer_.Enable(); operation_runner()->Copy( src, dest, option, FileSystemOperation::ERROR_BEHAVIOR_ABORT, - FileSystemOperationRunner::CopyProgressCallback(), + FileSystemOperation::CopyOrMoveProgressCallback(), RecordStatusCallback(run_loop.QuitClosure(), &status)); run_loop.Run(); update_observer_.Disable(); diff --git a/chromium/storage/browser/file_system/file_system_operation_runner.cc b/chromium/storage/browser/file_system/file_system_operation_runner.cc index 7c186bdee47..ab92adbc1bc 100644 --- a/chromium/storage/browser/file_system/file_system_operation_runner.cc +++ b/chromium/storage/browser/file_system/file_system_operation_runner.cc @@ -94,7 +94,7 @@ OperationID FileSystemOperationRunner::Copy( const FileSystemURL& dest_url, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( @@ -111,7 +111,7 @@ OperationID FileSystemOperationRunner::Copy( operation_raw->Copy( src_url, dest_url, option, error_behavior, progress_callback.is_null() - ? CopyProgressCallback() + ? CopyOrMoveProgressCallback() : base::BindRepeating(&FileSystemOperationRunner::OnCopyProgress, weak_ptr_, id, progress_callback), base::BindOnce(&FileSystemOperationRunner::DidFinish, weak_ptr_, id, @@ -119,10 +119,13 @@ OperationID FileSystemOperationRunner::Copy( return id; } -OperationID FileSystemOperationRunner::Move(const FileSystemURL& src_url, - const FileSystemURL& dest_url, - CopyOrMoveOption option, - StatusCallback callback) { +OperationID FileSystemOperationRunner::Move( + const FileSystemURL& src_url, + const FileSystemURL& dest_url, + CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, + StatusCallback callback) { base::File::Error error = base::File::FILE_OK; std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( file_system_context_->CreateFileSystemOperation(dest_url, &error)); @@ -135,9 +138,14 @@ OperationID FileSystemOperationRunner::Move(const FileSystemURL& src_url, } PrepareForWrite(id, dest_url); PrepareForWrite(id, src_url); - operation_raw->Move(src_url, dest_url, option, - base::BindOnce(&FileSystemOperationRunner::DidFinish, - weak_ptr_, id, std::move(callback))); + operation_raw->Move( + src_url, dest_url, option, error_behavior, + progress_callback.is_null() + ? CopyOrMoveProgressCallback() + : base::BindRepeating(&FileSystemOperationRunner::OnCopyProgress, + weak_ptr_, id, progress_callback), + base::BindOnce(&FileSystemOperationRunner::DidFinish, weak_ptr_, id, + std::move(callback))); return id; } @@ -691,8 +699,8 @@ void FileSystemOperationRunner::DidCreateSnapshot( void FileSystemOperationRunner::OnCopyProgress( const OperationID id, - const CopyProgressCallback& callback, - FileSystemOperation::CopyProgressType type, + const CopyOrMoveProgressCallback& callback, + FileSystemOperation::CopyOrMoveProgressType type, const FileSystemURL& source_url, const FileSystemURL& dest_url, int64_t size) { diff --git a/chromium/storage/browser/file_system/file_system_operation_runner.h b/chromium/storage/browser/file_system/file_system_operation_runner.h index 661cbe0b99e..74cd2c1dd6f 100644 --- a/chromium/storage/browser/file_system/file_system_operation_runner.h +++ b/chromium/storage/browser/file_system/file_system_operation_runner.h @@ -43,7 +43,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { using WriteCallback = FileSystemOperation::WriteCallback; using OpenFileCallback = FileSystemOperation::OpenFileCallback; using ErrorBehavior = FileSystemOperation::ErrorBehavior; - using CopyProgressCallback = FileSystemOperation::CopyProgressCallback; + using CopyOrMoveProgressCallback = + FileSystemOperation::CopyOrMoveProgressCallback; using CopyFileProgressCallback = FileSystemOperation::CopyFileProgressCallback; using CopyOrMoveOption = FileSystemOperation::CopyOrMoveOption; @@ -84,7 +85,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { const FileSystemURL& dest_url, CopyOrMoveOption option, ErrorBehavior error_behavior, - const CopyProgressCallback& progress_callback, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback); // Moves a file or directory from |src_url| to |dest_url|. A new file @@ -93,6 +94,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { OperationID Move(const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, + ErrorBehavior error_behavior, + const CopyOrMoveProgressCallback& progress_callback, StatusCallback callback); // Checks if a directory is present at |url|. @@ -283,8 +286,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { scoped_refptr<ShareableFileReference> file_ref); void OnCopyProgress(const OperationID id, - const CopyProgressCallback& callback, - FileSystemOperation::CopyProgressType type, + const CopyOrMoveProgressCallback& callback, + FileSystemOperation::CopyOrMoveProgressType type, const FileSystemURL& source_url, const FileSystemURL& dest_url, int64_t size); diff --git a/chromium/storage/browser/file_system/file_system_quota_client.h b/chromium/storage/browser/file_system/file_system_quota_client.h index 3a4261e42be..6ca864b4281 100644 --- a/chromium/storage/browser/file_system/file_system_quota_client.h +++ b/chromium/storage/browser/file_system/file_system_quota_client.h @@ -11,7 +11,6 @@ #include "base/compiler_specific.h" #include "base/component_export.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "storage/browser/file_system/file_system_quota_util.h" diff --git a/chromium/storage/browser/file_system/file_system_usage_cache.cc b/chromium/storage/browser/file_system/file_system_usage_cache.cc index 3fb3e21957f..61e411493e9 100644 --- a/chromium/storage/browser/file_system/file_system_usage_cache.cc +++ b/chromium/storage/browser/file_system/file_system_usage_cache.cc @@ -300,14 +300,9 @@ bool FileSystemUsageCache::FlushFile(const base::FilePath& file_path) { void FileSystemUsageCache::ScheduleCloseTimer() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (timer_.IsRunning()) { - timer_.Reset(); - return; - } - - timer_.Start(FROM_HERE, kCloseDelay, - base::BindOnce(&FileSystemUsageCache::CloseCacheFiles, - weak_factory_.GetWeakPtr())); + // This will restart the timer if it is already running. + timer_.Start(FROM_HERE, kCloseDelay, this, + &FileSystemUsageCache::CloseCacheFiles); } bool FileSystemUsageCache::HasCacheFileHandle(const base::FilePath& file_path) { diff --git a/chromium/storage/browser/file_system/file_system_usage_cache.h b/chromium/storage/browser/file_system/file_system_usage_cache.h index f46901a979f..a0ef4c1b7ad 100644 --- a/chromium/storage/browser/file_system/file_system_usage_cache.h +++ b/chromium/storage/browser/file_system/file_system_usage_cache.h @@ -14,7 +14,6 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" @@ -101,8 +100,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemUsageCache { std::map<base::FilePath, std::unique_ptr<base::File>> cache_files_; - base::WeakPtrFactory<FileSystemUsageCache> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(FileSystemUsageCache); }; diff --git a/chromium/storage/browser/file_system/file_writer_delegate.h b/chromium/storage/browser/file_system/file_writer_delegate.h index 48725b3acd6..70626b3f55e 100644 --- a/chromium/storage/browser/file_system/file_writer_delegate.h +++ b/chromium/storage/browser/file_system/file_writer_delegate.h @@ -11,7 +11,6 @@ #include "base/component_export.h" #include "base/files/file.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" diff --git a/chromium/storage/browser/file_system/filesystem_proxy_file_stream_reader.cc b/chromium/storage/browser/file_system/filesystem_proxy_file_stream_reader.cc index e60c66db978..632bc6a43c5 100644 --- a/chromium/storage/browser/file_system/filesystem_proxy_file_stream_reader.cc +++ b/chromium/storage/browser/file_system/filesystem_proxy_file_stream_reader.cc @@ -38,7 +38,7 @@ FileErrorOr<base::File::Info> DoGetFileInfo( return base::File::FILE_ERROR_NOT_FOUND; } - base::Optional<base::File::Info> info = + absl::optional<base::File::Info> info = shared_filesystem_proxy->data->GetFileInfo(path); if (!info.has_value()) { return base::File::FILE_ERROR_FAILED; diff --git a/chromium/storage/browser/file_system/memory_file_stream_reader.cc b/chromium/storage/browser/file_system/memory_file_stream_reader.cc index 0ca229bb8e8..2eba0f5e082 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_reader.cc +++ b/chromium/storage/browser/file_system/memory_file_stream_reader.cc @@ -14,17 +14,6 @@ namespace storage { -std::unique_ptr<FileStreamReader> FileStreamReader::CreateForMemoryFile( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset, - const base::Time& expected_modification_time) { - return base::WrapUnique(new MemoryFileStreamReader( - std::move(task_runner), std::move(memory_file_util), file_path, - initial_offset, expected_modification_time)); -} - MemoryFileStreamReader::MemoryFileStreamReader( scoped_refptr<base::TaskRunner> task_runner, base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, diff --git a/chromium/storage/browser/file_system/memory_file_stream_reader.h b/chromium/storage/browser/file_system/memory_file_stream_reader.h index 4f05d450522..342fc8e81c5 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_reader.h +++ b/chromium/storage/browser/file_system/memory_file_stream_reader.h @@ -20,6 +20,21 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamReader : public FileStreamReader { public: + // Creates a new FileReader for a memory file |file_path|. + // |initial_offset| specifies the offset in the file where the first read + // should start. If the given offset is out of the file range any + // read operation may error out with net::ERR_REQUEST_RANGE_NOT_SATISFIABLE. + // |expected_modification_time| specifies the expected last modification + // If the value is non-null, the reader will check the underlying file's + // actual modification time to see if the file has been modified, and if + // it does any succeeding read operations should fail with + // ERR_UPLOAD_FILE_CHANGED error. + MemoryFileStreamReader( + scoped_refptr<base::TaskRunner> task_runner, + base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, + const base::FilePath& file_path, + int64_t initial_offset, + const base::Time& expected_modification_time); ~MemoryFileStreamReader() override; // FileStreamReader overrides. @@ -29,15 +44,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamReader int64_t GetLength(net::Int64CompletionOnceCallback callback) override; private: - friend class FileStreamReader; - - MemoryFileStreamReader( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset, - const base::Time& expected_modification_time); - void OnReadCompleted(net::CompletionOnceCallback callback, int result); void OnGetLengthCompleted(net::Int64CompletionOnceCallback callback, int64_t result); diff --git a/chromium/storage/browser/file_system/memory_file_stream_reader_unittest.cc b/chromium/storage/browser/file_system/memory_file_stream_reader_unittest.cc index ebc2dec4cc6..d2a5a5cd706 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_reader_unittest.cc +++ b/chromium/storage/browser/file_system/memory_file_stream_reader_unittest.cc @@ -20,7 +20,6 @@ #include "base/test/task_environment.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "storage/browser/file_system/file_stream_reader.h" #include "storage/browser/file_system/file_stream_reader_test.h" #include "storage/browser/file_system/file_stream_test_utils.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" @@ -47,7 +46,7 @@ class MemoryFileStreamReaderTest : public FileStreamReaderTest { const std::string& file_name, int64_t initial_offset, const base::Time& expected_modification_time) override { - return FileStreamReader::CreateForMemoryFile( + return std::make_unique<MemoryFileStreamReader>( base::ThreadTaskRunnerHandle::Get(), file_util_->GetWeakPtr(), test_dir().AppendASCII(file_name), initial_offset, expected_modification_time); diff --git a/chromium/storage/browser/file_system/memory_file_stream_writer.cc b/chromium/storage/browser/file_system/memory_file_stream_writer.cc index 7f45e02a310..fe9933f8cd9 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_writer.cc +++ b/chromium/storage/browser/file_system/memory_file_stream_writer.cc @@ -14,16 +14,6 @@ namespace storage { -std::unique_ptr<FileStreamWriter> FileStreamWriter::CreateForMemoryFile( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset) { - return base::WrapUnique(new MemoryFileStreamWriter( - std::move(task_runner), std::move(memory_file_util), file_path, - initial_offset)); -} - MemoryFileStreamWriter::MemoryFileStreamWriter( scoped_refptr<base::TaskRunner> task_runner, base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, diff --git a/chromium/storage/browser/file_system/memory_file_stream_writer.h b/chromium/storage/browser/file_system/memory_file_stream_writer.h index 625a18edef3..83f3c8c3965 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_writer.h +++ b/chromium/storage/browser/file_system/memory_file_stream_writer.h @@ -18,6 +18,11 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter : public FileStreamWriter { public: + MemoryFileStreamWriter( + scoped_refptr<base::TaskRunner> task_runner, + base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, + const base::FilePath& file_path, + int64_t initial_offset); ~MemoryFileStreamWriter() override; // FileStreamWriter overrides. @@ -28,13 +33,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter int Flush(net::CompletionOnceCallback callback) override; private: - friend class FileStreamWriter; - MemoryFileStreamWriter( - scoped_refptr<base::TaskRunner> task_runner, - base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, - const base::FilePath& file_path, - int64_t initial_offset); - void OnWriteCompleted(net::CompletionOnceCallback callback, int result); // Stops the in-flight operation and calls |cancel_callback_| if it has been diff --git a/chromium/storage/browser/file_system/memory_file_stream_writer_unittest.cc b/chromium/storage/browser/file_system/memory_file_stream_writer_unittest.cc index 550b9d3d4ac..d73b747c6d5 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_writer_unittest.cc +++ b/chromium/storage/browser/file_system/memory_file_stream_writer_unittest.cc @@ -16,7 +16,6 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "storage/browser/file_system/file_stream_test_utils.h" -#include "storage/browser/file_system/file_stream_writer.h" #include "storage/browser/file_system/file_stream_writer_test.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" @@ -53,7 +52,7 @@ class MemoryFileStreamWriterTest : public FileStreamWriterTest { std::unique_ptr<FileStreamWriter> CreateWriter(const std::string& name, int64_t offset) override { - return FileStreamWriter::CreateForMemoryFile( + return std::make_unique<MemoryFileStreamWriter>( base::ThreadTaskRunnerHandle::Get(), file_util_->GetWeakPtr(), Path(name), offset); } diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.cc b/chromium/storage/browser/file_system/obfuscated_file_util.cc index 014f99a4fc9..bc180ebfb4d 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util.cc @@ -29,9 +29,7 @@ #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/quota/quota_limit_type.h" #include "storage/browser/file_system/sandbox_file_system_backend.h" -#include "storage/browser/file_system/sandbox_isolated_origin_database.h" #include "storage/browser/file_system/sandbox_origin_database.h" -#include "storage/browser/file_system/sandbox_prioritized_origin_database.h" #include "storage/browser/quota/quota_manager.h" #include "storage/common/database/database_identifier.h" #include "storage/common/file_system/file_system_util.h" @@ -224,11 +222,11 @@ class ObfuscatedOriginEnumerator ~ObfuscatedOriginEnumerator() override = default; // Returns the next origin. Returns empty if there are no more origins. - base::Optional<url::Origin> Next() override { + absl::optional<url::Origin> Next() override { OriginRecord record; if (origins_.empty()) { current_ = record; - return base::nullopt; + return absl::nullopt; } record = origins_.back(); origins_.pop_back(); @@ -979,41 +977,6 @@ int64_t ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) { return UsageForPath(VirtualPath::BaseName(path).value().size()); } -void ObfuscatedFileUtil::MaybePrepopulateDatabase( - const std::vector<std::string>& type_strings_to_prepopulate) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - SandboxPrioritizedOriginDatabase database(file_system_directory_, - env_override_); - std::string origin_string = database.GetPrimaryOrigin(); - if (origin_string.empty() || !database.HasOriginPath(origin_string)) - return; - const url::Origin origin = GetOriginFromIdentifier(origin_string); - - // Prepopulate the directory database(s) if and only if this instance - // has primary origin and the directory database is already there. - for (const std::string& type_string : type_strings_to_prepopulate) { - // Only handles known types. - if (!base::Contains(known_type_strings_, type_string)) - continue; - base::File::Error error = base::File::FILE_ERROR_FAILED; - base::FilePath path = - GetDirectoryForOriginAndType(origin, type_string, false, &error); - if (error != base::File::FILE_OK) - continue; - std::unique_ptr<SandboxDirectoryDatabase> db = - std::make_unique<SandboxDirectoryDatabase>(path, env_override_); - if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { - directories_[GetDirectoryDatabaseKey(origin, type_string)] = - std::move(db); - MarkUsed(); - // Don't populate more than one database, as it may rather hurt - // performance. - break; - } - } -} - base::FilePath ObfuscatedFileUtil::GetDirectoryForURL( const FileSystemURL& url, bool create, @@ -1304,14 +1267,8 @@ void ObfuscatedFileUtil::InvalidateUsageCache( void ObfuscatedFileUtil::MarkUsed() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (timer_.IsRunning()) { - timer_.Reset(); - } else { - timer_.Start(FROM_HERE, - base::TimeDelta::FromSeconds(db_flush_delay_seconds_), - base::BindOnce(&ObfuscatedFileUtil::DropDatabases, - base::Unretained(this))); - } + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(db_flush_delay_seconds_), + this, &ObfuscatedFileUtil::DropDatabases); } void ObfuscatedFileUtil::DropDatabases() { @@ -1346,19 +1303,8 @@ bool ObfuscatedFileUtil::InitOriginDatabase(const url::Origin& origin_hint, } } - std::unique_ptr<SandboxPrioritizedOriginDatabase> - prioritized_origin_database = - std::make_unique<SandboxPrioritizedOriginDatabase>( - file_system_directory_, env_override_); - - if (origin_hint.opaque() && HasIsolatedStorage(origin_hint)) { - const std::string isolated_origin_string = - GetIdentifierFromOrigin(origin_hint); - prioritized_origin_database->InitializePrimaryOrigin( - isolated_origin_string); - } - - origin_database_ = std::move(prioritized_origin_database); + origin_database_ = std::make_unique<SandboxOriginDatabase>( + file_system_directory_, env_override_); return true; } diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.h b/chromium/storage/browser/file_system/obfuscated_file_util.h index 5bf801251b2..372d35fa205 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util.h +++ b/chromium/storage/browser/file_system/obfuscated_file_util.h @@ -72,9 +72,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil public: virtual ~AbstractOriginEnumerator() = default; - // Returns the next origin. Returns base::nullopt if there are no more + // Returns the next origin. Returns absl::nullopt if there are no more // origins. - virtual base::Optional<url::Origin> Next() = 0; + virtual absl::optional<url::Origin> Next() = 0; // Returns the current origin's information. // |type_string| must be ascii string. @@ -196,13 +196,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil // on each path segment and add the results. static int64_t ComputeFilePathCost(const base::FilePath& path); - // Tries to prepopulate directory database for the given type strings. - // This tries from the first one in the given type_strings and stops - // once it succeeds to do so for one database (i.e. it prepopulates - // at most one database). - void MaybePrepopulateDatabase( - const std::vector<std::string>& type_strings_to_prepopulate); - // This will rewrite the databases to remove traces of deleted data from disk. void RewriteDatabases(); diff --git a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc index b6f3dd71c66..acc22212832 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc @@ -93,7 +93,7 @@ ObfuscatedFileUtilMemoryDelegate::~ObfuscatedFileUtilMemoryDelegate() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -base::Optional<ObfuscatedFileUtilMemoryDelegate::DecomposedPath> +absl::optional<ObfuscatedFileUtilMemoryDelegate::DecomposedPath> ObfuscatedFileUtilMemoryDelegate::ParsePath(const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DecomposedPath dp; @@ -102,11 +102,11 @@ ObfuscatedFileUtilMemoryDelegate::ParsePath(const base::FilePath& path) { // Ensure |path| is under |root_|. if (dp.components.size() < root_path_components_.size()) - return base::nullopt; + return absl::nullopt; for (size_t i = 0; i < root_path_components_.size(); i++) if (dp.components[i] != root_path_components_[i]) - return base::nullopt; + return absl::nullopt; dp.components.erase(dp.components.begin(), dp.components.begin() + root_path_components_.size()); @@ -119,7 +119,7 @@ ObfuscatedFileUtilMemoryDelegate::ParsePath(const base::FilePath& path) { } else if (dp.components[i] == base::FilePath::kParentDirectory) { // Beyond |root|? if (!i) - return base::nullopt; + return absl::nullopt; dp.components.erase(dp.components.begin() + i - 1, dp.components.begin() + i + 1); i -= 2; @@ -152,7 +152,7 @@ ObfuscatedFileUtilMemoryDelegate::ParsePath(const base::FilePath& path) { bool ObfuscatedFileUtilMemoryDelegate::DirectoryExists( const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); return dp && dp->entry && dp->entry->type == Entry::kDirectory; } @@ -161,7 +161,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CreateDirectory( bool exclusive, bool recursive) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp) return base::File::FILE_ERROR_NOT_FOUND; @@ -205,7 +205,7 @@ bool ObfuscatedFileUtilMemoryDelegate::DeleteFileOrDirectory( const base::FilePath& path, bool recursive) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp) return false; @@ -228,7 +228,7 @@ bool ObfuscatedFileUtilMemoryDelegate::IsLink(const base::FilePath& file_path) { bool ObfuscatedFileUtilMemoryDelegate::PathExists(const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); return dp && dp->entry; } @@ -262,7 +262,7 @@ void ObfuscatedFileUtilMemoryDelegate::CreateOrOpenInternal( base::File::Error ObfuscatedFileUtilMemoryDelegate::DeleteFile( const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry) return base::File::FILE_ERROR_NOT_FOUND; @@ -277,7 +277,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::EnsureFileExists( const base::FilePath& path, bool* created) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); *created = false; if (!dp || !dp->parent) return base::File::FILE_ERROR_NOT_FOUND; @@ -296,7 +296,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::GetFileInfo( const base::FilePath& path, base::File::Info* file_info) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry) return base::File::FILE_ERROR_NOT_FOUND; @@ -316,7 +316,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::Touch( const base::Time& last_access_time, const base::Time& last_modified_time) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry) return base::File::FILE_ERROR_FAILED; @@ -330,7 +330,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::Truncate( const base::FilePath& path, int64_t length) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry || dp->entry->type != Entry::kFile) return base::File::FILE_ERROR_NOT_FOUND; @@ -359,8 +359,8 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CopyOrMoveFile( FileSystemOperation::CopyOrMoveOption option, NativeFileUtil::CopyOrMoveMode mode) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> src_dp = ParsePath(src_path); - base::Optional<DecomposedPath> dest_dp = ParsePath(dest_path); + absl::optional<DecomposedPath> src_dp = ParsePath(src_path); + absl::optional<DecomposedPath> dest_dp = ParsePath(dest_path); if (!src_dp || !src_dp->entry || !dest_dp || !dest_dp->parent) return base::File::FILE_ERROR_NOT_FOUND; @@ -464,7 +464,7 @@ bool ObfuscatedFileUtilMemoryDelegate::CopyOrMoveFileInternal( size_t ObfuscatedFileUtilMemoryDelegate::ComputeDirectorySize( const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry || dp->entry->type != Entry::kDirectory) return 0; @@ -490,7 +490,7 @@ int ObfuscatedFileUtilMemoryDelegate::ReadFile(const base::FilePath& path, scoped_refptr<net::IOBuffer> buf, int buf_len) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || dp->entry->type != Entry::kFile) return net::ERR_FILE_NOT_FOUND; @@ -517,7 +517,7 @@ int ObfuscatedFileUtilMemoryDelegate::WriteFile( scoped_refptr<net::IOBuffer> buf, int buf_len) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); if (!dp || !dp->entry || dp->entry->type != Entry::kFile) return net::ERR_FILE_NOT_FOUND; @@ -580,7 +580,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CreateFileForTesting( if (result != base::File::FILE_OK) return result; - base::Optional<DecomposedPath> dp = ParsePath(path); + absl::optional<DecomposedPath> dp = ParsePath(path); DCHECK(dp && dp->entry->type == Entry::kFile); dp->entry->file_content = @@ -595,7 +595,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CopyInForeignFile( FileSystemOperation::CopyOrMoveOption /* option */, NativeFileUtil::CopyOrMoveMode /* mode */) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::Optional<DecomposedPath> dest_dp = ParsePath(dest_path); + absl::optional<DecomposedPath> dest_dp = ParsePath(dest_path); if (!dest_dp || !dest_dp->parent) return base::File::FILE_ERROR_NOT_FOUND; diff --git a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.h b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.h index d1240511303..9242697bb7d 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.h +++ b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.h @@ -112,7 +112,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtilMemoryDelegate // Parses the given path into a decomposed path and performs validity checks // and normalization. Returns an empty value if checks fail. - base::Optional<DecomposedPath> ParsePath(const base::FilePath& path); + absl::optional<DecomposedPath> ParsePath(const base::FilePath& path); // Creates or opens a file specified in |dp|. void CreateOrOpenInternal(const DecomposedPath& dp, int file_flags); diff --git a/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc b/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc index cd1d6cee87a..4290aa4ec38 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc @@ -36,7 +36,6 @@ #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/sandbox_directory_database.h" #include "storage/browser/file_system/sandbox_file_system_backend_delegate.h" -#include "storage/browser/file_system/sandbox_isolated_origin_database.h" #include "storage/browser/file_system/sandbox_origin_database.h" #include "storage/browser/quota/quota_manager.h" #include "storage/browser/test/async_file_test_helper.h" @@ -1605,7 +1604,7 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { enumerator = ofu()->CreateOriginEnumerator(); EXPECT_TRUE(enumerator.get()); std::set<Origin> origins_found; - base::Optional<url::Origin> enumerator_origin; + absl::optional<url::Origin> enumerator_origin; while ((enumerator_origin = enumerator->Next()).has_value()) { origins_found.insert(enumerator_origin.value()); SCOPED_TRACE(testing::Message() diff --git a/chromium/storage/browser/file_system/plugin_private_file_system_backend.cc b/chromium/storage/browser/file_system/plugin_private_file_system_backend.cc index ee251a933b2..94f3ccccf23 100644 --- a/chromium/storage/browser/file_system/plugin_private_file_system_backend.cc +++ b/chromium/storage/browser/file_system/plugin_private_file_system_backend.cc @@ -18,8 +18,6 @@ #include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h" #include "storage/browser/file_system/async_file_util_adapter.h" -#include "storage/browser/file_system/file_stream_reader.h" -#include "storage/browser/file_system/file_stream_writer.h" #include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_operation.h" #include "storage/browser/file_system/file_system_operation_context.h" @@ -27,6 +25,7 @@ #include "storage/browser/file_system/obfuscated_file_util.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/quota/quota_reservation.h" +#include "storage/browser/file_system/sandbox_file_stream_reader.h" #include "storage/browser/file_system/sandbox_file_stream_writer.h" #include "storage/common/file_system/file_system_util.h" #include "url/origin.h" @@ -208,7 +207,7 @@ PluginPrivateFileSystemBackend::CreateFileStreamReader( const base::Time& expected_modification_time, FileSystemContext* context) const { DCHECK(CanHandleType(url.type())); - return FileStreamReader::CreateForFileSystemFile(context, url, offset, + return std::make_unique<SandboxFileStreamReader>(context, url, offset, expected_modification_time); } @@ -260,7 +259,7 @@ PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner( std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( obfuscated_file_util()->CreateOriginEnumerator()); std::vector<url::Origin> origins; - base::Optional<url::Origin> origin; + absl::optional<url::Origin> origin; while ((origin = enumerator->Next()).has_value()) origins.push_back(std::move(origin).value()); return origins; @@ -275,7 +274,7 @@ PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner( std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( obfuscated_file_util()->CreateOriginEnumerator()); std::vector<url::Origin> origins; - base::Optional<url::Origin> origin; + absl::optional<url::Origin> origin; while ((origin = enumerator->Next()).has_value()) { if (host == origin->host()) origins.push_back(std::move(origin).value()); diff --git a/chromium/storage/browser/file_system/quota/open_file_handle_context.h b/chromium/storage/browser/file_system/quota/open_file_handle_context.h index 1140cee8724..f63a10f4d6a 100644 --- a/chromium/storage/browser/file_system/quota/open_file_handle_context.h +++ b/chromium/storage/browser/file_system/quota/open_file_handle_context.h @@ -7,8 +7,6 @@ #include <stdint.h> -#include <map> - #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" diff --git a/chromium/storage/browser/file_system/file_system_file_stream_reader.cc b/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc index 9d37b807519..8c426a02055 100644 --- a/chromium/storage/browser/file_system/file_system_file_stream_reader.cc +++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "storage/browser/file_system/file_system_file_stream_reader.h" +#include "storage/browser/file_system/sandbox_file_stream_reader.h" #include <stdint.h> @@ -16,6 +16,7 @@ #include "net/base/net_errors.h" #include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_operation_runner.h" +#include "storage/browser/file_system/memory_file_stream_reader.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/plugin_private_file_system_backend.h" @@ -23,16 +24,7 @@ // blob and fileapi into content namespace. namespace storage { -std::unique_ptr<FileStreamReader> FileStreamReader::CreateForFileSystemFile( - FileSystemContext* file_system_context, - const FileSystemURL& url, - int64_t initial_offset, - const base::Time& expected_modification_time) { - return base::WrapUnique(new FileSystemFileStreamReader( - file_system_context, url, initial_offset, expected_modification_time)); -} - -FileSystemFileStreamReader::FileSystemFileStreamReader( +SandboxFileStreamReader::SandboxFileStreamReader( FileSystemContext* file_system_context, const FileSystemURL& url, int64_t initial_offset, @@ -45,11 +37,11 @@ FileSystemFileStreamReader::FileSystemFileStreamReader( expected_modification_time_(expected_modification_time), has_pending_create_snapshot_(false) {} -FileSystemFileStreamReader::~FileSystemFileStreamReader() = default; +SandboxFileStreamReader::~SandboxFileStreamReader() = default; -int FileSystemFileStreamReader::Read(net::IOBuffer* buf, - int buf_len, - net::CompletionOnceCallback callback) { +int SandboxFileStreamReader::Read(net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback) { if (file_reader_) return file_reader_->Read(buf, buf_len, std::move(callback)); @@ -59,7 +51,7 @@ int FileSystemFileStreamReader::Read(net::IOBuffer* buf, return CreateSnapshot(); } -int64_t FileSystemFileStreamReader::GetLength( +int64_t SandboxFileStreamReader::GetLength( net::Int64CompletionOnceCallback callback) { if (file_reader_) return file_reader_->GetLength(std::move(callback)); @@ -68,16 +60,16 @@ int64_t FileSystemFileStreamReader::GetLength( return CreateSnapshot(); } -int FileSystemFileStreamReader::CreateSnapshot() { +int SandboxFileStreamReader::CreateSnapshot() { DCHECK(!has_pending_create_snapshot_); has_pending_create_snapshot_ = true; file_system_context_->operation_runner()->CreateSnapshotFile( - url_, base::BindOnce(&FileSystemFileStreamReader::DidCreateSnapshot, + url_, base::BindOnce(&SandboxFileStreamReader::DidCreateSnapshot, weak_factory_.GetWeakPtr())); return net::ERR_IO_PENDING; } -void FileSystemFileStreamReader::DidCreateSnapshot( +void SandboxFileStreamReader::DidCreateSnapshot( base::File::Error file_error, const base::File::Info& file_info, const base::FilePath& platform_path, @@ -111,7 +103,7 @@ void FileSystemFileStreamReader::DidCreateSnapshot( memory_file_util_delegate = file_system_context_->sandbox_delegate()->memory_file_util_delegate(); } - file_reader_ = FileStreamReader::CreateForMemoryFile( + file_reader_ = std::make_unique<MemoryFileStreamReader>( file_system_context_->default_file_task_runner(), memory_file_util_delegate, platform_path, initial_offset_, expected_modification_time_); @@ -124,7 +116,7 @@ void FileSystemFileStreamReader::DidCreateSnapshot( if (read_callback_) { DCHECK(!get_length_callback_); int rv = Read(read_buf_, read_buf_len_, - base::BindOnce(&FileSystemFileStreamReader::OnRead, + base::BindOnce(&SandboxFileStreamReader::OnRead, weak_factory_.GetWeakPtr())); if (rv != net::ERR_IO_PENDING) std::move(read_callback_).Run(rv); @@ -132,16 +124,16 @@ void FileSystemFileStreamReader::DidCreateSnapshot( } int64_t rv = file_reader_->GetLength(base::BindOnce( - &FileSystemFileStreamReader::OnGetLength, weak_factory_.GetWeakPtr())); + &SandboxFileStreamReader::OnGetLength, weak_factory_.GetWeakPtr())); if (rv != net::ERR_IO_PENDING) std::move(get_length_callback_).Run(rv); } -void FileSystemFileStreamReader::OnRead(int rv) { +void SandboxFileStreamReader::OnRead(int rv) { std::move(read_callback_).Run(rv); } -void FileSystemFileStreamReader::OnGetLength(int64_t rv) { +void SandboxFileStreamReader::OnGetLength(int64_t rv) { std::move(get_length_callback_).Run(rv); } diff --git a/chromium/storage/browser/file_system/file_system_file_stream_reader.h b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h index cc82aba94f9..07fe4597d08 100644 --- a/chromium/storage/browser/file_system/file_system_file_stream_reader.h +++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef STORAGE_BROWSER_FILE_SYSTEM_FILE_SYSTEM_FILE_STREAM_READER_H_ -#define STORAGE_BROWSER_FILE_SYSTEM_FILE_SYSTEM_FILE_STREAM_READER_H_ +#ifndef STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_FILE_STREAM_READER_H_ +#define STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_FILE_STREAM_READER_H_ #include <stdint.h> @@ -28,15 +28,22 @@ namespace storage { class FileSystemContext; -// Generic FileStreamReader implementation for FileSystem files. -// Note: This generic implementation would work for any filesystems but -// remote filesystem should implement its own reader rather than relying -// on FileSystemOperation::GetSnapshotFile() which may force downloading -// the entire contents for remote files. -class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemFileStreamReader +// FileStreamReader implementation for Sandboxed FileSystem files. +// This wraps either a LocalFileStreamReader or a MemoryFileStreamReader, +// depending on if we're in an incognito profile or not. +class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamReader : public FileStreamReader { public: - ~FileSystemFileStreamReader() override; + // Creates a new reader for a filesystem URL |url| from |initial_offset|. + // |expected_modification_time| specifies the expected last modification. if + // the value is non-null, the reader will check the underlying file's actual + // modification time to see if the file has been modified, and if it does any + // succeeding read operations should fail with ERR_UPLOAD_FILE_CHANGED error. + SandboxFileStreamReader(FileSystemContext* file_system_context, + const FileSystemURL& url, + int64_t initial_offset, + const base::Time& expected_modification_time); + ~SandboxFileStreamReader() override; // FileStreamReader overrides. int Read(net::IOBuffer* buf, @@ -46,12 +53,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemFileStreamReader private: friend class FileStreamReader; - friend class FileSystemFileStreamReaderTest; - - FileSystemFileStreamReader(FileSystemContext* file_system_context, - const FileSystemURL& url, - int64_t initial_offset, - const base::Time& expected_modification_time); int CreateSnapshot(); void DidCreateSnapshot(base::File::Error file_error, @@ -72,11 +73,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemFileStreamReader std::unique_ptr<FileStreamReader> file_reader_; scoped_refptr<ShareableFileReference> snapshot_ref_; bool has_pending_create_snapshot_; - base::WeakPtrFactory<FileSystemFileStreamReader> weak_factory_{this}; + base::WeakPtrFactory<SandboxFileStreamReader> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(FileSystemFileStreamReader); + DISALLOW_COPY_AND_ASSIGN(SandboxFileStreamReader); }; } // namespace storage -#endif // STORAGE_BROWSER_FILE_SYSTEM_FILE_SYSTEM_FILE_STREAM_READER_H_ +#endif // STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_FILE_STREAM_READER_H_ diff --git a/chromium/storage/browser/file_system/file_system_file_stream_reader_unittest.cc b/chromium/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc index 9dbc6661796..105920bce2d 100644 --- a/chromium/storage/browser/file_system/file_system_file_stream_reader_unittest.cc +++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "storage/browser/file_system/file_system_file_stream_reader.h" +#include "storage/browser/file_system/sandbox_file_stream_reader.h" #include <stddef.h> #include <stdint.h> @@ -21,7 +21,6 @@ #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "storage/browser/file_system/external_mount_points.h" - #include "storage/browser/file_system/file_stream_reader_test.h" #include "storage/browser/file_system/file_stream_test_utils.h" #include "storage/browser/file_system/file_system_context.h" @@ -38,9 +37,9 @@ namespace { const char kURLOrigin[] = "http://remote/"; } // namespace -class FileSystemFileStreamReaderTest : public FileStreamReaderTest { +class SandboxFileStreamReaderTest : public FileStreamReaderTest { public: - FileSystemFileStreamReaderTest() = default; + SandboxFileStreamReaderTest() = default; void SetUp() override { ASSERT_TRUE(dir_.CreateUniqueTempDir()); @@ -64,7 +63,7 @@ class FileSystemFileStreamReaderTest : public FileStreamReaderTest { const std::string& file_name, int64_t initial_offset, const base::Time& expected_modification_time) override { - return FileStreamReader::CreateForFileSystemFile( + return std::make_unique<SandboxFileStreamReader>( file_system_context_.get(), GetFileSystemURL(file_name), initial_offset, expected_modification_time); } @@ -113,6 +112,6 @@ class FileSystemFileStreamReaderTest : public FileStreamReaderTest { INSTANTIATE_TYPED_TEST_SUITE_P(FileSystem, FileStreamReaderTypedTest, - FileSystemFileStreamReaderTest); + SandboxFileStreamReaderTest); } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc b/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc index fcc3cfb2548..d08773d17d5 100644 --- a/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc +++ b/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc @@ -17,9 +17,9 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "storage/browser/file_system/file_observers.h" -#include "storage/browser/file_system/file_stream_reader.h" #include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_operation_runner.h" +#include "storage/browser/file_system/memory_file_stream_writer.h" #include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h" #include "storage/browser/file_system/plugin_private_file_system_backend.h" #include "storage/browser/quota/quota_manager_proxy.h" @@ -156,7 +156,7 @@ void SandboxFileStreamWriter::DidCreateSnapshotFile( memory_file_util_delegate = file_system_context_->sandbox_delegate()->memory_file_util_delegate(); } - file_writer_ = FileStreamWriter::CreateForMemoryFile( + file_writer_ = std::make_unique<MemoryFileStreamWriter>( file_system_context_->default_file_task_runner(), memory_file_util_delegate, platform_path, initial_offset_); diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend.h b/chromium/storage/browser/file_system/sandbox_file_system_backend.h index b6cf3cdd18f..9fdacef3b20 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend.h +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend.h @@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/component_export.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "storage/browser/file_system/file_system_backend.h" diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.cc b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.cc index b6cd5b58fd0..9402dc66a1a 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.cc +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.cc @@ -20,7 +20,6 @@ #include "base/task_runner_util.h" #include "base/time/time.h" #include "storage/browser/file_system/async_file_util_adapter.h" -#include "storage/browser/file_system/file_stream_reader.h" #include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_operation_context.h" #include "storage/browser/file_system/file_system_url.h" @@ -30,6 +29,7 @@ #include "storage/browser/file_system/quota/quota_backend_impl.h" #include "storage/browser/file_system/quota/quota_reservation.h" #include "storage/browser/file_system/quota/quota_reservation_manager.h" +#include "storage/browser/file_system/sandbox_file_stream_reader.h" #include "storage/browser/file_system/sandbox_file_stream_writer.h" #include "storage/browser/file_system/sandbox_file_system_backend.h" #include "storage/browser/file_system/sandbox_quota_observer.h" @@ -57,9 +57,6 @@ const char kTemporaryDirectoryName[] = "t"; const char kPersistentDirectoryName[] = "p"; const char kSyncableDirectoryName[] = "s"; -const char* const kPrepopulateTypes[] = {kPersistentDirectoryName, - kTemporaryDirectoryName}; - enum FileSystemError { kOK = 0, kIncognito, @@ -103,7 +100,7 @@ class SandboxObfuscatedOriginEnumerator } ~SandboxObfuscatedOriginEnumerator() override = default; - base::Optional<url::Origin> Next() override { return enum_->Next(); } + absl::optional<url::Origin> Next() override { return enum_->Next(); } bool HasFileSystemType(FileSystemType type) const override { return enum_->HasTypeDirectory( @@ -212,19 +209,6 @@ SandboxFileSystemBackendDelegate::SandboxFileSystemBackendDelegate( special_storage_policy_(special_storage_policy), file_system_options_(file_system_options), is_filesystem_opened_(false) { - // Prepopulate database only if it can run asynchronously (i.e. the current - // sequence is not file_task_runner). Usually this is the case but may not - // in test code. - if (!file_system_options.is_incognito() && - !file_task_runner_->RunsTasksInCurrentSequence()) { - std::vector<std::string> types_to_prepopulate( - &kPrepopulateTypes[0], - &kPrepopulateTypes[base::size(kPrepopulateTypes)]); - file_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&ObfuscatedFileUtil::MaybePrepopulateDatabase, - base::Unretained(obfuscated_file_util()), - types_to_prepopulate)); - } } SandboxFileSystemBackendDelegate::~SandboxFileSystemBackendDelegate() { @@ -322,7 +306,7 @@ SandboxFileSystemBackendDelegate::CreateFileStreamReader( FileSystemContext* context) const { if (!IsAccessValid(url)) return nullptr; - return FileStreamReader::CreateForFileSystemFile(context, url, offset, + return std::make_unique<SandboxFileStreamReader>(context, url, offset, expected_modification_time); } @@ -377,7 +361,7 @@ SandboxFileSystemBackendDelegate::GetOriginsForTypeOnFileTaskRunner( DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); std::vector<url::Origin> origins; - base::Optional<url::Origin> origin; + absl::optional<url::Origin> origin; while ((origin = enumerator->Next()).has_value()) { if (enumerator->HasFileSystemType(type)) origins.push_back(std::move(origin).value()); @@ -402,7 +386,7 @@ SandboxFileSystemBackendDelegate::GetOriginsForHostOnFileTaskRunner( DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); std::vector<url::Origin> origins; std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); - base::Optional<url::Origin> origin; + absl::optional<url::Origin> origin; while ((origin = enumerator->Next()).has_value()) { if (host == origin->host() && enumerator->HasFileSystemType(type)) origins.push_back(std::move(origin).value()); diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.h b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.h index 0c03378e630..e8d445e1c9e 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.h +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.h @@ -75,9 +75,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate public: virtual ~OriginEnumerator() {} - // Returns the next origin. Returns base::nullopt if there are no more + // Returns the next origin. Returns absl::nullopt if there are no more // origins. - virtual base::Optional<url::Origin> Next() = 0; + virtual absl::optional<url::Origin> Next() = 0; // Returns the current origin's information. virtual bool HasFileSystemType(FileSystemType type) const = 0; diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend_unittest.cc b/chromium/storage/browser/file_system/sandbox_file_system_backend_unittest.cc index 52d6d9f74d2..76b7c845fb6 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend_unittest.cc +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend_unittest.cc @@ -189,7 +189,7 @@ TEST_P(SandboxFileSystemBackendTest, EnumerateOrigins) { size_t temporary_actual_size = 0; size_t persistent_actual_size = 0; - base::Optional<url::Origin> current; + absl::optional<url::Origin> current; while ((current = enumerator->Next()).has_value()) { SCOPED_TRACE(testing::Message() << "EnumerateOrigin " << current->Serialize()); diff --git a/chromium/storage/browser/file_system/sandbox_isolated_origin_database.cc b/chromium/storage/browser/file_system/sandbox_isolated_origin_database.cc deleted file mode 100644 index a465dcd6be6..00000000000 --- a/chromium/storage/browser/file_system/sandbox_isolated_origin_database.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "storage/browser/file_system/sandbox_isolated_origin_database.h" - -#include "base/files/file_util.h" -#include "storage/browser/file_system/sandbox_origin_database.h" - -namespace storage { - -SandboxIsolatedOriginDatabase::SandboxIsolatedOriginDatabase( - const std::string& origin, - const base::FilePath& file_system_directory, - const base::FilePath& origin_directory) - : origin_(origin), - file_system_directory_(file_system_directory), - origin_directory_(origin_directory) {} - -SandboxIsolatedOriginDatabase::~SandboxIsolatedOriginDatabase() = default; - -bool SandboxIsolatedOriginDatabase::HasOriginPath(const std::string& origin) { - return (origin_ == origin); -} - -bool SandboxIsolatedOriginDatabase::GetPathForOrigin( - const std::string& origin, - base::FilePath* directory) { - if (origin != origin_) - return false; - *directory = origin_directory_; - return true; -} - -bool SandboxIsolatedOriginDatabase::RemovePathForOrigin( - const std::string& origin) { - return true; -} - -bool SandboxIsolatedOriginDatabase::ListAllOrigins( - std::vector<OriginRecord>* origins) { - origins->push_back(OriginRecord(origin_, origin_directory_)); - return true; -} - -void SandboxIsolatedOriginDatabase::DropDatabase() {} - -void SandboxIsolatedOriginDatabase::RewriteDatabase() {} - -} // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_isolated_origin_database.h b/chromium/storage/browser/file_system/sandbox_isolated_origin_database.h deleted file mode 100644 index 5700d72d431..00000000000 --- a/chromium/storage/browser/file_system/sandbox_isolated_origin_database.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_ -#define STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_ - -#include <string> -#include <vector> - -#include "base/component_export.h" -#include "base/macros.h" -#include "storage/browser/file_system/sandbox_origin_database_interface.h" - -namespace storage { - -// This origin database implementation supports only one origin -// (therefore is expected to run very fast). -class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxIsolatedOriginDatabase - : public SandboxOriginDatabaseInterface { - public: - static const base::FilePath::CharType kObsoleteOriginDirectory[]; - - // Initialize this database for |origin| which makes GetPathForOrigin return - // |origin_directory| (in |file_system_directory|). - SandboxIsolatedOriginDatabase(const std::string& origin, - const base::FilePath& file_system_directory, - const base::FilePath& origin_directory); - ~SandboxIsolatedOriginDatabase() override; - - // SandboxOriginDatabaseInterface overrides. - bool HasOriginPath(const std::string& origin) override; - bool GetPathForOrigin(const std::string& origin, - base::FilePath* directory) override; - bool RemovePathForOrigin(const std::string& origin) override; - bool ListAllOrigins(std::vector<OriginRecord>* origins) override; - void DropDatabase() override; - void RewriteDatabase() override; - - const std::string& origin() const { return origin_; } - - private: - const std::string origin_; - const base::FilePath file_system_directory_; - const base::FilePath origin_directory_; - - DISALLOW_COPY_AND_ASSIGN(SandboxIsolatedOriginDatabase); -}; - -} // namespace storage - -#endif // STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_ diff --git a/chromium/storage/browser/file_system/sandbox_isolated_origin_database_unittest.cc b/chromium/storage/browser/file_system/sandbox_isolated_origin_database_unittest.cc deleted file mode 100644 index 9f27cea81c0..00000000000 --- a/chromium/storage/browser/file_system/sandbox_isolated_origin_database_unittest.cc +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "storage/browser/file_system/sandbox_isolated_origin_database.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "storage/browser/file_system/sandbox_origin_database.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace storage { - -namespace { -const base::FilePath::CharType kOriginDirectory[] = FILE_PATH_LITERAL("iso"); -} // namespace - -TEST(SandboxIsolatedOriginDatabaseTest, BasicTest) { - base::ScopedTempDir dir; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - - std::string kOrigin("origin"); - SandboxIsolatedOriginDatabase database(kOrigin, dir.GetPath(), - base::FilePath(kOriginDirectory)); - - EXPECT_TRUE(database.HasOriginPath(kOrigin)); - - base::FilePath path1, path2; - - EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path1)); - EXPECT_FALSE(database.GetPathForOrigin("foo", &path1)); - - EXPECT_TRUE(database.HasOriginPath(kOrigin)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin, &path1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin, &path2)); - EXPECT_FALSE(path1.empty()); - EXPECT_FALSE(path2.empty()); - EXPECT_EQ(path1, path2); -} - -} // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.cc b/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.cc deleted file mode 100644 index d364b549cde..00000000000 --- a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.cc +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "storage/browser/file_system/sandbox_prioritized_origin_database.h" - -#include <memory> - -#include "base/check.h" -#include "base/files/file.h" -#include "base/files/file_util.h" -#include "base/pickle.h" -#include "storage/browser/file_system/sandbox_isolated_origin_database.h" -#include "storage/browser/file_system/sandbox_origin_database.h" -#include "third_party/leveldatabase/leveldb_chrome.h" - -namespace storage { - -const base::FilePath::CharType* const - SandboxPrioritizedOriginDatabase::kPrimaryDirectory = - FILE_PATH_LITERAL("primary"); - -const base::FilePath::CharType* const - SandboxPrioritizedOriginDatabase::kPrimaryOriginFile = - FILE_PATH_LITERAL("primary.origin"); - -namespace { - -bool WritePrimaryOriginFile(const base::FilePath& path, - const std::string& origin) { - base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); - if (!file.IsValid()) - return false; - if (!file.created()) - file.SetLength(0); - base::Pickle pickle; - pickle.WriteString(origin); - file.Write(0, static_cast<const char*>(pickle.data()), pickle.size()); - file.Flush(); - return true; -} - -bool ReadPrimaryOriginFile(const base::FilePath& path, std::string* origin) { - std::string buffer; - if (!base::ReadFileToString(path, &buffer)) - return false; - base::Pickle pickle(buffer.data(), buffer.size()); - base::PickleIterator iter(pickle); - return iter.ReadString(origin) && !origin->empty(); -} - -} // namespace - -SandboxPrioritizedOriginDatabase::SandboxPrioritizedOriginDatabase( - const base::FilePath& file_system_directory, - leveldb::Env* env_override) - : file_system_directory_(file_system_directory), - env_override_(env_override), - primary_origin_file_(file_system_directory_.Append(kPrimaryOriginFile)) {} - -SandboxPrioritizedOriginDatabase::~SandboxPrioritizedOriginDatabase() = default; - -bool SandboxPrioritizedOriginDatabase::InitializePrimaryOrigin( - const std::string& origin) { - const bool is_in_memory = - env_override_ && leveldb_chrome::IsMemEnv(env_override_); - if (!primary_origin_database_ && !is_in_memory) { - if (!MaybeLoadPrimaryOrigin() && ResetPrimaryOrigin(origin)) { - MaybeMigrateDatabase(origin); - primary_origin_database_ = - std::make_unique<SandboxIsolatedOriginDatabase>( - origin, file_system_directory_, - base::FilePath(kPrimaryDirectory)); - return true; - } - } - - if (primary_origin_database_) - return primary_origin_database_->HasOriginPath(origin); - - return false; -} - -std::string SandboxPrioritizedOriginDatabase::GetPrimaryOrigin() { - MaybeLoadPrimaryOrigin(); - if (primary_origin_database_) - return primary_origin_database_->origin(); - return std::string(); -} - -bool SandboxPrioritizedOriginDatabase::HasOriginPath( - const std::string& origin) { - MaybeInitializeDatabases(false); - if (primary_origin_database_ && - primary_origin_database_->HasOriginPath(origin)) - return true; - if (origin_database_) - return origin_database_->HasOriginPath(origin); - return false; -} - -bool SandboxPrioritizedOriginDatabase::GetPathForOrigin( - const std::string& origin, - base::FilePath* directory) { - MaybeInitializeDatabases(true); - if (primary_origin_database_ && - primary_origin_database_->GetPathForOrigin(origin, directory)) - return true; - DCHECK(origin_database_); - return origin_database_->GetPathForOrigin(origin, directory); -} - -bool SandboxPrioritizedOriginDatabase::RemovePathForOrigin( - const std::string& origin) { - MaybeInitializeDatabases(false); - if (primary_origin_database_ && - primary_origin_database_->HasOriginPath(origin)) { - primary_origin_database_.reset(); - base::DeletePathRecursively( - file_system_directory_.Append(kPrimaryOriginFile)); - return true; - } - if (origin_database_) - return origin_database_->RemovePathForOrigin(origin); - return true; -} - -bool SandboxPrioritizedOriginDatabase::ListAllOrigins( - std::vector<OriginRecord>* origins) { - // SandboxOriginDatabase may clear the |origins|, so call this before - // primary_origin_database_. - MaybeInitializeDatabases(false); - if (origin_database_ && !origin_database_->ListAllOrigins(origins)) - return false; - if (primary_origin_database_) - return primary_origin_database_->ListAllOrigins(origins); - return true; -} - -void SandboxPrioritizedOriginDatabase::DropDatabase() { - primary_origin_database_.reset(); - origin_database_.reset(); -} - -void SandboxPrioritizedOriginDatabase::RewriteDatabase() { - if (primary_origin_database_) - primary_origin_database_->RewriteDatabase(); - if (origin_database_) - origin_database_->RewriteDatabase(); -} - -bool SandboxPrioritizedOriginDatabase::MaybeLoadPrimaryOrigin() { - if (primary_origin_database_) - return true; - std::string saved_origin; - if (!ReadPrimaryOriginFile(primary_origin_file_, &saved_origin)) - return false; - primary_origin_database_ = std::make_unique<SandboxIsolatedOriginDatabase>( - saved_origin, file_system_directory_, base::FilePath(kPrimaryDirectory)); - return true; -} - -bool SandboxPrioritizedOriginDatabase::ResetPrimaryOrigin( - const std::string& origin) { - DCHECK(!primary_origin_database_); - if (!WritePrimaryOriginFile(primary_origin_file_, origin)) - return false; - // We reset the primary origin directory too. - // (This means the origin file corruption causes data loss - // We could keep the directory there as the same origin will likely - // become the primary origin, but let's play conservatively.) - base::DeletePathRecursively(file_system_directory_.Append(kPrimaryDirectory)); - return true; -} - -void SandboxPrioritizedOriginDatabase::MaybeMigrateDatabase( - const std::string& origin) { - MaybeInitializeNonPrimaryDatabase(false); - if (!origin_database_) - return; - if (origin_database_->HasOriginPath(origin)) { - base::FilePath directory_name; - if (origin_database_->GetPathForOrigin(origin, &directory_name) && - directory_name != base::FilePath(kPrimaryOriginFile)) { - base::FilePath from_path = file_system_directory_.Append(directory_name); - base::FilePath to_path = file_system_directory_.Append(kPrimaryDirectory); - - if (base::PathExists(to_path)) - base::DeletePathRecursively(to_path); - base::Move(from_path, to_path); - } - - origin_database_->RemovePathForOrigin(origin); - } - - std::vector<OriginRecord> origins; - origin_database_->ListAllOrigins(&origins); - if (origins.empty()) { - origin_database_->RemoveDatabase(); - origin_database_.reset(); - } -} - -void SandboxPrioritizedOriginDatabase::MaybeInitializeDatabases(bool create) { - MaybeLoadPrimaryOrigin(); - MaybeInitializeNonPrimaryDatabase(create); -} - -void SandboxPrioritizedOriginDatabase::MaybeInitializeNonPrimaryDatabase( - bool create) { - if (origin_database_) - return; - - origin_database_ = std::make_unique<SandboxOriginDatabase>( - file_system_directory_, env_override_); - if (!create && !base::DirectoryExists(origin_database_->GetDatabasePath())) { - origin_database_.reset(); - return; - } -} - -SandboxOriginDatabase* -SandboxPrioritizedOriginDatabase::GetSandboxOriginDatabase() { - MaybeInitializeNonPrimaryDatabase(true); - return origin_database_.get(); -} - -} // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.h b/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.h deleted file mode 100644 index d848ea7de74..00000000000 --- a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_PRIORITIZED_ORIGIN_DATABASE_H_ -#define STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_PRIORITIZED_ORIGIN_DATABASE_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/component_export.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "storage/browser/file_system/sandbox_origin_database_interface.h" - -namespace leveldb { -class Env; -} - -namespace storage { - -class ObfuscatedFileUtil; -class SandboxIsolatedOriginDatabase; -class SandboxOriginDatabase; - -class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxPrioritizedOriginDatabase - : public SandboxOriginDatabaseInterface { - public: - static const base::FilePath::CharType* const kPrimaryDirectory; - static const base::FilePath::CharType* const kPrimaryOriginFile; - - SandboxPrioritizedOriginDatabase(const base::FilePath& file_system_directory, - leveldb::Env* env_override); - ~SandboxPrioritizedOriginDatabase() override; - - // Sets |origin| as primary origin in this database (e.g. may - // allow faster access). - // Returns false if this database already has a primary origin - // which is different from |origin|. - bool InitializePrimaryOrigin(const std::string& origin); - std::string GetPrimaryOrigin(); - - // SandboxOriginDatabaseInterface overrides. - bool HasOriginPath(const std::string& origin) override; - bool GetPathForOrigin(const std::string& origin, - base::FilePath* directory) override; - bool RemovePathForOrigin(const std::string& origin) override; - bool ListAllOrigins(std::vector<OriginRecord>* origins) override; - void DropDatabase() override; - void RewriteDatabase() override; - - const base::FilePath& primary_origin_file() const { - return primary_origin_file_; - } - - private: - bool MaybeLoadPrimaryOrigin(); - bool ResetPrimaryOrigin(const std::string& origin); - void MaybeMigrateDatabase(const std::string& origin); - void MaybeInitializeDatabases(bool create); - void MaybeInitializeNonPrimaryDatabase(bool create); - - // For migration. - friend class ObfuscatedFileUtil; - SandboxOriginDatabase* GetSandboxOriginDatabase(); - - const base::FilePath file_system_directory_; - leveldb::Env* env_override_; - const base::FilePath primary_origin_file_; - std::unique_ptr<SandboxOriginDatabase> origin_database_; - std::unique_ptr<SandboxIsolatedOriginDatabase> primary_origin_database_; - - DISALLOW_COPY_AND_ASSIGN(SandboxPrioritizedOriginDatabase); -}; - -} // namespace storage - -#endif // STORAGE_BROWSER_FILE_SYSTEM_SANDBOX_PRIORITIZED_ORIGIN_DATABASE_H_ diff --git a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database_unittest.cc b/chromium/storage/browser/file_system/sandbox_prioritized_origin_database_unittest.cc deleted file mode 100644 index 1c805dabbeb..00000000000 --- a/chromium/storage/browser/file_system/sandbox_prioritized_origin_database_unittest.cc +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "storage/browser/file_system/sandbox_prioritized_origin_database.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "storage/browser/file_system/sandbox_origin_database.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace storage { - -TEST(SandboxPrioritizedOriginDatabaseTest, BasicTest) { - base::ScopedTempDir dir; - base::FilePath path; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - - const std::string kOrigin1("origin1"); - const std::string kOrigin2("origin2"); - - SandboxPrioritizedOriginDatabase database(dir.GetPath(), nullptr); - - // Set the kOrigin1 as a parimary origin. - EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1)); - - // Add two origins. - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path)); - - // Verify them. - EXPECT_TRUE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - EXPECT_FALSE(path.empty()); - EXPECT_TRUE(database.HasOriginPath(kOrigin2)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path)); - EXPECT_FALSE(path.empty()); - - std::vector<SandboxOriginDatabaseInterface::OriginRecord> origins; - database.ListAllOrigins(&origins); - ASSERT_EQ(2U, origins.size()); - EXPECT_TRUE(origins[0].origin == kOrigin1 || origins[1].origin == kOrigin1); - EXPECT_TRUE(origins[0].origin == kOrigin2 || origins[1].origin == kOrigin2); - EXPECT_NE(origins[0].path, origins[1].path); - - // Try remove path for kOrigin1. - database.RemovePathForOrigin(kOrigin1); - - // Verify the removal. - EXPECT_FALSE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.HasOriginPath(kOrigin2)); - database.ListAllOrigins(&origins); - ASSERT_EQ(1U, origins.size()); - EXPECT_EQ(kOrigin2, origins[0].origin); - - // Try remove path for kOrigin2. - database.RemovePathForOrigin(kOrigin2); - - // Verify the removal. - EXPECT_FALSE(database.HasOriginPath(kOrigin1)); - EXPECT_FALSE(database.HasOriginPath(kOrigin2)); - database.ListAllOrigins(&origins); - EXPECT_TRUE(origins.empty()); -} - -TEST(SandboxPrioritizedOriginDatabaseTest, SetPrimaryLaterTest) { - base::ScopedTempDir dir; - base::FilePath path; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - - const std::string kOrigin1("origin1"); - const std::string kOrigin2("origin2"); - - SandboxPrioritizedOriginDatabase database(dir.GetPath(), nullptr); - - EXPECT_TRUE(database.GetPrimaryOrigin().empty()); - - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path)); - - // Set the kOrigin1 as a parimary origin. - EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1)); - EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin()); - - // Regardless of whether it is initialized as primary or not - // they should just work. - EXPECT_TRUE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - EXPECT_FALSE(path.empty()); - EXPECT_TRUE(database.HasOriginPath(kOrigin2)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path)); - EXPECT_FALSE(path.empty()); -} - -TEST(SandboxPrioritizedOriginDatabaseTest, LostPrimaryOriginFileTest) { - base::ScopedTempDir dir; - base::FilePath path; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - - const std::string kOrigin1("origin1"); - const std::string kData("foo"); - - SandboxPrioritizedOriginDatabase database(dir.GetPath(), nullptr); - - EXPECT_TRUE(database.GetPrimaryOrigin().empty()); - - // Set the kOrigin1 as a parimary origin. - EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1)); - EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin()); - - // Make sure it works. - EXPECT_TRUE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - - // Reset the database. - database.DropDatabase(); - - // kOrigin1 should still be marked as primary. - EXPECT_TRUE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path)); - - // Corrupt the primary origin file. - base::WriteFile(database.primary_origin_file(), kData); - - // Reset the database. - database.DropDatabase(); - - // kOrigin1 is no longer marked as primary, and unfortunately we fail - // to find the data for the origin. - EXPECT_FALSE(database.HasOriginPath(kOrigin1)); -} - -TEST(SandboxPrioritizedOriginDatabaseTest, MigrationTest) { - base::ScopedTempDir dir; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - - const std::string kOrigin1("origin1"); - const std::string kOrigin2("origin2"); - const std::string kFakeDirectoryData1("0123456789"); - const std::string kFakeDirectoryData2("abcde"); - base::FilePath old_dir_db_path1, old_dir_db_path2; - base::FilePath path1, path2; - - // Initialize the directory with two origins using the regular - // SandboxOriginDatabase. - { - SandboxOriginDatabase database_old(dir.GetPath(), nullptr); - base::FilePath old_db_path = database_old.GetDatabasePath(); - EXPECT_FALSE(base::PathExists(old_db_path)); - - // Initialize paths for kOrigin1 and kOrigin2. - EXPECT_TRUE(database_old.GetPathForOrigin(kOrigin1, &path1)); - EXPECT_FALSE(path1.empty()); - EXPECT_TRUE(database_old.GetPathForOrigin(kOrigin2, &path2)); - EXPECT_FALSE(path2.empty()); - - EXPECT_TRUE(base::DirectoryExists(old_db_path)); - - // Populate the origin directory with some fake data. - old_dir_db_path1 = dir.GetPath().Append(path1); - ASSERT_TRUE(base::CreateDirectory(old_dir_db_path1)); - EXPECT_TRUE(base::WriteFile(old_dir_db_path1.AppendASCII("dummy"), - kFakeDirectoryData1)); - old_dir_db_path2 = dir.GetPath().Append(path2); - ASSERT_TRUE(base::CreateDirectory(old_dir_db_path2)); - EXPECT_TRUE(base::WriteFile(old_dir_db_path2.AppendASCII("dummy"), - kFakeDirectoryData2)); - } - - // Re-open the directory using sandboxPrioritizedOriginDatabase. - SandboxPrioritizedOriginDatabase database(dir.GetPath(), nullptr); - - // Set the kOrigin1 as a parimary origin. - // (Trying to initialize another origin should fail). - EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1)); - EXPECT_FALSE(database.InitializePrimaryOrigin(kOrigin2)); - - EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin()); - - // Regardless of whether the origin is registered as primary or not - // it should just work. - EXPECT_TRUE(database.HasOriginPath(kOrigin1)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path1)); - EXPECT_TRUE(database.HasOriginPath(kOrigin2)); - EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path2)); - - // The directory content must be kept (or migrated if necessary) as well. - std::string origin_db_data; - base::FilePath dir_db_path = dir.GetPath().Append(path1); - EXPECT_TRUE(base::PathExists(dir_db_path.AppendASCII("dummy"))); - EXPECT_TRUE(base::ReadFileToString(dir_db_path.AppendASCII("dummy"), - &origin_db_data)); - EXPECT_EQ(kFakeDirectoryData1, origin_db_data); - - origin_db_data.clear(); - dir_db_path = dir.GetPath().Append(path2); - EXPECT_TRUE(base::PathExists(dir_db_path.AppendASCII("dummy"))); - EXPECT_TRUE(base::ReadFileToString(dir_db_path.AppendASCII("dummy"), - &origin_db_data)); - EXPECT_EQ(kFakeDirectoryData2, origin_db_data); - - // After the migration the kOrigin1 directory database path must be gone. - EXPECT_FALSE(base::PathExists(old_dir_db_path1)); - EXPECT_TRUE(base::PathExists(old_dir_db_path2)); -} - -} // namespace storage diff --git a/chromium/storage/browser/file_system/transient_file_util.h b/chromium/storage/browser/file_system/transient_file_util.h index 836bba25b9d..0c29ba28fd2 100644 --- a/chromium/storage/browser/file_system/transient_file_util.h +++ b/chromium/storage/browser/file_system/transient_file_util.h @@ -5,8 +5,6 @@ #ifndef STORAGE_BROWSER_FILE_SYSTEM_TRANSIENT_FILE_UTIL_H_ #define STORAGE_BROWSER_FILE_SYSTEM_TRANSIENT_FILE_UTIL_H_ -#include <memory> - #include "base/component_export.h" #include "base/macros.h" #include "storage/browser/file_system/local_file_util.h" diff --git a/chromium/storage/browser/file_system/watcher_manager.h b/chromium/storage/browser/file_system/watcher_manager.h index a116bc388eb..5d6ad91d7f7 100644 --- a/chromium/storage/browser/file_system/watcher_manager.h +++ b/chromium/storage/browser/file_system/watcher_manager.h @@ -5,8 +5,6 @@ #ifndef STORAGE_BROWSER_FILE_SYSTEM_WATCHER_MANAGER_H_ #define STORAGE_BROWSER_FILE_SYSTEM_WATCHER_MANAGER_H_ -#include <vector> - #include "base/callback_forward.h" #include "base/files/file.h" diff --git a/chromium/storage/browser/quota/DIR_METADATA b/chromium/storage/browser/quota/DIR_METADATA index c03de17c44a..58c664b8940 100644 --- a/chromium/storage/browser/quota/DIR_METADATA +++ b/chromium/storage/browser/quota/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>Quota" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/browser/quota/OWNERS b/chromium/storage/browser/quota/OWNERS index 94ee5f99dc4..fc8d259ae9c 100644 --- a/chromium/storage/browser/quota/OWNERS +++ b/chromium/storage/browser/quota/OWNERS @@ -1,7 +1,8 @@ # Primary -jarrydg@chromium.org +ayui@chromium.org # Secondary +jarrydg@chromium.org jsbell@chromium.org kinuko@chromium.org mek@chromium.org diff --git a/chromium/storage/browser/quota/client_usage_tracker.cc b/chromium/storage/browser/quota/client_usage_tracker.cc index 84b1cbc885c..d6f715da30b 100644 --- a/chromium/storage/browser/quota/client_usage_tracker.cc +++ b/chromium/storage/browser/quota/client_usage_tracker.cc @@ -243,7 +243,11 @@ void ClientUsageTracker::DidGetOriginsForGlobalUsage( info->pending_jobs = origins_by_host.size() + 1; auto accumulator = base::BindRepeating( &ClientUsageTracker::AccumulateHostUsage, weak_factory_.GetWeakPtr(), - base::Owned(info), base::AdaptCallbackForRepeating(std::move(callback))); + base::Owned(info), + // The `accumulator` is called multiple times, but the `callback` inside + // of it will only be called a single time, so we give ownership to the + // `accumulator` itself. + base::Owned(std::make_unique<GlobalUsageCallback>(std::move(callback)))); for (const auto& host_and_origins : origins_by_host) { const std::string& host = host_and_origins.first; @@ -253,11 +257,11 @@ void ClientUsageTracker::DidGetOriginsForGlobalUsage( } // Fire the sentinel as we've now called GetUsageForOrigins for all clients. - accumulator.Run(0, 0); + std::move(accumulator).Run(0, 0); } void ClientUsageTracker::AccumulateHostUsage(AccumulateInfo* info, - GlobalUsageCallback callback, + GlobalUsageCallback* callback, int64_t limited_usage, int64_t unlimited_usage) { DCHECK_GT(info->pending_jobs, 0U); @@ -271,8 +275,8 @@ void ClientUsageTracker::AccumulateHostUsage(AccumulateInfo* info, DCHECK_GE(info->unlimited_usage, 0); global_usage_retrieved_ = true; - std::move(callback).Run(info->limited_usage + info->unlimited_usage, - info->unlimited_usage); + std::move(*callback).Run(info->limited_usage + info->unlimited_usage, + info->unlimited_usage); } void ClientUsageTracker::DidGetOriginsForHostUsage( @@ -310,13 +314,13 @@ void ClientUsageTracker::GetUsageForOrigins( } // Fire the sentinel as we've now called GetOriginUsage for all clients. - accumulator.Run(base::nullopt, 0); + accumulator.Run(absl::nullopt, 0); } void ClientUsageTracker::AccumulateOriginUsage( AccumulateInfo* info, const std::string& host, - const base::Optional<url::Origin>& origin, + const absl::optional<url::Origin>& origin, int64_t usage) { DCHECK_GT(info->pending_jobs, 0U); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); diff --git a/chromium/storage/browser/quota/client_usage_tracker.h b/chromium/storage/browser/quota/client_usage_tracker.h index e2e3909b53a..63bd56025de 100644 --- a/chromium/storage/browser/quota/client_usage_tracker.h +++ b/chromium/storage/browser/quota/client_usage_tracker.h @@ -74,7 +74,7 @@ class ClientUsageTracker : public SpecialStoragePolicy::Observer { void DidGetOriginsForGlobalUsage(GlobalUsageCallback callback, const std::vector<url::Origin>& origins); void AccumulateHostUsage(AccumulateInfo* info, - GlobalUsageCallback callback, + GlobalUsageCallback* callback, int64_t limited_usage, int64_t unlimited_usage); @@ -85,7 +85,7 @@ class ClientUsageTracker : public SpecialStoragePolicy::Observer { const std::vector<url::Origin>& origins); void AccumulateOriginUsage(AccumulateInfo* info, const std::string& host, - const base::Optional<url::Origin>& origin, + const absl::optional<url::Origin>& origin, int64_t usage); // Methods used by our GatherUsage tasks, as a task makes progress diff --git a/chromium/storage/browser/quota/quota_callbacks.h b/chromium/storage/browser/quota/quota_callbacks.h index f530e4628cb..1f8877f79f7 100644 --- a/chromium/storage/browser/quota/quota_callbacks.h +++ b/chromium/storage/browser/quota/quota_callbacks.h @@ -15,7 +15,7 @@ #include "base/callback.h" #include "base/containers/contains.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h" namespace url { @@ -46,7 +46,7 @@ using GetOriginsCallback = blink::mojom::StorageType type)>; using GetUsageInfoCallback = base::OnceCallback<void(UsageInfoEntries)>; using GetOriginCallback = - base::OnceCallback<void(const base::Optional<url::Origin>&)>; + base::OnceCallback<void(const absl::optional<url::Origin>&)>; // Simple template wrapper for a callback queue. template <typename CallbackType, typename... Args> @@ -118,4 +118,4 @@ class CallbackQueueMap { } // namespace storage -#endif // STORAGE_QUOTA_QUOTA_TYPES_H_ +#endif // STORAGE_BROWSER_QUOTA_QUOTA_CALLBACKS_H_ diff --git a/chromium/storage/browser/quota/quota_client.h b/chromium/storage/browser/quota/quota_client.h index 9d86a42d497..aa25e1372f2 100644 --- a/chromium/storage/browser/quota/quota_client.h +++ b/chromium/storage/browser/quota/quota_client.h @@ -7,9 +7,6 @@ #include <stdint.h> -#include <string> -#include <vector> - #include "base/callback.h" #include "base/component_export.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" diff --git a/chromium/storage/browser/quota/quota_database.cc b/chromium/storage/browser/quota/quota_database.cc index ceba20334e4..075ca3a072d 100644 --- a/chromium/storage/browser/quota/quota_database.cc +++ b/chromium/storage/browser/quota/quota_database.cc @@ -14,14 +14,15 @@ #include "base/auto_reset.h" #include "base/bind.h" #include "base/containers/contains.h" +#include "base/dcheck_is_on.h" #include "base/files/file_util.h" #include "base/metrics/histogram_macros.h" #include "sql/database.h" #include "sql/meta_table.h" #include "sql/statement.h" #include "sql/transaction.h" +#include "storage/browser/quota/quota_database_migrations.h" #include "storage/browser/quota/special_storage_policy.h" -#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h" #include "url/gurl.h" using blink::mojom::StorageType; @@ -29,90 +30,89 @@ using blink::mojom::StorageType; namespace storage { namespace { -// Definitions for database schema. - -const int kQuotaDatabaseCurrentSchemaVersion = 5; -const int kQuotaDatabaseCompatibleVersion = 2; +// Version number of the database schema. +// +// We support migrating the database schema from versions that are at most 2 +// years old. Older versions are unsupported, and will cause the database to get +// razed. +// +// Version 1 - 2011-03-17 - http://crrev.com/78521 (unsupported) +// Version 2 - 2010-04-25 - http://crrev.com/82847 (unsupported) +// Version 3 - 2011-07-08 - http://crrev.com/91835 (unsupported) +// Version 4 - 2011-10-17 - http://crrev.com/105822 (unsupported) +// Version 5 - 2015-10-19 - https://crrev.com/354932 +// Version 6 - 2021-04-27 - https://crrev.com/c/2757450 +const int kQuotaDatabaseCurrentSchemaVersion = 6; +const int kQuotaDatabaseCompatibleVersion = 6; -const char kHostQuotaTable[] = "HostQuotaTable"; -const char kOriginInfoTable[] = "OriginInfoTable"; -const char kEvictionInfoTable[] = "EvictionInfoTable"; +// Definitions for database schema. +const char kHostQuotaTable[] = "quota"; +const char kBucketTable[] = "buckets"; +const char kEvictionInfoTable[] = "eviction_info"; const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped"; const int kCommitIntervalMs = 30000; } // anonymous namespace +// static +const char QuotaDatabase::kDefaultBucket[] = "default"; + const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = { {kHostQuotaTable, "(host TEXT NOT NULL," " type INTEGER NOT NULL," - " quota INTEGER DEFAULT 0," - " UNIQUE(host, type))"}, - {kOriginInfoTable, - "(origin TEXT NOT NULL," + " quota INTEGER NOT NULL," + " PRIMARY KEY(host, type))" + " WITHOUT ROWID"}, + {kBucketTable, + "(id INTEGER PRIMARY KEY," + " origin TEXT NOT NULL," " type INTEGER NOT NULL," - " used_count INTEGER DEFAULT 0," - " last_access_time INTEGER DEFAULT 0," - " last_modified_time INTEGER DEFAULT 0," - " UNIQUE(origin, type))"}, + " name TEXT NOT NULL," + " use_count INTEGER NOT NULL," + " last_accessed INTEGER NOT NULL," + " last_modified INTEGER NOT NULL," + " expiration INTEGER NOT NULL," + " quota INTEGER NOT NULL)"}, {kEvictionInfoTable, "(origin TEXT NOT NULL," " type INTEGER NOT NULL," - " last_eviction_time INTEGER DEFAULT 0," - " UNIQUE(origin, type))"}}; + " last_eviction_time INTEGER NOT NULL," + " PRIMARY KEY(origin, type))"}}; +const size_t QuotaDatabase::kTableCount = base::size(QuotaDatabase::kTables); // static const QuotaDatabase::IndexSchema QuotaDatabase::kIndexes[] = { - { "HostIndex", - kHostQuotaTable, - "(host)", - false }, - { "OriginInfoIndex", - kOriginInfoTable, - "(origin)", - false }, - { "OriginLastAccessTimeIndex", - kOriginInfoTable, - "(last_access_time)", - false }, - { "OriginLastModifiedTimeIndex", - kOriginInfoTable, - "(last_modified_time)", - false }, + {"buckets_by_storage_key", kBucketTable, "(origin, type, name)", true}, + {"buckets_by_last_accessed", kBucketTable, "(type, last_accessed)", false}, + {"buckets_by_last_modified", kBucketTable, "(type, last_modified)", false}, + {"buckets_by_expiration", kBucketTable, "(expiration)", false}, }; +const size_t QuotaDatabase::kIndexCount = base::size(QuotaDatabase::kIndexes); -struct QuotaDatabase::QuotaTableImporter { - bool Append(const QuotaTableEntry& entry) { - entries.push_back(entry); - return true; - } - std::vector<QuotaTableEntry> entries; -}; - -// Clang requires explicit out-of-line constructors for them. -QuotaDatabase::QuotaTableEntry::QuotaTableEntry() - : type(StorageType::kUnknown), quota(0) {} - -QuotaDatabase::QuotaTableEntry::QuotaTableEntry(const std::string& host, - StorageType type, - int64_t quota) - : host(host), type(type), quota(quota) {} +QuotaDatabase::BucketTableEntry::BucketTableEntry() = default; -QuotaDatabase::OriginInfoTableEntry::OriginInfoTableEntry() - : type(StorageType::kUnknown), used_count(0) {} +QuotaDatabase::BucketTableEntry::BucketTableEntry(const BucketTableEntry&) = + default; +QuotaDatabase::BucketTableEntry& QuotaDatabase::BucketTableEntry::operator=( + const QuotaDatabase::BucketTableEntry&) = default; -QuotaDatabase::OriginInfoTableEntry::OriginInfoTableEntry( - const url::Origin& origin, +QuotaDatabase::BucketTableEntry::BucketTableEntry( + const int64_t bucket_id, + url::Origin origin, StorageType type, - int used_count, - const base::Time& last_access_time, - const base::Time& last_modified_time) - : origin(origin), + std::string name, + int use_count, + const base::Time& last_accessed, + const base::Time& last_modified) + : bucket_id(bucket_id), + origin(std::move(origin)), type(type), - used_count(used_count), - last_access_time(last_access_time), - last_modified_time(last_modified_time) {} + name(std::move(name)), + use_count(use_count), + last_accessed(last_accessed), + last_modified(last_modified) {} // QuotaDatabase ------------------------------------------------------------ QuotaDatabase::QuotaDatabase(const base::FilePath& path) @@ -137,11 +137,8 @@ bool QuotaDatabase::GetHostQuota(const std::string& host, if (!LazyOpen(false)) return false; - const char* kSql = - "SELECT quota" - " FROM HostQuotaTable" - " WHERE host = ? AND type = ?"; - + static constexpr char kSql[] = + "SELECT quota FROM quota WHERE host = ? AND type = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, host); statement.BindInt(1, static_cast<int>(type)); @@ -168,36 +165,149 @@ bool QuotaDatabase::SetHostQuota(const std::string& host, return true; } +QuotaErrorOr<BucketId> QuotaDatabase::CreateBucket( + const url::Origin& origin, + const std::string& bucket_name) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(crbug/1210259): Add DCHECKs for input validation. + if (!LazyOpen(/*create_if_needed=*/true)) + return QuotaError::kDatabaseError; + + // TODO(crbug/1210252): Update to not execute 2 sql statements on creation. + QuotaErrorOr<BucketId> bucket_result = GetBucketId(origin, bucket_name); + if (!bucket_result.ok()) + return bucket_result.error(); + + if (!bucket_result.value().is_null()) + return QuotaError::kEntryExistsError; + + base::Time now = base::Time::Now(); + static constexpr char kSql[] = + // clang-format off + "INSERT INTO buckets(" + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified," + "expiration," + "quota) " + "VALUES (?, 0, ?, 0, ?, ?, ?, 0)"; + // clang-format on + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + // Bucket usage is only for temporary storage types. + static_assert(static_cast<int>(StorageType::kTemporary) == 0, + "The type value baked in the SQL statement above is wrong."); + statement.BindString(0, origin.GetURL().spec()); + statement.BindString(1, bucket_name); + statement.BindTime(2, now); + statement.BindTime(3, now); + statement.BindTime(4, base::Time::Max()); + + if (!statement.Run()) + return QuotaError::kDatabaseError; + + ScheduleCommit(); + + int64_t bucket_id = db_->GetLastInsertRowId(); + DCHECK_GT(bucket_id, 0); + return BucketId(bucket_id); +} + +QuotaErrorOr<BucketId> QuotaDatabase::GetBucketId( + const url::Origin& origin, + const std::string& bucket_name) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!LazyOpen(/*create_if_needed=*/true)) + return QuotaError::kDatabaseError; + + static constexpr char kSql[] = + "SELECT id FROM buckets WHERE origin = ? AND type = ? AND name = ?"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindString(0, origin.GetURL().spec()); + // Bucket usage is only for temporary storage types. + statement.BindInt(1, static_cast<int>(StorageType::kTemporary)); + statement.BindString(2, bucket_name); + + if (!statement.Step()) { + return statement.Succeeded() + ? QuotaErrorOr<BucketId>(BucketId()) + : QuotaErrorOr<BucketId>(QuotaError::kDatabaseError); + } + return BucketId(statement.ColumnInt64(0)); +} + bool QuotaDatabase::SetOriginLastAccessTime(const url::Origin& origin, StorageType type, - base::Time last_access_time) { + base::Time last_accessed) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(true)) return false; sql::Statement statement; - OriginInfoTableEntry entry; + BucketTableEntry entry; if (GetOriginInfo(origin, type, &entry)) { - ++entry.used_count; - const char* kSql = - "UPDATE OriginInfoTable" - " SET used_count = ?, last_access_time = ?" - " WHERE origin = ? AND type = ?"; + ++entry.use_count; + static constexpr char kSql[] = + // clang-format off + "UPDATE buckets " + "SET use_count = ?, last_accessed = ? " + "WHERE origin = ? AND type = ? AND name = ?"; + // clang-format on statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); } else { - entry.used_count = 1; - const char* kSql = - "INSERT INTO OriginInfoTable" - " (used_count, last_access_time, origin, type, last_modified_time)" - " VALUES (?, ?, ?, ?, ?)"; + entry.use_count = 1; + // INSERT statement column ordering matches UPDATE statement above for + // reuse of binding values. + static constexpr char kSql[] = + // clang-format off + "INSERT INTO buckets(" + "use_count," + "last_accessed," + "origin," + "type," + "name," + "last_modified," + "expiration," + "quota) " + "VALUES (?, ?, ?, ?, ?, ?, ?, 0)"; + // clang-format on statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindTime(4, last_access_time); + statement.BindTime(5, last_accessed); + statement.BindTime(6, base::Time::Max()); } - statement.BindInt(0, entry.used_count); - statement.BindTime(1, last_access_time); + statement.BindInt(0, entry.use_count); + statement.BindTime(1, last_accessed); statement.BindString(2, origin.GetURL().spec()); statement.BindInt(3, static_cast<int>(type)); + statement.BindString(4, kDefaultBucket); + + if (!statement.Run()) + return false; + + ScheduleCommit(); + return true; +} + +bool QuotaDatabase::SetBucketLastAccessTime(const int64_t bucket_id, + base::Time last_accessed) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!LazyOpen(true)) + return false; + + BucketTableEntry entry; + if (!GetBucketInfo(bucket_id, &entry)) + return false; + + ++entry.use_count; + static constexpr char kSql[] = + "UPDATE buckets SET use_count = ?, last_accessed = ? WHERE id = ?"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt(0, entry.use_count); + statement.BindTime(1, last_accessed); + statement.BindInt64(2, bucket_id); if (!statement.Run()) return false; @@ -208,31 +318,68 @@ bool QuotaDatabase::SetOriginLastAccessTime(const url::Origin& origin, bool QuotaDatabase::SetOriginLastModifiedTime(const url::Origin& origin, StorageType type, - base::Time last_modified_time) { + base::Time last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(true)) return false; sql::Statement statement; - OriginInfoTableEntry entry; + BucketTableEntry entry; if (GetOriginInfo(origin, type, &entry)) { - const char* kSql = - "UPDATE OriginInfoTable" - " SET last_modified_time = ?" - " WHERE origin = ? AND type = ?"; + static constexpr char kSql[] = + // clang-format off + "UPDATE buckets " + "SET last_modified = ? " + "WHERE origin = ? AND type = ? AND name = ?"; + // clang-format on statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); } else { - const char* kSql = - "INSERT INTO OriginInfoTable" - " (last_modified_time, origin, type, last_access_time) VALUES (?, ?, ?, ?)"; + static constexpr char kSql[] = + // clang-format off + "INSERT INTO buckets(" + "last_modified," + "origin," + "type," + "name," + "last_accessed," + "use_count," + "expiration," + "quota) " + "VALUES (?, ?, ?, ?, ?, 0, ?, 0)"; + // clang-format on statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindTime(3, last_modified_time); + statement.BindTime(4, last_modified); + statement.BindTime(5, base::Time::Max()); } - statement.BindTime(0, last_modified_time); + statement.BindTime(0, last_modified); statement.BindString(1, origin.GetURL().spec()); statement.BindInt(2, static_cast<int>(type)); + statement.BindString(3, kDefaultBucket); + + if (!statement.Run()) + return false; + + ScheduleCommit(); + return true; +} + +bool QuotaDatabase::SetBucketLastModifiedTime(const int64_t bucket_id, + base::Time last_modified) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!LazyOpen(true)) + return false; + + BucketTableEntry entry; + if (!GetBucketInfo(bucket_id, &entry)) + return false; + + static constexpr char kSql[] = + "UPDATE buckets SET last_modified = ? WHERE id = ?"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindTime(0, last_modified); + statement.BindInt64(1, bucket_id); if (!statement.Run()) return false; @@ -243,17 +390,18 @@ bool QuotaDatabase::SetOriginLastModifiedTime(const url::Origin& origin, bool QuotaDatabase::GetOriginLastEvictionTime(const url::Origin& origin, StorageType type, - base::Time* last_modified_time) { + base::Time* last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(last_modified_time); + DCHECK(last_modified); if (!LazyOpen(false)) return false; - static const char kSql[] = - "SELECT last_eviction_time" - " FROM EvictionInfoTable" - " WHERE origin = ? AND type = ?"; - + static constexpr char kSql[] = + // clang-format off + "SELECT last_eviction_time " + "FROM eviction_info " + "WHERE origin = ? AND type = ?"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, origin.GetURL().spec()); statement.BindInt(1, static_cast<int>(type)); @@ -261,23 +409,24 @@ bool QuotaDatabase::GetOriginLastEvictionTime(const url::Origin& origin, if (!statement.Step()) return false; - *last_modified_time = statement.ColumnTime(0); + *last_modified = statement.ColumnTime(0); return true; } bool QuotaDatabase::SetOriginLastEvictionTime(const url::Origin& origin, StorageType type, - base::Time last_modified_time) { + base::Time last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(true)) return false; - static const char kSql[] = - "INSERT OR REPLACE INTO EvictionInfoTable" - " (last_eviction_time, origin, type)" - " VALUES (?, ?, ?)"; + static constexpr char kSql[] = + // clang-format off + "INSERT OR REPLACE INTO eviction_info(last_eviction_time, origin, type) " + "VALUES (?, ?, ?)"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindTime(0, last_modified_time); + statement.BindTime(0, last_modified); statement.BindString(1, origin.GetURL().spec()); statement.BindInt(2, static_cast<int>(type)); @@ -294,10 +443,8 @@ bool QuotaDatabase::DeleteOriginLastEvictionTime(const url::Origin& origin, if (!LazyOpen(false)) return false; - static const char kSql[] = - "DELETE FROM EvictionInfoTable" - " WHERE origin = ? AND type = ?"; - + static constexpr char kSql[] = + "DELETE FROM eviction_info WHERE origin = ? AND type = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, origin.GetURL().spec()); statement.BindInt(1, static_cast<int>(type)); @@ -317,12 +464,24 @@ bool QuotaDatabase::RegisterInitialOriginInfo( return false; for (const auto& origin : origins) { - const char* kSql = - "INSERT OR IGNORE INTO OriginInfoTable" - " (origin, type) VALUES (?, ?)"; + static constexpr char kSql[] = + // clang-format off + "INSERT OR IGNORE INTO buckets(" + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified," + "expiration," + "quota) " + "VALUES (?, ?, ?, 0, 0, 0, ?, 0)"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, origin.GetURL().spec()); statement.BindInt(1, static_cast<int>(type)); + statement.BindString(2, kDefaultBucket); + statement.BindTime(3, base::Time::Max()); if (!statement.Run()) return false; @@ -334,27 +493,66 @@ bool QuotaDatabase::RegisterInitialOriginInfo( bool QuotaDatabase::GetOriginInfo(const url::Origin& origin, StorageType type, - QuotaDatabase::OriginInfoTableEntry* entry) { + QuotaDatabase::BucketTableEntry* entry) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(false)) return false; - const char* kSql = - "SELECT * FROM OriginInfoTable" - " WHERE origin = ? AND type = ?"; + static constexpr char kSql[] = + // clang-format off + "SELECT " + "id," + "use_count," + "last_accessed," + "last_modified " + "FROM buckets " + "WHERE origin = ? AND type = ? AND name = ?"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, origin.GetURL().spec()); statement.BindInt(1, static_cast<int>(type)); + statement.BindString(2, kDefaultBucket); if (!statement.Step()) return false; // TODO(crbug.com/889590): Use helper for url::Origin creation from string. - *entry = OriginInfoTableEntry( - url::Origin::Create(GURL(statement.ColumnString(0))), - static_cast<StorageType>(statement.ColumnInt(1)), statement.ColumnInt(2), - statement.ColumnTime(3), statement.ColumnTime(4)); + *entry = BucketTableEntry(statement.ColumnInt64(0), origin, type, + kDefaultBucket, statement.ColumnInt(1), + statement.ColumnTime(2), statement.ColumnTime(3)); + return true; +} +bool QuotaDatabase::GetBucketInfo(const int64_t bucket_id, + QuotaDatabase::BucketTableEntry* entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!LazyOpen(false)) + return false; + + static constexpr char kSql[] = + // clang-format off + "SELECT " + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified " + "FROM buckets " + "WHERE id = ?"; + // clang-format on + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, bucket_id); + + if (!statement.Step()) + return false; + + // TODO(crbug.com/889590): Use helper for url::Origin creation from string. + *entry = BucketTableEntry( + bucket_id, url::Origin::Create(GURL(statement.ColumnString(0))), + static_cast<StorageType>(statement.ColumnInt(1)), + statement.ColumnString(2), statement.ColumnInt(3), + statement.ColumnTime(4), statement.ColumnTime(5)); return true; } @@ -364,10 +562,8 @@ bool QuotaDatabase::DeleteHostQuota( if (!LazyOpen(false)) return false; - const char* kSql = - "DELETE FROM HostQuotaTable" - " WHERE host = ? AND type = ?"; - + static constexpr char kSql[] = + "DELETE FROM quota WHERE host = ? AND type = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, host); statement.BindInt(1, static_cast<int>(type)); @@ -385,13 +581,28 @@ bool QuotaDatabase::DeleteOriginInfo(const url::Origin& origin, if (!LazyOpen(false)) return false; - const char* kSql = - "DELETE FROM OriginInfoTable" - " WHERE origin = ? AND type = ?"; - + static constexpr char kSql[] = + "DELETE FROM buckets WHERE origin = ? AND type = ? AND name = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, origin.GetURL().spec()); statement.BindInt(1, static_cast<int>(type)); + statement.BindString(2, kDefaultBucket); + + if (!statement.Run()) + return false; + + ScheduleCommit(); + return true; +} + +bool QuotaDatabase::DeleteBucketInfo(const int64_t bucket_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!LazyOpen(false)) + return false; + + static constexpr char kSql[] = "DELETE FROM buckets WHERE id = ?"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, bucket_id); if (!statement.Run()) return false; @@ -403,19 +614,22 @@ bool QuotaDatabase::DeleteOriginInfo(const url::Origin& origin, bool QuotaDatabase::GetLRUOrigin(StorageType type, const std::set<url::Origin>& exceptions, SpecialStoragePolicy* special_storage_policy, - base::Optional<url::Origin>* origin) { + absl::optional<url::Origin>* origin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(origin); if (!LazyOpen(false)) return false; - static const char kSql[] = - "SELECT origin FROM OriginInfoTable" - " WHERE type = ?" - " ORDER BY last_access_time ASC"; + static constexpr char kSql[] = + // clang-format off + "SELECT origin FROM buckets " + "WHERE type = ? AND name = ? " + "ORDER BY last_accessed"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt(0, static_cast<int>(type)); + statement.BindString(1, kDefaultBucket); while (statement.Step()) { url::Origin read_origin = @@ -423,9 +637,10 @@ bool QuotaDatabase::GetLRUOrigin(StorageType type, if (base::Contains(exceptions, read_origin)) continue; + GURL read_gurl = read_origin.GetURL(); if (special_storage_policy && - (special_storage_policy->IsStorageDurable(read_origin.GetURL()) || - special_storage_policy->IsStorageUnlimited(read_origin.GetURL()))) { + (special_storage_policy->IsStorageDurable(read_gurl) || + special_storage_policy->IsStorageUnlimited(read_gurl))) { continue; } @@ -437,6 +652,49 @@ bool QuotaDatabase::GetLRUOrigin(StorageType type, return statement.Succeeded(); } +bool QuotaDatabase::GetLRUBucket(StorageType type, + const std::set<url::Origin>& exceptions, + SpecialStoragePolicy* special_storage_policy, + absl::optional<int64_t>* bucket_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(bucket_id); + if (!LazyOpen(false)) + return false; + + static constexpr char kSql[] = + // clang-format off + "SELECT id, origin FROM buckets " + "WHERE type = ? " + "ORDER BY last_accessed"; + // clang-format on + + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt(0, static_cast<int>(type)); + + while (statement.Step()) { + int64_t read_bucket_id = statement.ColumnInt64(0); + url::Origin read_origin = + url::Origin::Create(GURL(statement.ColumnString(1))); + if (base::Contains(exceptions, read_origin)) + continue; + + // TODO(crbug/1176774): Once BucketTable holds bucket durability info, + // add logic to allow durable buckets to also bypass eviction. + GURL read_gurl = read_origin.GetURL(); + if (special_storage_policy && + (special_storage_policy->IsStorageDurable(read_gurl) || + special_storage_policy->IsStorageUnlimited(read_gurl))) { + continue; + } + + *bucket_id = read_bucket_id; + return true; + } + + bucket_id->reset(); + return statement.Succeeded(); +} + bool QuotaDatabase::GetOriginsModifiedBetween(StorageType type, std::set<url::Origin>* origins, base::Time begin, @@ -446,25 +704,20 @@ bool QuotaDatabase::GetOriginsModifiedBetween(StorageType type, if (!LazyOpen(false)) return false; - DCHECK(!begin.is_max() && end != base::Time()); - static constexpr char kSqlQuerySince[] = - "SELECT origin FROM OriginInfoTable" - " WHERE type = ? AND last_modified_time >= ?"; - - static constexpr char kSqlQueryBetween[] = - "SELECT origin FROM OriginInfoTable" - " WHERE type = ? AND last_modified_time >= ? AND last_modified_time < ?"; + DCHECK(!begin.is_max()); + DCHECK(end != base::Time()); + static constexpr char kSql[] = + // clang-format off + "SELECT origin FROM buckets " + "WHERE type = ? AND name = ?" + "AND last_modified >= ? AND last_modified < ?"; + // clang-format on - sql::Statement statement; - if (end.is_max()) { - statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSqlQuerySince)); - } else { - statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSqlQueryBetween)); - } + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt(0, static_cast<int>(type)); - statement.BindTime(1, begin); - if (!end.is_max()) - statement.BindTime(2, end); + statement.BindString(1, kDefaultBucket); + statement.BindTime(2, begin); + statement.BindTime(3, end); origins->clear(); while (statement.Step()) @@ -473,6 +726,35 @@ bool QuotaDatabase::GetOriginsModifiedBetween(StorageType type, return statement.Succeeded(); } +bool QuotaDatabase::GetBucketsModifiedBetween(StorageType type, + std::set<int64_t>* bucket_ids, + base::Time begin, + base::Time end) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(bucket_ids); + if (!LazyOpen(false)) + return false; + + DCHECK(!begin.is_max()); + DCHECK(end != base::Time()); + static constexpr char kSql[] = + // clang-format off + "SELECT id FROM buckets " + "WHERE type = ? AND last_modified >= ? AND last_modified < ?"; + // clang-format on + + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt(0, static_cast<int>(type)); + statement.BindTime(1, begin); + statement.BindTime(2, end); + + bucket_ids->clear(); + while (statement.Step()) + bucket_ids->insert(statement.ColumnInt64(0)); + + return statement.Succeeded(); +} + bool QuotaDatabase::IsOriginDatabaseBootstrapped() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(true)) @@ -564,13 +846,8 @@ bool QuotaDatabase::LazyOpen(bool create_if_needed) { bool QuotaDatabase::EnsureDatabaseVersion() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - static const size_t kTableCount = base::size(kTables); - static const size_t kIndexCount = base::size(kIndexes); if (!sql::MetaTable::DoesTableExist(db_.get())) - return CreateSchema(db_.get(), meta_table_.get(), - kQuotaDatabaseCurrentSchemaVersion, - kQuotaDatabaseCompatibleVersion, kTables, kTableCount, - kIndexes, kIndexCount); + return CreateSchema(); if (!meta_table_->Init(db_.get(), kQuotaDatabaseCurrentSchemaVersion, kQuotaDatabaseCompatibleVersion)) @@ -583,66 +860,71 @@ bool QuotaDatabase::EnsureDatabaseVersion() { } if (meta_table_->GetVersionNumber() < kQuotaDatabaseCurrentSchemaVersion) { - if (!UpgradeSchema(meta_table_->GetVersionNumber())) + if (!QuotaDatabaseMigrations::UpgradeSchema(*this)) return ResetSchema(); } -#ifndef NDEBUG +#if DCHECK_IS_ON() DCHECK(sql::MetaTable::DoesTableExist(db_.get())); - for (size_t i = 0; i < kTableCount; ++i) { - DCHECK(db_->DoesTableExist(kTables[i].table_name)); - } + for (const TableSchema& table : kTables) + DCHECK(db_->DoesTableExist(table.table_name)); #endif return true; } -// static -bool QuotaDatabase::CreateSchema(sql::Database* database, - sql::MetaTable* meta_table, - int schema_version, - int compatible_version, - const TableSchema* tables, - size_t tables_size, - const IndexSchema* indexes, - size_t indexes_size) { +bool QuotaDatabase::CreateSchema() { // TODO(kinuko): Factor out the common code to create databases. - sql::Transaction transaction(database); + sql::Transaction transaction(db_.get()); if (!transaction.Begin()) return false; - if (!meta_table->Init(database, schema_version, compatible_version)) + if (!meta_table_->Init(db_.get(), kQuotaDatabaseCurrentSchemaVersion, + kQuotaDatabaseCompatibleVersion)) { return false; + } - for (size_t i = 0; i < tables_size; ++i) { - std::string sql("CREATE TABLE "); - sql += tables[i].table_name; - sql += tables[i].columns; - if (!database->Execute(sql.c_str())) { - VLOG(1) << "Failed to execute " << sql; + for (const TableSchema& table : kTables) { + if (!CreateTable(table)) return false; - } } - for (size_t i = 0; i < indexes_size; ++i) { - std::string sql; - if (indexes[i].unique) - sql += "CREATE UNIQUE INDEX "; - else - sql += "CREATE INDEX "; - sql += indexes[i].index_name; - sql += " ON "; - sql += indexes[i].table_name; - sql += indexes[i].columns; - if (!database->Execute(sql.c_str())) { - VLOG(1) << "Failed to execute " << sql; + for (const IndexSchema& index : kIndexes) { + if (!CreateIndex(index)) return false; - } } return transaction.Commit(); } +bool QuotaDatabase::CreateTable(const TableSchema& table) { + std::string sql("CREATE TABLE "); + sql += table.table_name; + sql += table.columns; + if (!db_->Execute(sql.c_str())) { + VLOG(1) << "Failed to execute " << sql; + return false; + } + return true; +} + +bool QuotaDatabase::CreateIndex(const IndexSchema& index) { + std::string sql; + if (index.unique) + sql += "CREATE UNIQUE INDEX "; + else + sql += "CREATE INDEX "; + sql += index.index_name; + sql += " ON "; + sql += index.table_name; + sql += index.columns; + if (!db_->Execute(sql.c_str())) { + VLOG(1) << "Failed to execute " << sql; + return false; + } + return true; +} + bool QuotaDatabase::ResetSchema() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!db_file_path_.empty()); @@ -664,57 +946,16 @@ bool QuotaDatabase::ResetSchema() { return LazyOpen(true); } -bool QuotaDatabase::UpgradeSchema(int current_version) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(0, db_->transaction_nesting()); - - if (current_version == 2) { - QuotaTableImporter importer; - if (!DumpQuotaTable(base::BindRepeating(&QuotaTableImporter::Append, - base::Unretained(&importer)))) { - return false; - } - ResetSchema(); - - sql::Transaction transaction(db_.get()); - if (!transaction.Begin()) - return false; - for (const auto& entry : importer.entries) { - if (!InsertOrReplaceHostQuota(entry.host, entry.type, entry.quota)) - return false; - } - return transaction.Commit(); - } else if (current_version < 5) { - sql::Transaction transaction(db_.get()); - if (!transaction.Begin()) - return false; - - const QuotaDatabase::TableSchema& eviction_table_schema = kTables[2]; - DCHECK_EQ(strcmp(kEvictionInfoTable, eviction_table_schema.table_name), 0); - - std::string sql("CREATE TABLE "); - sql += eviction_table_schema.table_name; - sql += eviction_table_schema.columns; - if (!db_->Execute(sql.c_str())) { - VLOG(1) << "Failed to execute " << sql; - return false; - } - - meta_table_->SetVersionNumber(5); - return transaction.Commit(); - } - return false; -} - bool QuotaDatabase::InsertOrReplaceHostQuota(const std::string& host, StorageType type, int64_t quota) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(db_.get()); - const char* kSql = - "INSERT OR REPLACE INTO HostQuotaTable" - " (quota, host, type)" - " VALUES (?, ?, ?)"; + static constexpr char kSql[] = + // clang-format off + "INSERT OR REPLACE INTO quota(quota, host, type)" + "VALUES (?, ?, ?)"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt64(0, quota); statement.BindString(1, host); @@ -727,14 +968,14 @@ bool QuotaDatabase::DumpQuotaTable(const QuotaTableCallback& callback) { if (!LazyOpen(true)) return false; - const char* kSql = "SELECT * FROM HostQuotaTable"; + static constexpr char kSql[] = "SELECT * FROM quota"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); while (statement.Step()) { - QuotaTableEntry entry = QuotaTableEntry( - statement.ColumnString(0), - static_cast<StorageType>(statement.ColumnInt(1)), - statement.ColumnInt64(2)); + QuotaTableEntry entry = { + .host = statement.ColumnString(0), + .type = static_cast<StorageType>(statement.ColumnInt(1)), + .quota = statement.ColumnInt64(2)}; if (!callback.Run(entry)) return true; @@ -743,22 +984,32 @@ bool QuotaDatabase::DumpQuotaTable(const QuotaTableCallback& callback) { return statement.Succeeded(); } -bool QuotaDatabase::DumpOriginInfoTable( - const OriginInfoTableCallback& callback) { +bool QuotaDatabase::DumpBucketTable(const BucketTableCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!LazyOpen(true)) return false; - const char* kSql = "SELECT * FROM OriginInfoTable"; + static constexpr char kSql[] = + // clang-format off + "SELECT " + "id," + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified " + "FROM buckets"; + // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); while (statement.Step()) { - OriginInfoTableEntry entry( - url::Origin::Create(GURL(statement.ColumnString(0))), - static_cast<StorageType>(statement.ColumnInt(1)), - statement.ColumnInt(2), statement.ColumnTime(3), - statement.ColumnTime(4)); + BucketTableEntry entry(statement.ColumnInt64(0), + url::Origin::Create(GURL(statement.ColumnString(1))), + static_cast<StorageType>(statement.ColumnInt(2)), + statement.ColumnString(3), statement.ColumnInt(4), + statement.ColumnTime(5), statement.ColumnTime(6)); if (!callback.Run(entry)) return true; @@ -773,10 +1024,10 @@ bool operator<(const QuotaDatabase::QuotaTableEntry& lhs, std::tie(rhs.host, rhs.type, rhs.quota); } -bool operator<(const QuotaDatabase::OriginInfoTableEntry& lhs, - const QuotaDatabase::OriginInfoTableEntry& rhs) { - return std::tie(lhs.origin, lhs.type, lhs.used_count, lhs.last_access_time) < - std::tie(rhs.origin, rhs.type, rhs.used_count, rhs.last_access_time); +bool operator<(const QuotaDatabase::BucketTableEntry& lhs, + const QuotaDatabase::BucketTableEntry& rhs) { + return std::tie(lhs.origin, lhs.type, lhs.use_count, lhs.last_accessed) < + std::tie(rhs.origin, rhs.type, rhs.use_count, rhs.last_accessed); } } // namespace storage diff --git a/chromium/storage/browser/quota/quota_database.h b/chromium/storage/browser/quota/quota_database.h index 764216d9afc..416d068b920 100644 --- a/chromium/storage/browser/quota/quota_database.h +++ b/chromium/storage/browser/quota/quota_database.h @@ -19,7 +19,9 @@ #include "base/sequence_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h" +#include "base/util/type_safety/id_type.h" +#include "components/services/storage/public/cpp/quota_error_or.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h" #include "url/origin.h" namespace sql { @@ -31,25 +33,36 @@ namespace storage { class SpecialStoragePolicy; -// Stores all origin scoped quota managed data and metadata. +// IDs will always be generated by SQLite, and all valid BucketIds are positive. +using BucketId = util::IdType64<class BucketTag>; + +// Stores all quota managed origin bucket data and metadata. // // Instances are owned by QuotaManagerImpl. There is one instance per // QuotaManagerImpl instance. All the methods of this class, except the // constructor, must called on the DB thread. class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { public: - struct COMPONENT_EXPORT(STORAGE_BROWSER) OriginInfoTableEntry { - OriginInfoTableEntry(); - OriginInfoTableEntry(const url::Origin& origin, - blink::mojom::StorageType type, - int used_count, - const base::Time& last_access_time, - const base::Time& last_modified_time); + struct COMPONENT_EXPORT(STORAGE_BROWSER) BucketTableEntry { + BucketTableEntry(); + BucketTableEntry(int64_t bucket_id, + url::Origin origin, + blink::mojom::StorageType type, + std::string name, + int use_count, + const base::Time& last_accessed, + const base::Time& last_modified); + + BucketTableEntry(const BucketTableEntry&); + BucketTableEntry& operator=(const BucketTableEntry&); + + int64_t bucket_id = -1; url::Origin origin; - blink::mojom::StorageType type; - int used_count; - base::Time last_access_time; - base::Time last_modified_time; + blink::mojom::StorageType type = blink::mojom::StorageType::kUnknown; + std::string name; + int use_count = 0; + base::Time last_accessed; + base::Time last_modified; }; // If 'path' is empty, an in memory database will be used. @@ -67,16 +80,39 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { int64_t quota); bool DeleteHostQuota(const std::string& host, blink::mojom::StorageType type); + // Creates a bucket with `bucket_name` for the `origin` and returns the bucket + // id. Returns an QuotaError if a bucket with the same `bucket_name` for an + // `origin` already exists or if the operation has failed. + // TODO(crbug/1203467): Include more policies when supported. + QuotaErrorOr<BucketId> CreateBucket(const url::Origin& origin, + const std::string& bucket_name); + + // Retrieves the bucket id of the bucket with `bucket_name` for `origin`. + // If one does not exist, it will return an empty BucketId. Returns an error + // if the operation has failed. + QuotaErrorOr<BucketId> GetBucketId(const url::Origin& origin, + const std::string& bucket_name); + + // TODO(crbug.com/1202167): Remove once all usages have updated to use + // SetBucketLastAccessTime. bool SetOriginLastAccessTime(const url::Origin& origin, blink::mojom::StorageType type, - base::Time last_access_time); + base::Time last_accessed); + + // Called by QuotaClient implementers to update when the bucket was last + // accessed. + bool SetBucketLastAccessTime(int64_t bucket_id, base::Time last_accessed); + // TODO(crbug.com/1202167): Remove once all usages have updated to use + // SetBucketLastModifiedTime. bool SetOriginLastModifiedTime(const url::Origin& origin, blink::mojom::StorageType type, - base::Time last_modified_time); + base::Time last_modified); + + // Called by QuotaClient implementers to update when the bucket was last + // modified. + bool SetBucketLastModifiedTime(int64_t bucket_id, base::Time last_modified); - // Gets the time |origin| was last evicted. Returns whether the record could - // be found. bool GetOriginLastEvictionTime(const url::Origin& origin, blink::mojom::StorageType type, base::Time* last_eviction_time); @@ -89,38 +125,67 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { bool DeleteOriginLastEvictionTime(const url::Origin& origin, blink::mojom::StorageType type); - // Register initial |origins| info |type| to the database. + // Register initial `origins` info `type` to the database. // This method is assumed to be called only after the installation or // the database schema reset. bool RegisterInitialOriginInfo(const std::set<url::Origin>& origins, blink::mojom::StorageType type); - // Gets the OriginInfoTableEntry for |origin|. Returns whether the record - // could be found. + // TODO(crbug.com/1202167): Remove once all usages have been updated to use + // GetBucketInfo. Gets the BucketTableEntry for `origin`. Returns whether the + // record for an origin's default bucket could be found. bool GetOriginInfo(const url::Origin& origin, blink::mojom::StorageType type, - OriginInfoTableEntry* entry); + BucketTableEntry* entry); + + // Gets the table entry for `bucket`. Returns whether the record for an + // origin bucket can be found. + bool GetBucketInfo(int64_t bucket_id, BucketTableEntry* entry); + // TODO(crbug.com/1202167): Remove once all usages have been updated to use + // DeleteBucketInfo. Deletes the default bucket for `origin`. bool DeleteOriginInfo(const url::Origin& origin, blink::mojom::StorageType type); - // Sets |origin| to the least recently used origin of origins not included - // in |exceptions| and not granted the special unlimited storage right. - // It returns false when it failed in accessing the database. - // |origin| is set to nullopt when there is no matching origin. + // Deletes the specified bucket. + bool DeleteBucketInfo(int64_t bucket_id); + + // TODO(crbug.com/1202167): Remove once all usages have been updated to use + // GetLRUBucket. Sets `origin` to the least recently used origin of origins + // not included in `exceptions` and not granted the special unlimited storage + // right. Returns false when it fails in accessing the database. + // `origin` is set to nullopt when there is no matching origin. + // This is limited to the origin's default bucket. bool GetLRUOrigin(blink::mojom::StorageType type, const std::set<url::Origin>& exceptions, SpecialStoragePolicy* special_storage_policy, - base::Optional<url::Origin>* origin); + absl::optional<url::Origin>* origin); - // Populates |origins| with the ones that have been modified since - // the |begin| and until the |end|. Returns whether the - // operation succeeded. + // Sets `bucket_id` to the least recently used bucket from origins not + // included in `exceptions` and not granted special unlimited storage right. + // Returns false when it fails in accessing the database. `bucket_id` is + // set to nullopt when there is no matching bucket. + bool GetLRUBucket(blink::mojom::StorageType type, + const std::set<url::Origin>& exceptions, + SpecialStoragePolicy* special_storage_policy, + absl::optional<int64_t>* bucket_id); + + // TODO(crbug.com/1202167): Remove once all usages have been updated to use + // GetBucketsModifiedBetween. Populates `origins` with the ones that have had + // their default bucket modified since the `begin` and until the `end`. + // Returns whether the operation succeeded. bool GetOriginsModifiedBetween(blink::mojom::StorageType type, std::set<url::Origin>* origins, base::Time begin, base::Time end); + // Populates `bucket_ids` with the buckets that have been modified since the + // `begin` and until the `end`. Returns whether the operation succeeded. + bool GetBucketsModifiedBetween(blink::mojom::StorageType type, + std::set<int64_t>* bucket_ids, + base::Time begin, + base::Time end); + // Returns false if SetOriginDatabaseBootstrapped has never // been called before, which means existing origins may not have been // registered. @@ -129,20 +194,16 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { private: struct COMPONENT_EXPORT(STORAGE_BROWSER) QuotaTableEntry { - QuotaTableEntry(); - QuotaTableEntry(const std::string& host, - blink::mojom::StorageType type, - int64_t quota); std::string host; - blink::mojom::StorageType type; - int64_t quota; + blink::mojom::StorageType type = blink::mojom::StorageType::kUnknown; + int64_t quota = 0; }; friend COMPONENT_EXPORT(STORAGE_BROWSER) bool operator<( const QuotaTableEntry& lhs, const QuotaTableEntry& rhs); friend COMPONENT_EXPORT(STORAGE_BROWSER) bool operator<( - const OriginInfoTableEntry& lhs, - const OriginInfoTableEntry& rhs); + const BucketTableEntry& lhs, + const BucketTableEntry& rhs); // Structures used for CreateSchema. struct TableSchema { @@ -158,10 +219,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { using QuotaTableCallback = base::RepeatingCallback<bool(const QuotaTableEntry&)>; - using OriginInfoTableCallback = - base::RepeatingCallback<bool(const OriginInfoTableEntry&)>; - - struct QuotaTableImporter; + using BucketTableCallback = + base::RepeatingCallback<bool(const BucketTableEntry&)>; // For long-running transactions support. We always keep a transaction open // so that multiple transactions can be batched. They are flushed @@ -178,19 +237,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { blink::mojom::StorageType type, int64_t quota); - static bool CreateSchema(sql::Database* database, - sql::MetaTable* meta_table, - int schema_version, - int compatible_version, - const TableSchema* tables, - size_t tables_size, - const IndexSchema* indexes, - size_t indexes_size); + bool CreateSchema(); + bool CreateTable(const TableSchema& table); + bool CreateIndex(const IndexSchema& index); - // |callback| may return false to stop reading data. + // `callback` may return false to stop reading data. bool DumpQuotaTable(const QuotaTableCallback& callback); - bool DumpOriginInfoTable(const OriginInfoTableCallback& callback); - + bool DumpBucketTable(const BucketTableCallback& callback); const base::FilePath db_file_path_; @@ -202,10 +255,15 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { base::OneShotTimer timer_; friend class QuotaDatabaseTest; + friend class QuotaDatabaseMigrations; + friend class QuotaDatabaseMigrationsTest; friend class QuotaManagerImpl; + static const char kDefaultBucket[]; static const TableSchema kTables[]; + static const size_t kTableCount; static const IndexSchema kIndexes[]; + static const size_t kIndexCount; SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(QuotaDatabase); diff --git a/chromium/storage/browser/quota/quota_database_migrations.cc b/chromium/storage/browser/quota/quota_database_migrations.cc new file mode 100644 index 00000000000..44f892a0667 --- /dev/null +++ b/chromium/storage/browser/quota/quota_database_migrations.cc @@ -0,0 +1,124 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "storage/browser/quota/quota_database_migrations.h" + +#include <string> + +#include "sql/database.h" +#include "sql/meta_table.h" +#include "sql/statement.h" +#include "sql/transaction.h" +#include "storage/browser/quota/quota_database.h" + +namespace storage { + +// static +bool QuotaDatabaseMigrations::UpgradeSchema(QuotaDatabase& quota_database) { + DCHECK_EQ(0, quota_database.db_->transaction_nesting()); + + // Reset tables for versions lower than 5 since they are unsupported. + if (quota_database.meta_table_->GetVersionNumber() < 5) + return quota_database.ResetSchema(); + + if (quota_database.meta_table_->GetVersionNumber() == 5) { + if (!MigrateToVersion6(quota_database)) + return false; + } + + return quota_database.meta_table_->GetVersionNumber() == 6; +} + +bool QuotaDatabaseMigrations::MigrateToVersion6(QuotaDatabase& quota_database) { + sql::Database* db = quota_database.db_.get(); + sql::Transaction transaction(db); + if (!transaction.Begin()) + return false; + + // Create tables with latest schema. + for (size_t i = 0; i < QuotaDatabase::kTableCount; ++i) { + if (!quota_database.CreateTable(QuotaDatabase::kTables[i])) + return false; + } + + // Create all indexes for tables. + for (size_t i = 0; i < QuotaDatabase::kIndexCount; ++i) { + if (!quota_database.CreateIndex(QuotaDatabase::kIndexes[i])) + return false; + } + + // Copy OriginInfoTable data into new bucket table. + const char kImportOriginInfoSql[] = + // clang-format off + "INSERT INTO buckets(" + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified," + "expiration," + "quota) " + "SELECT " + "origin," + "type," + "?," + "used_count," + "last_access_time," + "last_modified_time," + "?," + "0 " + "FROM OriginInfoTable"; + // clang-format on + sql::Statement import_origin_info_statement( + db->GetCachedStatement(SQL_FROM_HERE, kImportOriginInfoSql)); + import_origin_info_statement.BindString(0, QuotaDatabase::kDefaultBucket); + import_origin_info_statement.BindTime(1, base::Time::Max()); + if (!import_origin_info_statement.Run()) + return false; + + // Delete OriginInfoTable. + const char kDeleteOriginInfoTableSql[] = "DROP TABLE OriginInfoTable"; + if (!db->Execute(kDeleteOriginInfoTableSql)) + return false; + + // Copy HostQuotaTable data into the new quota table. + const char kImportQuotaSql[] = + // clang-format off + "INSERT INTO quota(host, type, quota) " + "SELECT host, type, quota " + "FROM HostQuotaTable"; + // clang-format on + sql::Statement import_quota_statement( + db->GetCachedStatement(SQL_FROM_HERE, kImportQuotaSql)); + if (!import_quota_statement.Run()) + return false; + + // Delete HostQuotaTable. + const char kDeleteQuotaHostTableSql[] = "DROP TABLE HostQuotaTable"; + if (!db->Execute(kDeleteQuotaHostTableSql)) + return false; + + // Copy EvictionInfoTable data into the new eviction_info table. + const char kImportEvictionInfoSql[] = + // clang-format off + "INSERT INTO eviction_info(origin, type, last_eviction_time) " + "SELECT origin, type, last_eviction_time " + "FROM EvictionInfoTable"; + // clang-format on + sql::Statement import_eviction_info_statement( + db->GetCachedStatement(SQL_FROM_HERE, kImportEvictionInfoSql)); + if (!import_eviction_info_statement.Run()) + return false; + + // Delete EvictionInfoTable. + const char kDeleteEvictionInfoTableSql[] = "DROP TABLE EvictionInfoTable"; + if (!db->Execute(kDeleteEvictionInfoTableSql)) + return false; + + quota_database.meta_table_->SetVersionNumber(6); + return transaction.Commit(); +} + +} // namespace storage diff --git a/chromium/storage/browser/quota/quota_database_migrations.h b/chromium/storage/browser/quota/quota_database_migrations.h new file mode 100644 index 00000000000..97a5b1ac581 --- /dev/null +++ b/chromium/storage/browser/quota/quota_database_migrations.h @@ -0,0 +1,31 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_MIGRATIONS_H_ +#define STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_MIGRATIONS_H_ + +namespace storage { + +class QuotaDatabase; + +// Helper class of QuotaDatabase which handles the QuotaManager SQL database +// schema migrations. Any change that requires a change in the schema version +// and adds new tables, columns, or modifies existing data should have a +// migration to avoid data loss. +// +// QuotaDatabaseMigrations is a friended class of QuotaDatabase and updates the +// existing SQL QuotaManager database owned by the QuotaDatabase class. +class QuotaDatabaseMigrations { + public: + // Upgrades the SQL database owned by `quota_database` to the latest schema, + // and updates the sql::MetaTable version accordingly. + static bool UpgradeSchema(QuotaDatabase& quota_database); + + private: + static bool MigrateToVersion6(QuotaDatabase& quota_database); +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_MIGRATIONS_H_ diff --git a/chromium/storage/browser/quota/quota_database_migrations_unittest.cc b/chromium/storage/browser/quota/quota_database_migrations_unittest.cc new file mode 100644 index 00000000000..0752382b1f5 --- /dev/null +++ b/chromium/storage/browser/quota/quota_database_migrations_unittest.cc @@ -0,0 +1,131 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/path_service.h" +#include "sql/database.h" +#include "sql/meta_table.h" +#include "sql/statement.h" +#include "sql/test/test_helpers.h" +#include "storage/browser/quota/quota_database.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace storage { + +class QuotaDatabaseMigrationsTest : public testing::Test { + public: + void SetUp() override { ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); } + + base::FilePath DbPath() { + return temp_directory_.GetPath().AppendASCII("quota_manager.db"); + } + + protected: + // The textual contents of |file| are read from + // "storage/test/data/quota_database/" and returned in the string + // |contents|. Returns true if the file exists and is read successfully, false + // otherwise. + std::string GetDatabaseData(const char* file) { + base::FilePath source_path; + base::PathService::Get(base::DIR_SOURCE_ROOT, &source_path); + source_path = source_path.AppendASCII("storage/test/data/quota_database"); + source_path = source_path.AppendASCII(file); + EXPECT_TRUE(base::PathExists(source_path)); + + std::string contents; + base::ReadFileToString(source_path, &contents); + return contents; + } + + bool LoadDatabase(const char* file, const base::FilePath& db_path) { + std::string contents = GetDatabaseData(file); + if (contents.empty()) + return false; + + sql::Database db; + if (!db.Open(db_path) || !db.Execute(contents.data())) + return false; + return true; + } + + void MigrateDatabase() { + QuotaDatabase db(DbPath()); + EXPECT_TRUE(db.LazyOpen(true)); + EXPECT_TRUE(db.db_.get()); + } + + std::string GetCurrentSchema() { + base::FilePath current_version_path = + temp_directory_.GetPath().AppendASCII("current_version.db"); + EXPECT_TRUE(LoadDatabase("version_6.sql", current_version_path)); + sql::Database db; + EXPECT_TRUE(db.Open(current_version_path)); + return db.GetSchema(); + } + + base::ScopedTempDir temp_directory_; +}; + +TEST_F(QuotaDatabaseMigrationsTest, UpgradeSchemaFromV5) { + ASSERT_TRUE(LoadDatabase("version_5.sql", DbPath())); + + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + ASSERT_TRUE(db.DoesTableExist("HostQuotaTable")); + ASSERT_TRUE(db.DoesTableExist("EvictionInfoTable")); + ASSERT_TRUE(db.DoesTableExist("OriginInfoTable")); + ASSERT_FALSE(db.DoesTableExist("buckets")); + + // Check populated data. + EXPECT_EQ( + "http://a/|0|123|13260644621105493|13242931862595604," + "http://b/|0|111|13250042735631065|13260999511438890," + "http://c/|1|321|13261163582572088|13261079941303629", + sql::test::ExecuteWithResults( + &db, "SELECT * FROM OriginInfoTable ORDER BY origin ASC", "|", + ",")); + EXPECT_EQ("a.com,b.com,c.com", + sql::test::ExecuteWithResults( + &db, "SELECT host FROM HostQuotaTable ORDER BY host ASC", "|", + ",")); + } + + MigrateDatabase(); + + // Verify upgraded schema. + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + ASSERT_TRUE(db.DoesTableExist("quota")); + ASSERT_TRUE(db.DoesTableExist("eviction_info")); + ASSERT_TRUE(db.DoesTableExist("buckets")); + ASSERT_FALSE(db.DoesTableExist("HostQuotaTable")); + ASSERT_FALSE(db.DoesTableExist("EvictionInfoTable")); + ASSERT_FALSE(db.DoesTableExist("OriginInfoTable")); + + // Check that OriginInfoTable data is migrated to bucket table. + EXPECT_EQ( + "1|http://a/|0|default|123|13260644621105493|13242931862595604|" + "9223372036854775807|0," + "2|http://b/|0|default|111|13250042735631065|13260999511438890|" + "9223372036854775807|0," + "3|http://c/|1|default|321|13261163582572088|13261079941303629|" + "9223372036854775807|0", + sql::test::ExecuteWithResults( + &db, "SELECT * FROM buckets ORDER BY origin ASC", "|", ",")); + + // Check that HostQuotaTable data is migrated to quota table. + EXPECT_EQ("a.com,b.com,c.com", + sql::test::ExecuteWithResults( + &db, "SELECT host FROM quota ORDER BY host ASC", "|", ",")); + + EXPECT_EQ(GetCurrentSchema(), db.GetSchema()); + } +} + +} // namespace storage diff --git a/chromium/storage/browser/quota/quota_database_unittest.cc b/chromium/storage/browser/quota/quota_database_unittest.cc index 8ba2e040a5c..62028a519c3 100644 --- a/chromium/storage/browser/quota/quota_database_unittest.cc +++ b/chromium/storage/browser/quota/quota_database_unittest.cc @@ -29,343 +29,41 @@ namespace storage { namespace { -const char kDBFileName[] = "quota_manager.db"; -} // namespace // Declared to shorten the line lengths. -static const blink::mojom::StorageType kTemporary = +static const blink::mojom::StorageType kTemp = blink::mojom::StorageType::kTemporary; -static const blink::mojom::StorageType kPersistent = +static const blink::mojom::StorageType kPerm = blink::mojom::StorageType::kPersistent; -class QuotaDatabaseTest : public testing::Test { - protected: - using QuotaTableEntry = QuotaDatabase::QuotaTableEntry; - using QuotaTableCallback = QuotaDatabase::QuotaTableCallback; - using OriginInfoTableCallback = QuotaDatabase::OriginInfoTableCallback; - - void LazyOpen(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - EXPECT_FALSE(db.LazyOpen(false)); - ASSERT_TRUE(db.LazyOpen(true)); - EXPECT_TRUE(db.db_.get()); - EXPECT_TRUE(kDbFile.empty() || base::PathExists(kDbFile)); - } - - void Reopen(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(false)); - EXPECT_TRUE(db.db_.get()); - EXPECT_TRUE(kDbFile.empty() || base::PathExists(kDbFile)); - } - - void UpgradeSchemaV2toV5(const base::FilePath& kDbFile) { - const QuotaTableEntry entries[] = { - QuotaTableEntry("a", kTemporary, 1), - QuotaTableEntry("b", kTemporary, 2), - QuotaTableEntry("c", kPersistent, 3), - }; - - CreateV2Database(kDbFile, entries, base::size(entries)); - - QuotaDatabase db(kDbFile); - EXPECT_TRUE(db.LazyOpen(true)); - EXPECT_TRUE(db.db_.get()); - - using Verifier = EntryVerifier<QuotaTableEntry>; - Verifier verifier(entries, entries + base::size(entries)); - EXPECT_TRUE(db.DumpQuotaTable( - base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); - EXPECT_TRUE(verifier.table.empty()); - - EXPECT_TRUE(db.db_->DoesTableExist("EvictionInfoTable")); - EXPECT_TRUE(db.db_->DoesIndexExist("sqlite_autoindex_EvictionInfoTable_1")); - } - - void HostQuota(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); - - const char* kHost = "foo.com"; - const int kQuota1 = 13579; - const int kQuota2 = kQuota1 + 1024; - - int64_t quota = -1; - EXPECT_FALSE(db.GetHostQuota(kHost, kTemporary, "a)); - EXPECT_FALSE(db.GetHostQuota(kHost, kPersistent, "a)); - - // Insert quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kTemporary, kQuota1)); - EXPECT_TRUE(db.GetHostQuota(kHost, kTemporary, "a)); - EXPECT_EQ(kQuota1, quota); - - // Update quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kTemporary, kQuota2)); - EXPECT_TRUE(db.GetHostQuota(kHost, kTemporary, "a)); - EXPECT_EQ(kQuota2, quota); +const char kDefaultBucket[] = "default"; - // Quota for persistent must not be updated. - EXPECT_FALSE(db.GetHostQuota(kHost, kPersistent, "a)); - - // Delete temporary storage quota. - EXPECT_TRUE(db.DeleteHostQuota(kHost, kTemporary)); - EXPECT_FALSE(db.GetHostQuota(kHost, kTemporary, "a)); +// TODO(crbug.com/889590): Replace with common converter. +url::Origin ToOrigin(const std::string& url) { + return url::Origin::Create(GURL(url)); +} - // Delete persistent quota by setting it to zero. - EXPECT_TRUE(db.SetHostQuota(kHost, kPersistent, 0)); - EXPECT_FALSE(db.GetHostQuota(kHost, kPersistent, "a)); - } +} // namespace - void OriginLastAccessTimeLRU(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); +// Test parameter indicates if the database should be created for incognito +// mode. True will create the database in memory. +class QuotaDatabaseTest : public testing::TestWithParam<bool> { + protected: + using QuotaTableEntry = QuotaDatabase::QuotaTableEntry; + using BucketTableEntry = QuotaDatabase::BucketTableEntry; - std::set<url::Origin> exceptions; - base::Optional<url::Origin> origin; - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_FALSE(origin.has_value()); + void SetUp() override { ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); } - // TODO(crbug.com/889590): Use helper for url::Origin creation from string. - const url::Origin kOrigin1 = url::Origin::Create(GURL("http://a/")); - const url::Origin kOrigin2 = url::Origin::Create(GURL("http://b/")); - const url::Origin kOrigin3 = url::Origin::Create(GURL("http://c/")); - const url::Origin kOrigin4 = url::Origin::Create(GURL("http://p/")); + void TearDown() override { ASSERT_TRUE(temp_directory_.Delete()); } - // Adding three temporary storages, and - EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin1, kTemporary, - base::Time::FromJavaTime(10))); - EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin2, kTemporary, - base::Time::FromJavaTime(20))); - EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin3, kTemporary, - base::Time::FromJavaTime(30))); + bool use_in_memory_db() const { return GetParam(); } - // one persistent. - EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin4, kPersistent, - base::Time::FromJavaTime(40))); - - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_EQ(kOrigin1, origin); - - // Test that unlimited origins are exluded from eviction, but - // protected origins are not excluded. - scoped_refptr<MockSpecialStoragePolicy> policy( - new MockSpecialStoragePolicy); - policy->AddUnlimited(kOrigin1.GetURL()); - policy->AddProtected(kOrigin2.GetURL()); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, policy.get(), &origin)); - EXPECT_EQ(kOrigin2, origin); - - // Test that durable origins are excluded from eviction. - policy->AddDurable(kOrigin2.GetURL()); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, policy.get(), &origin)); - EXPECT_EQ(kOrigin3, origin); - - exceptions.insert(kOrigin1); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_EQ(kOrigin2, origin); - - exceptions.insert(kOrigin2); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_EQ(kOrigin3, origin); - - exceptions.insert(kOrigin3); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_FALSE(origin.has_value()); - - EXPECT_TRUE( - db.SetOriginLastAccessTime(kOrigin1, kTemporary, base::Time::Now())); - - // Delete origin/type last access time information. - EXPECT_TRUE(db.DeleteOriginInfo(kOrigin3, kTemporary)); - - // Querying again to see if the deletion has worked. - exceptions.clear(); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_EQ(kOrigin2, origin); - - exceptions.insert(kOrigin1); - exceptions.insert(kOrigin2); - EXPECT_TRUE(db.GetLRUOrigin(kTemporary, exceptions, nullptr, &origin)); - EXPECT_FALSE(origin.has_value()); - } - - void OriginLastModifiedBetween(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); - - std::set<url::Origin> origins; - EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemporary, &origins, base::Time(), - base::Time::Max())); - EXPECT_TRUE(origins.empty()); - - const url::Origin kOrigin1 = url::Origin::Create(GURL("http://a/")); - const url::Origin kOrigin2 = url::Origin::Create(GURL("http://b/")); - const url::Origin kOrigin3 = url::Origin::Create(GURL("http://c/")); - - // Report last mod time for the test origins. - EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin1, kTemporary, - base::Time::FromJavaTime(0))); - EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin2, kTemporary, - base::Time::FromJavaTime(10))); - EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin3, kTemporary, - base::Time::FromJavaTime(20))); - - EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemporary, &origins, base::Time(), - base::Time::Max())); - EXPECT_EQ(3U, origins.size()); - EXPECT_EQ(1U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(1U, origins.count(kOrigin3)); - - EXPECT_TRUE(db.GetOriginsModifiedBetween( - kTemporary, &origins, base::Time::FromJavaTime(5), base::Time::Max())); - EXPECT_EQ(2U, origins.size()); - EXPECT_EQ(0U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(1U, origins.count(kOrigin3)); - - EXPECT_TRUE(db.GetOriginsModifiedBetween( - kTemporary, &origins, base::Time::FromJavaTime(15), base::Time::Max())); - EXPECT_EQ(1U, origins.size()); - EXPECT_EQ(0U, origins.count(kOrigin1)); - EXPECT_EQ(0U, origins.count(kOrigin2)); - EXPECT_EQ(1U, origins.count(kOrigin3)); - - EXPECT_TRUE(db.GetOriginsModifiedBetween( - kTemporary, &origins, base::Time::FromJavaTime(25), base::Time::Max())); - EXPECT_TRUE(origins.empty()); - - EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemporary, &origins, - base::Time::FromJavaTime(5), - base::Time::FromJavaTime(15))); - EXPECT_EQ(1U, origins.size()); - EXPECT_EQ(0U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(0U, origins.count(kOrigin3)); - - EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemporary, &origins, - base::Time::FromJavaTime(0), - base::Time::FromJavaTime(20))); - EXPECT_EQ(2U, origins.size()); - EXPECT_EQ(1U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(0U, origins.count(kOrigin3)); - - // Update origin1's mod time but for persistent storage. - EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin1, kPersistent, - base::Time::FromJavaTime(30))); - - // Must have no effects on temporary origins info. - EXPECT_TRUE(db.GetOriginsModifiedBetween( - kTemporary, &origins, base::Time::FromJavaTime(5), base::Time::Max())); - EXPECT_EQ(2U, origins.size()); - EXPECT_EQ(0U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(1U, origins.count(kOrigin3)); - - // One more update for persistent origin2. - EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin2, kPersistent, - base::Time::FromJavaTime(40))); - - EXPECT_TRUE(db.GetOriginsModifiedBetween(kPersistent, &origins, - base::Time::FromJavaTime(25), - base::Time::Max())); - EXPECT_EQ(2U, origins.size()); - EXPECT_EQ(1U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(0U, origins.count(kOrigin3)); - - EXPECT_TRUE(db.GetOriginsModifiedBetween(kPersistent, &origins, - base::Time::FromJavaTime(35), - base::Time::Max())); - EXPECT_EQ(1U, origins.size()); - EXPECT_EQ(0U, origins.count(kOrigin1)); - EXPECT_EQ(1U, origins.count(kOrigin2)); - EXPECT_EQ(0U, origins.count(kOrigin3)); + base::FilePath DbPath() { + return temp_directory_.GetPath().AppendASCII("quota_manager.db"); } - void OriginLastEvicted(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); - - const url::Origin kOrigin1 = url::Origin::Create(GURL("http://a/")); - const url::Origin kOrigin2 = url::Origin::Create(GURL("http://b/")); - const url::Origin kOrigin3 = url::Origin::Create(GURL("http://c/")); - - base::Time last_eviction_time; - EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time(), last_eviction_time); - - // Report last eviction time for the test origins. - EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin1, kTemporary, - base::Time::FromJavaTime(10))); - EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin2, kTemporary, - base::Time::FromJavaTime(20))); - EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin3, kTemporary, - base::Time::FromJavaTime(30))); - - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time::FromJavaTime(10), last_eviction_time); - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin2, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time::FromJavaTime(20), last_eviction_time); - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin3, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time::FromJavaTime(30), last_eviction_time); - - // Delete last eviction times for the test origins. - EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin1, kTemporary)); - EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin2, kTemporary)); - EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin3, kTemporary)); - - last_eviction_time = base::Time(); - EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time(), last_eviction_time); - EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin2, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time(), last_eviction_time); - EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin3, kTemporary, - &last_eviction_time)); - EXPECT_EQ(base::Time(), last_eviction_time); - - // Deleting an origin that is not present should not fail. - EXPECT_TRUE(db.DeleteOriginLastEvictionTime( - url::Origin::Create(GURL("http://notpresent.com")), kTemporary)); - } - - void RegisterInitialOriginInfo(const base::FilePath& kDbFile) { - QuotaDatabase db(kDbFile); - - const url::Origin kOrigins[] = {url::Origin::Create(GURL("http://a/")), - url::Origin::Create(GURL("http://b/")), - url::Origin::Create(GURL("http://c/"))}; - std::set<url::Origin> origins(kOrigins, kOrigins + base::size(kOrigins)); - - EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kTemporary)); - - QuotaDatabase::OriginInfoTableEntry info; - info.used_count = -1; - EXPECT_TRUE(db.GetOriginInfo(url::Origin::Create(GURL("http://a/")), - kTemporary, &info)); - EXPECT_EQ(0, info.used_count); - - EXPECT_TRUE( - db.SetOriginLastAccessTime(url::Origin::Create(GURL("http://a/")), - kTemporary, base::Time::FromDoubleT(1.0))); - info.used_count = -1; - EXPECT_TRUE(db.GetOriginInfo(url::Origin::Create(GURL("http://a/")), - kTemporary, &info)); - EXPECT_EQ(1, info.used_count); - - EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kTemporary)); - - info.used_count = -1; - EXPECT_TRUE(db.GetOriginInfo(url::Origin::Create(GURL("http://a/")), - kTemporary, &info)); - EXPECT_EQ(1, info.used_count); + bool LazyOpen(QuotaDatabase* db, bool create_if_needed) { + return db->LazyOpen(create_if_needed); } template <typename EntryType> @@ -382,288 +80,695 @@ class QuotaDatabaseTest : public testing::Test { } }; - void DumpQuotaTable(const base::FilePath& kDbFile) { - QuotaTableEntry kTableEntries[] = { - QuotaTableEntry("http://go/", kTemporary, 1), - QuotaTableEntry("http://oo/", kTemporary, 2), - QuotaTableEntry("http://gle/", kPersistent, 3)}; - QuotaTableEntry* begin = kTableEntries; - QuotaTableEntry* end = kTableEntries + base::size(kTableEntries); - - QuotaDatabase db(kDbFile); - EXPECT_TRUE(db.LazyOpen(true)); - AssignQuotaTable(db.db_.get(), begin, end); - db.Commit(); - - using Verifier = EntryVerifier<QuotaTableEntry>; - Verifier verifier(begin, end); - EXPECT_TRUE(db.DumpQuotaTable( - base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); - EXPECT_TRUE(verifier.table.empty()); + bool DumpQuotaTable(QuotaDatabase* quota_database, + const QuotaDatabase::QuotaTableCallback& callback) { + return quota_database->DumpQuotaTable(callback); } - void DumpOriginInfoTable(const base::FilePath& kDbFile) { - base::Time now(base::Time::Now()); - using Entry = QuotaDatabase::OriginInfoTableEntry; - Entry kTableEntries[] = { - Entry(url::Origin::Create(GURL("http://go/")), kTemporary, 2147483647, - now, now), - Entry(url::Origin::Create(GURL("http://oo/")), kTemporary, 0, now, now), - Entry(url::Origin::Create(GURL("http://gle/")), kTemporary, 1, now, - now), - }; - Entry* begin = kTableEntries; - Entry* end = kTableEntries + base::size(kTableEntries); - - QuotaDatabase db(kDbFile); - EXPECT_TRUE(db.LazyOpen(true)); - AssignOriginInfoTable(db.db_.get(), begin, end); - db.Commit(); - - using Verifier = EntryVerifier<Entry>; - Verifier verifier(begin, end); - EXPECT_TRUE(db.DumpOriginInfoTable( - base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); - EXPECT_TRUE(verifier.table.empty()); - } - - void GetOriginInfo(const base::FilePath& kDbFile) { - const url::Origin kOrigin = url::Origin::Create(GURL("http://go/")); - using Entry = QuotaDatabase::OriginInfoTableEntry; - Entry kTableEntries[] = { - Entry(kOrigin, kTemporary, 100, base::Time(), base::Time())}; - Entry* begin = kTableEntries; - Entry* end = kTableEntries + base::size(kTableEntries); - - QuotaDatabase db(kDbFile); - EXPECT_TRUE(db.LazyOpen(true)); - AssignOriginInfoTable(db.db_.get(), begin, end); - db.Commit(); - - { - Entry entry; - EXPECT_TRUE(db.GetOriginInfo(kOrigin, kTemporary, &entry)); - EXPECT_EQ(kTableEntries[0].type, entry.type); - EXPECT_EQ(kTableEntries[0].origin, entry.origin); - EXPECT_EQ(kTableEntries[0].used_count, entry.used_count); - EXPECT_EQ(kTableEntries[0].last_access_time, entry.last_access_time); - EXPECT_EQ(kTableEntries[0].last_modified_time, entry.last_modified_time); - } - - { - Entry entry; - EXPECT_FALSE( - db.GetOriginInfo(url::Origin::Create(GURL("http://notpresent.org/")), - kTemporary, &entry)); - } + bool DumpBucketTable(QuotaDatabase* quota_database, + const QuotaDatabase::BucketTableCallback& callback) { + return quota_database->DumpBucketTable(callback); } - private: - template <typename Iterator> - void AssignQuotaTable(sql::Database* db, Iterator itr, Iterator end) { - ASSERT_NE(db, (sql::Database*)nullptr); - for (; itr != end; ++itr) { + template <typename Container> + void AssignQuotaTable(QuotaDatabase* quota_database, Container&& entries) { + ASSERT_NE(quota_database->db_.get(), nullptr); + for (const auto& entry : entries) { const char* kSql = - "INSERT INTO HostQuotaTable" - " (host, type, quota)" - " VALUES (?, ?, ?)"; + // clang-format off + "INSERT INTO quota(host, type, quota) " + "VALUES (?, ?, ?)"; + // clang-format on sql::Statement statement; - statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.Assign( + quota_database->db_.get()->GetCachedStatement(SQL_FROM_HERE, kSql)); ASSERT_TRUE(statement.is_valid()); - statement.BindString(0, itr->host); - statement.BindInt(1, static_cast<int>(itr->type)); - statement.BindInt64(2, itr->quota); + statement.BindString(0, entry.host); + statement.BindInt(1, static_cast<int>(entry.type)); + statement.BindInt64(2, entry.quota); EXPECT_TRUE(statement.Run()); } + quota_database->Commit(); } - template <typename Iterator> - void AssignOriginInfoTable(sql::Database* db, Iterator itr, Iterator end) { - ASSERT_NE(db, (sql::Database*)nullptr); - for (; itr != end; ++itr) { + template <typename Container> + void AssignBucketTable(QuotaDatabase* quota_database, Container&& entries) { + ASSERT_NE(quota_database->db_.get(), (sql::Database*)nullptr); + for (const auto& entry : entries) { const char* kSql = - "INSERT INTO OriginInfoTable" - " (origin, type, used_count, last_access_time, last_modified_time)" - " VALUES (?, ?, ?, ?, ?)"; + // clang-format off + "INSERT INTO buckets(" + "id," + "origin," + "type," + "name," + "use_count," + "last_accessed," + "last_modified," + "expiration," + "quota) " + "VALUES (?, ?, ?, ?, ?, ?, ?, 0, 0)"; + // clang-format on sql::Statement statement; - statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.Assign( + quota_database->db_->GetCachedStatement(SQL_FROM_HERE, kSql)); ASSERT_TRUE(statement.is_valid()); - statement.BindString(0, itr->origin.GetURL().spec()); - statement.BindInt(1, static_cast<int>(itr->type)); - statement.BindInt(2, itr->used_count); - statement.BindTime(3, itr->last_access_time); - statement.BindTime(4, itr->last_modified_time); + statement.BindInt64(0, entry.bucket_id); + statement.BindString(1, entry.origin.GetURL().spec()); + statement.BindInt(2, static_cast<int>(entry.type)); + statement.BindString(3, entry.name); + statement.BindInt(4, entry.use_count); + statement.BindTime(5, entry.last_accessed); + statement.BindTime(6, entry.last_modified); EXPECT_TRUE(statement.Run()); } + quota_database->Commit(); } - bool OpenDatabase(sql::Database* db, const base::FilePath& kDbFile) { - if (kDbFile.empty()) { - return db->OpenInMemory(); - } - if (!base::CreateDirectory(kDbFile.DirName())) - return false; - if (!db->Open(kDbFile)) - return false; - db->Preload(); - return true; - } + private: + base::test::SingleThreadTaskEnvironment task_environment_; + base::ScopedTempDir temp_directory_; +}; - // Create V2 database and populate some data. - void CreateV2Database( - const base::FilePath& kDbFile, - const QuotaTableEntry* entries, - size_t entries_size) { - std::unique_ptr<sql::Database> db(new sql::Database); - std::unique_ptr<sql::MetaTable> meta_table(new sql::MetaTable); - - // V2 schema definitions. - static const int kCurrentVersion = 2; - static const int kCompatibleVersion = 2; - static const char kHostQuotaTable[] = "HostQuotaTable"; - static const char kOriginLastAccessTable[] = "OriginLastAccessTable"; - static const QuotaDatabase::TableSchema kTables[] = { - { kHostQuotaTable, - "(host TEXT NOT NULL," - " type INTEGER NOT NULL," - " quota INTEGER," - " UNIQUE(host, type))" }, - { kOriginLastAccessTable, - "(origin TEXT NOT NULL," - " type INTEGER NOT NULL," - " used_count INTEGER," - " last_access_time INTEGER," - " UNIQUE(origin, type))" }, - }; - static const QuotaDatabase::IndexSchema kIndexes[] = { - { "HostIndex", - kHostQuotaTable, - "(host)", - false }, - { "OriginLastAccessIndex", - kOriginLastAccessTable, - "(origin, last_access_time)", - false }, - }; - - ASSERT_TRUE(OpenDatabase(db.get(), kDbFile)); - EXPECT_TRUE(QuotaDatabase::CreateSchema( - db.get(), meta_table.get(), kCurrentVersion, kCompatibleVersion, - kTables, base::size(kTables), kIndexes, base::size(kIndexes))); - - // V2 and V3 QuotaTable are compatible, so we can simply use - // AssignQuotaTable to poplulate v2 database here. - db->BeginTransaction(); - AssignQuotaTable(db.get(), entries, entries + entries_size); - db->CommitTransaction(); +TEST_P(QuotaDatabaseTest, LazyOpen) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_FALSE(LazyOpen(&db, /*create_if_needed=*/false)); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + if (GetParam()) { + // Path should not exist for incognito mode. + ASSERT_FALSE(base::PathExists(DbPath())); + } else { + ASSERT_TRUE(base::PathExists(DbPath())); } +} - base::test::SingleThreadTaskEnvironment task_environment_; -}; +TEST_P(QuotaDatabaseTest, HostQuota) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + const char* kHost = "foo.com"; + const int kQuota1 = 13579; + const int kQuota2 = kQuota1 + 1024; + + int64_t quota = -1; + EXPECT_FALSE(db.GetHostQuota(kHost, kTemp, "a)); + EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); + + // Insert quota for temporary. + EXPECT_TRUE(db.SetHostQuota(kHost, kTemp, kQuota1)); + EXPECT_TRUE(db.GetHostQuota(kHost, kTemp, "a)); + EXPECT_EQ(kQuota1, quota); + + // Update quota for temporary. + EXPECT_TRUE(db.SetHostQuota(kHost, kTemp, kQuota2)); + EXPECT_TRUE(db.GetHostQuota(kHost, kTemp, "a)); + EXPECT_EQ(kQuota2, quota); + + // Quota for persistent must not be updated. + EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); + + // Delete temporary storage quota. + EXPECT_TRUE(db.DeleteHostQuota(kHost, kTemp)); + EXPECT_FALSE(db.GetHostQuota(kHost, kTemp, "a)); + + // Delete persistent quota by setting it to zero. + EXPECT_TRUE(db.SetHostQuota(kHost, kPerm, 0)); + EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); +} + +TEST_P(QuotaDatabaseTest, CreateBucket) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + url::Origin origin = ToOrigin("http://google/"); + std::string bucket_name = "google_bucket"; + + QuotaErrorOr<BucketId> result = db.CreateBucket(origin, bucket_name); + ASSERT_TRUE(result.ok()); + ASSERT_FALSE(result.value().is_null()); + + // Trying to create an existing bucket should return false. + result = db.CreateBucket(origin, bucket_name); + ASSERT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kEntryExistsError); +} + +TEST_P(QuotaDatabaseTest, GetBucketId) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + // Add a bucket entry into the bucket table. + url::Origin origin = ToOrigin("http://google/"); + std::string bucket_name = "google_bucket"; + QuotaErrorOr<BucketId> result = db.CreateBucket(origin, bucket_name); + ASSERT_TRUE(result.ok()); -TEST_F(QuotaDatabaseTest, LazyOpen) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - LazyOpen(kDbFile); - LazyOpen(base::FilePath()); + BucketId created_bucket_id = result.value(); + ASSERT_FALSE(created_bucket_id.is_null()); + + db.GetBucketId(origin, bucket_name); + ASSERT_TRUE(result.ok()); + EXPECT_EQ(result.value(), created_bucket_id); + + // Can't retrieve buckets with name mismatch. + result = db.GetBucketId(origin, "does_not_exist"); + ASSERT_TRUE(result.ok()); + EXPECT_TRUE(result.value().is_null()); + + // Can't retrieve buckets with origin mismatch. + result = db.GetBucketId(ToOrigin("http://example/"), bucket_name); + ASSERT_TRUE(result.ok()); + EXPECT_TRUE(result.value().is_null()); } -TEST_F(QuotaDatabaseTest, UpgradeSchema) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - UpgradeSchemaV2toV5(kDbFile); +TEST_P(QuotaDatabaseTest, OriginLastAccessTimeLRU) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + std::set<url::Origin> exceptions; + absl::optional<url::Origin> origin; + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_FALSE(origin.has_value()); + + const url::Origin kOrigin1 = ToOrigin("http://a/"); + const url::Origin kOrigin2 = ToOrigin("http://b/"); + const url::Origin kOrigin3 = ToOrigin("http://c/"); + const url::Origin kOrigin4 = ToOrigin("http://p/"); + + // Adding three temporary storages, and + EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin1, kTemp, + base::Time::FromJavaTime(10))); + EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin2, kTemp, + base::Time::FromJavaTime(20))); + EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin3, kTemp, + base::Time::FromJavaTime(30))); + + // one persistent. + EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin4, kPerm, + base::Time::FromJavaTime(40))); + + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_EQ(kOrigin1, origin); + + // Test that unlimited origins are excluded from eviction, but + // protected origins are not excluded. + scoped_refptr<MockSpecialStoragePolicy> policy(new MockSpecialStoragePolicy); + policy->AddUnlimited(kOrigin1.GetURL()); + policy->AddProtected(kOrigin2.GetURL()); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, policy.get(), &origin)); + EXPECT_EQ(kOrigin2, origin); + + // Test that durable origins are excluded from eviction. + policy->AddDurable(kOrigin2.GetURL()); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, policy.get(), &origin)); + EXPECT_EQ(kOrigin3, origin); + + exceptions.insert(kOrigin1); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_EQ(kOrigin2, origin); + + exceptions.insert(kOrigin2); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_EQ(kOrigin3, origin); + + exceptions.insert(kOrigin3); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_FALSE(origin.has_value()); + + EXPECT_TRUE(db.SetOriginLastAccessTime(kOrigin1, kTemp, base::Time::Now())); + + // Delete origin/type last access time information. + EXPECT_TRUE(db.DeleteOriginInfo(kOrigin3, kTemp)); + + // Querying again to see if the deletion has worked. + exceptions.clear(); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_EQ(kOrigin2, origin); + + exceptions.insert(kOrigin1); + exceptions.insert(kOrigin2); + EXPECT_TRUE(db.GetLRUOrigin(kTemp, exceptions, nullptr, &origin)); + EXPECT_FALSE(origin.has_value()); } -TEST_F(QuotaDatabaseTest, HostQuota) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - HostQuota(kDbFile); - HostQuota(base::FilePath()); +TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + std::set<url::Origin> exceptions; + absl::optional<int64_t> bucket_id; + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_FALSE(bucket_id.has_value()); + + // Insert bucket entries into BucketTable. + base::Time now(base::Time::Now()); + using Entry = QuotaDatabase::BucketTableEntry; + Entry bucket1 = Entry(0, ToOrigin("http://a/"), kTemp, "A", 99, now, now); + Entry bucket2 = Entry(1, ToOrigin("http://b/"), kTemp, "B", 0, now, now); + Entry bucket3 = Entry(2, ToOrigin("http://c/"), kTemp, "C", 1, now, now); + Entry bucket4 = Entry(3, ToOrigin("http://d/"), kPerm, "D", 5, now, now); + Entry kTableEntries[] = {bucket1, bucket2, bucket3, bucket4}; + AssignBucketTable(&db, kTableEntries); + + // Update access time for three temporary storages, and + EXPECT_TRUE(db.SetBucketLastAccessTime(bucket1.bucket_id, + base::Time::FromJavaTime(10))); + EXPECT_TRUE(db.SetBucketLastAccessTime(bucket2.bucket_id, + base::Time::FromJavaTime(20))); + EXPECT_TRUE(db.SetBucketLastAccessTime(bucket3.bucket_id, + base::Time::FromJavaTime(30))); + + // one persistent. + EXPECT_TRUE(db.SetBucketLastAccessTime(bucket4.bucket_id, + base::Time::FromJavaTime(40))); + + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_EQ(bucket1.bucket_id, bucket_id); + + // Test that unlimited origins are excluded from eviction, but + // protected origins are not excluded. + scoped_refptr<MockSpecialStoragePolicy> policy(new MockSpecialStoragePolicy); + policy->AddUnlimited(bucket1.origin.GetURL()); + policy->AddProtected(bucket2.origin.GetURL()); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, policy.get(), &bucket_id)); + EXPECT_EQ(bucket2.bucket_id, bucket_id); + + // Test that durable origins are excluded from eviction. + policy->AddDurable(bucket2.origin.GetURL()); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, policy.get(), &bucket_id)); + EXPECT_EQ(bucket3.bucket_id, bucket_id); + + exceptions.insert(bucket1.origin); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_EQ(bucket2.bucket_id, bucket_id); + + exceptions.insert(bucket2.origin); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_EQ(bucket3.bucket_id, bucket_id); + + exceptions.insert(bucket3.origin); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_FALSE(bucket_id.has_value()); + + EXPECT_TRUE(db.SetBucketLastAccessTime(bucket1.bucket_id, base::Time::Now())); + + // Delete origin/type last access time information. + EXPECT_TRUE(db.DeleteBucketInfo(bucket3.bucket_id)); + + // Querying again to see if the deletion has worked. + exceptions.clear(); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_EQ(bucket2.bucket_id, bucket_id); + + exceptions.insert(bucket1.origin); + exceptions.insert(bucket2.origin); + EXPECT_TRUE(db.GetLRUBucket(kTemp, exceptions, nullptr, &bucket_id)); + EXPECT_FALSE(bucket_id.has_value()); } -TEST_F(QuotaDatabaseTest, OriginLastAccessTimeLRU) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - OriginLastAccessTimeLRU(kDbFile); - OriginLastAccessTimeLRU(base::FilePath()); +TEST_P(QuotaDatabaseTest, OriginLastModifiedBetween) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + std::set<url::Origin> origins; + EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemp, &origins, base::Time(), + base::Time::Max())); + EXPECT_TRUE(origins.empty()); + + const url::Origin kOrigin1 = ToOrigin("http://a/"); + const url::Origin kOrigin2 = ToOrigin("http://b/"); + const url::Origin kOrigin3 = ToOrigin("http://c/"); + + // Report last mod time for the test origins. + EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin1, kTemp, + base::Time::FromJavaTime(0))); + EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin2, kTemp, + base::Time::FromJavaTime(10))); + EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin3, kTemp, + base::Time::FromJavaTime(20))); + + EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemp, &origins, base::Time(), + base::Time::Max())); + EXPECT_EQ(3U, origins.size()); + EXPECT_EQ(1U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(1U, origins.count(kOrigin3)); + + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kTemp, &origins, base::Time::FromJavaTime(5), base::Time::Max())); + EXPECT_EQ(2U, origins.size()); + EXPECT_EQ(0U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(1U, origins.count(kOrigin3)); + + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kTemp, &origins, base::Time::FromJavaTime(15), base::Time::Max())); + EXPECT_EQ(1U, origins.size()); + EXPECT_EQ(0U, origins.count(kOrigin1)); + EXPECT_EQ(0U, origins.count(kOrigin2)); + EXPECT_EQ(1U, origins.count(kOrigin3)); + + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kTemp, &origins, base::Time::FromJavaTime(25), base::Time::Max())); + EXPECT_TRUE(origins.empty()); + + EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemp, &origins, + base::Time::FromJavaTime(5), + base::Time::FromJavaTime(15))); + EXPECT_EQ(1U, origins.size()); + EXPECT_EQ(0U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(0U, origins.count(kOrigin3)); + + EXPECT_TRUE(db.GetOriginsModifiedBetween(kTemp, &origins, + base::Time::FromJavaTime(0), + base::Time::FromJavaTime(20))); + EXPECT_EQ(2U, origins.size()); + EXPECT_EQ(1U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(0U, origins.count(kOrigin3)); + + // Update origin1's mod time but for persistent storage. + EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin1, kPerm, + base::Time::FromJavaTime(30))); + + // Must have no effects on temporary origins info. + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kTemp, &origins, base::Time::FromJavaTime(5), base::Time::Max())); + EXPECT_EQ(2U, origins.size()); + EXPECT_EQ(0U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(1U, origins.count(kOrigin3)); + + // One more update for persistent origin2. + EXPECT_TRUE(db.SetOriginLastModifiedTime(kOrigin2, kPerm, + base::Time::FromJavaTime(40))); + + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kPerm, &origins, base::Time::FromJavaTime(25), base::Time::Max())); + EXPECT_EQ(2U, origins.size()); + EXPECT_EQ(1U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(0U, origins.count(kOrigin3)); + + EXPECT_TRUE(db.GetOriginsModifiedBetween( + kPerm, &origins, base::Time::FromJavaTime(35), base::Time::Max())); + EXPECT_EQ(1U, origins.size()); + EXPECT_EQ(0U, origins.count(kOrigin1)); + EXPECT_EQ(1U, origins.count(kOrigin2)); + EXPECT_EQ(0U, origins.count(kOrigin3)); } -TEST_F(QuotaDatabaseTest, OriginLastModifiedBetween) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - OriginLastModifiedBetween(kDbFile); - OriginLastModifiedBetween(base::FilePath()); +TEST_P(QuotaDatabaseTest, BucketLastModifiedBetween) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + std::set<int64_t> bucket_ids; + EXPECT_TRUE(db.GetBucketsModifiedBetween(kTemp, &bucket_ids, base::Time(), + base::Time::Max())); + EXPECT_TRUE(bucket_ids.empty()); + + // Insert bucket entries into BucketTable. + base::Time now(base::Time::Now()); + using Entry = QuotaDatabase::BucketTableEntry; + Entry bucket1 = Entry(0, ToOrigin("http://a/"), kTemp, "A", 0, now, now); + Entry bucket2 = Entry(1, ToOrigin("http://b/"), kTemp, "B", 0, now, now); + Entry bucket3 = Entry(2, ToOrigin("http://c/"), kTemp, "C", 0, now, now); + Entry bucket4 = Entry(3, ToOrigin("http://d/"), kPerm, "D", 0, now, now); + Entry kTableEntries[] = {bucket1, bucket2, bucket3, bucket4}; + AssignBucketTable(&db, kTableEntries); + + // Report last mod time for the buckets. + EXPECT_TRUE(db.SetBucketLastModifiedTime(bucket1.bucket_id, + base::Time::FromJavaTime(0))); + EXPECT_TRUE(db.SetBucketLastModifiedTime(bucket2.bucket_id, + base::Time::FromJavaTime(10))); + EXPECT_TRUE(db.SetBucketLastModifiedTime(bucket3.bucket_id, + base::Time::FromJavaTime(20))); + EXPECT_TRUE(db.SetBucketLastModifiedTime(bucket4.bucket_id, + base::Time::FromJavaTime(30))); + + EXPECT_TRUE(db.GetBucketsModifiedBetween(kTemp, &bucket_ids, base::Time(), + base::Time::Max())); + EXPECT_EQ(3U, bucket_ids.size()); + EXPECT_EQ(1U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket4.bucket_id)); + + EXPECT_TRUE(db.GetBucketsModifiedBetween( + kTemp, &bucket_ids, base::Time::FromJavaTime(5), base::Time::Max())); + EXPECT_EQ(2U, bucket_ids.size()); + EXPECT_EQ(0U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket4.bucket_id)); + + EXPECT_TRUE(db.GetBucketsModifiedBetween( + kTemp, &bucket_ids, base::Time::FromJavaTime(15), base::Time::Max())); + EXPECT_EQ(1U, bucket_ids.size()); + EXPECT_EQ(0U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket4.bucket_id)); + + EXPECT_TRUE(db.GetBucketsModifiedBetween( + kTemp, &bucket_ids, base::Time::FromJavaTime(25), base::Time::Max())); + EXPECT_TRUE(bucket_ids.empty()); + + EXPECT_TRUE(db.GetBucketsModifiedBetween(kTemp, &bucket_ids, + base::Time::FromJavaTime(5), + base::Time::FromJavaTime(15))); + EXPECT_EQ(1U, bucket_ids.size()); + EXPECT_EQ(0U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket4.bucket_id)); + + EXPECT_TRUE(db.GetBucketsModifiedBetween(kTemp, &bucket_ids, + base::Time::FromJavaTime(0), + base::Time::FromJavaTime(20))); + EXPECT_EQ(2U, bucket_ids.size()); + EXPECT_EQ(1U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket4.bucket_id)); + + EXPECT_TRUE(db.GetBucketsModifiedBetween(kPerm, &bucket_ids, + base::Time::FromJavaTime(0), + base::Time::FromJavaTime(35))); + EXPECT_EQ(1U, bucket_ids.size()); + EXPECT_EQ(0U, bucket_ids.count(bucket1.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket2.bucket_id)); + EXPECT_EQ(0U, bucket_ids.count(bucket3.bucket_id)); + EXPECT_EQ(1U, bucket_ids.count(bucket4.bucket_id)); } -TEST_F(QuotaDatabaseTest, OriginLastEvicted) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - OriginLastEvicted(kDbFile); - OriginLastEvicted(base::FilePath()); +TEST_P(QuotaDatabaseTest, OriginLastEvicted) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + + const url::Origin kOrigin1 = ToOrigin("http://a/"); + const url::Origin kOrigin2 = ToOrigin("http://b/"); + const url::Origin kOrigin3 = ToOrigin("http://c/"); + + base::Time last_eviction_time; + EXPECT_FALSE( + db.GetOriginLastEvictionTime(kOrigin1, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time(), last_eviction_time); + + // Report last eviction time for the test origins. + EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin1, kTemp, + base::Time::FromJavaTime(10))); + EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin2, kTemp, + base::Time::FromJavaTime(20))); + EXPECT_TRUE(db.SetOriginLastEvictionTime(kOrigin3, kTemp, + base::Time::FromJavaTime(30))); + + EXPECT_TRUE( + db.GetOriginLastEvictionTime(kOrigin1, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time::FromJavaTime(10), last_eviction_time); + EXPECT_TRUE( + db.GetOriginLastEvictionTime(kOrigin2, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time::FromJavaTime(20), last_eviction_time); + EXPECT_TRUE( + db.GetOriginLastEvictionTime(kOrigin3, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time::FromJavaTime(30), last_eviction_time); + + // Delete last eviction times for the test origins. + EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin1, kTemp)); + EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin2, kTemp)); + EXPECT_TRUE(db.DeleteOriginLastEvictionTime(kOrigin3, kTemp)); + + last_eviction_time = base::Time(); + EXPECT_FALSE( + db.GetOriginLastEvictionTime(kOrigin1, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time(), last_eviction_time); + EXPECT_FALSE( + db.GetOriginLastEvictionTime(kOrigin2, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time(), last_eviction_time); + EXPECT_FALSE( + db.GetOriginLastEvictionTime(kOrigin3, kTemp, &last_eviction_time)); + EXPECT_EQ(base::Time(), last_eviction_time); + + // Deleting an origin that is not present should not fail. + EXPECT_TRUE(db.DeleteOriginLastEvictionTime(ToOrigin("http://notpresent.com"), + kTemp)); } -TEST_F(QuotaDatabaseTest, BootstrapFlag) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); +TEST_P(QuotaDatabaseTest, RegisterInitialOriginInfo) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - QuotaDatabase db(kDbFile); + const url::Origin kOrigins[] = {ToOrigin("http://a/"), ToOrigin("http://b/"), + ToOrigin("http://c/")}; + std::set<url::Origin> origins(kOrigins, std::end(kOrigins)); - EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); - EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(true)); - EXPECT_TRUE(db.IsOriginDatabaseBootstrapped()); - EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(false)); - EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); + EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kTemp)); + + QuotaDatabase::BucketTableEntry info; + info.use_count = -1; + EXPECT_TRUE(db.GetOriginInfo(ToOrigin("http://a/"), kTemp, &info)); + EXPECT_EQ(0, info.use_count); + + EXPECT_TRUE(db.SetOriginLastAccessTime(ToOrigin("http://a/"), kTemp, + base::Time::FromDoubleT(1.0))); + info.use_count = -1; + EXPECT_TRUE(db.GetOriginInfo(ToOrigin("http://a/"), kTemp, &info)); + EXPECT_EQ(1, info.use_count); + + EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kTemp)); + + info.use_count = -1; + EXPECT_TRUE(db.GetOriginInfo(ToOrigin("http://a/"), kTemp, &info)); + EXPECT_EQ(1, info.use_count); } -TEST_F(QuotaDatabaseTest, RegisterInitialOriginInfo) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - RegisterInitialOriginInfo(kDbFile); - RegisterInitialOriginInfo(base::FilePath()); +TEST_P(QuotaDatabaseTest, DumpQuotaTable) { + QuotaTableEntry kTableEntries[] = { + {.host = "http://go/", .type = kTemp, .quota = 1}, + {.host = "http://oo/", .type = kTemp, .quota = 2}, + {.host = "http://gle/", .type = kPerm, .quota = 3}}; + + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + AssignQuotaTable(&db, kTableEntries); + + using Verifier = EntryVerifier<QuotaTableEntry>; + Verifier verifier(kTableEntries, std::end(kTableEntries)); + EXPECT_TRUE(DumpQuotaTable( + &db, base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); + EXPECT_TRUE(verifier.table.empty()); } -TEST_F(QuotaDatabaseTest, DumpQuotaTable) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - DumpQuotaTable(kDbFile); - DumpQuotaTable(base::FilePath()); +TEST_P(QuotaDatabaseTest, DumpBucketTable) { + base::Time now(base::Time::Now()); + using Entry = QuotaDatabase::BucketTableEntry; + Entry kTableEntries[] = { + Entry(0, ToOrigin("http://go/"), kTemp, kDefaultBucket, 2147483647, now, + now), + Entry(1, ToOrigin("http://oo/"), kTemp, kDefaultBucket, 0, now, now), + Entry(2, ToOrigin("http://gle/"), kTemp, kDefaultBucket, 1, now, now), + }; + + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + AssignBucketTable(&db, kTableEntries); + + using Verifier = EntryVerifier<Entry>; + Verifier verifier(kTableEntries, std::end(kTableEntries)); + EXPECT_TRUE(DumpBucketTable( + &db, base::BindRepeating(&Verifier::Run, base::Unretained(&verifier)))); + EXPECT_TRUE(verifier.table.empty()); } -TEST_F(QuotaDatabaseTest, DumpOriginInfoTable) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - DumpOriginInfoTable(kDbFile); - DumpOriginInfoTable(base::FilePath()); +TEST_P(QuotaDatabaseTest, GetOriginInfo) { + const url::Origin kOrigin = ToOrigin("http://go/"); + using Entry = QuotaDatabase::BucketTableEntry; + Entry kTableEntries[] = {Entry(0, kOrigin, kTemp, kDefaultBucket, 100, + base::Time(), base::Time())}; + + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + AssignBucketTable(&db, kTableEntries); + + { + Entry entry; + EXPECT_TRUE(db.GetOriginInfo(kOrigin, kTemp, &entry)); + EXPECT_EQ(kTableEntries[0].type, entry.type); + EXPECT_EQ(kTableEntries[0].origin, entry.origin); + EXPECT_EQ(kTableEntries[0].name, entry.name); + EXPECT_EQ(kTableEntries[0].use_count, entry.use_count); + EXPECT_EQ(kTableEntries[0].last_accessed, entry.last_accessed); + EXPECT_EQ(kTableEntries[0].last_modified, entry.last_modified); + } + + { + Entry entry; + EXPECT_FALSE( + db.GetOriginInfo(ToOrigin("http://notpresent.org/"), kTemp, &entry)); + } } -TEST_F(QuotaDatabaseTest, GetOriginInfo) { - GetOriginInfo(base::FilePath()); +TEST_P(QuotaDatabaseTest, GetBucketInfo) { + using Entry = QuotaDatabase::BucketTableEntry; + Entry kTableEntries[] = {Entry(123, ToOrigin("http://go/"), kTemp, + "TestBucket", 100, base::Time(), + base::Time())}; + + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + AssignBucketTable(&db, kTableEntries); + + { + Entry entry; + EXPECT_TRUE(db.GetBucketInfo(kTableEntries[0].bucket_id, &entry)); + EXPECT_EQ(kTableEntries[0].bucket_id, entry.bucket_id); + EXPECT_EQ(kTableEntries[0].type, entry.type); + EXPECT_EQ(kTableEntries[0].origin, entry.origin); + EXPECT_EQ(kTableEntries[0].name, entry.name); + EXPECT_EQ(kTableEntries[0].use_count, entry.use_count); + EXPECT_EQ(kTableEntries[0].last_accessed, entry.last_accessed); + EXPECT_EQ(kTableEntries[0].last_modified, entry.last_modified); + } + + { + Entry entry; + EXPECT_FALSE(db.GetBucketInfo(456, &entry)); + } +} + +// Non-parameterized tests. +TEST_F(QuotaDatabaseTest, BootstrapFlag) { + QuotaDatabase db(DbPath()); + + EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); + EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(true)); + EXPECT_TRUE(db.IsOriginDatabaseBootstrapped()); + EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(false)); + EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); } TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) { - base::ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); - const base::FilePath kDbFile = data_dir.GetPath().AppendASCII(kDBFileName); - LazyOpen(kDbFile); - ASSERT_TRUE(sql::test::CorruptSizeInHeader(kDbFile)); + // Create database, force corruption and close db by leaving scope. + { + QuotaDatabase db(DbPath()); + ASSERT_TRUE(LazyOpen(&db, /*create_if_needed=*/true)); + ASSERT_TRUE(sql::test::CorruptSizeInHeader(DbPath())); + } + // Reopen database and verify schema reset on reopen. { sql::test::ScopedErrorExpecter expecter; expecter.ExpectError(SQLITE_CORRUPT); - Reopen(kDbFile); + QuotaDatabase db(DbPath()); + ASSERT_TRUE(LazyOpen(&db, /*create_if_needed=*/false)); EXPECT_TRUE(expecter.SawExpectedErrors()); } } +INSTANTIATE_TEST_SUITE_P(All, + QuotaDatabaseTest, + /* is_incognito */ testing::Bool()); + } // namespace storage diff --git a/chromium/storage/browser/quota/quota_features.h b/chromium/storage/browser/quota/quota_features.h index 6bf775fdfdb..5cf4cb0b047 100644 --- a/chromium/storage/browser/quota/quota_features.h +++ b/chromium/storage/browser/quota/quota_features.h @@ -29,4 +29,4 @@ extern const base::FeatureParam<double> kShouldRemainAvailableRatio; } // namespace storage -#endif // STORAGE_QUOTA_QUOTA_FEATURES_H_ +#endif // STORAGE_BROWSER_QUOTA_QUOTA_FEATURES_H_ diff --git a/chromium/storage/browser/quota/quota_manager_impl.cc b/chromium/storage/browser/quota/quota_manager_impl.cc index 727512649d8..017884bd927 100644 --- a/chromium/storage/browser/quota/quota_manager_impl.cc +++ b/chromium/storage/browser/quota/quota_manager_impl.cc @@ -90,6 +90,20 @@ bool IsSupportedIncognitoType(StorageType type) { return type == StorageType::kTemporary || type == StorageType::kPersistent; } +QuotaErrorOr<BucketId> CreateBucketOnDBThread(const url::Origin& origin, + const std::string& bucket_name, + QuotaDatabase* database) { + DCHECK(database); + return database->CreateBucket(origin, bucket_name); +} + +QuotaErrorOr<BucketId> GetBucketIdOnDBThread(const url::Origin& origin, + const std::string& bucket_name, + QuotaDatabase* database) { + DCHECK(database); + return database->GetBucketId(origin, bucket_name); +} + bool GetPersistentHostQuotaOnDBThread(const std::string& host, int64_t* quota, QuotaDatabase* database) { @@ -111,7 +125,7 @@ bool SetPersistentHostQuotaOnDBThread(const std::string& host, bool GetLRUOriginOnDBThread(StorageType type, const std::set<url::Origin>& exceptions, SpecialStoragePolicy* policy, - base::Optional<url::Origin>* origin, + absl::optional<url::Origin>* origin, QuotaDatabase* database) { DCHECK(database); database->GetLRUOrigin(type, exceptions, policy, origin); @@ -127,14 +141,14 @@ bool DeleteOriginInfoOnDBThread(const url::Origin& origin, base::Time now = base::Time::Now(); if (is_eviction) { - QuotaDatabase::OriginInfoTableEntry entry; + QuotaDatabase::BucketTableEntry entry; database->GetOriginInfo(origin, type, &entry); UMA_HISTOGRAM_COUNTS_1M( QuotaManagerImpl::kEvictedOriginAccessedCountHistogram, - entry.used_count); + entry.use_count); UMA_HISTOGRAM_COUNTS_1000( QuotaManagerImpl::kEvictedOriginDaysSinceAccessHistogram, - (now - entry.last_access_time).InDays()); + (now - entry.last_accessed).InDays()); } if (!database->DeleteOriginInfo(origin, type)) @@ -230,7 +244,7 @@ class QuotaManagerImpl::UsageAndQuotaInfoGatherer : public QuotaTask { bool is_unlimited, bool is_session_only, bool is_incognito, - base::Optional<int64_t> quota_override_size, + absl::optional<int64_t> quota_override_size, UsageAndQuotaForDevtoolsCallback callback) : QuotaTask(manager), origin_(origin), @@ -385,7 +399,7 @@ class QuotaManagerImpl::UsageAndQuotaInfoGatherer : public QuotaTask { int64_t desired_host_quota_ = 0; int64_t host_usage_ = 0; const bool is_override_enabled_; - base::Optional<int64_t> quota_override_size_; + absl::optional<int64_t> quota_override_size_; blink::mojom::UsageBreakdownPtr host_usage_breakdown_; QuotaSettings settings_; SEQUENCE_CHECKER(sequence_checker_); @@ -869,20 +883,20 @@ class QuotaManagerImpl::DumpQuotaTableHelper { // goes out of scope, the object is deleted. // This class is not thread-safe because there can be races when entries_ is // modified. -class QuotaManagerImpl::DumpOriginInfoTableHelper { +class QuotaManagerImpl::DumpBucketTableHelper { public: - bool DumpOriginInfoTableOnDBThread(QuotaDatabase* database) { + bool DumpBucketTableOnDBThread(QuotaDatabase* database) { DCHECK(database); - return database->DumpOriginInfoTable(base::BindRepeating( - &DumpOriginInfoTableHelper::AppendEntry, base::Unretained(this))); + return database->DumpBucketTable(base::BindRepeating( + &DumpBucketTableHelper::AppendEntry, base::Unretained(this))); } - void DidDumpOriginInfoTable(const base::WeakPtr<QuotaManagerImpl>& manager, - DumpOriginInfoTableCallback callback, - bool success) { + void DidDumpBucketTable(const base::WeakPtr<QuotaManagerImpl>& manager, + DumpBucketTableCallback callback, + bool success) { if (!manager) { // The operation was aborted. - std::move(callback).Run(OriginInfoTableEntries()); + std::move(callback).Run(BucketTableEntries()); return; } manager->DidDatabaseWork(success); @@ -890,12 +904,12 @@ class QuotaManagerImpl::DumpOriginInfoTableHelper { } private: - bool AppendEntry(const OriginInfoTableEntry& entry) { + bool AppendEntry(const BucketTableEntry& entry) { entries_.push_back(entry); return true; } - OriginInfoTableEntries entries_; + BucketTableEntries entries_; }; // QuotaManagerImpl ----------------------------------------------------------- @@ -939,6 +953,32 @@ void QuotaManagerImpl::SetQuotaSettings(const QuotaSettings& settings) { settings_timestamp_ = base::TimeTicks::Now(); } +void QuotaManagerImpl::CreateBucket( + const url::Origin& origin, + const std::string& bucket_name, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + LazyInitialize(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&CreateBucketOnDBThread, origin, bucket_name), + base::BindOnce(&QuotaManagerImpl::DidGetBucketId, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + +void QuotaManagerImpl::GetBucketId( + const url::Origin& origin, + const std::string& bucket_name, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + LazyInitialize(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&GetBucketIdOnDBThread, origin, bucket_name), + base::BindOnce(&QuotaManagerImpl::DidGetBucketId, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + void QuotaManagerImpl::GetUsageInfo(GetUsageInfoCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); LazyInitialize(); @@ -987,7 +1027,7 @@ void QuotaManagerImpl::GetUsageAndQuotaForDevtools( type == StorageType::kTemporary && special_storage_policy_ && special_storage_policy_->IsStorageSessionOnly(origin.GetURL()); - base::Optional<int64_t> quota_override = GetQuotaOverrideForOrigin(origin); + absl::optional<int64_t> quota_override = GetQuotaOverrideForOrigin(origin); UsageAndQuotaInfoGatherer* helper = new UsageAndQuotaInfoGatherer( this, origin, type, IsStorageUnlimited(origin, type), is_session_only, @@ -1020,7 +1060,7 @@ void QuotaManagerImpl::GetUsageAndQuota(const url::Origin& origin, type == StorageType::kTemporary && special_storage_policy_ && special_storage_policy_->IsStorageSessionOnly(origin.GetURL()); - base::Optional<int64_t> quota_override = GetQuotaOverrideForOrigin(origin); + absl::optional<int64_t> quota_override = GetQuotaOverrideForOrigin(origin); UsageAndQuotaInfoGatherer* helper = new UsageAndQuotaInfoGatherer( this, origin, type, IsStorageUnlimited(origin, type), is_session_only, @@ -1462,15 +1502,14 @@ void QuotaManagerImpl::DumpQuotaTable(DumpQuotaTableCallback callback) { std::move(callback))); } -void QuotaManagerImpl::DumpOriginInfoTable( - DumpOriginInfoTableCallback callback) { +void QuotaManagerImpl::DumpBucketTable(DumpBucketTableCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DumpOriginInfoTableHelper* helper = new DumpOriginInfoTableHelper; + DumpBucketTableHelper* helper = new DumpBucketTableHelper; PostTaskAndReplyWithResultForDBThread( FROM_HERE, - base::BindOnce(&DumpOriginInfoTableHelper::DumpOriginInfoTableOnDBThread, + base::BindOnce(&DumpBucketTableHelper::DumpBucketTableOnDBThread, base::Unretained(helper)), - base::BindOnce(&DumpOriginInfoTableHelper::DidDumpOriginInfoTable, + base::BindOnce(&DumpBucketTableHelper::DidDumpBucketTable, base::Owned(helper), weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -1580,7 +1619,7 @@ void QuotaManagerImpl::SetStoragePressureCallback( if (origin_for_pending_storage_pressure_callback_.has_value()) { storage_pressure_callback_.Run( std::move(origin_for_pending_storage_pressure_callback_.value())); - origin_for_pending_storage_pressure_callback_ = base::nullopt; + origin_for_pending_storage_pressure_callback_ = absl::nullopt; } } @@ -1592,7 +1631,7 @@ int QuotaManagerImpl::GetOverrideHandleId() { void QuotaManagerImpl::OverrideQuotaForOrigin( int handle_id, const url::Origin& origin, - base::Optional<int64_t> quota_size) { + absl::optional<int64_t> quota_size) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (quota_size.has_value()) { DCHECK_GE(next_override_handle_id_, handle_id); @@ -1624,11 +1663,11 @@ void QuotaManagerImpl::WithdrawOverridesForHandle(int handle_id) { } } -base::Optional<int64_t> QuotaManagerImpl::GetQuotaOverrideForOrigin( +absl::optional<int64_t> QuotaManagerImpl::GetQuotaOverrideForOrigin( const url::Origin& origin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!base::Contains(devtools_overrides_, origin)) { - return base::nullopt; + return absl::nullopt; } return devtools_overrides_[origin].quota_size; } @@ -1683,14 +1722,14 @@ void QuotaManagerImpl::DidGetPersistentGlobalUsageForHistogram( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage); - // We DumpOriginInfoTable last to ensure the trackers caches are loaded. - DumpOriginInfoTable( - base::BindOnce(&QuotaManagerImpl::DidDumpOriginInfoTableForHistogram, + // We DumpBucketTable last to ensure the trackers caches are loaded. + DumpBucketTable( + base::BindOnce(&QuotaManagerImpl::DidDumpBucketTableForHistogram, weak_factory_.GetWeakPtr())); } -void QuotaManagerImpl::DidDumpOriginInfoTableForHistogram( - const OriginInfoTableEntries& entries) { +void QuotaManagerImpl::DidDumpBucketTableForHistogram( + const BucketTableEntries& entries) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::map<url::Origin, int64_t> usage_map = GetUsageTracker(StorageType::kTemporary)->GetCachedOriginsUsage(); @@ -1705,8 +1744,8 @@ void QuotaManagerImpl::DidDumpOriginInfoTableForHistogram( if (it == usage_map.end() || it->second == 0) continue; - base::TimeDelta age = now - std::max(info.last_access_time, - info.last_modified_time); + base::TimeDelta age = + now - std::max(info.last_accessed, info.last_modified); UMA_HISTOGRAM_COUNTS_1000("Quota.AgeOfOriginInDays", age.InDays()); int64_t kilobytes = std::max(it->second / INT64_C(1024), INT64_C(1)); @@ -1736,7 +1775,7 @@ std::set<url::Origin> QuotaManagerImpl::GetEvictionOriginExceptions() { void QuotaManagerImpl::DidGetEvictionOrigin( GetOriginCallback callback, - const base::Optional<url::Origin>& origin) { + const absl::optional<url::Origin>& origin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Make sure the returned origin is (still) not in the origin_in_use_ set // and has not been accessed since we posted the task. @@ -1744,7 +1783,7 @@ void QuotaManagerImpl::DidGetEvictionOrigin( if (origin.has_value() && (base::Contains(origins_in_use_, *origin) || base::Contains(access_notified_origins_, *origin))) { - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); } else { std::move(callback).Run(origin); } @@ -1814,11 +1853,11 @@ void QuotaManagerImpl::GetLRUOrigin(StorageType type, DCHECK(lru_origin_callback_.is_null()); lru_origin_callback_ = std::move(callback); if (db_disabled_) { - std::move(lru_origin_callback_).Run(base::nullopt); + std::move(lru_origin_callback_).Run(absl::nullopt); return; } - auto origin = std::make_unique<base::Optional<url::Origin>>(); + auto origin = std::make_unique<absl::optional<url::Origin>>(); auto* origin_ptr = origin.get(); PostTaskAndReplyWithResultForDBThread( FROM_HERE, @@ -1853,7 +1892,7 @@ void QuotaManagerImpl::DidSetPersistentHostQuota(const std::string& host, } void QuotaManagerImpl::DidGetLRUOrigin( - std::unique_ptr<base::Optional<url::Origin>> origin, + std::unique_ptr<absl::optional<url::Origin>> origin, bool success) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DidDatabaseWork(success); @@ -1864,7 +1903,7 @@ void QuotaManagerImpl::DidGetLRUOrigin( namespace { void DidGetSettingsThreadAdapter(base::TaskRunner* task_runner, OptionalQuotaSettingsCallback callback, - base::Optional<QuotaSettings> settings) { + absl::optional<QuotaSettings> settings) { task_runner->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::move(settings))); } @@ -1893,7 +1932,7 @@ void QuotaManagerImpl::GetQuotaSettings(QuotaSettingsCallback callback) { weak_factory_.GetWeakPtr())))); } -void QuotaManagerImpl::DidGetSettings(base::Optional<QuotaSettings> settings) { +void QuotaManagerImpl::DidGetSettings(absl::optional<QuotaSettings> settings) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!settings) { settings = settings_; @@ -1951,6 +1990,14 @@ void QuotaManagerImpl::DidDatabaseWork(bool success) { db_disabled_ = !success; } +void QuotaManagerImpl::DidGetBucketId( + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback, + QuotaErrorOr<BucketId> result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DidDatabaseWork(result.ok()); + std::move(callback).Run(std::move(result)); +} + void QuotaManagerImpl::PostTaskAndReplyWithResultForDBThread( const base::Location& from_here, base::OnceCallback<bool(QuotaDatabase*)> task, @@ -1965,6 +2012,21 @@ void QuotaManagerImpl::PostTaskAndReplyWithResultForDBThread( std::move(reply)); } +template <typename ValueType> +void QuotaManagerImpl::PostTaskAndReplyWithResultForDBThread( + base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task, + base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply, + const base::Location& from_here) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Deleting manager will post another task to DB sequence to delete + // |database_|, therefore we can be sure that database_ is alive when this + // task runs. + base::PostTaskAndReplyWithResult( + db_runner_.get(), from_here, + base::BindOnce(std::move(task), base::Unretained(database_.get())), + std::move(reply)); +} + // static std::tuple<int64_t, int64_t> QuotaManagerImpl::CallGetVolumeInfo( GetVolumeInfoFn get_volume_info_fn, diff --git a/chromium/storage/browser/quota/quota_manager_impl.h b/chromium/storage/browser/quota/quota_manager_impl.h index 817f16ecd9c..01701a0c9db 100644 --- a/chromium/storage/browser/quota/quota_manager_impl.h +++ b/chromium/storage/browser/quota/quota_manager_impl.h @@ -25,10 +25,10 @@ #include "base/memory/ref_counted.h" #include "base/memory/ref_counted_delete_on_sequence.h" #include "base/memory/weak_ptr.h" -#include "base/optional.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "components/services/storage/public/cpp/quota_error_or.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -39,6 +39,7 @@ #include "storage/browser/quota/quota_settings.h" #include "storage/browser/quota/quota_task.h" #include "storage/browser/quota/special_storage_policy.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h" #include "url/origin.h" @@ -160,6 +161,19 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // Returns a proxy object that can be used on any thread. QuotaManagerProxy* proxy() { return proxy_.get(); } + // Creates a bucket for `origin` with `bucket_name` and returns the BucketId + // to the callback. Will return a QuotaError to the callback on failure. + void CreateBucket(const url::Origin& origin, + const std::string& bucket_name, + base::OnceCallback<void(QuotaErrorOr<BucketId>)>); + + // Retrieves the BucketId of the bucket with `bucket_name` for `origin` and + // returns it to the callback. Will return an empty BucketId if a bucket does + // not exist. Will return a QuotaError on operation failure. + void GetBucketId(const url::Origin& origin, + const std::string& bucket_name, + base::OnceCallback<void(QuotaErrorOr<BucketId>)>); + // Called by clients or webapps. Returns usage per host. void GetUsageInfo(GetUsageInfoCallback callback); @@ -289,7 +303,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl int GetOverrideHandleId(); void OverrideQuotaForOrigin(int handle_id, const url::Origin& origin, - base::Optional<int64_t> quota_size); + absl::optional<int64_t> quota_size); // Called when a DevTools client releases all overrides, however, overrides // will not be disabled for any origins for which there are other DevTools // clients/QuotaOverrideHandle with an active override. @@ -348,7 +362,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl class HostDataDeleter; class GetModifiedSinceHelper; class DumpQuotaTableHelper; - class DumpOriginInfoTableHelper; + class DumpBucketTableHelper; class StorageCleanupHelper; struct QuotaOverride { @@ -365,16 +379,16 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl }; using QuotaTableEntry = QuotaDatabase::QuotaTableEntry; - using OriginInfoTableEntry = QuotaDatabase::OriginInfoTableEntry; + using BucketTableEntry = QuotaDatabase::BucketTableEntry; using QuotaTableEntries = std::vector<QuotaTableEntry>; - using OriginInfoTableEntries = std::vector<OriginInfoTableEntry>; + using BucketTableEntries = std::vector<BucketTableEntry>; using QuotaSettingsCallback = base::OnceCallback<void(const QuotaSettings&)>; using DumpQuotaTableCallback = base::OnceCallback<void(const QuotaTableEntries&)>; - using DumpOriginInfoTableCallback = - base::OnceCallback<void(const OriginInfoTableEntries&)>; + using DumpBucketTableCallback = + base::OnceCallback<void(const BucketTableEntries&)>; // The values returned total_space, available_space. using StorageCapacityCallback = base::OnceCallback<void(int64_t, int64_t)>; @@ -422,7 +436,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl std::set<url::Origin> GetCachedOrigins(blink::mojom::StorageType type); void DumpQuotaTable(DumpQuotaTableCallback callback); - void DumpOriginInfoTable(DumpOriginInfoTableCallback callback); + void DumpBucketTable(DumpBucketTableCallback callback); void DeleteOriginDataInternal(const url::Origin& origin, blink::mojom::StorageType type, @@ -446,12 +460,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl int64_t available_space); void DidGetPersistentGlobalUsageForHistogram(int64_t usage, int64_t unlimited_usage); - void DidDumpOriginInfoTableForHistogram( - const OriginInfoTableEntries& entries); + void DidDumpBucketTableForHistogram(const BucketTableEntries& entries); std::set<url::Origin> GetEvictionOriginExceptions(); void DidGetEvictionOrigin(GetOriginCallback callback, - const base::Optional<url::Origin>& origin); + const absl::optional<url::Origin>& origin); // QuotaEvictionHandler. void GetEvictionOrigin(blink::mojom::StorageType type, @@ -471,10 +484,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl QuotaCallback callback, const int64_t* new_quota, bool success); - void DidGetLRUOrigin(std::unique_ptr<base::Optional<url::Origin>> origin, + void DidGetLRUOrigin(std::unique_ptr<absl::optional<url::Origin>> origin, bool success); void GetQuotaSettings(QuotaSettingsCallback callback); - void DidGetSettings(base::Optional<QuotaSettings> settings); + void DidGetSettings(absl::optional<QuotaSettings> settings); void GetStorageCapacity(StorageCapacityCallback callback); void ContinueIncognitoGetStorageCapacity(const QuotaSettings& settings); void DidGetStorageCapacity( @@ -482,6 +495,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl void DidDatabaseWork(bool success); + void DidGetBucketId(base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback, + QuotaErrorOr<BucketId> result); + void DeleteOnCorrectThread() const; void MaybeRunStoragePressureCallback(const url::Origin& origin, @@ -499,13 +515,20 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // TODO(crbug.com/1102433): Define and explain StoragePressure in the README. void DetermineStoragePressure(int64_t free_space, int64_t total_space); - base::Optional<int64_t> GetQuotaOverrideForOrigin(const url::Origin&); + absl::optional<int64_t> GetQuotaOverrideForOrigin(const url::Origin&); + // TODO(ayui): Replace instances to use result with QuotaErrorOr. void PostTaskAndReplyWithResultForDBThread( const base::Location& from_here, base::OnceCallback<bool(QuotaDatabase*)> task, base::OnceCallback<void(bool)> reply); + template <typename ValueType> + void PostTaskAndReplyWithResultForDBThread( + base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task, + base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply, + const base::Location& from_here = base::Location::Current()); + static std::tuple<int64_t, int64_t> CallGetVolumeInfo( GetVolumeInfoFn get_volume_info_fn, const base::FilePath& path); @@ -520,7 +543,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl bool db_disabled_; bool eviction_disabled_; - base::Optional<url::Origin> origin_for_pending_storage_pressure_callback_; + absl::optional<url::Origin> origin_for_pending_storage_pressure_callback_; scoped_refptr<base::SingleThreadTaskRunner> io_thread_; scoped_refptr<base::SequencedTaskRunner> db_runner_; mutable std::unique_ptr<QuotaDatabase> database_; diff --git a/chromium/storage/browser/quota/quota_manager_proxy.cc b/chromium/storage/browser/quota/quota_manager_proxy.cc index de6b66c63c8..44cdffebcae 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.cc +++ b/chromium/storage/browser/quota/quota_manager_proxy.cc @@ -28,6 +28,22 @@ namespace storage { +namespace { + +void DidGetBucketId( + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback, + QuotaErrorOr<BucketId> result) { + if (callback_task_runner->RunsTasksInCurrentSequence()) { + std::move(callback).Run(std::move(result)); + return; + } + callback_task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(result))); +} + +} // namespace + QuotaManagerProxy::QuotaManagerProxy( QuotaManagerImpl* quota_manager_impl, scoped_refptr<base::SequencedTaskRunner> quota_manager_impl_task_runner) @@ -80,6 +96,59 @@ void QuotaManagerProxy::RegisterClient( } } +void QuotaManagerProxy::CreateBucket( + const url::Origin& origin, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) { + if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) { + quota_manager_impl_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&QuotaManagerProxy::CreateBucket, this, origin, + bucket_name, std::move(callback_task_runner), + std::move(callback))); + return; + } + + DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_); + if (!quota_manager_impl_) { + DidGetBucketId(std::move(callback_task_runner), std::move(callback), + QuotaErrorOr<BucketId>(QuotaError::kUnknownError)); + return; + } + + quota_manager_impl_->CreateBucket( + origin, bucket_name, + base::BindOnce(&DidGetBucketId, std::move(callback_task_runner), + std::move(callback))); +} + +void QuotaManagerProxy::GetBucketId( + const url::Origin& origin, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback) { + if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) { + quota_manager_impl_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&QuotaManagerProxy::GetBucketId, this, origin, + bucket_name, std::move(callback_task_runner), + std::move(callback))); + return; + } + + DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_); + if (!quota_manager_impl_) { + DidGetBucketId(std::move(callback_task_runner), std::move(callback), + QuotaErrorOr<BucketId>(QuotaError::kUnknownError)); + return; + } + + quota_manager_impl_->GetBucketId( + origin, bucket_name, + base::BindOnce(&DidGetBucketId, std::move(callback_task_runner), + std::move(callback))); +} + void QuotaManagerProxy::NotifyStorageAccessed(const url::Origin& origin, blink::mojom::StorageType type, base::Time access_time) { @@ -268,7 +337,7 @@ QuotaManagerProxy::GetQuotaOverrideHandle() { void QuotaManagerProxy::OverrideQuotaForOrigin( int handle_id, url::Origin origin, - base::Optional<int64_t> quota_size, + absl::optional<int64_t> quota_size, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::OnceClosure callback) { if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) { diff --git a/chromium/storage/browser/quota/quota_manager_proxy.h b/chromium/storage/browser/quota/quota_manager_proxy.h index ac64cf6265b..f5452f146cb 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.h +++ b/chromium/storage/browser/quota/quota_manager_proxy.h @@ -18,6 +18,7 @@ #include "base/thread_annotations.h" #include "base/time/time.h" #include "base/types/pass_key.h" +#include "components/services/storage/public/cpp/quota_error_or.h" #include "components/services/storage/public/mojom/quota_client.mojom-forward.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "storage/browser/quota/quota_callbacks.h" @@ -75,6 +76,24 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy mojo::PendingRemote<mojom::QuotaClient> client, QuotaClientType client_type, const std::vector<blink::mojom::StorageType>& storage_types); + + // Creates a bucket for `origin` with `bucket_name` and returns the BucketId + // to the callback. Will return an QuotaError to the callback on failure. + virtual void CreateBucket( + const url::Origin& origin, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback); + + // Retrieves the BucketId of the bucket with `bucket_name` for `origin` and + // returns it to the callback. Will return an empty BucketId if a bucket does + // not exist. Will return a QuotaError on operation failure. + virtual void GetBucketId( + const url::Origin& origin, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(QuotaErrorOr<BucketId>)> callback); + virtual void NotifyStorageAccessed(const url::Origin& origin, blink::mojom::StorageType type, base::Time access_time); @@ -124,7 +143,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy void OverrideQuotaForOrigin( int handle_id, url::Origin origin, - base::Optional<int64_t> quota_size, + absl::optional<int64_t> quota_size, scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::OnceClosure callback); void WithdrawOverridesForHandle(int handle_id); diff --git a/chromium/storage/browser/quota/quota_manager_unittest.cc b/chromium/storage/browser/quota/quota_manager_unittest.cc index 691e6195b4f..b36e087c850 100644 --- a/chromium/storage/browser/quota/quota_manager_unittest.cc +++ b/chromium/storage/browser/quota/quota_manager_unittest.cc @@ -89,7 +89,7 @@ class QuotaManagerImplTest : public testing::Test { protected: using QuotaTableEntry = QuotaManagerImpl::QuotaTableEntry; using QuotaTableEntries = QuotaManagerImpl::QuotaTableEntries; - using OriginInfoTableEntries = QuotaManagerImpl::OriginInfoTableEntries; + using BucketTableEntries = QuotaManagerImpl::BucketTableEntries; public: QuotaManagerImplTest() : mock_time_counter_(0) {} @@ -142,7 +142,7 @@ class QuotaManagerImplTest : public testing::Test { // TODO(crbug.com/1163009): Remove this method and replace all calls with // CreateAndRegisterClient() after all QuotaClients - // have been mojofied + // have been mojofied. MockQuotaClient* CreateAndRegisterLegacyClient( base::span<const MockOriginData> mock_data, QuotaClientType client_type, @@ -159,6 +159,20 @@ class QuotaManagerImplTest : public testing::Test { return mock_quota_client_ptr; } + void CreateBucket(const url::Origin& origin, const std::string& bucket_name) { + quota_manager_impl_->CreateBucket( + origin, bucket_name, + base::BindOnce(&QuotaManagerImplTest::DidGetBucketId, + weak_factory_.GetWeakPtr())); + } + + void GetBucketId(const url::Origin& origin, const std::string& bucket_name) { + quota_manager_impl_->GetBucketId( + origin, bucket_name, + base::BindOnce(&QuotaManagerImplTest::DidGetBucketId, + weak_factory_.GetWeakPtr())); + } + void GetUsageInfo() { usage_info_.clear(); quota_manager_impl_->GetUsageInfo(base::BindOnce( @@ -365,11 +379,14 @@ class QuotaManagerImplTest : public testing::Test { &QuotaManagerImplTest::DidDumpQuotaTable, weak_factory_.GetWeakPtr())); } - void DumpOriginInfoTable() { - origin_info_entries_.clear(); - quota_manager_impl_->DumpOriginInfoTable( - base::BindOnce(&QuotaManagerImplTest::DidDumpOriginInfoTable, - weak_factory_.GetWeakPtr())); + void DumpBucketTable() { + bucket_entries_.clear(); + quota_manager_impl_->DumpBucketTable(base::BindOnce( + &QuotaManagerImplTest::DidDumpBucketTable, weak_factory_.GetWeakPtr())); + } + + void DidGetBucketId(QuotaErrorOr<BucketId> result) { + bucket_id_ = std::move(result); } void DidGetUsageInfo(UsageInfoEntries entries) { @@ -442,7 +459,7 @@ class QuotaManagerImplTest : public testing::Test { usage_ = global_usage; } - void DidGetEvictionOrigin(const base::Optional<url::Origin>& origin) { + void DidGetEvictionOrigin(const absl::optional<url::Origin>& origin) { eviction_origin_ = origin; DCHECK(!origin.has_value() || !origin->GetURL().is_empty()); } @@ -457,8 +474,8 @@ class QuotaManagerImplTest : public testing::Test { quota_entries_ = entries; } - void DidDumpOriginInfoTable(const OriginInfoTableEntries& entries) { - origin_info_entries_ = entries; + void DidDumpBucketTable(const BucketTableEntries& entries) { + bucket_entries_ = entries; } void GetUsage_WithModifyTestBody(const StorageType type); @@ -512,7 +529,7 @@ class QuotaManagerImplTest : public testing::Test { int64_t quota() const { return quota_; } int64_t total_space() const { return total_space_; } int64_t available_space() const { return available_space_; } - const base::Optional<url::Origin>& eviction_origin() const { + const absl::optional<url::Origin>& eviction_origin() const { return eviction_origin_; } const std::set<url::Origin>& modified_origins() const { @@ -520,17 +537,15 @@ class QuotaManagerImplTest : public testing::Test { } StorageType modified_origins_type() const { return modified_origins_type_; } const QuotaTableEntries& quota_entries() const { return quota_entries_; } - const OriginInfoTableEntries& origin_info_entries() const { - return origin_info_entries_; - } + const BucketTableEntries& bucket_entries() const { return bucket_entries_; } const QuotaSettings& settings() const { return settings_; } - base::FilePath profile_path() const { return data_dir_.GetPath(); } int status_callback_count() const { return status_callback_count_; } void reset_status_callback_count() { status_callback_count_ = 0; } protected: base::test::ScopedFeatureList scoped_feature_list_; base::test::TaskEnvironment task_environment_; + QuotaErrorOr<BucketId> bucket_id_; static std::vector<QuotaClientType> AllClients() { // TODO(pwnall): Implement using something other than an empty vector? @@ -556,11 +571,11 @@ class QuotaManagerImplTest : public testing::Test { int64_t quota_; int64_t total_space_; int64_t available_space_; - base::Optional<url::Origin> eviction_origin_; + absl::optional<url::Origin> eviction_origin_; std::set<url::Origin> modified_origins_; StorageType modified_origins_type_; QuotaTableEntries quota_entries_; - OriginInfoTableEntries origin_info_entries_; + BucketTableEntries bucket_entries_; QuotaSettings settings_; int status_callback_count_; @@ -617,6 +632,40 @@ TEST_F(QuotaManagerImplTest, GetUsageInfo) { } } +TEST_F(QuotaManagerImplTest, CreateBucket) { + url::Origin origin = ToOrigin("http://a.com/"); + std::string bucket_name = "BucketA"; + + CreateBucket(origin, bucket_name); + task_environment_.RunUntilIdle(); + ASSERT_TRUE(bucket_id_.ok()); + + // Try creating a bucket with the same name. + CreateBucket(origin, bucket_name); + task_environment_.RunUntilIdle(); + EXPECT_FALSE(bucket_id_.ok()); +} + +TEST_F(QuotaManagerImplTest, GetBucketId) { + url::Origin origin = ToOrigin("http://a.com/"); + std::string bucket_name = "BucketA"; + + CreateBucket(origin, bucket_name); + task_environment_.RunUntilIdle(); + ASSERT_TRUE(bucket_id_.ok()); + BucketId created_bucket_id = bucket_id_.value(); + + GetBucketId(origin, bucket_name); + task_environment_.RunUntilIdle(); + ASSERT_TRUE(bucket_id_.ok()); + BucketId retrieved_bucket_id = bucket_id_.value(); + EXPECT_EQ(created_bucket_id, retrieved_bucket_id); + + GetBucketId(origin, "BucketB"); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(bucket_id_.value().is_null()); +} + TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) { static const MockOriginData kData[] = { { "http://foo.com/", kTemp, 10 }, @@ -1680,22 +1729,22 @@ TEST_F(QuotaManagerImplTest, EvictOriginData) { int64_t predelete_host_pers = usage(); for (const MockOriginData& data : kData1) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } for (const MockOriginData& data : kData2) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } task_environment_.RunUntilIdle(); EvictOriginData(ToOrigin("http://foo.com/"), kTemp); task_environment_.RunUntilIdle(); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type == kTemp) EXPECT_NE(std::string("http://foo.com/"), entry.origin.GetURL().spec()); } @@ -1805,7 +1854,7 @@ TEST_F(QuotaManagerImplTest, EvictOriginDataWithDeletionError) { int64_t predelete_host_pers = usage(); for (const MockOriginData& data : kData) - NotifyStorageAccessed(url::Origin::Create(GURL(data.origin)), data.type); + NotifyStorageAccessed(ToOrigin(data.origin), data.type); task_environment_.RunUntilIdle(); client->AddOriginToErrorSet(ToOrigin("http://foo.com/"), kTemp); @@ -1817,11 +1866,11 @@ TEST_F(QuotaManagerImplTest, EvictOriginDataWithDeletionError) { EXPECT_EQ(QuotaStatusCode::kErrorInvalidModification, status()); } - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); bool found_origin_in_database = false; - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type == kTemp && entry.origin == ToOrigin("http://foo.com/")) { found_origin_in_database = true; break; @@ -1994,10 +2043,10 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultiple) { EXPECT_EQ(3, status_callback_count()); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type != kTemp) continue; @@ -2079,10 +2128,10 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultipleClientsDifferentTypes) { EXPECT_EQ(2, status_callback_count()); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type != kTemp) continue; @@ -2118,8 +2167,7 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultipleClientsDifferentTypes) { } TEST_F(QuotaManagerImplTest, DeleteOriginDataNoClients) { - DeleteOriginData(url::Origin::Create(GURL("http://foo.com/")), kTemp, - AllQuotaClientTypes()); + DeleteOriginData(ToOrigin("http://foo.com/"), kTemp, AllQuotaClientTypes()); task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); } @@ -2168,12 +2216,12 @@ TEST_F(QuotaManagerImplTest, DeleteOriginDataMultiple) { const int64_t predelete_bar_pers = usage(); for (const MockOriginData& data : kData1) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } for (const MockOriginData& data : kData2) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } task_environment_.RunUntilIdle(); @@ -2185,10 +2233,10 @@ TEST_F(QuotaManagerImplTest, DeleteOriginDataMultiple) { EXPECT_EQ(3, status_callback_count()); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type != kTemp) continue; @@ -2261,12 +2309,12 @@ TEST_F(QuotaManagerImplTest, DeleteOriginDataMultipleClientsDifferentTypes) { const int64_t predelete_bar_pers = usage(); for (const MockOriginData& data : kData1) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } for (const MockOriginData& data : kData2) { - quota_manager_impl()->NotifyStorageAccessed( - url::Origin::Create(GURL(data.origin)), data.type, base::Time::Now()); + quota_manager_impl()->NotifyStorageAccessed(ToOrigin(data.origin), + data.type, base::Time::Now()); } task_environment_.RunUntilIdle(); @@ -2277,10 +2325,10 @@ TEST_F(QuotaManagerImplTest, DeleteOriginDataMultipleClientsDifferentTypes) { EXPECT_EQ(2, status_callback_count()); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); - for (const auto& entry : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { if (entry.type != kPerm) continue; @@ -2517,10 +2565,9 @@ TEST_F(QuotaManagerImplTest, DumpQuotaTable) { task_environment_.RunUntilIdle(); const QuotaTableEntry kEntries[] = { - QuotaTableEntry("example1.com", kPerm, 1), - QuotaTableEntry("example2.com", kPerm, 20), - QuotaTableEntry("example3.com", kPerm, 300), - }; + {.host = "example1.com", .type = kPerm, .quota = 1}, + {.host = "example2.com", .type = kPerm, .quota = 20}, + {.host = "example3.com", .type = kPerm, .quota = 300}}; std::set<QuotaTableEntry> entries(kEntries, kEntries + base::size(kEntries)); for (const auto& quota_entry : quota_entries()) { @@ -2531,7 +2578,7 @@ TEST_F(QuotaManagerImplTest, DumpQuotaTable) { EXPECT_TRUE(entries.empty()); } -TEST_F(QuotaManagerImplTest, DumpOriginInfoTable) { +TEST_F(QuotaManagerImplTest, DumpBucketTable) { using std::make_pair; quota_manager_impl()->NotifyStorageAccessed(ToOrigin("http://example.com/"), @@ -2542,7 +2589,7 @@ TEST_F(QuotaManagerImplTest, DumpOriginInfoTable) { kPerm, base::Time::Now()); task_environment_.RunUntilIdle(); - DumpOriginInfoTable(); + DumpBucketTable(); task_environment_.RunUntilIdle(); using TypedOrigin = std::pair<GURL, StorageType>; @@ -2553,14 +2600,14 @@ TEST_F(QuotaManagerImplTest, DumpOriginInfoTable) { }; std::set<Entry> entries(kEntries, kEntries + base::size(kEntries)); - for (const auto& origin_info : origin_info_entries()) { + for (const auto& entry : bucket_entries()) { SCOPED_TRACE(testing::Message() - << "host = " << origin_info.origin << ", " - << "type = " << static_cast<int>(origin_info.type) << ", " - << "used_count = " << origin_info.used_count); - EXPECT_EQ(1u, entries.erase(make_pair( - make_pair(origin_info.origin.GetURL(), origin_info.type), - origin_info.used_count))); + << "host = " << entry.origin << ", " + << "type = " << static_cast<int>(entry.type) << ", " + << "use_count = " << entry.use_count); + EXPECT_EQ(1u, entries.erase( + make_pair(make_pair(entry.origin.GetURL(), entry.type), + entry.use_count))); } EXPECT_TRUE(entries.empty()); } @@ -2892,7 +2939,7 @@ TEST_F(QuotaManagerImplTest, OverrideQuotaForOrigin_Disable) { base::RunLoop run_loop3; handle2->OverrideQuotaForOrigin( - origin, base::nullopt, + origin, absl::nullopt, base::BindLambdaForTesting([&]() { run_loop3.Quit(); })); run_loop3.Run(); diff --git a/chromium/storage/browser/quota/quota_override_handle.cc b/chromium/storage/browser/quota/quota_override_handle.cc index 6ff4125c171..333387cd7fe 100644 --- a/chromium/storage/browser/quota/quota_override_handle.cc +++ b/chromium/storage/browser/quota/quota_override_handle.cc @@ -30,7 +30,7 @@ QuotaOverrideHandle::~QuotaOverrideHandle() { void QuotaOverrideHandle::OverrideQuotaForOrigin( url::Origin origin, - base::Optional<int64_t> quota_size, + absl::optional<int64_t> quota_size, base::OnceClosure callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!id_.has_value()) { @@ -50,7 +50,7 @@ void QuotaOverrideHandle::OverrideQuotaForOrigin( void QuotaOverrideHandle::DidGetOverrideHandleId(int id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!id_.has_value()); - id_ = base::make_optional(id); + id_ = absl::make_optional(id); for (auto& callback : override_callback_queue_) { std::move(callback).Run(); diff --git a/chromium/storage/browser/quota/quota_override_handle.h b/chromium/storage/browser/quota/quota_override_handle.h index 81f7ab9acbd..71531db7541 100644 --- a/chromium/storage/browser/quota/quota_override_handle.h +++ b/chromium/storage/browser/quota/quota_override_handle.h @@ -31,7 +31,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaOverrideHandle { QuotaOverrideHandle(const QuotaOverrideHandle&) = delete; void OverrideQuotaForOrigin(url::Origin origin, - base::Optional<int64_t> quota_size, + absl::optional<int64_t> quota_size, base::OnceClosure callback); private: @@ -43,7 +43,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaOverrideHandle { const scoped_refptr<QuotaManagerProxy> quota_manager_proxy_ GUARDED_BY_CONTEXT(sequence_checker_); - base::Optional<int> id_ GUARDED_BY_CONTEXT(sequence_checker_); + absl::optional<int> id_ GUARDED_BY_CONTEXT(sequence_checker_); std::vector<base::OnceClosure> override_callback_queue_ GUARDED_BY_CONTEXT(sequence_checker_); @@ -53,4 +53,4 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaOverrideHandle { } // namespace storage -#endif // STORAGE_BROWSER_QUOTA_QUOTA_OVERRIDE_HANDLE_ +#endif // STORAGE_BROWSER_QUOTA_QUOTA_OVERRIDE_HANDLE_H_ diff --git a/chromium/storage/browser/quota/quota_settings.cc b/chromium/storage/browser/quota/quota_settings.cc index ebc116cd60b..13958ce112c 100644 --- a/chromium/storage/browser/quota/quota_settings.cc +++ b/chromium/storage/browser/quota/quota_settings.cc @@ -53,7 +53,7 @@ QuotaSettings CalculateIncognitoDynamicSettings( return settings; } -base::Optional<QuotaSettings> CalculateNominalDynamicSettings( +absl::optional<QuotaSettings> CalculateNominalDynamicSettings( const base::FilePath& partition_path, bool is_incognito, QuotaDeviceInfoHelper* device_info_helper) { @@ -123,7 +123,7 @@ base::Optional<QuotaSettings> CalculateNominalDynamicSettings( int64_t total = device_info_helper->AmountOfTotalDiskSpace(partition_path); if (total == -1) { LOG(ERROR) << "Unable to compute QuotaSettings."; - return base::nullopt; + return absl::nullopt; } // Pool size calculated by ratio. diff --git a/chromium/storage/browser/quota/quota_settings.h b/chromium/storage/browser/quota/quota_settings.h index 971adebed31..d8fd5702fe0 100644 --- a/chromium/storage/browser/quota/quota_settings.h +++ b/chromium/storage/browser/quota/quota_settings.h @@ -6,14 +6,13 @@ #define STORAGE_BROWSER_QUOTA_QUOTA_SETTINGS_H_ #include <stdint.h> -#include <memory> #include "base/callback.h" #include "base/component_export.h" #include "base/files/file_path.h" -#include "base/optional.h" #include "base/time/time.h" #include "storage/browser/quota/quota_device_info_helper.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace storage { @@ -61,9 +60,9 @@ struct QuotaSettings { // Function type used to return the settings in response to a // GetQuotaSettingsFunc invocation. If the embedder cannot -// produce a settings values, base::nullopt can be returned. +// produce a settings values, absl::nullopt can be returned. using OptionalQuotaSettingsCallback = - base::OnceCallback<void(base::Optional<QuotaSettings>)>; + base::OnceCallback<void(absl::optional<QuotaSettings>)>; // Function type used to query the embedder about the quota manager settings. // This function is invoked on the UI thread. diff --git a/chromium/storage/browser/quota/quota_settings_unittest.cc b/chromium/storage/browser/quota/quota_settings_unittest.cc index a2b2a564f1c..ef2bf9a1c64 100644 --- a/chromium/storage/browser/quota/quota_settings_unittest.cc +++ b/chromium/storage/browser/quota/quota_settings_unittest.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/files/scoped_temp_dir.h" -#include "base/optional.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" @@ -17,6 +16,7 @@ #include "storage/browser/quota/quota_features.h" #include "storage/browser/quota/quota_settings.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/abseil-cpp/absl/types/optional.h" using ::testing::_; @@ -42,14 +42,14 @@ class QuotaSettingsTest : public testing::Test { void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); } // Synchronous proxy to GetNominalDynamicSettings(). - base::Optional<QuotaSettings> GetSettings( + absl::optional<QuotaSettings> GetSettings( bool is_incognito, QuotaDeviceInfoHelper* device_info_helper) { - base::Optional<QuotaSettings> quota_settings; + absl::optional<QuotaSettings> quota_settings; base::RunLoop run_loop; GetNominalDynamicSettings( profile_path(), is_incognito, device_info_helper, - base::BindLambdaForTesting([&](base::Optional<QuotaSettings> settings) { + base::BindLambdaForTesting([&](absl::optional<QuotaSettings> settings) { quota_settings = std::move(settings); run_loop.Quit(); })); @@ -79,7 +79,7 @@ class QuotaSettingsIncognitoTest : public QuotaSettingsTest { } void GetAndTestSettings(const int64_t physical_memory_amount) { - base::Optional<QuotaSettings> settings = + absl::optional<QuotaSettings> settings = GetSettings(true, &device_info_helper_); ASSERT_TRUE(settings.has_value()); EXPECT_LE( @@ -99,7 +99,7 @@ TEST_F(QuotaSettingsTest, Default) { ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_)) .WillByDefault(::testing::Return(2000)); - base::Optional<QuotaSettings> settings = + absl::optional<QuotaSettings> settings = GetSettings(false, &device_info_helper); ASSERT_TRUE(settings.has_value()); // 1600 = 2000 * default PoolSizeRatio (0.8) @@ -121,7 +121,7 @@ TEST_F(QuotaSettingsTest, FeatureParamsWithLargeFixedQuota) { ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_)) .WillByDefault(::testing::Return(2000)); - base::Optional<QuotaSettings> settings = + absl::optional<QuotaSettings> settings = GetSettings(false, &device_info_helper); ASSERT_TRUE(settings.has_value()); @@ -143,7 +143,7 @@ TEST_F(QuotaSettingsTest, FeatureParamsWithSmallFixedQuota) { ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_)) .WillByDefault(::testing::Return(2000)); - base::Optional<QuotaSettings> settings = + absl::optional<QuotaSettings> settings = GetSettings(false, &device_info_helper); ASSERT_TRUE(settings.has_value()); @@ -162,7 +162,7 @@ TEST_F(QuotaSettingsTest, FeatureParamsWithoutFixedQuota) { ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_)) .WillByDefault(::testing::Return(2000)); - base::Optional<QuotaSettings> settings = + absl::optional<QuotaSettings> settings = GetSettings(false, &device_info_helper); ASSERT_TRUE(settings.has_value()); diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc index 90034aadf3a..b9e36ed9b03 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc @@ -224,7 +224,7 @@ void QuotaTemporaryStorageEvictor::OnGotEvictionRoundInfo( } void QuotaTemporaryStorageEvictor::OnGotEvictionOrigin( - const base::Optional<url::Origin>& origin) { + const absl::optional<url::Origin>& origin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!origin.has_value()) { diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h index f2ccb09d5f4..7503ffd2ca6 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h @@ -14,9 +14,9 @@ #include "base/component_export.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/optional.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" namespace url { @@ -84,7 +84,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaTemporaryStorageEvictor { int64_t total_space, int64_t current_usage, bool current_usage_is_complete); - void OnGotEvictionOrigin(const base::Optional<url::Origin>& origin); + void OnGotEvictionOrigin(const absl::optional<url::Origin>& origin); void OnEvictionComplete(blink::mojom::QuotaStatusCode status); void OnEvictionRoundStarted(); diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc b/chromium/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc index a247b821386..4624ff1ca11 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc @@ -72,7 +72,7 @@ class MockQuotaEvictionHandler : public QuotaEvictionHandler { int64_t global_quota, GetOriginCallback callback) override { if (origin_order_.empty()) - std::move(callback).Run(base::nullopt); + std::move(callback).Run(absl::nullopt); else std::move(callback).Run(origin_order_.front()); } @@ -167,8 +167,8 @@ class QuotaTemporaryStorageEvictorTest : public testing::Test { } void TaskForRepeatedEvictionTest( - const std::pair<base::Optional<url::Origin>, int64_t>& origin_to_be_added, - const base::Optional<url::Origin>& origin_to_be_accessed, + const std::pair<absl::optional<url::Origin>, int64_t>& origin_to_be_added, + const absl::optional<url::Origin>& origin_to_be_accessed, int expected_usage_after_first, int expected_usage_after_second) { EXPECT_GE(4, num_get_usage_and_quota_for_eviction_); @@ -276,7 +276,7 @@ TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionTest) { base::BindRepeating( &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest, weak_factory_.GetWeakPtr(), - std::make_pair(ToOrigin("http://www.e.com"), e_size), base::nullopt, + std::make_pair(ToOrigin("http://www.e.com"), e_size), absl::nullopt, initial_total_size - d_size, initial_total_size - d_size + e_size - c_size)); EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage()); @@ -308,8 +308,8 @@ TEST_F(QuotaTemporaryStorageEvictorTest, RepeatedEvictionSkippedTest) { quota_eviction_handler()->set_task_for_get_usage_and_quota( base::BindRepeating( &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest, - weak_factory_.GetWeakPtr(), std::make_pair(base::nullopt, 0), - base::nullopt, initial_total_size - d_size, + weak_factory_.GetWeakPtr(), std::make_pair(absl::nullopt, 0), + absl::nullopt, initial_total_size - d_size, initial_total_size - d_size)); EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage()); // disable_timer_for_testing(); diff --git a/chromium/storage/browser/quota/special_storage_policy.h b/chromium/storage/browser/quota/special_storage_policy.h index 0b31aa0c134..bb81e51c990 100644 --- a/chromium/storage/browser/quota/special_storage_policy.h +++ b/chromium/storage/browser/quota/special_storage_policy.h @@ -5,9 +5,6 @@ #ifndef STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_ #define STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_ -#include <string> - -#include "base/callback_forward.h" #include "base/component_export.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" diff --git a/chromium/storage/common/database/DIR_METADATA b/chromium/storage/common/database/DIR_METADATA index f337a384213..67bdd01e3be 100644 --- a/chromium/storage/common/database/DIR_METADATA +++ b/chromium/storage/common/database/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>WebSQL" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/common/database/OWNERS b/chromium/storage/common/database/OWNERS deleted file mode 100644 index e69de29bb2d..00000000000 --- a/chromium/storage/common/database/OWNERS +++ /dev/null diff --git a/chromium/storage/common/file_system/DIR_METADATA b/chromium/storage/common/file_system/DIR_METADATA index e704db93ca3..a32478d8fb0 100644 --- a/chromium/storage/common/file_system/DIR_METADATA +++ b/chromium/storage/common/file_system/DIR_METADATA @@ -9,4 +9,3 @@ monorail { component: "Blink>Storage>FileSystem" } -team_email: "storage-dev@chromium.org"
\ No newline at end of file diff --git a/chromium/storage/common/file_system/file_system_util.cc b/chromium/storage/common/file_system/file_system_util.cc index 4b457f803cd..1dba5ce3c44 100644 --- a/chromium/storage/common/file_system/file_system_util.cc +++ b/chromium/storage/common/file_system/file_system_util.cc @@ -9,9 +9,9 @@ #include <algorithm> #include "base/check.h" +#include "base/containers/contains.h" #include "base/macros.h" #include "base/notreached.h" -#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" #include "build/build_config.h" |